2010-04-30 19:40Is that all that's wrong with PHP?While my previous blog post covered what may be an actual bug in PHP, there are still a couple of gotchas which might be worth mentioning. Firstly there is the inconsistent way it deals with single and double quotes around strings, and then there are the undesirable consequences of how it juggles variable types, for which I have an example. Of course, all languages have their problems, with the obvious exception of Groovy, the superiority of which I will demonstrate with a one-liner, possibly accompanied by an excuse to explain why that simple one-liner was so hard to write. StringsImagine setting up the following variable in PHP: This is an array whose only element is an array of one element (with one key). While a contrived example, it is is perfectly common to have two dimensional arrays in programming. Now, as the keys of these arrays and the value in the innermost array are all strings, it is natural to want to create a string using a reference to $a and its contents. For example, the documentation says you can do this: and the result would be Array because the array $b gets cast to the string Array. Equivalently you can run: which returns the same answer, but uses the fact that within double quotes, the string keys of array elements must not be enclosed within quotes at all. This might be surprising, but if you do the natural thing of putting single quotes in the example above, you get this error back: Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING Extending these examples, it is perfectly possible to do: and get the answer d as expected. Remembering the syntax error above, then, you might think that the following would be perfectly syntactically legal: and you’d be right. What it returns, though, is Array[c] which is precisely what you don’t want, and it doesn’t even produce a warning to tell you it’s done this. Apart from a vague comment that: “For anything more complex, you should use the complex syntax.” the fine documentation does not indicate that accessing the second dimension of an array should be impossible in what it calls the “simple syntax” for strings. As some of my co-workers would argue, though, this is why one should always use the complex syntax. Type jugglingNow consider the following code: A textbook example of defensive coding, no? No, a textbook example of underhanded coding. Admittedly this mistake cropped up quite legitimately in a piece of excellent code written by a co-worker, but the danger of this code is that PHP is happy to follow your logic and everything will work as you intend, until $arrayFoo has the value you were trying to treat specially, at which point your code will execute the wrong branch and you will be left wondering why. The reason this is an issue with PHP and not (just) with coding mistakes should become more clear when I explain the type juggling that PHP is doing while interpreting this code. To put this in context, then, $arrayFoo is supposed to be an array (and if it isn’t, you should be using That is only the first undesired behaviour, though. What then happens is, the GroovyAlso in some PHP code recently I saw something like this: $foo = array(
$start => 0, $start + 86400 => 100, $start + 86400 * 2 => 200, $start + 86400 * 3 => 300, $start + 86400 * 4 => 400, $start + 86400 * 5 => 500, ); which I wanted to refactor but realised that without writing a The result of all this effort is the beautiful one-liner in the code below: def start = 0
def map = [:] (0..5).each{map[start + 86400*it]=100*it} print map which produces the following output: [0:0, 86400:100, 172800:200, 259200:300, 345600:400, 432000:500]
This is such easy to understand, concise code, it almost slips right off the page and into your brain directly. What’s more, it is also easily maintainable, and you could add the equivalent of two whole PHP lines of code just by changing the 5 to a 7, a one bit change in Groovy! Compared to PHP’s 62 bytes extra, that means PHP is 496 times more bloated. Unfortunately, though, Groovy takes about 496 times as long to execute this code in the Groovy console, so it’s a bit of a trade-off. It also took me about 496 times as long to work out what the magic syntax is in Groovy for populating a map like that this. Is it a good enough excuse to say that I haven’t written any Groovy in a long time and that’s why it took me so many attempts to write that one-liner? Trackbacks
Trackback specific URI for this entry
No Trackbacks
Comments
Display comments as
(Linear | Threaded)
All groovy seems to really give you here is the neat (0..5).each syntax. In PHP, what you've written looks like this:
$start = 0;
$foo = array();
for ($i=0;$i≤5;$i++) {$array[$start+86400*$i] = 100 * $i;}
Which is just as much of a one-liner, if you'll insist on writing all your braces on the same line. The difference is that PHP isn't relying on a magic 'it' variable, which is only implicitly declared and initialized in groovy.
Almost ironically, this PHP blogging software couldn't handle the "less than" sign in your comment, so it stripped it and all the subsequent characters you wrote from the HTML output.
Fortunately the unabridged comment was still stored in the database, so I took the liberty of converting the "less than" to a "less than or equal to", which makes the syntax invalid (and untypeable) but still I hope gets across your point.
In fact, you yourself showed me how to make the PHP even tidier:
foreach (range(0,5) as $i) { $array[$start+86400*$i] = 100 * $i; }
:)
|
QuicksearchCategoriesSyndicate This BlogBlog Administration |