Archive for the ‘PHP’ Category

The special variable “_”

Friday, April 30th, 2010

Reading this blog post, Destructuring binds in Ruby just now reminded me of a feature I love about Prolog which I wish would make it into other languages.

Firstly, I love assigning a list to a list of lvalues i.e. variables; this is possible in both PHP and Perl which I use regularly; and no doubt many other languages. (But not Java: why not!?)

    ($a, $b) =      ($b, $a);  // Perl
list($a, $b) = array($b, $a);  // PHP

PHP, as always, wins in inelegance, having the left side syntactically different to the right side. While it’s obviously the case that a list of values and a list of lvalues are technically different, I don’t think this difference should be expressed in the syntax.

I mean, in most languages you write e.g. $foo=4 and $bar=$foo; in both those cases you write $foo but yet they do something different (lvalue and rvalue); given that you write them the same there i think the same should apply to lists.

But I digress – What I want to mention is using “underscore” to mean “any variable”. I first saw this in Prolog.

For example, imagine you have to implement an interface (e.g. in Java), it requires you to write a function taking two parameters, but one of the parameters you don’t care about. Wouldn’t it be nice to write

interface ExistingApi {
   public void createObject(String name, Object otherInformation);
}

class MyInstanceOfTheApi {
   public void createObject(String name, _) {
      ...
   }
}

i.e. this shows clearly you do not care about the second parameter.

In current Java (and all languages I program including Perl, PHP) you have to give all variables a name even if you don’t use them, either in function definitions or in “assign to a list” scenarios mentioned above. It is then left as an exercise to the reader to determine if these variables are used or not, and indeed an exercise to the writer to name the variable they are never going to use.

I mean yes, technically you can actually just call variables “_” (or “$_” (except in Perl where “$_” already means something)) but that would then be a coding convention as opposed to a language feature, and who knows if the coding convention is actually used correctly by a programmer. (If “_” is a variable there’s nothing stopping someone from using its value.)

And then you have the problem if you have two variables you don’t care about, you can’t call them both “_”.

By the way, Programming in Prolog is an excellent book.

PHP infinite recursion

Wednesday, November 18th, 2009

What can I say? How about “toy language”?

$ php -r 'function foo() { foo(); } foo();'
Segmentation fault

I’m not saying that infinite recursion is a good idea, but during development it can happen by accident, and I don’t expect such a simple error to crash the PHP interpreter! (Also it took me about 20 minutes to debug this problem, as I had no idea where it happened, nor indeed what the problem was..)

PHP 5.2.6 on Linux 2.6.26 Debian

Never close PHP class files with the “?>” tag

Friday, August 21st, 2009

When developing PHP, a front-end PHP file will include other files: classes, utilities, etc.

When writing those class files, one also needs to use the <?php tag at the start of the file, otherwise PHP will simply take the text and output it unchanged to the browser. (PHP’s assumption is that it sits in a web page, with probably more markup than code, so by default characters in the source code get copied one-to-one to the browser and the <?php?> tags are necessary to introduce PHP to the “exceptional circumstance” that one might actually want to program some PHP.)

If one must open the class source file with <?php then it would seem to make aesthetic sense to close it with ?>. However, there are no negative side-effects if one does not close the tag, plus one very negative side-effect if one does close it.

We performed a minor release a while ago, after which the display of generated PDF files no longer worked. Yet the minor release had nothing to do with the section of code that produced PDFs. What sort of weird action-at-a-distance could possibly be happening here?

The reason was that one class file in the minor release had a blank line after the ?> tag. This was impossible to spot in the text editor. The blank line was printed to the browser, which was also invisible in nearly all of the site, as HTML ignores blank lines. PDFs probably do as well (I haven’t checked) but the problem wasn’t with the content. As HTTP response content is streamed to the browser (as opposed to being collected first and then sent to the browser at the end of the request), HTTP headers can only be set before the first byte of output has been produced by the software. As the blank line in the class source file consituted content, and the source file was (necessarily) parsed before the code could be executed, the HTTP header “Content-Type: text/pdf” couldn’t be sent, and various errors about headers not being able to be sent, combined with the binary source of the PDF, arrived at the user’s screen.

So given there are no disadvantages, and one particulary weird source of bugs can be removed, I would say one should never end PHP files with ?>.

mysqli_affected_rows

Wednesday, October 8th, 2008

Recently I programmed the following screen in PHP:

  • The user logs in
  • The user has a subscription
  • The subscription has a number of states (“terminate”, “auto-extend”, ..)
  • There is a screen allowing the user to change this state
  • The screen is a set of radio buttons – each radio button relates to one state
  • The user clicks on the radio-button representing the state they wish, clicks “ok”, and the new state gets saved to the database

Not rocket science eh? Well, unbelievably my implementation of the above had a bug. How on earth was that possible?

The bug was the following: If you changed the state, everything worked fine. But if you chose the same state as is already selected, an Exception gets thrown.

Initially I suspected a simple coding mistake. When I looked at the code, everything looked right. I had used the following “algorithm”:

  • Update the “subscription” row using SQL
  • Check the result of the SQL statement, that exactly 1 row was updated (in case e.g. id referenced a non-existing subscription, which would be an error)

I used the PHP function mysqli_affected_rows for that and unbelievably that has the following functionality: it only returns the number of changed rows i.e. the number of rows:

  • Matching the where clause, and
  • Currently having values different to those values being written to the row.

I can’t imagine a case where one would want to know that. I couldn’t find any function to return the number of rows matching, independent of if the values were changed or not. (The older version mysql_affected_rows exhibits the identical functionality.)

So I had to write the following function:

/**
 * Returns the number of rows which matched the WHERE
 * clause on the last UPDATE statement. This is not the
 * same as mysqli_affected_rows, which only returns the
 * number of changed rows.
 */
public static function DbUpdatedRows() {
    $link = self::DbGetLink();  // mysqli object
    $info = mysqli_info($link);
    if (preg_match('/Rows matched: (\d+) +Changed/',
            $info, $matches))
        return $matches[1];
    throw new Exception("DbUpdatedRows called although ".
        "it doesn't look like an UPDATE was the ".
        "last statement: mysqli_info returned '$info'");
}

I’ve just checked, and in InnoDB inside a transaction, it’s good to see that (as with Oracle) write-locks are indeed placed on all matched rows not just updated rows.

And don’t get me started on using DB-specific function calls (i.e. functions named mysql_x) as opposed to using a DB-abstraction layer like DBI in Perl, JDBC in Java, etc. Nor why I’m using PHP or MySQL in the first place.

Next PHP uselessness of the day

Tuesday, December 11th, 2007

There is the option “php -l” which checks the validity of a source file. Obviously it doesn’t do a wonderful job as it doesn’t detect misspelt variable or method names; but I suppose it’s better than nothing.

So I apply this recursively to all the files under a certain directory. For reasons I won’t go into here there are Postscript fonts checked into the source directory. To this files, “php -l” outputs:

No syntax errors detected in ./pdflib/fonts/php_Times-Italic.afm

I assert “php -l” is not very useful.

Unbelievable PHP limitation of the day

Monday, December 10th, 2007

If one defines a class with the member variable:

protected static $bytes = 12582912;

then that’s fine. However if one defines it as:

protected static $bytes  = 12*1024*1024; // 12 MB

then that gives a compile error:

Parse error: syntax error, unexpected '*', expecting ',' or ';'

I know of no other language that I’ve ever programmed (i.e. including BASIC, and C) where you can write a value, but you can’t write an expression.

How broken is that!

Putting spaces around the *, or adding brackets around the whole expression, does not help.

(PHP 5.2.0)