Posts Tagged ‘string parsing’

In my previous post (which you can reach here: http://blackscorner.me/2011/09/29/strings-and-interpolation-a-love-story-part-1/) I discussed interpolation in PHP.  Apart from professing my love for PHP’s implementation of interpolation (+1 poet points to me!), I showed some examples of its uses, and compared that to the equivalent statements using concatenation. However, besides novice PHP coders, intermediate coders and above usually know about interpolation (whether or not they know it goes by that name). However, many intermediate coders (and some advanced!) don’t know the full capabilities of PHP’s interpolation implementation. The examples I showed in the previous post only show one part of the story! There are actually two different syntax’s for interpolation in PHP, simple (which was shown in the previous example) and complex (which I will discuss in this article).

Lets take a look at an example of simple syntax just to refresh our memory (coders are notoriously forgetful!):

$var = "variable";

echo "I am a $var";

A lot of coders wrongly assume that this is the only form of interpolation available in PHP, and thus conclude that if you want to use, say, an element in an array, or an attribute of an object, you have to use concatenation. When given a scenario in which you want to use an array element in a string, many would write the following:


$arr = array("element1", "element2", "element3");
echo "the value at index 1 is: " . $arr[1];

However, PHP can interpolate the element $arr[1] using simple syntax! The above echo statement is equivalent to the following:

echo "The value at index 1 is: $arr[1]";

The same goes for associative arrays! So the following is also valid:


$assoc = array("key1" => "value1", "key2" => "value2");
echo "The value of the array at the key 'key1' is: $assoc[key1]";

Notice the lack of single quotes around the associative array’s key. As I said earlier, you can also use simple syntax to interpolate an objects attributes (or properties). Obviously the property in question has to be public. The following illustrates what I mean:

class foo {
public $var;
function __construct(){
$var = "World!";
     }
}
$foo = new foo();
//the following statements are equivalent
echo "Hello " . $foo->var;
echo "Hello $foo->var";
Here are some more examples for clarification (taken from the PHP manual)
<?php
$juices = array("apple", "orange", "koolaid1" => "purple");

echo "He drank some $juices[0] juice.".PHP_EOL;
echo "He drank some $juices[1] juice.".PHP_EOL;
echo "He drank some juice made of $juice[0]s.".PHP_EOL; // Won't work
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;

class people {
public $john = "John Smith";
public $jane = "Jane Smith";
public $robert = "Robert Paulsen";

public $smith = "Smith";
}

$people = new people();

echo "$people->john drank some $juices[0] juice.".PHP_EOL;
echo "$people->john then said hello to $people->jane.".PHP_EOL;
echo "$people->john's wife greeted $people->robert.".PHP_EOL;
echo "$people->robert greeted the two $people->smiths."; // Won't work
?>
Awesome right! But thats not all! Not even close. PHP also has complex syntax (which I mentioned above). Despite what you may think, its not called complex syntax because it is in itself complex, but rather because it allows you to interpolate complex expressions. To use complex notation, you must use curly brackets ({ and }) to surround your expression you want interpolated. The PHP manual describes complex notations functionality as follows:
Any scalar variable, array element or object property with a string representation can be included via this syntax. Simply write the expression the same way as it would appear outside the string, and then wrap it in { and }. Since { can not be escaped, this syntax will only be recognized when the $ immediately follows the {. Use {\$ to get a literal {$.
Lets look at an example shall we! This will show improper use of complex syntax, then 2 examples of correct use. I will use a simple variable here.
<?php
$great = 'fantastic';

// Won't work, outputs: This is { fantastic}
echo "This is { $great}";
// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
?>
Of course you can also use complex notation with object properties and array elements as I did above with simple syntax
<?php
echo "This square is {$square->width} centimeters broad.";
echo "This works: {$arr['key']}";</div>
?>
Notice that I used single quotes in the array element example. Complex syntax is the only place you can use single quoted array keys, as opposed to simple syntax which, as shown above, can’t have the single quotes (if you are curious why this is, leave a comment and ill try to get back to you).  Where complex syntax really shines though, is its ability to interpolate more complex expressions than simple object propertys or array elements. For example, say you are taking advantage of PHP’s variable variables (link will be below). Assume you have a function called getName() which returns the name of the variable you want to access. You can do
<?php
function getName(){ return 'var'; }
//note single quotes and thus lack of interpolation
$var = 'value of $var';

echo "This is the value of the var named by
the return value of getName(): {${getName()}}";
//output: This is the value of the var named by the return value of getName(): value of $var
//of course, if the function is a method of some class, you can also do this:
$object = new Some_Class_With_getName_Method();
echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
?>
Unfortunately, you can’t interpolate just the return value from a function. So the following won’t work:
<?php
// Won't work, outputs: This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";
?>
Unfortunately, since PHP depends on the variable sigil ($) to proceed the opening curly bracket to use complex syntax, interpolating functions is impossible. But PHP’s ability to interpolate many things really makes it an amazing language. What is truly unfortunate is that many programmers are unaware of how far PHP’s capabilities go! Most know about simple syntax, but many are unaware of the power of complex syntax.
Here are a bunch more examples (from the PHP manual) of things that will and won’t work with complex syntax so you can get an idea of its use.
<?php
// Show all errors
error_reporting(E_ALL);

$great = 'fantastic';

// Won't work, outputs: This is { fantastic}
echo "This is { $great}";

// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";

// Works
echo "This square is {$square->width}00 centimeters broad.";

// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}";

// Works
echo "This works: {$arr[4][3]}";

// This is wrong for the same reason as $foo[bar] is wrong  outside a string.
// In other words, it will still work, but only because PHP first looks for a
// constant named foo; an error of level E_NOTICE (undefined constant) will be
// thrown.
echo "This is wrong: {$arr[foo][3]}";

// Works. When using multi-dimensional arrays, always use braces around arrays
// when inside of strings
echo "This works: {$arr['foo'][3]}";

// Works.
echo "This works: " . $arr['foo'][3];

echo "This works too: {$obj->values[3]->name}";

echo "This is the value of the var named $name: {${$name}}";

echo "This is the value of the var named by the return value of getName(): {${getName()}}";

echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";

// Won't work, outputs: This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";
?>
<?php
class foo {
var $bar = 'I am bar.';
}

$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo "{$foo->$bar}\n";
echo "{$foo->$baz[1]}\n";
?>
<?php
 class foo {
 var $bar = 'I am bar.';
 }$foo = new foo();
 $bar = 'bar';
 $baz = array('foo', 'bar', 'baz', 'quux');
 echo "{$foo->$bar}\n";
 echo "{$foo->$baz[1]}\n";
 ?>
<?php
// Show all errors.
error_reporting(E_ALL);

class beers {
const softdrink = 'rootbeer';
public static $ale = 'ipa';
}

$rootbeer = 'A & W';
$ipa = 'Alexander Keith\'s';

// This works; outputs: I'd like an A & W
echo "I'd like an {${beers::softdrink}}\n";

// This works too; outputs: I'd like an Alexander Keith's
echo "I'd like an {${beers::$ale}}\n";
?>
Well I hope you enjoyed reading about string interpolation as much as I enjoyed writing about it. PHP really is an amazing language, and touches like this are what really set it apart from other languages, and is what’s key to PHP’s wide success.
Links of Interest
Part 1:
String Parsing (Go here for a full explanation of the examples I posted, as well as comments and discussion about it):
Simple Syntax:
Variable Variables:

I am a frequent forum goer to the website http://www.phpfreaks.com/ (My username is Mikesta707), and one thing I see a lot from PHP novices is a question like

Hey, I am trying to echo a string, but it doesn’t look right. I’m using a variable and but instead of its value all I see is the php code! my code looks like

$str = "Poop";

echo 'I have to take a $str';

please halp!

Now, anyone who has uses PHP at an intermediate level or higher will tell this hypothetical novice to either use double quotes, or concatenate. The solutions would be as follows


$str = "Poop";

echo "I have to take a $str";//double quotes

echo 'I have to take a ' . $str;//concatenation

And of course, their error will be fixed, and they can go on their merry way, or post about another problem they have. In addition to the above solutions, one could also use heredoc syntax, but that is generally reserved for multi-line strings and can be a little complex for a new programmer. Many forum posters wouldn’t bother even mentioning it.

Anyways, what many posters fail to do in these cases, is explain why what they wrote failed. As a result of this, even people who know to use double quotes or concatenate will often not really know why you have to do that, beyond “uh.. just because man.”  In my experience as a forum poster for phpfreaks, I see a solution that concatenates rather than using double quotes more frequently, and this produces a very interesting effect.

Concatenation is simple enough, and easy to rationalize the use of without wondering why you were wrong. Without knowing about the use of double quotes (or simply not realizing), one may naturally assume, after having the above problem and being told to concatenate, that they can’t put variables inside strings.

This is half correct, as it is true with single quotes, but incorrect in terms of double quotes. This can lead an overall assumption that if you want to create a string that is composed partly of one or more variables, then you must always concatenate. Over the years I have worked with quite a few developers who have been looking over my shoulder while I am writing some code, and told me, “Hey, you gotta concatenate there!” or something along those lines when using double quotes. Usually this will come with the look of quiet satisfaction at having corrected (or thinking they corrected) a fellow coder’s mistake.

Unfortunately, because of this assumption many people miss out on one of my favorite features of PHP called Interpolation,  as well as having a somewhat faulty understanding of how strings work in PHP. For those who don’t know, interpolation is defined by Wikipedia as the following:

The process of evaluating an expression or string literal containing one or more variables, yielding a result in which the variables are replaced with their corresponding values in memory. It is a specialized instance of concatenation.

Now this basically means that when you put a variable inside of a string, PHP does a sort of replace, where the name of the variable (say, $str) is replaced with its value (say, “Poop”). PHP supports interpolation, but only when using double quotes or the heredoc string syntax. To take a simple example:

//The following are all equivalent
$n = "Mike";
echo "Hi i'm $n";//interpolation
echo 'Hi i\'m ' . $n;//concatenation
echo <<<EOT
Hi i'm $n
EOT;//heredoc syntax

As I said earlier, Interpolation is one of my favorite attributes of PHP. Interpolation isn’t supported in many languages (Perl, Tcl, Ruby and most unix shells are the others). PHP uses a sigil, or a symbol attached to a variable to show its a variable (and not a global constant), unlike many languages (including C, C++, C#, java, javascript, etc.) so interpolation is possible. Interpolation really makes creating strings that would be complex or look ugly in other languages easy and clean. Lets compare two strings, one in PHP and one in C++/C#/Java/ect…


//assume we have created 3 variables, $a $b and $c in PHP, and a b and c in C++

//PHP string
$str = "The first 3 letters of the alphabet are $a $b and $c";

//equivalent string in C++/C#/java/etc...
//assume we have the proper header includes
string str = "The first 3 letters of the alphabet are " + a + " " + b + " and " + c;

As you can see, the PHP version is much easier on the eyes, and much nicer to write! Of course, most languages that don’t support interpolation have a specialized form of interpolation in function form using string formatting (for example, printf() from C/Lisp).

To sum things up, I absolutely love interpolation, and think its one of the most amazing features of PHP. Its a very simple feature, but elegant at the same time, and extremely useful. Out of all of PHP’s amazing features, I know that I use this one the most. I love interpolation so much actually, that I plan on writing a part 2 to this post very soon. It will probably be a tad bit shorter, but will have some good information.

Part 2: [Click me]

Links of Interest:

String parsing (Interpolation):
http://www.php.net/manual/en/language.types.string.php#language.types.string.parsing

Single quotes:
http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.single

Double quotes:
http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.double

Heredoc:
http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc

Interpolation (Wikipedia):
http://en.wikipedia.org/wiki/Variable_(computer_science)#Interpolation