Archive for the ‘PHP’ Category.

PHP Lorem Ipsum Generator

For the most up-to-date information regarding this script go to the PHP Lorem Ipsum page in the scripts section.

The other day I needed to populate a database with some placeholder content. Doing this manually was out of the question so I decided I’d find a text generator, specifically a Lorem Ipsum generator. For anyone unaware, Lorem Ipsum is non-sense, placeholder text used in publishing and design. It allows the developer to see their work completely populated with text, without having to actually create the text. Obviously, for this purpose, any kind of text generator would work to some extent, but traditionally Lorem Ipsum is used.

To get to the point, I successfully located several web-based generators, but no stand-alone PHP class or function. To be honest, I didn’t look too hard and someone a little more determined not to write any code most likely would have found it, but I decided to create my own PHP Lorem Ipsum generator. Here is a rundown of some of the features in the current version:

PHP Lorem Ipsum Generator
Version: 1.0
License: BSD

Download:
Link moved Here.

Features

  • Generates content in three modes: Plain, HTML (content blocks nested in <p> tags), and Text (plain text in paragraph form)
  • Sentences are punctuated and vary in length based on statistics collected here: http://hearle.nahoo.net/Academic/Maths/Sentence.html. Sentence length will vary on a Guassian distribution.
  • HTML output is ‘clean-code’ formatted with tabs and new lines rather than just blobs of code
  • More output formats to come…

Feel free to request additional features.

Usage

The only public method in the class is getContent.

Description
string getContent( int $wordCount [, string $format = html] [, boolean $loremipsum = true] )

Returns the desired amount of content as a string.

Parameters

wordCount
The number of words to be returned.

format
The output mode, one of ‘html’, ‘txt’, or ‘plain’. HTML by default.

  • HTML: The content is divided into paragraphs, using the paragraph ( <p></p> ) tag.
  • Text: The content is divided into paragraphs with the leading line of each paragraph tabbed
  • Plain: The content is returned unformatted

loremipsum
Whether or not the content should begin with ‘Lorem ipsum’. True by default.

Example

require('LoremIpsum.class.php');

$generator = new LoremIpsumGenerator;

//100 words in html format
$generator->getContent(100);

//100 words without any formatting
$generator->getContent(100, 'plain');

//100 words with 'text' formatting
$generator->getContent(100, 'txt');

//100 words with html format, not beginning with lorem ipsum
$generator->getContent(100, NULL, false);

//or
$generator->getContent(100, 'html', false);

Additional Notes
Both the HTML and Text output modes use paragraph formatting. The mean word count of each paragraph is predetermined and can be set in the constructor, currently the default is 100. Note that this is the mean word count, the actual word count for each paragraph will vary in the same way the length of each sentence will vary.

Changelog
Version 1.1 (Planned)

  • Additional output modes. List mode and possibly more

Version 1.0:

  • Initial Release

PHP: Complex Variables in Strings

If you are at all familiar with PHP you are probably aware that you can put variables inside double quotes. For example:

$x = 5;
echo "x is equal to $x";

The above code will output “x is equal to 5″. This method works fine with simple variables, but will fail with references to member variables of objects or arrays:

//will not work
echo "x is equal to $myObject->x";

//also won't work
echo "x is equal to $myArra['x']";

To avoid this problem, PHP allows you to use curly braces to seperate variables that need to be parsed:

//will work
echo "x is equal to {$myObject->x}";

This is also useful in situations where you want to output a variable in the middle of a word:

//will not work
$birthday = 16;
echo "My birthday is on the $birthdayth";

//will work
echo "My birthday is on the {$birthday}th";

Note that { cannot be escaped in a string. If { is followed by $ PHP will assume that you want to parse a variable. To get the literal {$ you must escape it like this:

echo "Curly brace followed by dollar sign: {\$";

//will output
//Curly brace followed by dollar sign: {$

Strings and Output in PHP

I’ve seen a lot of questions and false assumptions regarding strings and output. Here is a short review of some common questions:

print vs. echo

I often see people suggesting that others should use echo as opposed to print for performance reasons. While it is true that echo is faster than print, the difference is insignificant. The reason echo is faster is because print behaves like a function (even though it’s a language construct) and sets a return value. This being the case, there are some important differences between the two, and there are a few cases where you have to use print in place of echo.

As I mentioned, print behaves like a function. You can use it just as any other funciton call and it has a return value (always 1). Like print, echo is also a language contruct, but does not behave like a function. Here are some cases where print must be used in place of echo:

$b ? print "true" : print "false";
//with echo
function isOne($x)
{
	if($x == 1)
	{
		echo $x . ' = 1';
		return true;
	}
	else
	{
		echo $x . ' != 1';
		return false;
	}
}

//with print
function isOne($x)
{
	if($x == 1)
		return print($x . ' = 1');
	else
		return !print($x . ' != 1');
}

In the print implementation of isOne the speed difference between echo and print is negated.

Concatenated strings Vs. Multiple calls to echo

Is it faster to concatenate all of your output into a single string and then output it or is it faster to output your strings as you go? The answer is the former; concatenating strings is faster than doing output. Does this mean that you should cram all of your output into one string and output it at the end of your script? Not necessarily. Like the performance difference between print and echo, the performance difference here is almost always negligible. Use which ever method makes sense at the time. You should prefer to concatenate your output, but sometimes ‘output as you go’ makes for cleaner code which is more important in this case.

Double vs. Single quotes

PHP provides two different ways to encase strings: Double quotes and single quotes. There is an important difference between the two. If your string is encased in double quotes, you can place variables with in it like so:

$x = 5;

echo "x is equal to $x";

What this means is that PHP must parse the string, looking for any variables. Single quotes on the other hand are never parsed, meaning that if your string contains no variables it is preferable to use single quotes. Similar to the previous examples, the performance difference is minor; however, using double quotes for no apparent reason is just wasting runtime. Here are some good reasons to use double quotes:

$x = 5;
//your string contains a variable
echo "x = $x";
//your string contains single quotes
echo "Matt said, 'peanut butter is awesome'";

In the second case, it would be faster to escape your single quotes using \ but the performance difference is minor and using double quotes looks cleaner.

Output without echo (or print)

Print and echo are not the only ways to do output. At any point in your code you can close your PHP tags and start doing output as if it were normal HTML:

<?php
for($i = 0; $i < 10; $i++)
{
	?>
	<p>Hello</p>
	<?php
}
?>

This will output Hello, nested in paragraph tags, ten times. This method is useful when you have a large amount of output that you don’t want to have to worry about nesting in quotes. Personally, when using this method, I prefer to use PHP’s alternate control flow syntax:

<?php if($x == 10) : ?>
	<div>X is equal to 10</div>
<?php else : ?>
	<div>X is not equal to 10</div>
<?php endif; ?>

You can use this syntax with all of PHP’s control flow statements (ie while, if, for, foreach, switch, etc…).

Output Buffering

What should you do if you have a large string that needs to be manipulated? Normally if you had a very large string, such as a block of HTML, you could use the method I just described, however, doing it like that would output the string immediately. Using quotes is clumsy and unnecessary. The answer is to use an output buffer:

<?php
ob_start(); //start the output buffer
?>
<div>My Website</div>
<p>This is my website where I write about stuff and junk. Enjoy!<p>
<div class="footer">copyright 2009 tinsology.net</div>
<?php
$output = ob_get_clean();
echo str_replace('2009', '2010', $output);
?>

In the above example, ob_start() starts the output buffer. From this point on, any output, including output from print and echo, will be stored in the buffer. ob_get_clean() returns the output as a string and deletes the buffer content. PHP’s output control functions contain some very useful functionality, I highly recommend that you read the documentation carefully: PHP output control functions

Strings Are Arrays

I’ve seen a lot of people asking questions about how to find a certain character or sequence inside a string. It is common for people to turn to the library in order to find a function that does this for them, but it is likely the case that the answer is right in front of you. If you need to search thorough a string for whatever reason you can index it as an array. This is the case in a lot of language (PHP, C++, Java).

In a non-type-safe language like PHP people often forget the distinction between primitive types and other constructs. Primitives are often things like int, float, double, long, and char. Strings are generally not a primitive type but an array of chars. Most languages tend to hide this fact from you, because strings are so common it is often more convenient for the programmer to deal with them as if they were not an array of characters.  For example, Java does not support operator overloading; you can only use arithmetic operators (+, -, *) on primitive types, with the exception of strings, which can be appended using the + operator.

So how can you use this fact to your advantage? There are many cases where indexing strings rather than passing them to some function can serve your purpose more efficiently. Here are some examples in PHP:

Ex.
You have several lines of text and you want to count the instances of a particular word. One way to do this would be to use explode to turn the text into an array of words and then count the instances of that word:

$text = 'cat dog chicken cat bird mouse cat lizard';
$words = explode(' ' , $text);
$count = 0;
foreach($words as $word)
{
     if($word == 'cat')
          $count++;
}
echo $count; //should output 3

One function call and one loop, pretty simple right? Maybe not. It is important to remember that function calls may a lot more than they appear. In order to split the string into an array of words, explode must search through the string for a space. If all you need to do is count the number of instances of a word, there is no need to waste time constructing an array of words and then looping through that array. Here is a more efficient way:

$curr = '';
$count = 0;
$searchStr = 'cat';
$text = 'cat dog chicken cat bird mouse cat lizard';
$len = strlen($text);

for($i = 0; $i < $len; $i++)
{
     if($text[$i] == ' ')
     {
          if($curr == $searchStr)
               $count++;

          $curr = '';
     }
     else
          $curr .= $text[$i];
}

The above example contains several more lines of code, but it is important to remember that the number of lines in a program should not be used to measure the performance of a program.

Short Tags

The standard opening tag for php is <?php, however there are two alternative opening tags:

<? – short for <?php
<?= – short for <?php echo

Although they may be convenient, you should never use these tags. The main reason I don’t use them is because short tags can be disabled in the php.ini, so if your application relies on them, it will fail when this feature is disabled. Recently a couple of short tags crept into (by my own mistake) one of my applications and a user reported he was getting a parse error on the last line of code in the file. After looking over the code several times I replaced the short tags with the longer version and all was well.

If you are writing portable applications I recommend that you disable short tags in your own php.ini, so in the case that you place one by mistake (as I did) you will get the error message instead of one of your users reporting it weeks later.

Plugin Compatibility

For various reasons, there are some people out that who have chosen to hang onto older versions of WordPress. Personally I do not recommend this behavior, but as a plugin developer, you might not want to exclude these people from using your plugin. Does this mean you should refrain from using features that were implemented in later versions for the benefit of those who have not upgraded? Absolutely not. One thing you can do, however, is to emulate or implement the newer features your plugin relies on for older versions.

This is actually very simple to do considering you can simply take the code directly from the latest version of WordPress. In order to do this properly, you should make use of PHP’s function_exists function. For example: the function admin_url was not part of WordPress until version 2.6. Normally, if you were to use this function, users with older version of WordPress would not be able to use it. You can, however, define it yourself:

if(!function_exists('admin_url'))
{
	function admin_url($path = '') {
	$url = site_url('wp-admin/', 'admin');

	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
		$url .= ltrim($path, '/');

	return $url;
	}
}

Notice that the function declaration is inside the if(!function_exists(‘admin_url’)) block. If you simply defined the function as you normally would users with WordPress 2.6+ would receive an error.

Another thing to notice is that the code for admin_url contains a call to a function site_url. This function also was not defined until WordPress 2.6 so you’ll have to do the same thing for this function. For some functions it will be the case that you will have to do this for many functions, and in some cases you won’t be able to do this at all due to more significant differences between older and newer versions.

Here is a file I’m using called compat.php that defines several functions and constants that do not exist in earlier versions of WordPress.

//These functions replicate WordPress functionality
//Used in cases where a WordPress function is not
//available (ie a version that does not have that function)
if(!function_exists('is_ssl'))
{
	function is_ssl() {
		return ( isset($_SERVER['HTTPS']) && 'on' == strtolower($_SERVER['HTTPS']) ) ? true : false;
	}
}

if(!function_exists('force_ssl_admin'))
{
	function force_ssl_admin($force = '') {
		static $forced;

		if ( '' != $force ) {
			$old_forced = $forced;
			$forced = $force;
			return $old_forced;
		}

		return $forced;
	}
}

if(!function_exists('force_ssl_login'))
{
	function force_ssl_login($force = '') {
		static $forced;

		if ( '' != $force ) {
			$old_forced = $forced;
			$forced = $force;
			return $old_forced;
		}

		return $forced;
	}
}

if(!function_exists('site_url'))
{
	function site_url($path = '', $scheme = null) {
	// should the list of allowed schemes be maintained elsewhere?
	$orig_scheme = $scheme;
	if ( !in_array($scheme, array('http', 'https')) ) {
		if ( ('login_post' == $scheme) && ( force_ssl_login() || force_ssl_admin() ) )
			$scheme = 'https';
		elseif ( ('login' == $scheme) && ( force_ssl_admin() ) )
			$scheme = 'https';
		elseif ( ('admin' == $scheme) && force_ssl_admin() )
			$scheme = 'https';
		else
			$scheme = ( is_ssl() ? 'https' : 'http' );
	}

	$url = str_replace( 'http://', "{$scheme}://", get_option('siteurl') );

	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
		$url .= '/' . ltrim($path, '/');

	return apply_filters('site_url', $url, $path, $orig_scheme);
	}
}

if(!function_exists('admin_url'))
{
	function admin_url($path = '') {
	$url = site_url('wp-admin/', 'admin');

	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
		$url .= ltrim($path, '/');

	return $url;
	}
}

if ( !defined('WP_CONTENT_URL') )
	define( 'WP_CONTENT_URL', get_option('siteurl') . '/wp-content'); // full url - WP_CONTENT_DIR is defined further up

if ( !defined('WP_PLUGIN_URL') )
	define( 'WP_PLUGIN_URL', WP_CONTENT_URL . '/plugins' );

if(!function_exists('plugins_url'))
{
	function plugins_url($path = '')
	{
	$scheme = ( is_ssl() ? 'https' : 'http' );
	$url = WP_PLUGIN_URL;
	if ( 0 === strpos($url, 'http') ) {
		if ( is_ssl() )
			$url = str_replace( 'http://', "{$scheme}://", $url );
	}

	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
		$url .= '/' . ltrim($path, '/');

	return $url;
	}
}

PHP IMAP Notes

Previously I wrote about using PHP’s IMAP functions. Now I’d like to provide a more detailed, and less wordy, overview of some of the more common IMAP functions. Enjoy!

imap_open

imap_open opens a connection to the specified mailbox. It takes up to 5 parameters:

Mailbox:
This is the address and port of the mail server you are connecting to. Typically this parameter will look like one of the following:

  • mail.domain.net:143
  • localhost
  • 127.0.0.1:110

The port number is optional, but it is much more efficient if one is provided. The default IMAP port is 143 and POP3 is 110

Username
Typically the email address you are trying to access mail from, but not necessarily.

Password
The password corresponding to the username

Options
The options, or flags, modify your connection stream. The default is /imap but I’ve found that /imap/novalidate-cert is often necessary. If you are trying to connect using POP3 you’ll have to set this to /pop3.

Retries
The number of connection retries. If your mail server limits the number of connection attempts it is important that this value be set to 0, otherwise you may lock yourself out of your account.

Don’t forget to close the connection stream using imap_close($mailbox) where mailbox is the connection stream you opened with imap_open.

imap_fetch_overview

imap_fetch_overview returns an overview of one or more emails. This function Always returns an array, even if only a single message is specified.

imap_stream
A connection stream created with imap_open

message id or sequence
imap_fetch_overview takes either a single message id, or a sequence formatted as x:y (ex. 1:5 will return message 1 through 5 inclusive).

Options
This parameter must be set to FT_UID if the sequence parameter is a sequence of UIDs rather than message ids. Using UIDs is often preferable to message ids because message ids are not guaranteed to remain the same. Some functions however, require that you use message ids.

This function returns a lot of useful information about a particular email. Read the function documentation for a full list. While this function does return to and from headers, it does not return the cc and bcc headers. You will have to use imap_headerinfo to obtain these. Note that imap_headerinfo cannot take a UID as a message parameter, you’ll have to use message ids.

imap_check

This function returns information about the specified mailbox. Most likely if you are using this function, you are using it to obtain the number of messages in the mailbox.

Setting and Unsetting Message Flags

Each message in a mailbox has a set of flags, probably the most interesting one is the SEEN flag. The seen flag indicates if the email has been opened or read. Usually this flag is set when using the imap_body function to obtain the body of a message. If you want to mark an email as seen you can use imap_setflag_full. To set the email as unread, use imap_clearflag_full to unset the SEEN flag.

Deleting Emails

The imap_delete flags an email for deletion. This function is really a shortcut for calling imap_setflag_full with the deleted flag. Likewise, imap_undelete is a shortcut for calling imap_clearflag_full with the deleted flag. Note that these functions do not actually delete the message. In order to delete the message you must either call imap_expunge or imap_close with the optional flag CL_EXPUNGE.

Searching the mailbox

The imap_search function is great for emails that meet a certain criteria. Personally I use this function mostly to find unopened emails.

PHP Error Handling

Previously I wrote about Exceptions as a way of dealing with error cases in PHP. Exceptions are a great way to anticipate errors and handle them appropriately. Unfortunately, however, it is not possible to anticipate every error and you users still might be presented with an ugly error message generated by PHP. One way to prevent users from seeing warnings or errors generated by PHP is to turn off error reporting. The down side to using this method is that you might not be aware that an error is occuring, and you’ll be even less aware of the details of that error.

A better solution would be to use a custom error handler. PHP provides you with a function that allows you to override the default error handler called set_error_handler. This function takes as input a callback, which is your custom error handling function. Once you call set_error_handler, PHP will no longer report errors as it normally would and instead pass those errors to your function. The function you define must take at least two inputs: error number, and error message, and optionally three additional parameters: error file, error line, and error context. I’ll go into more detail about this later, lets define our function:

set_error_handler('customHandler');

function customHandler($eNum, $eMsg, $eFile, $eLine, $eContext)
{
     switch(eNum)
     {
          case E_WARNING:
               echo "the following warning occured on line $eLine in $eFile: $eMsg";
               break;
          case E_NOTICE:
               echo "the following notice occured on line $eLine in $eFile: $eMsg";
               break;
          case E_ERROR:
               echo "the following error occured on line $eLine in $eFile: $eMsg";
               break;
     }
     return true;
}

In the above example we override the defualt error handler with our custom handler, customHandler. Anytime an error or warning occurs PHP will pass that error to our function. In this case, we use a switch statement to deal with each of our three error types: E_WARNING, E_NOTICE, and E_ERROR. Note that there are actually several more error types; you can find them Here.

Once the error has been passed to our function, we simply output the error message and the file and line number it occured in. This isn’t a whole lot different than the default behavior, but this code could easily be modified to create a database entry everytime an error occurs. Using this method, you could review all of the errors your users are getting as well as give them a customized error message. In the code above, I do not use the eContext parameter in my error reporting. eContext is an array containing of every variable at the time the error occured. Typically this is not something you show to a user, but can be very useful in debugging your program.

Note that the function we created returns true when it is complete. This is important. If it were to return false PHP would return control to the default error handler. If you wish to restore the default error handler you can use the restore_error_handler function.

Now that you know how to write a function that will override the default behavior when an error occurs, you might want to trigger your own errors that can be handled by this function. You can do this using the trigger_error function with an error message as the first parameter and optionally an error type as the second parameter. The defuault error type for trigger_error is E_USER_NOTICE, but it can also be set to E_USER_WARNING, or E_USER_ERROR. The method of triggering a user error and handling it with a custom error handler is similar to exception handling, though I would advice using this method only when reporting errors. If an error can be recovered from or there is an alternatice behavior that your program should use, exceptions are the way to go. If you want to present your user with custom error messages and track when errors occur, custom error handling is the way to go.

PHP Exception Handling

If you’ve ever coded in Java or C++ you probably know what exceptions are. If not, that’s okay. I’ll go over the basics.

Exceptions modify the control flow of a program. Usually, they are generated by functions when an error occurs. Throwing and catching exceptions allow the programmer to anticipate an error and handle it accordingly. For example: Say you write a function to open up a file and read its contents. When the function tries to open the file, however, it finds that the file does not exist. Generally this would just generate a nasty error and your program would terminate. If the programmer is aware that this is a possibility, however, he or she could check for that and throw an exception which would be caught and handled in a more user friendly fashion.

Enough talk lets see some code.

function open_file($fileName)
{
     if($contents = @file_get_contents($fileName))
          return $contents;
     else
          throw new Exception('Bad File Name!');
}

try
{
     $text = read_file('MyFile.txt');
}
catch(Exception $e)
{
     echo $e->getMessage();
}

In the code above, our function call, read_file, is surrounded by a try block which is followed by a catch block. The try block tells PHP that it should try to execute the code inside the block, while looking for the exception specified by the catch statement. The body of the catch statement tells PHP what to do in the event that exception is caught. In the case above if the file cannot be opened we simply echo ‘Bad File Name!’.

This example of course is trivial, but using exceptions you can better handle errors as they occur, which is bound to happen anytime user input is involved.

In the example above, a general exception is thrown. The exception itself is an object, the one above, has a constructor that takes as input a string. PHP, however, lets us define our own exceptions. Here’s how:

class CustomException extends Exception
{
     private $message;

     function __construct($message)
     {
          $this->message = $message;
     }

     function getMessage()
     {
          return $this->message;
     }
}

In the example above we define an exception called CustomException. Note that in the class declaration it states the CustomException extends Exception. In order for an exception to be thrown our custom exception class must extend Exception. A side effect of this is that if a function throws an exception within a try block, if the catch block is set to catch a general exception, it will catch ANY exception, including our CustomException. In the example, I create an exception class that is effectively identical to a general exception (though stripped down). You can however, define your exceptions in whatever way suits your needs.

It is important to remember when using exceptions, that if the exception occurs, code within the try block will stop executing. Be careful when putting code within a try block, only add code that cannot be executed if the exception occurs. For instance, if we call read_file, only code that needs the contents of that file should be inside the try block.

I Just Took a PHP Test…

So I was going through the process of signing up on a freelancers website, and the site offered various tests meant to prove proficiency in a given subject. I decided I’d give it a try so I took the PHP5 test. 30 minutes later I found out that I passed and did better than 66% of people that have taken the test. The only problem is that of the 40 questions, I can only think of one that was relevant to PHP programming. The remaining questions were completely obscure and pointless.

You might think that I’m just upset about not knowing the answers, but I actually did know the answers to most of them. That, however, doesn’t make them any less pointless. Let me give you an example. One of the questions asked what the output of the following code:

$arr = 'a';
$arr[0] = 'b';
echo $arr;
echo $arr[0];

The options were ‘ab’, ‘bb’, ‘b’, and an error. This is actually one of the better questions, but the reason why it is ridiculous is because you would never encounter code like this. What the question is attempting to determine, is your understanding of strings in PHP (strings are character arrays). The answer happens to be ‘bb’, but if you couldn’t figure that out don’t worry.

Here’s another example:

$x = 99;
$y = 9;
$z = 8;
echo $x++/$y++ + --$z;

If you can’t figure this out, that problem is not with you, but with the jackass that wrote this code. I honestly don’t know what this question is trying to show, other than your ability to stare at terrible code for 5 minutes trying to figure out what it does. I recall from my freshman year of college, taking intro to programming. Within the first week of this course, which assumed you had no knowledge of programming, everyone knew that this was bad code. In fact I recall a professor explicitly writing code similar to this on the board and telling us if we write our code like this, he won’t grade it. By the way I think the answer is 17.

Want another one? Okay, which of the following is a function that can help you determine if a function exists:

is_function ()
function_exists ()
fexists ()
None of the above

Even if I had never seen a line of PHP code in my life I could answer this by tabbing over to google. Every question on the test (with the exception of the one that I mentioned) fell into the category of completely pointless and obscure, or “Do you know how to look up what a function does using google”.

the one question that I mentioned that was actually a good question, was about outputting each value of an arbitrary list, that is a list that contain sub-lists as well as individual elements. The correct way to do this is with a recursive function and is_array().

So what’s the point of this rant you say? My point is that if you are a PHP programmer don’t waste time with these tests and definitely don’t spend money to take one. If you are looking for a PHP programmer don’t place any merit on the results of one of these tests. The only way to tell if someone is a good programmer is to see and run their code. Furthermore, the only way to become a good programmer is to write lots of code of your own, look at other people’s code, and get advice from experienced coders.