Archive for the 'PHP' Category

PHP Tag Cloud Remove Common Words

Friday, July 11th, 2008

If you have an application that allows a user to enter arbitrary tags for an entity, you might want to filter their tag input based on certain criteria. This tutorial assumes that you will be working with a space-separated list of tags, e.g. from a form input field. If your tag input is coming from an array, you can try $tags = implode(' ', $tag_array); to prepare it for the rest of the code presented here.

Firstly, we’ll cover the tag filter. A list of the most common English words was compiled by merging data from the following resources:
http://en.wikipedia.org/wiki/Most_common_words_in_English
http://www.askoxford.com/oec/mainpage/oec02/?view=uk
http://esl.about.com/library/vocabulary/bl1000_list1.htm
http://www.deafandblind.com/word_frequency.htm

We can look at the whole list later for reference, but to make an effective tag filter, many had to be removed by hand. Additionally, this script disregards words with less than three letters, so those were removed as well. Many search applications, including the one that inspired this coding, won’t mess with those. Here is a space-separated list of the common English-language words to be filtered:

able about after again all also and any are bad been before being between but came can cause change come could did differ different does don't down each end even every far few for form found four from get good great had has have her here him his how into its just keep let many may might more most much must near need never new next not now off one only other our out over part put said same say seem set should side some still such take than that the their them then there these they thing this three through too two upon use very was way went were what when where which while who will with would you your

Let’s use the following example for a space-separated tag string:

fluffy is freeze you Rocket don't cute boulder fry

The following PHP code will filter out the common words as well as words that contain less than three letters. It only pulls strings with alpha characters, and additionally converts all tags to lowercase:

$tag_filter = array('able', 'about', 'after', 'again', 'all', 'also', 'and', 'any', 'are', 'bad', 'been', 'before', 'being', 'between', 'but', 'came', 'can', 'cause', 'change', 'come', 'could', 'did', 'differ', 'different', 'does', 'don', 'down', 'each', 'end', 'even', 'every', 'far', 'few', 'for', 'form', 'found', 'four', 'from', 'get', 'good', 'great', 'had', 'has', 'have', 'her', 'here', 'him', 'his', 'how', 'into', 'its', 'just', 'keep', 'let', 'many', 'may', 'might', 'more', 'most', 'much', 'must', 'near', 'need', 'never', 'new', 'next', 'not', 'now', 'off', 'one', 'only', 'other', 'our', 'out', 'over', 'part', 'put', 'said', 'same', 'say', 'seem', 'set', 'should', 'side', 'some', 'still', 'such', 'take', 'than', 'that', 'the', 'their', 'them', 'then', 'there', 'these', 'they', 'thing', 'this', 'three', 'through', 'too', 'two', 'upon', 'use', 'very', 'was', 'way', 'went', 'were', 'what', 'when', 'where', 'which', 'while', 'who', 'will', 'with', 'would', 'you', 'your', );

$tags = 'fluffy is freeze you rocket don\'t cute boulder fry';
preg_match_all('/([a-zA-Z]{3,})/', $tags, $matches);
$matches[0] = array_map('strtolower', $matches[0]);
$tags = array_diff($matches[0], $tag_filter);

The $tags array would then be filtered and lowercased, producing the following output with print_r($tags):

Array
(
    [0] => fluffy
    [1] => freeze
    [3] => rocket
    [5] => cute
    [6] => boulder
    [7] => fry
)

If you need to convert it from the array back to a space-separated string, try $tags = implode(' ', $tags);. You may also of course add more words to the word list — that could come in handy with other application-specific functions such as cursing filters.

Here is the full list of common words merged from the above-stated resources, separated by spaces, including those with less than three letters:

a able about act add after again air all also am an and animal answer any are as ask at back bad be been before being between big boy build but by call came can case cause change child city close come company could country cover cross day did differ different do does don't down draw each early earth end even every eye fact far farm father feel few find first follow food for form found four from get give go good government great group grow had hand hard has have he head help her here high him his home hot house how i if important in into is it its just keep kind know land large last late learn leave left let life light like line little live long look low made make man many may me mean men might more most mother move mr mrs much must my name near need never new next night no north not now number of off office old on one only or other our out over own page part people person picture place plant play point port press problem public put read real right round run said same saw say school sea see seem self sentence set she should show side small so some sound spell stand start state still story study such sun take tell than that the their them then there these they thing think this thought three through time to too tree try turn two under up upon us use very want was water way we week well went were what when where which while who why will with woman word work world would write year you young your

.htaccess Add Trailing Slash to URL

Friday, January 11th, 2008

If you are rewriting your URLs using .htaccess and mod_rewrite, you might run into a problem where trailing slashes are ignored.

Here is an example scenario. Say you have PHP script that takes query arguments like this (replace example.org with your domain, of course):

http://example.org/index.php?page=content&title=welcome

You are rewriting it to look like this:

http://example.org/content/welcome/

For reference, here’s an example .htaccess script that would do that (there are plenty of other ways, this is one basic example):

RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/$ /index.php?page=$1&title=$2 [QSA,L]

And here is the problem with that! If you try a URL like this (without the trailing slash):

http://example.org/content/welcome

404! OH NOES!!

So, one alternative is to change the .htaccess directive to look like this:

RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ /index.php?page=$1&title=$2 [QSA,L]

So now both of these URLs work!

http://example.org/content/welcome/, AND
http://example.org/content/welcome

BUT WAIT! Trailing slashes are prettier, and we don’t want two separate URLs for the same content! Google doesn’t even like that! OOOH NOOOES!!

How to force a trailing slash in the URL:

  • Make your rewrites require the trailing slash, as with the first example:
    RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/$ /index.php?page=$1&title=$2 [QSA,L]
  • Add this code below your regular rewrites:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
    RewriteRule (.*)$ http://example.org/$1/ [R=301,L]

Note: This should work no matter how your application handles URLs. Some applications, however, such as WordPress, pull in the entire URL query regardless of slashes. If your application inherently does not care about trailing slashes in its RewriteRules, then you must put these directives before your other rewrites. The reason for that is because if it goes after them, then the application’s own RewriteRule will go into effect, accepting the URL without the trailing slash, and will likely ignore any subsequent rules (because of the [L] flag). The reason I suggest in this tutorial to put the script after your normal rewrites is for optimization and that can only apply when your normal rewrites require a trailing slash. If the URL has a trailing slash, as is the desired scenario, then it should go ahead and apply the rules and not even bother looking at the redirection directive.

Another point to keep in mind is that this script will redirect and add a trailing slash even for bogus URLs. E.g. - if you type this hypothetical non-existent URL into the address bar:

http://example.org/garhtrehstreetreetree

It is going to rewrite and forward it to the following URL with a trailing slash:

http://example.org/garhtrehstreetreetree/

Before displaying the expected 404 error. Note that this is not typical behaviour of Apache server. However; I do not consider this quirk to be a big deal at all, and I believe that it is unavoidable since we are handling this with .htaccess.

Explanation of the directives and regular expressions:

The two RewriteCond lines test to make sure the requested filename is not an actual file or directory, respectively. This makes sense because we’re rewriting URLs here; the requested URLs are not actual files, they are references to actual files and query arguments.

The regular expression in the third RewriteCond does two things. It checks to make sure the requested “filename” does not have an extension. If for whatever reason it has an extension, then we probably don’t want to add a trailing slash! Note: This expression considers an extension anything that has a period followed by between 1 and 5 letters and numbers. That covers your .js and your .phtml, at least. Feel free to change the 1 and 5 to suit your application. The other thing the third RewriteCond does is make sure that the URL doesn’t already have a trailing slash. If it didn’t do that check, the redirect could attempt to loop forever and that’s annoying!

The last line, the RewriteRule, will capture the entire URL path. It then does a 301 redirect to the same URL path with a trailing slash appended.

IMPORTANT UPDATE (IMPORTANT UPDATE TO IMPORTANT UPDATE: IMPORTANT UPDATE NOW IRRELEVANT — SEE EVEN MORE IMPORTANT UPDATE): It appears that some configurations do not support lookaheads in regular expressions! I have a strong suspicion but do not know for sure that the issue is the Apache version. This tutorial should work fine for Apache 2, and may not work for Apache 1.3. That, specifically, was the case with the configurations I tested. Here is an alternative route if you are getting internal server errors with the original method:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)([^/])$ http://example.org/$1$2/ [R=301,L]

I do not think it is as pretty, but ya gotta do what ya gotta do!

EVEN MORE IMPORTANT UPDATE: After browsing the web for a minute, I came across another site that has a similar (but different) tutorial. After looking at the example therein, I metaphorically smacked my forehead and realized that a very small part of the original example (specifically, the lookahead ((?!/)) part) was not necessary, and it now works on all tested servers. The tutorial has been updated to reflect this change and is now even prettier than it was before. Thank you other person, I feel dumb now and hats off to you.

Working with server time in JavaScript (and PHP)

Friday, August 31st, 2007

Dealing with timezone offsets can be frustrating in any coding environment. It’s pretty easy to get the server time into the client side JavaScript using PHP. The following code will create a JavaScript Date object that holds the current server date/time:

<script type="text/javascript">
var dateServer = new Date('<?= date('F d, Y H:i:s') ?>');
<script type="text/javascript">

Once that’s done you can work with the dateServer Date object and it will reflect the server’s local date/time. However, what if I need to calculate the date multiple times on-the-fly (e.g. - from within in a loop)? That might come in handy for things like timer scripts. We’ll first need to know the offset between the server time and local time:

<script type="text/javascript">
var dateLocal  = new Date();
var dateServer = new Date('<?= date('F d, Y H:i:s') ?>');
var dateOffset = dateServer - dateLocal;
<script type="text/javascript">

dateOffset now holds the offset in milliseconds. Here’s how to make use of the offset for future JavaScript Date object instances:

<script type="text/javascript">
var dateLocal  = new Date();
var dateServer = new Date('<?= date('F d, Y H:i:s') ?>');
var dateOffset = dateServer - dateLocal;

var newDate = new Date();
newDate.setTime(newDate.getTime() + dateOffset);
<script type="text/javascript">

That’s it! The newDate variable now holds the server time using the calculated offset from the previous PHP date() call.

UPDATE: I have created an example script that illustrates its use in a recursive clock function. As a side note, the setTimeout() JavaScript function produced much better results than setInterval() for this particular application. setInterval() was causing it to skip seconds for some reason, possibly something to do with this computer being bogged down with processes. At any rate, while setInterval() looks cleaner and more elegant, it looks like setTimeout() is the ideal route for a live timer or clock script.

Output Spacer Using PHP

Thursday, August 4th, 2005

Here’s a neat way to output a spacer image using PHP. I would assume that it is faster that using imagecreatefrompng(), imagepng(), and other image functions. The reason that I like using it is just because it takes fewer lines of code. The following was coded by myself, though inspired from another script, which I couldn’t find :-/. It is great for scripts that deal with outputting images; If an error occurs, just output a spacer using this code.

header("Content-type: image/png");
echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABnRSTlMA/wD/AP83WBt9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAADElEQVR42mP4//8/AAX+Av4zEpUUAAAAAElFTkSuQmCC');

Checking Whether PHP is in Module Mode or CGI

Saturday, July 9th, 2005

It can be handy to know whether your web server is running PHP as an Apache Module or CGI. Sometimes that simple factor can be the root of major headaches when trying to get to the root of a problem with a script. When file permissions become a problem, or keys in the $_SERVER superglobal are returning unexpected result, this is a good place to start debugging.

Finding out whether PHP is being run as a module or CGI is not terribly difficult. Here is one way to find out.

First, create a new PHP file with the following lines of code:

<?php
phpinfo();
?>

Save it to your webserver, and run the script. Look for the line near the top that says “Server API.” If it has “CGI” for the server API then you are in CGI mode, and if it has something similar to “Apache Handler” then you are in module mode. That’s it!

BEST Way to Integrate eSPG into Wordpress

Monday, June 20th, 2005

There are a few sites out there with instructions on integrating Enhanced Simple PHP Gallery into Wordpress. The method I am going to describe, however, is the best. One key feature of this method that sets it apart is that it makes use of the TITLE tag. Another feature is that when you change the theme of Wordpress, it will change in your eSPG installation as well. It also makes use of the add_filter function in Wordpress to dynamically add the necessary code to the HTML HEAD. Here’s how it’s done:

Make a backup of header.php in your eSPG installation directory. Then, replace its contents with the contents of this file.

Then, make a backup of footer.php. Replace the contents of footer.php with the contents of this file:

You will need to edit sp_styles.css to match your theme. If you do not want to include the sidebar, there are a few more steps involved. If you are interested, leave a comment on here and I will add the steps to this post. Also leave a comment if there are any questions; I will probably end up opening a forum thread for this. As always, please let me know if you use this!

Calculate Age from Birthday with PHP

Monday, June 13th, 2005

So I just whipped up a PHP function that takes a birthdate and outputs an age in years. Here’s the code:

function age_from_birthdate($month, $day, $year) {
return floor((mktime(0, 0, 0) - mktime(0, 0, 0, $month, $day, $year)) / 31556952);
}

It doesn’t specifically take leap years into account, but it compensates by using the average number of days in the Gregorian calendar, 365.2425. It has been tested a little, and seems to be pretty accurate. Of course, it’s not perfect. It doesn’t take the time of day into account either, it just sets the time to midnight. To me, those things are not a huge deal. I am currently using this function on the about page. Please let me know if you find any problems with it. Feel free to use this function in your application. It would be neat to know if you use it, so please let me know!

EXIF Data for Simple PHP Gallery!

Wednesday, April 20th, 2005

I finally got around to adding some EXIF functionality to the photo gallery. It turned out that I could not do my own custom solution because some functions were not available to me. However, I found a neat PHP application called The PHP JPEG Metadata Toolkit that helped do the trick. When you are looking through the gallery, if you go to a specific photo you will notice a new link that says “EXIF Data.” The link will open in a new window, and it shows you all of the EXIF data contained within the image. This way you can see what camera settings I used to take the pictures, as well as some other info.

Jam Session

Sunday, February 27th, 2005

Charlie Page, Billy Waddell, and myself are havin a lil jam session. Charlie on guitar, Billy on “string” :-), and me on drum kit… I’ll be postin’ some more mp3s soon! Also, I wrote a little PHP/.htaccess script that dynamically generates a playlist file to allow an MP3 to stream to the browser… Hopefully no one comes by here that actually knows how easy that actually is when it comes down to it … So, this post is doubling as the testing ground for the new script! The files won’t play for you? Leave a comment, lemmie know!

the first rehearsal: check it.
roadhouse blues!!: check it.
(i actually added a little singin track, it’s really quiet and crappy… but it’s mostly there as a feeble attempt to keep people interested that aren’t so much into instrumental music)

Hey i found some more MP3s! These are in less stream-friendly bitrates than the first ones, so they may not be for the faint-of-bandwidth. Then again, they might work fine! Only one way to find out, do it do it do it!!!

Marcus Pendergrass on keys, myself on kit (”yesyou” is not the real name of the song, I don’t even know if it is a real song… We were messing around): check it.

I have had the privilege of working with the community theater in town on a few productions. One that I participated in is called “Murder at Rutherford House.” It was a fun dinner theater and most of the cast got to do a radio spot! check it.

PHP Security Troubles

Tuesday, February 22nd, 2005

Eek!! While trying to install a spell checker, I’m getting weird PHP security errors:

Warning: Cannot execute using backquotes for security reasons in /home /[path] /wp-content /spell-plugin /spellchecker.php on line 97

error = 'System error: Aspell program execution failed (`/usr/bin/aspell -a --lang=en_US --personal= /home /[path] /wp-content /spell-plugin /aspell.personal < /home /.raggs /jam_dan /soulpass.com /wp-content /spell-plugin /aspell_data_jDnEzd 2>&1`)';

I’ve researched the problem and found little tidbits of helpful info, but nothing too solid or exact. C’mon now, I get on the computer to escape stress, and this isn’t helping! hehh… *sigh*