Feb. 13th, 2008

haggholm: (Default)

Once again, the weak typing and checks of PHP drive me to the brink of insanity (or still farther past it, depending on your definitions). Consider the following: I am picking a random element from an array and returning it, optionally removing it, to tweak test parameters. The array is associative, so I need to return a pair of $key, $value. I whip out iteration #1 of the utility function, which just returns array($key => $value). Makes sense, right? Key => value. Now I go on with my main testing function:

$arr = array(...);
list($key, $value) = $this->extractRandomArrayElement($arr);
// $key is null???
// $value is null???

If you've been paying attention, you should be laughing at me (in my lame defence, I haven't had any coffee yet today). Of course the list construct assumes that I'm returning array($key, $value) while I'm returning array($key => $value)—a significant difference, and I'm trying to use list with two elements to extract a single-element array. (list is meant for numeric arrays, anyway.) Of course this code should fail. But it fails silently. The standard modus operandi for PHP when you do something completely nonsensical appears to be not to throw an exception and die (as Python would) or a fatal error and die (as PHP at least does on static syntax errors), but to assign null to everyone concerned and go on as though nothing had happened.

This is not helpful in the least.

haggholm: (Default)

I'm feeling very bloggy today.

Anyway, I'm getting more comfortable with PHPUnit, and although I've spoken of it in near-monosyllables here before, I haven't really written a ground-up post talking about what it is, what it does, and why you'd be a fool to write PHP code without it (or something like it; there are other PHP testing frameworks).


Unit testing theory, 101 )
PHPUnit )
Code coverage reports (with PHPUnit) )
Wrapping it up (in an XML configuration file) )
haggholm: (Default)

When comparing an expression with a bool, PHP does not perform type widening, but treats it as evaluation of a Boolean expression.

// true:
print_r((true == 8) ? 'true' : 'false');
// false:
print_r(((int)true == 8) ? 'true' : 'false');
haggholm: (Default)

HTTP 1.1, as per RFC 2616, supports no less than three ways of specifying the length of the response to a simple GET request:

  • In a Content-Length header, as in HTTP 1.0;
  • By means of the header Connection: close, which means content follows and ends only when we close the connection on you;
  • By means of the header Transfer-Encoding: chunked, which means that the message is transferred in chunks, each of which begins with a chunk size—in hex, unlike the decimal representation of Content-Length—and ends with good old CRLFCRLF.
I do not know why this is so, but it annoys me, particularly as it turns out that some servers will ignore you if you specify, in your GET request, HTTP version 1.0 (I'm looking at you, Slashdot—as the first example I came across).

haggholm: (Default)

I think this has already been by most blog-heavy day yet (five posts!—not counting this one); and when I first created this blog, posting was less than a monthly occurrence. Since today has largely been a list of vented frustrations (apart from that PHPUnit post), let me just say that it's nice to rediscover the sense of accomplishment one gets from hacking together low-level bits of code, now and then. HTTP GET may be recalcitrant, but damn it, my client now handles the three content length specifications (unless you do something exotic with your Transfer-Encoding; I submit User-Agent: Crude-RSS 0.1 for a reason…

I can also parse valid and well-formed XML documents (I make no attempts at performing any sophisticated verification: It assumes valid XML and behaviour is undefined in all other cases, though it'll puke with an error message if it's something obvious like mismatched tags), collect the elements in a tree, and…do something with it. All I've done so far is download the Slashdot RSS feed (from http://rss.slashdot.org/Slashdot/slashdot), parse it, and spit out an HTML document based thereon (with a <h3> for every <title>, and so on). I'm toying with the idea of adding an SMTP client to email a version somewhere (with all formatting stripped out). I don't feel like setting up a mailserver, though; I should telnet around a bit and see if I can find an SMTP server that contents itself with the very basics…

I should reassure the reader unfamiliar with this stuff that none of it is as difficult as it sounds; it's a few evenings' after-work hobby programming by someone whose C++ is decent but a tad rusty; it's all under 750 lines (in spite of being rusty C++); and parsing a valid and well-formed XML document is a lot easier than it may sound. I don't want to write an HTML parser…

As a postscript, I notice that I committed a sin that would surely have poor Strunk spinning in his grave (in addition, surely is an adverb): Three paragraphs, all ending in ellipses. Each seemed a good idea at the time, and I am much too tired to alter them. To the reader sensitive to style: My apologies, and good night.

Most Popular Tags