Msphpsql: PHP 7.2 Unable to load dynamic library - undefined symbol: call_user_function

Created on 13 May 2018  路  13Comments  路  Source: microsoft/msphpsql

I am having problems setting up the driver on PHP 7.2. The same procedure (as described in the repro section) was used to set it up on 7.1, which I still use on the same server, which has Plesk and multiple PHP versions installed (although note the below has nothing to do with Plesk).

Driver version or file name

Release Version 5.2.0 (stable)

Client operating system

Ubuntu 16.04.4 LTS

PHP version

7.2

Microsoft ODBC Driver version

Package: msodbcsql17
Version: 17.1.0.1-1

Problem description

The module cannot be loaded, with error:
PHP Warning: PHP Startup: Unable to load dynamic library 'sqlsrv.so' (tried: /opt/plesk/php/7.2/lib/php/modules/sqlsrv.so (/opt/plesk/php/7.2/lib/php/modules/sqlsrv.so: undefined symbol: call_user_function), /opt/plesk/php/7.2/lib/php/modules/sqlsrv.so.so (/opt/plesk/php/7.2/lib/php/modules/sqlsrv.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0

Repro code

  1. /opt/plesk/php/7.2/bin/pecl install sqlsrv
  2. Find the compiled extension:
    find / -name 'sqlsrv.so'
  3. Copy compiled extension to correct dir:
    cp /usr/lib/php/20151012/sqlsrv.so /opt/plesk/php/7.2/lib/php/modules/
  4. Create .ini (with 75- prefix, so it's loaded last)
    echo "extension=sqlsrv.so" > /opt/plesk/php/7.2/etc/php.d/75-sqlsrv.ini
  5. Try running a php command, e.g.:
root@ocelot:~# /opt/plesk/php/7.2/bin/php -v
PHP Warning:  PHP Startup: Unable to load dynamic library 'sqlsrv.so' (tried: /opt/plesk/php/7.2/lib/php/modules/sqlsrv.so (/opt/plesk/php/7.2/lib/php/modules/sqlsrv.so: undefined symbol: call_user_function), /opt/plesk/php/7.2/lib/php/modules/sqlsrv.so.so (/opt/plesk/php/7.2/lib/php/modules/sqlsrv.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
PHP 7.2.5 (cli) (built: Apr 27 2018 10:11:23) ( NTS )
Copyright (c) 1997-2018 The PHP Group
configuration

Most helpful comment

Ok, got it. By looking at the output, I realised it's not using the correct API, like you mentioned before.

root@ocelot:~# /opt/plesk/php/7.2/bin/pecl install sqlsrv
Starting to download sqlsrv-5.2.0.tgz (171,728 bytes)
.....................................done: 171,728 bytes
33 source files, building
running: phpize
Configuring for:
PHP Api Version:         20151012
Zend Module Api No:      20151012
Zend Extension Api No:   320151012
building in /tmp/pear-build-rootjrBqt7/sqlsrv-5.2.0

However:

root@ocelot:~# /opt/plesk/php/7.2/bin/php -i | grep "PHP API"
PHP API => 20170718

The solution was to install plesk-php72-dev and fix the PECL config, like described here. After reinstalling it already copies it in the correct modules dir.
So yes, it's was probably just a multi-php Plesk specific issue (don't know if the OS provided one installs the dev package).
Thank you for helping out :)

All 13 comments

@SlimDeluxe I have never seen this specific error message before. Have you tried installing PHP and sqlsrv without Plesk?

@david-puglielli , in short, no I haven't.
My dev machine is without plesk but still at 7.0 (ubuntu 16.04 default) :) sqlsrv 5.2.0 works fine here. I haven't bothered with multiple php versions on dev because I am building a single product with only 1 supported platform (it's hosted and managed, not distributable). It's sub-optimal, I know :)
I wanted to switch to 7.2 on production because with 7.1 I am having problems with segfaults on medium loads and I suspect the sqlsrv package or maybe redis, which are the only 2 I use from pecl.

May 12 15:24:46 ocelot kernel: [22220.537668] php-fpm[5476]: segfault at 2026ad0 ip 000000002026ad0 sp 00007ffde1781188 error 15
May 12 15:24:46 ocelot systemd[1]: plesk-php71-fpm.service: Main process exited, code=dumped, status=11/SEGV0
May 12 15:24:47 ocelot systemd[1]: plesk-php71-fpm.service: Unit entered failed state.
May 12 15:24:47 ocelot systemd[1]: plesk-php71-fpm.service: Failed with result 'core-dump'.

@SlimDeluxe I just noticed that in your repro, you copy the extension from /usr/lib/php/20151012/ (in step 3 of your repro). The API number 20151012 refers to PHP 7.0, but you need the extension for PHP 7.2 (the different versions are not compatible with each other). You are getting the wrong sqlsrv.so in step 2, probably one that was already on your system. PECL should install the extension into /usr/lib/php/20170718. Please see if you have the extension in this directory after installing with PECL, that would be the correct sqlsrv.so to use.

@david-puglielli I don't have such a directory, also in step no.2 I search for it system-wide and I also see it has the modified date 13th May, so it's definitely the one PECL compiled.
What happens if I compile it on some other machine with 7.2 and copy it over to this one? I've never done that.

If it's the extension pecl compiled, then you are probably running pecl for PHP 7.0, and if you don't have the directory I referred to, then I suspect you compiled PHP 7.2 from source (the default extension directory is different if you install PHP from source as opposed to your package manager). In any case, the sqlsrv.so that you have compiled from pecl is not compatible with your PHP installation. Please run the following:

pecl version

and note which version of PHP is listed. Then run

php -i | grep extension_dir

and note what the default extension directory is, and let us know what the output of these commands are. Thanks!

Note: I am not using the default/OS provided PHP, my PHP binaries are in /opt/plesk/php/7.2/bin/

But here's the output for both commands:

root@ocelot:~# /opt/plesk/php/7.2/bin/pecl version
PEAR Version: 1.10.5
PHP Version: 7.2.5
Zend Engine Version: 3.2.0
Running on: Linux ocelot 4.4.0-124-generic #148-Ubuntu SMP Wed May 2 13:00:18 UTC 2018 x86_64
root@ocelot:~# /opt/plesk/php/7.2/bin/php -i | grep extension_dir
extension_dir => /opt/plesk/php/7.2/lib/php/modules => /opt/plesk/php/7.2/lib/php/modules

I will retry installing the extension with PECL to see the output, maybe it has something about this.

Ok, got it. By looking at the output, I realised it's not using the correct API, like you mentioned before.

root@ocelot:~# /opt/plesk/php/7.2/bin/pecl install sqlsrv
Starting to download sqlsrv-5.2.0.tgz (171,728 bytes)
.....................................done: 171,728 bytes
33 source files, building
running: phpize
Configuring for:
PHP Api Version:         20151012
Zend Module Api No:      20151012
Zend Extension Api No:   320151012
building in /tmp/pear-build-rootjrBqt7/sqlsrv-5.2.0

However:

root@ocelot:~# /opt/plesk/php/7.2/bin/php -i | grep "PHP API"
PHP API => 20170718

The solution was to install plesk-php72-dev and fix the PECL config, like described here. After reinstalling it already copies it in the correct modules dir.
So yes, it's was probably just a multi-php Plesk specific issue (don't know if the OS provided one installs the dev package).
Thank you for helping out :)

Solved a similar problem as follows:

pecl config-set php_ini /etc/php/7.2/cli/php.ini
pecl uninstall pdo_sqlsrv
pecl install pdo_sqlsrv

And also put the package
apt-get install php7.2-dev
Otherwise, an error occurred
sh: 1: phpize7.2: not found ERROR: phpize failed

install plesk-php72-dev

Find and put this package failed

--

I also have this similar error.

Finally, I successfully build the Docker image with the PHP-MSSQL.

My Dockerfile contents are as follows:

# Install required packages
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install -y software-properties-common
RUN apt-get install -y python-software-properties
RUN LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php
RUN apt-get update
RUN apt-get install -y apt-transport-https apt-utils curl php7.1-cli php7.1-mysql php7.1-curl
RUN apt-get install -y php7.1-xml php7.1-dom php7.1-xsl php7.1-json php7.1-odbc php7.1-dev
RUN apt-get install -y libcurl3-openssl-dev

RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | tee /etc/apt/sources.list.d/mssql-tools.list
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get install -y mssql-tools
RUN apt-get install -y unixodbc-dev

RUN export PATH="$PATH:/opt/mssql-tools/bin"
RUN export PATH="$PATH:/opt/mssql-tools/bin"
RUN pecl config-set php_ini /etc/php/7.1/cli/php.ini
RUN pecl install sqlsrv
RUN pecl install pdo_sqlsrv
RUN echo extension=sqlsrv.so >> `php --ini | grep "Scan for additional .ini files" | sed -e "s|.*:\s*||"`/20-sqlsrv.ini
RUN echo extension=pdo_sqlsrv.so >> `php --ini | grep "Scan for additional .ini files" | sed -e "s|.*:\s*||"`/30-pdo_sqlsrv.ini

#Install cim-web service
WORKDIR /root/dbp-dataexchange
COPY ./config.ini ./
COPY ./*.php ./

ENTRYPOINT [ "bash" ]

Hopefully this build can help someone to build the PHP-MSSQL environment.

I have encountered this case, I fixed on Ubuntu the following:

sudo update-alternatives --set php /usr/bin/php7.2

sudo update-alternatives --set php-config /usr/bin/php7.2-config
and:

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv

For the life of me on Ubuntu 16.04 I cannot get the pdo_sqlsrv drivers to run. The sqlsrv driver works fine. I'm using the latest 5.6.1 .. I'm about to try the 5.7.0 preview. What would cause this to happen?

`

PHP Startup: Unable to load dynamic library 'pdo_sqlsrv.so' (tried: /usr/lib/php/20180731/pdo_sqlsrv.so (/usr/lib/php/20180731/pdo_sqlsrv.so: undefined symbol: php_pdo_register_driver), /usr/lib/php/20180731/pdo_sqlsrv.so.so (/usr/lib/php/20180731/pdo_sqlsrv.so.so: undefined symbol: php_pdo_register_driver)) in Unknown on line 0

`

Hi @Fever905,

I assume pecl install pdo_sqlsrv was successful, but for pdo_sqlsrv to work it has to load after pdo.so. Thus, please make sure you follow the instructions

Thank you that sovled it!!
I added extension=pdo.so just above the extension=pdo_sqlsrv.so and it worked!

I also removed all the odbc mssq-tools, some freetds and freetds-dev stuff i had and then reinstalled mssql-tools, unixodbc, unixodbc-dev and msodbcsql17

Was this page helpful?
0 / 5 - 0 ratings