Blog

Unable to load http.so

Unable to load http.so

Fortunately, it doesn’t happen too often, but every now and again I rub elbows with downright infuriating problems in the OSS world.  If you go off the reservation (off the ‘rez), and attempt to make unsupported configurations work, you expect these types of things.  But when you’re targeting a basic, happy path use case, you don’t.  Thus began my 3+ day excursion into getting pecl_http to work with PHP 5.5…

My setup was as vanilla as it comes: Apache 2.4 and PHP 5.5 running on Amazon Linux.  I had the need to create a php page that would do a simple HTTP GET, parse out some data, and echo that information.  There are a ton of ways/technologies to do this, but I happened to have an EC2 instance running Apache and PHP.  A simple search indicated that I could use pecl_http, a common PHP extension that provides HTTP support.


NOTE: It’s worth mentioning that the 2.X version of the pecl_http API has changed IMMENSELY. Previously, it was more static/C-style functions, but the 2.X version is fully object-oriented. This ticked off more than a few people and you’ll find many posts outlining how to get version 1.x (usually 1.7.6) working. This post focuses on version 2.0.7.

Installing pecl_http on an Amazon Linux EC2 instance is easy enough:

sudo yum install php55-pecl-http

Once that was complete, further installation instructions indicated that a quick updated was needed to my php.ini:

extension=http.so

I restarted apache and hit a test PHP page, which simply consists of:

<?php phpinfo() ?>

The PHP info page also lists all loaded extensions. Interestingly enough, I did not see the pecl_http support extension listed. As it turns out, PHP extensions can be a total cluster. When troubleshooting them, make sure you verify the following:

  • Double check that the extension is compatible with your target version of PHP
  • The shared library for the extension in question (in this case http.so) has been successfully compiled/installed to the correct location
  • Verify that any dependencies required by the extension have been successfully compiled/installed and have been loaded by PHP, prior to the extension being loaded

I found two, indispensable means for debugging this.  Rather than using/parsing the phpinfo page, it’s easy enough to do this, to verify if an extension is loaded or not:

<?php echo var_dump(extension_loaded("http")); ?>

This prints out a simple true/false. Sure enough, I was seeing “false.” Next, I ran the PHP version command:

php -v

This displayed the following:

PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/5.5/modules/http.so' - /usr/lib64/php/5.5/modules/http.so: undefined symbol: php_persistent_handle_abandon in Unknown on line 0
PHP 5.5.14 (cli) (built: Jul 9 2014 21:40:15)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies

Alright, we’re finally getting somewhere. So PHP fails to load the extension because… undefined symbol: php_persistent_handle_abandon??! WTF?

I’ll just cut to the chase and save you a ton of time here. Forget about searching The Goog for ‘php_persistent_handle_abandon’ (or any other, missing function call for that matter…). Anytime you come across the error message: “Unable to load dynamic library <some path> – undefined symbol <function name > in Unknown on line 0”, it simply means that a dependencies for that extension hasn’t been installed or loaded.  Thus, loading the extension fails.  Get those dependencies installed and loaded, and you’re in business.

As it turns out pecl_http has a few hard dependencies:

  • PEAR 1.4.1 or newer
  • raphf 1.0.0 or newer
  • propro 1.0.0 or newer
  • PHP extension hash
  • PHP extension iconv

The latter two are simply a part of PHP (5.5, at least).  The rest were installed when I originally did the ‘yum install’ for php55-pecl-http, like any good package manager would do. I verified that these dependencies were loaded and they were displayed on my phpinfo page.  I edited php.ini to load the http.so extension.  So what gives?

It turns out this was a dependency load order issue. PHP loads extensions in the order specified in the .ini file, or in the alphabetical order it finds individual extension .ini files in. In other words, http.so was being loaded before all its dependencies. I updated my php.ini to be:

extension=raphf.so
extension=propro.so
extension=http.so

This time, running php -v revealed:

PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/5.5/modules/http.so' - /usr/lib64/php/5.5/modules/http.so: undefined symbol: php_iconv_string in Unknown on line 0

Ok, so the undefined function has changed to ‘php_iconv_string’. A quick search indicated that this was defined in iconv, which is included in PHP itself and should be loaded. For good measure, I updated my php.ini file one more time:

extension=iconv.so
extension=raphf.so
extension=propro.so
extension=http.so

This time, php -v reported no errors (a couple warnings for some extensions already being loaded) and my phpinfo page listed ‘HTTP Support’ as a loaded extension 🙂

Now, getting http_pecl to successfully run on a PHP page? That’s for another post…

I spent a fair amount of time researching and working to resolve this issue. I came across more than a few posts that suggested re-compiling PHP or re-compiling the extension. For me, that’s a non-starter; I would sooner find another solution. If you’re asking users to custom compile code they don’t own, something’s very, very wrong.

The root of this issue was actually captured in a php bug. While Mike is correct – this isn’t technically a bug in pecl_http – it would be nice if there was more focus on resolving the issue at hand. If you author an extension that has dependencies, I guarantee that users will hit this issue. Be it a function of how PHP loads extensions or not, a little more support can go a long way.

2 Comments

  • Deepak on Oct 22, 2016 Reply

    This was a very useful article. In addition to the extensions that you mentioned had to be added to the .ini file, I had to add an extension of json.so. This is because i got a message of undefined symbol for php_json_decode_ex. Thanks.

  • Ross Carver on Mar 26, 2015 Reply

    Great article. The issue is indeed common and arises because “h” comes before “i”, but http.so needs iconv.so. What a dumb dependency setup. Thanks!

Leave Reply