Hosting6 min lezen

PHP Upgrade – undefined function dl

Door Cipriano Groenendal op maandag, 17 januari, 2011

In dit artikel

A few days ago we updated the PHP version on our webhosting platform from PHP 5.3.2.to 5.3.3. We use a stock Debian PHP 5.3.3 with several of our own patches added. The upgrade went as planned, but afterwards we noticed that the dl() function didn’t work: Fatal Error: Call to undefined function dl().
We quickly tested PHP 5.3.2 as well and noticed the exact same problem in it. Guess there’s nothing like an update to make people notice old problems.

Step 1: Read The Fine Manual

This function has been removed

This function has been removed

Our first stop was the documentation on dl(), which contained a big fat warning. According to the PHP site the function dl() has been removed in PHP 5.3 from some SAPI’s. SAPI’s are the different ways you can connect the PHP language to a webserver, such as CGI, FastCGI, CLI or mod_php. Our servers are configured to make use of PHP’s  CGI/FastCGI SAPI, and as such the dl() function should have still been available to us. Time to run some more tests and figure out where exactly this problem occurs. Luckily we had an easily reproduced test case:

print("Loading memcache...");
dl("memcache.so");
print("success.");

Normally this should print the fact that it was successful loading memcache, but instead we got: “Fatal Error: Call to undefined function dl()”.  A quick check with to the php_sapi_name() function confirms that we are, indeed, running with the cgi-fcgi SAPI, so the dl() function should be available, but somehow it’s not. To see if there was something wrong with the compilation of PHP we took the PHP cli binary from the same compile and ran the same scripts, which this time gave us a nice and expected “Loading memcache…success.”. So it’s not the compile, it’s something specific to the CGI binary. On a hunch, we ran the CGI binary from the shell, expecting the same error as before. Oddly enough though, we got a nice “Loading memcache…success” on the shell. Hmm. So it’s definitely not something that’s gone wrong with the compile, but it’s something that enables or disables these functions in runtime. Around this time someone found an old, open, bug report on the php bug site where people were having the same problem, including a quote of the source code.

The source of the problem

One of the advantages of PHP is of course the fact that it’s open source, and as such we can access the source code. Our first foray into the code brought us to the code quoted on the PHP bug site in “ext/standard/dl.c”, which contains all the logic about the dl() function. Around line 78 we found a block of code that was supposed to throw an E_DEPRECATED if you use the dl() function in PHP 5.3.

print("Loading memcache...");
dl("memcache.so");
print("success.");

I’ll admit, this block threw us off for a bit. After all, we were running a sapi_module who’s first three letters were “cgi”, so we should have had the “dl() is deprecated” warning pop up, but we didn’t even get that, our PHP acted as if the whole dl() function wasn’t even loaded. But, in the end, this confirmed to us that the problem was not in the compiled source code, but in some runtime variables that were stopping PHP from loading the dl() function. We tried to call the cgi binary in a multitude of ways, but never got any different responses. If we ran it through our webserver, with or without suexec enabled, we would get a Fatal error. If we ran the same code from the shell, using the same binary, even if we went through the suexec wrapper from the shell, we’d get a success message.

Solution from source control

At this point we made use of another great feature of open source software. We left a response on the bug on the php site, hoping for some assistance and called it a night. Now surely, waiting one night doesn’t mean we get any response, so we weren’t terribly disappointed when we didn’t get any responses the next day. So, with some new caffeinated beverages we assaulted this problem again, going back to the source, and started skimming through patch notes. Browsing and searching through the commits we finally found a 2 year old commit made early in the PHP_5_3 branch

print("Loading memcache...");
dl("memcache.so");
print("success.");

Now we’re getting somewhere! The comment here says more then enough “Disable dl() in CGI and FastCGI modes“.  For some reason, early on in the development cycle of PHP 5.3, it was decided to disable the dl() function for the CGI sapi for PHP 5.3. The documentation, however, claims this function is still available, and another part of the code claims the dl() function has been marked as deprecated. With this commit it was easy enough to patch our PHP. We took this patch, reverted it on our local source, compiled, packaged and deployed to a test server, and two seconds and an F5 later we got the message we had been hunting for for two days on our test page:

print("Loading memcache...");
dl("memcache.so");
print("success.");

The only thing we had left to do now is place our findings on the php bug report and deploy this fix to the rest of our clusters, all of whom can now dl() to their heart’s content.
[widget id=”magereport_widget-4″ /]

Hi! Mijn naam is Dion, Account Manager at Hypernode

Wil je meer weten over Hypernode's Managed E-commerce Hosting? Plan je online meeting.

plan een een-op-een meeting tel:+31648362102

Visit Hypernode at