skip to Main Content

I am currently in the process of trying to integrate a PostgreSQL database into a PHP application.

When I run php -m, it lists a very long list of extensions/modules which are allegedly installed, such as pdo_pgsql. (The extension I wish to use).

However, when I edit my php.ini file and uncomment the extension=pdo_pgsql line, enabling the extension, PHP will start throwing errors at me constantly:

PHP Warning: PHP Startup: Unable to load dynamic library ‘pdo_pgsql’
(tried: /usr/local/lib/php/pecl/20230831/pdo_pgsql

Obviously, the problem here is that my php.ini file is stating extension_dir="/usr/local/lib/php/pecl/20230831", and even from looking there myself, that folder is empty.

Are the extensions/modules which the php -m command said are installed actually installed? If so, where could they be found (so that I can point my php.ini file’s extension_dir line there).

I am running macOS Sonoma 14.5, and I installed PHP using Homebrew, it is version 8.3.8.

I have tried using the UNIX terminal command find . -name "*pgsql*" -exec ls -ld {} ; to search for the extension, yet have found nothing.

Running php -m returns

[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dba
dom
exif
FFI
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
intl
json
ldap
libxml
mbstring
mysqli
mysqlnd
odbc
openssl
pcntl
pcre
PDO
pdo_dblib
pdo_mysql
PDO_ODBC
pdo_pgsql
pdo_sqlite
pgsql
Phar
posix
pq
pspell
random
raphf
readline
Reflection
session
shmop
SimpleXML
soap
sockets
sodium
SPL
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tidy
tokenizer
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache

And the full error which PHP gives me is

PHP Warning: PHP Startup: Unable to load dynamic library ‘pdo_pgsql’
(tried: /usr/local/lib/php/pecl/20230831/pdo_pgsql
(dlopen(/usr/local/lib/php/pecl/20230831/pdo_pgsql, 0x0009): tried:
‘/usr/local/lib/php/pecl/20230831/pdo_pgsql’ (no such file),
‘/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/php/pecl/20230831/pdo_pgsql’
(no such file), ‘/usr/local/lib/php/pecl/20230831/pdo_pgsql’ (no such
file)), /usr/local/lib/php/pecl/20230831/pdo_pgsql.so
(dlopen(/usr/local/lib/php/pecl/20230831/pdo_pgsql.so, 0x0009): tried:
‘/usr/local/lib/php/pecl/20230831/pdo_pgsql.so’ (no such file),
‘/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/php/pecl/20230831/pdo_pgsql.so’
(no such file), ‘/usr/local/lib/php/pecl/20230831/pdo_pgsql.so’ (no
such file))) in Unknown on line 0

Warning: PHP Startup: Unable to load dynamic library ‘pdo_pgsql’
(tried: /usr/local/lib/php/pecl/20230831/pdo_pgsql
(dlopen(/usr/local/lib/php/pecl/20230831/pdo_pgsql, 0x0009): tried:
‘/usr/local/lib/php/pecl/20230831/pdo_pgsql’ (no such file),
‘/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/php/pecl/20230831/pdo_pgsql’
(no such file), ‘/usr/local/lib/php/pecl/20230831/pdo_pgsql’ (no such
file)), /usr/local/lib/php/pecl/20230831/pdo_pgsql.so
(dlopen(/usr/local/lib/php/pecl/20230831/pdo_pgsql.so, 0x0009): tried:
‘/usr/local/lib/php/pecl/20230831/pdo_pgsql.so’ (no such file),
‘/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/php/pecl/20230831/pdo_pgsql.so’
(no such file), ‘/usr/local/lib/php/pecl/20230831/pdo_pgsql.so’ (no
such file))) in Unknown on line 0 [PHP Modules]

2

Answers


  1. Chosen as BEST ANSWER

    This took me way too long, however I think I now know the answer.

    Turns out, that the pdo_pgsql extension (and all the other extensions) are statically linked, and thus are ingrained into the PHP binary. Thus, they will not be found in any extension folder. In fact, you don't even have to include them in the php.ini file. It's already installed. Just use it in your .php files. 🤦


  2. TLDR

    In this case, i.e. where you’re trying to connect to a Postgres DB, “where are the extensions?” is the wrong question. Homebrew’s PHP was compiled with pdo_pgsql statically linked, so no dynamic extension is required. What is required is that libpq be installed: be sure to have run brew install libpq.

    Further context

    How can we tell pdo_pgsql is compiled into PHP? Well, for one (as you found yourself), php -m lists the module. Also, running brew info php will display, amongst other things, a link to the recipe used to compile PHP:

    ❯ brew info php    
    ==> php: stable 8.3.8 (bottled), HEAD
    General-purpose scripting language
    https://www.php.net/
    Installed
    /opt/homebrew/Cellar/php/8.3.8 (524 files, 88.8MB) *
      Poured from bottle using the formulae.brew.sh API on 2024-06-08 at 16:58:15
    From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/p/php.rb
    

    Following that GitHub link to php.rb you can see configure was called with args that includes the following:

      --with-pdo-dblib=#{Formula["freetds"].opt_prefix}
      --with-pdo-mysql=mysqlnd
      --with-pdo-odbc=unixODBC,#{Formula["unixodbc"].opt_prefix}
      --with-pdo-pgsql=#{Formula["libpq"].opt_prefix}
      --with-pdo-sqlite
      --with-pgsql=#{Formula["libpq"].opt_prefix}
    

    Checking the PDO installation docs we can see that step 2 says (my emphasis):

    When installing PDO as a shared module, the php.ini file needs to be updated so that the PDO extension will be loaded automatically when PHP runs … If you built PDO and the database-specific extensions statically, you can skip this step.

    (Perhaps it should say “you should skip this step”, since not doing so yields the error message you’ve been seeing.)

    Finally, with the extension not referenced in php.ini, instantiating a PDO connection with a correctly formatted DSN, and attempting to use that to run a query does, in fact, work.

    Lazy example:

    $conn = new PDO(
      "pgsql: user=postgres password=password host=localhost dbname=my_db"
    );
    $stmt = $conn->query("select * from my_table");
    $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
    foreach ($rs as $r) {
        print_r($r);
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search