Although I’ve been working with PHP for some years now, I’ve never really fussed too much about the internals of the language itself. If it works, I don’t really care to know too much about why. And generally PHP does work.
Then, the other day, I was merrily working away on what I thought was a simple piece of code to convert a structured PHP array into a string (yep — serialization, but for a particular purpose). It was a brief and rather neat little recursive function, and it worked. Well, it did at first. Then when I tried it in a ‘real world’ scenario, I found that all of a sudden, it didn’t work — and not in a nice, neat ‘Oops, you can’t do that’ kind of a way, but in an ‘Oh crap, I’m so broken I’m going to bring Apache down with me’ kind of a way.
So I was getting sementation faults when the array was especially large — although by ‘large’ I only mean a few hundred elements, with a maximum nesting depth of three levels. Nothing too outrageous.
At first I was totally at a loss. Changing random things (an extra space here or there) seemed to fix the problem but then it’d appear again with different data. I tried more and more outlandish fixes but nothing seemed to fix the problem for good. So I began to dig around a bit and discovered one of PHP’s dirty little secrets — it’s not very good at recursion. There aren’t many references to it, although there are several bugs listed (including this very old one with a response from Zeev himself) which tend to be answered with ‘just don’t do it’. Yeah that’ s helpful, thanks.
Seems that PHP uses the stack to store stuff during recursion, and fills it up pretty quickly in doing so. Now obviously all languages have limits, but to be aware (for some years) of one so fundamental, and not at least trap for it (and maybe throw a ‘too much recursion’ error, or somesuch) strikes me as idiotic. It would’ve saved me a day and a half’s detective work trying to identify the problem, at least. No wonder PHP has such a poor reputation among ‘serious’ programmers.
So do I have any wise words of advice to offer anyone in a similar fix? Sorry, no. I ended up rewriting my elegant recursive function as a hideous iterative monstrosity that piggybacks on PHP’s own serialize() function. Apparently you can up the stack size in Apache, or even fiddle with some obscure internal PHP setting and recomiple it to a similar end, but that doesn’t seem like much of a solution to me — just putting the problem off and hoping for the best.
Oh and FYI: I was running my code on PHP5.04, Apache 2 (although it seems clear that the problem applies to all versions of PHP and Apache on Linux). Oh yeah — here’s a kicker: I tried it on my Windows Apache setup and couldn’t reproduce the problem even with a massive array and multiple iterations. Chalk one up for Microsoft!