Posts tagged ‘Strings’

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.