Tommy D’s Sexy Blog

TagLine Here

PHP Tip, more on building web forms

Filed under: PHP Tips — Tommy D. at 10:10 am on Sunday, July 10, 2005

Sometimes when building web forms, you may need to collect multiple values for a single field. Perhaps you have a form which gives a list of common hobbies, and visitors can check all hobbies which interest them. But how do you get PHP to realize that the user has made multiple selections? All you need to do is append square brackets to the end of the field name in your HTML.

For example,
<input type=”checkbox” name=”hobbies[]” value=”Computers”>Computers
<input type=”checkbox” name=”hobbies[]” value=”Fishing”>Fishing
<input type=”checkbox” name=”hobbies[]” value=”Hiking”>Hiking

If a visitor selects all three checkboxes, when the form is posted, your script will have an array named $_POST[hobbies] which contains the three hobbies as its elements.

PHP Tip, using flush()

Filed under: PHP Tips — Tommy D. at 9:40 am on Saturday, July 9, 2005

You may have noticed that scripts which take a long time to execute often display nothing but a blank “loading” page in the web browser until they finish running. If you find yourself in this situation with a script you’ve written, it’s possible to make the script output incrementally. To do this, use the flush() command. flush() will force the script to send any data in the output buffer to the browser immediately, instead of waiting until execution terminates.

For example, suppose you have a newsletter with several thousand subscribers and because each message contains a unique unsubscription link, the mails must be sent to one recipient at a time. Unfortunately, your script takes upwards of 10 minutes to run, and you’re never sure how far along it is until the entire thing finishes. This can be solved by adding flush() into the loop, to print out a realtime status message after every 100 emails:

<?
$result = mysql_query(‘SELECT DISTINCT email FROM newsletter_subscribers’, $db);
while($myrow = mysql_fetch_array($result)){
$body = ” … body plus unsubscription link would go here … “;
mail($myrow[email], ‘This Month’s Newsletter’, $body, ‘From: newsletter@example.com’);
if($tick % 100 == 0){
echo “$tick messages have been sent…<br>”;
flush();
}
}
?>

Once you use flush() a few times, you’ll start finding more and more places where it comes in handy!

PHP Tip, “date math”

Filed under: PHP Tips — Tommy D. at 12:19 pm on Friday, July 8, 2005

Are you struggling with “date math?” If you’ve fallen into the trap of converting string-based timestamps into month, day, year, hour, minute, and second, and then trying to perform some sort of math or calculations based upon these values, consider storing timestamps in epoch format instead. Today’s tip is a bit longer than usual but you might find it worth the extra read!

“Epoch” time represents the number of seconds which have elapsed since midnight, January 1st, 1970 GMT. Because the format is based upon a value which has some meaning in terms of time – seconds – calculating time becomes a snap compared to calculating time with string values. As an example, suppose you currently store datestamps in string format, and you have an existing stamp, e.g. “2003-03-04 13:56:11.”

To find the date and time 8 hours after that stamp, you’d need something like this:

<?
$stamp = “2003-03-04 13:56:11″;
list($date, $time) = split(‘ ‘, $stamp);
list($year, $month, $day) = split(‘-’, $date);
list($hour, $minute, $second) = split(‘:’, $time);
#Add 8 hours
if(($hour + 8) <= 23){
$hour += 8;
#We got lucky!
die(“$year-$month-$day $hour:$minute:$second”);
}
else{
#A rather large amount of code would go here,
#determining whether it’s necessary to add
#a month and year, whether or not we’re dealing
#with a leap year, etc.
}
?>

If you’re doing things that way, you’re punishing yourself entirely too much. Here’s how it works using epoch stamps. Let’s start with the same time – 13:56:11 on March 3rd 2003 – and add 8 hours:

<?
$stamp = 1046807771;
echo date(“Y-m-d H:i:s”, $stamp + (3600 * 8));
?>

And there you have it, we know that 8 hours from our starting point would be 2003-03-04 21:56:11. No muss, no fuss, no bother. Another example, this one perhaps a bit more practical, is determining whether or not a specific event happened within a certain time period. Suppose your website tracks customer logins in a database, and automatically forces logins more than 24 hours old to expire. This, too, is easier with epoch:

<?
$lastlogin = 1046807771;
if($lastlogin < (time() – 86400)){
die(“Sorry, your login has expired!”);
}
?>

The time() function returns the current epoch timestamp. By comparing the last login stamp to the result of time() minus 86400 – the number of seconds in a day – we can determine whether or not the last login occurred more than 24 hours ago.

Aside from making date calculations simpler, there are three other advantages to using epoch time as opposed to string-based timestamps:

First, most (if not all) unix systems inherently support the epoch format and use it to track time internally; epoch time is often referred to as “unix time” for this reason.

Second, because epoch time is measured according to GMT, the integer representing the accurate epoch time is exactly the same everywhere in the world. This eliminates some timezone confusion and provides for more portability between different servers in different timezones. Of course, the current epoch time has different meaning in different time zones, our example of 1046807771 would have been 11:56 AM in the Pacific timezone and 2:56 PM on the east coast.

Finally, on some systems, an epoch time representation uses less storage space than a string-based one. Consider the difference in size between the integer 1046807771 and the string “2003-03-04 13:56:11.” In MySQL, an integer (such as an epoch value) takes only 4 bytes of storage[1], whereas a datetime value requires 8 bytes, and a timestamp stored as a varchar could require 15-20 bytes. Storing timestamps as integer(10) fields instead of datestamp or varchar fields in your database can save space.

[1] MySQL’s timestamp data type, which displays as YYYYMMDDHHMMSS, is stored as an epoch value and requires only 4 bytes as well. If all of your date math will be done within SQL queries, use the timestamp data type instead of storing epoch stamps in integer fields.

PHP Tip, using the uniqid() function

Filed under: PHP Tips — Tommy D. at 11:54 am on Thursday, July 7, 2005

If you have a need for a unique string, consider using PHP’s built in uniqid() function. uniqid() will return a string value based upon the current system time, comprised of both letters and numbers, such as “3e5f173a6d6ed.”

This can be useful in a number of situations:

– Creating unique order IDs
– Generating default passwords
– Naming temporary files

When you call uniqid(), you must pass a string argument, though an empty string (” or “”) is sufficient. If you pass a non-empty string, it will be prepended to the return value. For example,

$fp = fopen(‘/var/tmp/’ . uniqid(‘tmp’) . ‘.file’, ‘wb’);

…would create a resource handle to a file with a name such as “/var/tmp/tmp3e5f2151b0fd0.file.”

The string returned by uniqid() is unique to the microsecond at which it was generated. In other words, if two scripts on your server call uniqid() at the exact same microsecond, they may receive the exact same return value. However, because there are one million microseconds in a second, this degree of uniqueness is more than enough for most applications.

PHP Tip, using the rand() function

Filed under: PHP Tips — Tommy D. at 2:03 pm on Wednesday, July 6, 2005

Before using the rand() function, it’s a good idea to seed the random number generator first. This can be done with the srand() function. Its most common form is:

srand((double)microtime() * 1000000);

If you don’t take this step before using rand(), it’s possible – likely, even – that your “random” numbers will not necessarily be random.

PHP Tip, using fopen(), fread(), and fclose()

Filed under: PHP Tips — Tommy D. at 8:19 am on Tuesday, July 5, 2005

If you want to read the contents of a file into a variable, it is not necessary to use the fopen(), fread(), and fclose() commands. Instead, take advantage of PHP’s file() command, which will read a file into an array which is automatically split on newlines:

$text = file(“text.txt”);

If you’d rather have the file read into a string variable instead of an array, use the implode() command in conjunction with file() :

$text = implode(“”, file(“text.txt”));

Supposing that the file text.txt contains the following four lines:

This
is
a
test.

…the first example would create $text as an array with four elements, element [0] holding “This\n” and element [3] holding “test.” The second example would create $text as a string, holding the value “This\nis\na\ntest.”

PHP Tip, writing a MySQL query

Filed under: PHP Tips — Tommy D. at 12:32 pm on Monday, July 4, 2005

When writing a MySQL query, it is not necessary to use escaped double quotes (\”) when representing literal strings within the query. Single quotes (apostrophes) will work fine. For example, the following two lines of code will perform the same query:

$result = mysql_query(“SELECT foo FROM bar WHERE baz=\”test\”", $db);
$result = mysql_query(“SELECT foo FROM bar WHERE baz=’test’”, $db);

As will this code perform the same query:

$var = ‘test’;

$result = mysql_query(“SELECT foo FROM bar WHERE baz=’$var’”, $db);

There is not necessarily a performance gain between one method or the other, but using single quotes instead of escaped double quotes greatly improves the readability of your code.

PHP Tip, echoing text

Filed under: PHP Tips — Tommy D. at 11:35 am on Sunday, July 3, 2005

When echoing text or assigning variables, your script will execute faster if you use single quotes (apostrophes) instead of quotation marks around text which does not contain variables. For example, consider the following two statements:

echo ‘Hello, world, this is a test!’;

echo “Hello, world, this is a test!”;

Execution of the first statement will be faster than that of the second. When PHP sees a literal string surrounded by quotation marks (double quotes), it takes time to interpret the string and determine whether or not it must be expanded by replacing variable names with their contents. PHP does not perform this step when it encounters a literal string expressed within single quotes. Accordingly, strings surrounded with single quotes will not be expanded. In the following example,

$var = ‘good day’;

echo ‘Today is a $var!’;

…The result would be “Today is a $var,” as PHP would not replace the $var with “good day” in the single-quoted string.

Of course, the speed difference is negotiable; we’re talking milliseconds or even picoseconds worth of execution time for either statement on a fast server. However, the speed improvement in large scripts, e.g. those which contain several hundred or several thousand assignment or echo statements, can be noticeable.

PHP Tip, PHP & forms

Filed under: PHP Tips — Tommy D. at 12:31 pm on Saturday, July 2, 2005

When an HTML form is posted to a PHP script, PHP automatically converts periods in field names to underscores. For example, if you had form fields called “first.name” and “last.name” you would access them in PHP by using $_POST['first_name'] and $_POST['last_name'].

Attempting to use the field names with periods, e.g. $_POST['first.name'], will not work.

PHP Tip, using date()

Filed under: PHP Tips — Tommy D. at 12:14 pm on Friday, July 1, 2005

When using the date() function, keep in mind that you should use date(“i”) to obtain the minute. A great deal of code incorrectly uses date(“m”) for this, e.g.

$timenow = date(“H:m:s”); //incorrect

Passing “m” to the date() function will return the current month as a number from 1 to 12, not the current minute.