about summary refs log tree commit diff
path: root/nixpkgs/pkgs/top-level/php-packages.nix
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-04-27 21:04:56 +0000
committerAlyssa Ross <hi@alyssa.is>2020-04-27 21:04:56 +0000
commita4e6c7d26af697f4346cacb7ab18dcd7fcfc056e (patch)
tree47950e79183035018882419c4eff5047d1537b99 /nixpkgs/pkgs/top-level/php-packages.nix
parent5b00523fb58512232b819a301c4309f579c7f09c (diff)
parent22a3bf9fb9edad917fb6cd1066d58b5e426ee975 (diff)
downloadnixlib-a4e6c7d26af697f4346cacb7ab18dcd7fcfc056e.tar
nixlib-a4e6c7d26af697f4346cacb7ab18dcd7fcfc056e.tar.gz
nixlib-a4e6c7d26af697f4346cacb7ab18dcd7fcfc056e.tar.bz2
nixlib-a4e6c7d26af697f4346cacb7ab18dcd7fcfc056e.tar.lz
nixlib-a4e6c7d26af697f4346cacb7ab18dcd7fcfc056e.tar.xz
nixlib-a4e6c7d26af697f4346cacb7ab18dcd7fcfc056e.tar.zst
nixlib-a4e6c7d26af697f4346cacb7ab18dcd7fcfc056e.zip
Merge commit '22a3bf9fb9edad917fb6cd1066d58b5e426ee975'
Diffstat (limited to 'nixpkgs/pkgs/top-level/php-packages.nix')
-rw-r--r--nixpkgs/pkgs/top-level/php-packages.nix1352
1 files changed, 749 insertions, 603 deletions
diff --git a/nixpkgs/pkgs/top-level/php-packages.nix b/nixpkgs/pkgs/top-level/php-packages.nix
index cc830fa34986..0cda058459df 100644
--- a/nixpkgs/pkgs/top-level/php-packages.nix
+++ b/nixpkgs/pkgs/top-level/php-packages.nix
@@ -1,704 +1,731 @@
-{ stdenv, lib, pkgs, fetchgit, php, autoconf, pkgconfig, re2c
-, bzip2, curl, libxml2, openssl, gmp5, icu, oniguruma, libsodium, html-tidy
-, libzip, zlib, pcre, pcre2, libxslt, aspell, openldap, cyrus_sasl, uwimap
-, pam, libiconv, enchant1, libXpm, gd, libwebp, libjpeg, libpng, freetype
-, libffi, freetds, postgresql, sqlite, recode, net-snmp, unixODBC }:
+{ stdenv, lib, pkgs, fetchgit, php, phpWithExtensions, autoconf, pkgconfig, re2c
+, gettext, bzip2, curl, libxml2, openssl, gmp, icu, oniguruma, libsodium
+, html-tidy, libzip, zlib, pcre, pcre2, libxslt, aspell, openldap, cyrus_sasl
+, uwimap, pam, libiconv, enchant1, libXpm, gd, libwebp, libjpeg, libpng
+, freetype, libffi, freetds, postgresql, sqlite, net-snmp, unixODBC, libedit
+, readline, rsync
+}:
 
 let
-  self = with self; {
-    buildPecl = import ../build-support/build-pecl.nix {
-      inherit php;
-      inherit (pkgs) stdenv autoreconfHook fetchurl re2c;
-    };
+  buildPecl = import ../build-support/build-pecl.nix {
+    inherit php lib;
+    inherit (pkgs) stdenv autoreconfHook fetchurl re2c;
+  };
 
-    # Wrap mkDerivation to prepend pname with "php-" to make names consistent
-    # with how buildPecl does it and make the file easier to overview.
-    mkDerivation = { pname, ... }@args: pkgs.stdenv.mkDerivation (args // {
-      pname = "php-${pname}";
-    });
+  # Wrap mkDerivation to prepend pname with "php-" to make names consistent
+  # with how buildPecl does it and make the file easier to overview.
+  mkDerivation = { pname, ... }@args: pkgs.stdenv.mkDerivation (args // {
+    pname = "php-${pname}";
+  });
 
   isPhp73 = pkgs.lib.versionAtLeast php.version "7.3";
   isPhp74 = pkgs.lib.versionAtLeast php.version "7.4";
 
-  apcu = buildPecl {
-    version = "5.1.18";
-    pname = "apcu";
-
-    sha256 = "0ayykd4hfvdzk7qnr5k6yq5scwf6rb2i05xscfv76q5dmkkynvfl";
-
-    buildInputs = [ (if isPhp73 then pkgs.pcre2 else pkgs.pcre) ];
-    doCheck = true;
-    checkTarget = "test";
-    checkFlagsArray = ["REPORT_EXIT_STATUS=1" "NO_INTERACTION=1"];
-    makeFlags = [ "phpincludedir=$(dev)/include" ];
-    outputs = [ "out" "dev" ];
-  };
-
-  apcu_bc = buildPecl {
-    version = "1.0.5";
-    pname = "apcu_bc";
+  pcre' = if (lib.versionAtLeast php.version "7.3") then pcre2 else pcre;
+in
+{
+  inherit buildPecl;
 
-    sha256 = "0ma00syhk2ps9k9p02jz7rii6x3i2p986il23703zz5npd6y9n20";
+  # This is a set of interactive tools based on PHP.
+  packages = {
+    box = mkDerivation rec {
+      version = "2.7.5";
+      pname = "box";
 
-    buildInputs = [ apcu (if isPhp73 then pkgs.pcre2 else pkgs.pcre) ];
-  };
+      src = pkgs.fetchurl {
+        url = "https://github.com/box-project/box2/releases/download/${version}/box-${version}.phar";
+        sha256 = "1zmxdadrv0i2l8cz7xb38gnfmfyljpsaz2nnkjzqzksdmncbgd18";
+      };
 
-  ast = buildPecl {
-    version = "1.0.5";
-    pname = "ast";
-
-    sha256 = "16c5isldm4csjbcvz1qk2mmrhgvh24sxsp6w6f5a37xpa3vciawp";
-  };
+      phases = [ "installPhase" ];
+      buildInputs = [ pkgs.makeWrapper ];
 
-  box = mkDerivation rec {
-    version = "2.7.5";
-    pname = "box";
-
-    src = pkgs.fetchurl {
-      url = "https://github.com/box-project/box2/releases/download/${version}/box-${version}.phar";
-      sha256 = "1zmxdadrv0i2l8cz7xb38gnfmfyljpsaz2nnkjzqzksdmncbgd18";
-    };
-
-    phases = [ "installPhase" ];
-    buildInputs = [ pkgs.makeWrapper ];
-
-    installPhase = ''
-      mkdir -p $out/bin
-      install -D $src $out/libexec/box/box.phar
-      makeWrapper ${php}/bin/php $out/bin/box \
-        --add-flags "-d phar.readonly=0 $out/libexec/box/box.phar"
-    '';
+      installPhase = ''
+        mkdir -p $out/bin
+        install -D $src $out/libexec/box/box.phar
+        makeWrapper ${phpWithExtensions}/bin/php $out/bin/box \
+          --add-flags "-d phar.readonly=0 $out/libexec/box/box.phar"
+      '';
 
-    meta = with pkgs.lib; {
-      description = "An application for building and managing Phars";
-      license = licenses.mit;
-      homepage = https://box-project.github.io/box2/;
-      maintainers = with maintainers; [ jtojnar ];
+      meta = with pkgs.lib; {
+        description = "An application for building and managing Phars";
+        license = licenses.mit;
+        homepage = "https://box-project.github.io/box2/";
+        maintainers = with maintainers; [ jtojnar ];
+      };
     };
-  };
 
-  composer = mkDerivation rec {
-    version = "1.9.3";
-    pname = "composer";
+    composer = mkDerivation rec {
+      version = "1.9.3";
+      pname = "composer";
 
-    src = pkgs.fetchurl {
-      url = "https://getcomposer.org/download/${version}/composer.phar";
-      sha256 = "VRZVwvyB9BBlCPQrvEsk6r00sCKxO8Hn2WQr9IPQp9Q=";
-    };
+      src = pkgs.fetchurl {
+        url = "https://getcomposer.org/download/${version}/composer.phar";
+        sha256 = "VRZVwvyB9BBlCPQrvEsk6r00sCKxO8Hn2WQr9IPQp9Q=";
+      };
 
-    dontUnpack = true;
+      dontUnpack = true;
 
-    nativeBuildInputs = [ pkgs.makeWrapper ];
+      nativeBuildInputs = [ pkgs.makeWrapper ];
 
-    installPhase = ''
-      mkdir -p $out/bin
-      install -D $src $out/libexec/composer/composer.phar
-      makeWrapper ${php}/bin/php $out/bin/composer \
-        --add-flags "$out/libexec/composer/composer.phar" \
-        --prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.unzip ]}
-    '';
+      installPhase = ''
+        mkdir -p $out/bin
+        install -D $src $out/libexec/composer/composer.phar
+        makeWrapper ${phpWithExtensions}/bin/php $out/bin/composer \
+          --add-flags "$out/libexec/composer/composer.phar" \
+          --prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.unzip ]}
+      '';
 
-    meta = with pkgs.lib; {
-      description = "Dependency Manager for PHP";
-      license = licenses.mit;
-      homepage = https://getcomposer.org/;
-      maintainers = with maintainers; [ globin offline ];
+      meta = with pkgs.lib; {
+        description = "Dependency Manager for PHP";
+        license = licenses.mit;
+        homepage = "https://getcomposer.org/";
+        maintainers = with maintainers; [ globin offline ];
+      };
     };
-  };
-
-  couchbase = buildPecl rec {
-    version = "2.6.1";
-    pname = "couchbase";
-
-    buildInputs = [ pkgs.libcouchbase pkgs.zlib igbinary pcs ];
-
-    src = pkgs.fetchFromGitHub {
-      owner = "couchbase";
-      repo = "php-couchbase";
-      rev = "v${version}";
-      sha256 = "0jdzgcvab1vpxai23brmmvizjjq2d2dik9aklz6bzspfb512qjd6";
-    };
-
-    configureFlags = [ "--with-couchbase" ];
-
-    patches = [
-      (pkgs.writeText "php-couchbase.patch" ''
-        --- a/config.m4
-        +++ b/config.m4
-        @@ -9,7 +9,7 @@ if test "$PHP_COUCHBASE" != "no"; then
-             LIBCOUCHBASE_DIR=$PHP_COUCHBASE
-           else
-             AC_MSG_CHECKING(for libcouchbase in default path)
-        -    for i in /usr/local /usr; do
-        +    for i in ${pkgs.libcouchbase}; do
-               if test -r $i/include/libcouchbase/couchbase.h; then
-                 LIBCOUCHBASE_DIR=$i
-                 AC_MSG_RESULT(found in $i)
-        @@ -154,6 +154,8 @@ COUCHBASE_FILES=" \
-             igbinary_inc_path="$phpincludedir"
-           elif test -f "$phpincludedir/ext/igbinary/igbinary.h"; then
-             igbinary_inc_path="$phpincludedir"
-        +  elif test -f "${igbinary.dev}/include/ext/igbinary/igbinary.h"; then
-        +    igbinary_inc_path="${igbinary.dev}/include"
-           fi
-           if test "$igbinary_inc_path" = ""; then
-             AC_MSG_WARN([Cannot find igbinary.h])
-      '')
-    ];
 
-    meta.broken = isPhp74; # Build error
-  };
+    php-cs-fixer = mkDerivation rec {
+      version = "2.16.1";
+      pname = "php-cs-fixer";
 
-  event = buildPecl {
-    version = "2.5.3";
-    pname = "event";
+      src = pkgs.fetchurl {
+        url = "https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v${version}/php-cs-fixer.phar";
+        sha256 = "1dq1nhy666zg6d4fkfsjwhj1vwh1ncap2c9ljplxv98a9mm6fk68";
+      };
 
-    sha256 = "12liry5ldvgwp1v1a6zgfq8w6iyyxmsdj4c71bp157nnf58cb8hb";
+      phases = [ "installPhase" ];
+      buildInputs = [ pkgs.makeWrapper ];
 
-    configureFlags = [
-      "--with-event-libevent-dir=${pkgs.libevent.dev}"
-      "--with-event-core"
-      "--with-event-extra"
-      "--with-event-pthreads"
-    ];
-    nativeBuildInputs = [ pkgs.pkgconfig ];
-    buildInputs = with pkgs; [ openssl libevent ];
-
-    meta = with pkgs.lib; {
-      description = ''
-        This is an extension to efficiently schedule I/O, time and signal based
-        events using the best I/O notification mechanism available for specific platform.
+      installPhase = ''
+        mkdir -p $out/bin
+        install -D $src $out/libexec/php-cs-fixer/php-cs-fixer.phar
+        makeWrapper ${php}/bin/php $out/bin/php-cs-fixer \
+          --add-flags "$out/libexec/php-cs-fixer/php-cs-fixer.phar"
       '';
-      license = licenses.php301;
-      homepage = "https://bitbucket.org/osmanov/pecl-event/";
-    };
-  };
-
-  igbinary = buildPecl {
-    version = "3.0.1";
-    pname = "igbinary";
 
-    sha256 = "1w8jmf1qpggdvq0ndfi86n7i7cqgh1s8q6hys2lijvi37rzn0nar";
+      meta = with pkgs.lib; {
+        description = "A tool to automatically fix PHP coding standards issues";
+        license = licenses.mit;
+        homepage = "http://cs.sensiolabs.org/";
+        maintainers = with maintainers; [ jtojnar ];
+      };
+    };
 
-    configureFlags = [ "--enable-igbinary" ];
-    makeFlags = [ "phpincludedir=$(dev)/include" ];
-    outputs = [ "out" "dev" ];
-  };
+    php-parallel-lint = mkDerivation rec {
+      version = "1.0.0";
+      pname = "php-parallel-lint";
+
+      src = pkgs.fetchFromGitHub {
+        owner = "JakubOnderka";
+        repo = "PHP-Parallel-Lint";
+        rev = "v${version}";
+        sha256 = "16nv8yyk2z3l213dg067l6di4pigg5rd8yswr5xgd18jwbys2vnw";
+      };
+
+      buildInputs = [
+        pkgs.makeWrapper
+        php.packages.composer
+        php.packages.box
+      ];
+
+      buildPhase = ''
+        composer dump-autoload
+        box build
+      '';
 
-  imagick = buildPecl {
-    version = "3.4.4";
-    pname = "imagick";
+      installPhase = ''
+        mkdir -p $out/bin
+        install -D parallel-lint.phar $out/libexec/php-parallel-lint/php-parallel-lint.phar
+        makeWrapper ${php}/bin/php $out/bin/php-parallel-lint \
+          --add-flags "$out/libexec/php-parallel-lint/php-parallel-lint.phar"
+      '';
 
-    sha256 = "0xvhaqny1v796ywx83w7jyjyd0nrxkxf34w9zi8qc8aw8qbammcd";
+      meta = with pkgs.lib; {
+        description = "This tool check syntax of PHP files faster than serial check with fancier output";
+        license = licenses.bsd2;
+        homepage = "https://github.com/JakubOnderka/PHP-Parallel-Lint";
+        maintainers = with maintainers; [ jtojnar ];
+      };
+    };
 
-    configureFlags = [ "--with-imagick=${pkgs.imagemagick.dev}" ];
-    nativeBuildInputs = [ pkgs.pkgconfig ];
-    buildInputs = [ (if isPhp73 then pkgs.pcre2 else pkgs.pcre) ];
-  };
+    phpcbf = mkDerivation rec {
+      version = "3.5.4";
+      pname = "phpcbf";
 
-  mailparse = buildPecl {
-    version = "3.0.3";
-    pname = "mailparse";
+      src = pkgs.fetchurl {
+        url = "https://github.com/squizlabs/PHP_CodeSniffer/releases/download/${version}/phpcbf.phar";
+        sha256 = "18x7fk59l821pivw1i2r868y78qgs0qk47b9il1smwi6plwyyflr";
+      };
 
-    sha256 = "00nk14jbdbln93mx3ag691avc11ff94hkadrcv5pn51c6ihsxbmz";
-  };
+      phases = [ "installPhase" ];
+      nativeBuildInputs = [ pkgs.makeWrapper ];
 
-  maxminddb = buildPecl rec {
-    pname = "maxminddb";
-    version = "1.6.0";
+      installPhase = ''
+        mkdir -p $out/bin
+        install -D $src $out/libexec/phpcbf/phpcbf.phar
+        makeWrapper ${phpWithExtensions}/bin/php $out/bin/phpcbf \
+          --add-flags "$out/libexec/phpcbf/phpcbf.phar"
+      '';
 
-    src = pkgs.fetchFromGitHub {
-      owner = "maxmind";
-      repo = "MaxMind-DB-Reader-php";
-      rev = "v${version}";
-      sha256 = "0sa943ij9pgz55aik93lllb8lh063bvr66ibn77p3y3p41vdiabz";
+      meta = with pkgs.lib; {
+        description = "PHP coding standard beautifier and fixer";
+        license = licenses.bsd3;
+        homepage = "https://squizlabs.github.io/PHP_CodeSniffer/";
+        maintainers = with maintainers; [ cmcdragonkai etu ];
+      };
     };
 
-    buildInputs = [ pkgs.libmaxminddb ];
-    sourceRoot = "source/ext";
+    phpcs = mkDerivation rec {
+      version = "3.5.4";
+      pname = "phpcs";
 
-    meta = with pkgs.lib; {
-      description = "C extension that is a drop-in replacement for MaxMind\\Db\\Reader";
-      license = with licenses; [ asl20 ];
-      maintainers = with maintainers; [ ajs124 das_j ];
-    };
-  };
+      src = pkgs.fetchurl {
+        url = "https://github.com/squizlabs/PHP_CodeSniffer/releases/download/${version}/phpcs.phar";
+        sha256 = "1lrybdxxig3yqd3i3nwji5jjn377p50sbpm4s4852dlsxz9qnlgs";
+      };
 
-  memcached = buildPecl rec {
-    version = "3.1.5";
-    pname = "memcached";
+      phases = [ "installPhase" ];
+      buildInputs = [ pkgs.makeWrapper ];
 
-    src = fetchgit {
-      url = "https://github.com/php-memcached-dev/php-memcached";
-      rev = "v${version}";
-      sha256 = "01mbh2m3kfbdvih3c8g3g9h4vdd80r0i9g2z8b3lx3mi8mmcj380";
-    };
+      installPhase = ''
+        mkdir -p $out/bin
+        install -D $src $out/libexec/phpcs/phpcs.phar
+        makeWrapper ${phpWithExtensions}/bin/php $out/bin/phpcs \
+          --add-flags "$out/libexec/phpcs/phpcs.phar"
+      '';
 
-    configureFlags = [
-      "--with-zlib-dir=${pkgs.zlib.dev}"
-      "--with-libmemcached-dir=${pkgs.libmemcached}"
-    ];
+      meta = with pkgs.lib; {
+        description = "PHP coding standard tool";
+        license = licenses.bsd3;
+        homepage = "https://squizlabs.github.io/PHP_CodeSniffer/";
+        maintainers = with maintainers; [ javaguirre etu ];
+      };
+    };
 
-    nativeBuildInputs = [ pkgs.pkgconfig ];
-    buildInputs = with pkgs; [ cyrus_sasl zlib ];
-  };
+    phpstan = mkDerivation rec {
+      version = "0.12.18";
+      pname = "phpstan";
 
-  mongodb = buildPecl {
-    pname = "mongodb";
-    version = "1.6.1";
-
-    sha256 = "1j1w4n33347j9kwvxwsrix3gvjbiqcn1s5v59pp64s536cci8q0m";
-
-    nativeBuildInputs = [ pkgs.pkgconfig ];
-    buildInputs = with pkgs; [
-      cyrus_sasl
-      icu
-      openssl
-      snappy
-      zlib
-      (if isPhp73 then pcre2 else pcre)
-    ] ++ lib.optional (pkgs.stdenv.isDarwin) pkgs.darwin.apple_sdk.frameworks.Security;
-  };
+      src = pkgs.fetchurl {
+        url = "https://github.com/phpstan/phpstan/releases/download/${version}/phpstan.phar";
+        sha256 = "0xf0q2z6rhpnbys53si05mddfyjn3wx5wc8zx5y6dv5fzw6z7rch";
+      };
 
-  oci8 = buildPecl {
-    version = "2.2.0";
-    pname = "oci8";
+      phases = [ "installPhase" ];
+      nativeBuildInputs = [ pkgs.makeWrapper ];
 
-    sha256 = "0jhivxj1nkkza4h23z33y7xhffii60d7dr51h1czjk10qywl7pyd";
-    buildInputs = [ pkgs.oracle-instantclient ];
-    configureFlags = [ "--with-oci8=shared,instantclient,${pkgs.oracle-instantclient.lib}/lib" ];
+      installPhase = ''
+        mkdir -p $out/bin
+        install -D $src $out/libexec/phpstan/phpstan.phar
+        makeWrapper ${phpWithExtensions}/bin/php $out/bin/phpstan \
+          --add-flags "$out/libexec/phpstan/phpstan.phar"
+      '';
 
-    postPatch = ''
-      sed -i -e 's|OCISDKMANINC=`.*$|OCISDKMANINC="${pkgs.oracle-instantclient.dev}/include"|' config.m4
-    '';
-  };
+      meta = with pkgs.lib; {
+        description = "PHP Static Analysis Tool";
+        longDescription = ''
+        PHPStan focuses on finding errors in your code without actually running
+        it. It catches whole classes of bugs even before you write tests for the
+        code. It moves PHP closer to compiled languages in the sense that the
+        correctness of each line of the code can be checked before you run the
+        actual line.
+      '';
+        license = licenses.mit;
+        homepage = "https://github.com/phpstan/phpstan";
+        maintainers = with maintainers; [ etu ];
+      };
+    };
 
-  pcov = buildPecl {
-    version = "1.0.6";
-    pname = "pcov";
+    psalm = mkDerivation rec {
+      version = "3.9.3";
+      pname = "psalm";
 
-    sha256 = "1psfwscrc025z8mziq69pcx60k4fbkqa5g2ia8lplb94mmarj0v1";
+      src = pkgs.fetchurl {
+        url = "https://github.com/vimeo/psalm/releases/download/${version}/psalm.phar";
+        sha256 = "KHm2n06y/yxN5B2rCVxT5ja7HxkyxAMsjZ5HLb3xr4M=";
+      };
 
-    buildInputs = [ (if isPhp73 then pkgs.pcre2 else pkgs.pcre) ];
-  };
+      phases = [ "installPhase" ];
+      nativeBuildInputs = [ pkgs.makeWrapper ];
 
-  pcs = buildPecl {
-    version = "1.3.3";
-    pname = "pcs";
+      installPhase = ''
+        mkdir -p $out/bin
+        install -D $src $out/libexec/psalm/psalm.phar
+        makeWrapper ${php}/bin/php $out/bin/psalm \
+          --add-flags "$out/libexec/psalm/psalm.phar"
+      '';
 
-    sha256 = "0d4p1gpl8gkzdiv860qzxfz250ryf0wmjgyc8qcaaqgkdyh5jy5p";
+      meta = with pkgs.lib; {
+        description = "A static analysis tool for finding errors in PHP applications";
+        license = licenses.mit;
+        homepage = "https://github.com/vimeo/psalm";
+      };
+    };
 
-    meta.broken = isPhp74; # Build error
-  };
+    psysh = mkDerivation rec {
+      version = "0.9.12";
+      pname = "psysh";
 
-  pdo_oci = buildPecl rec {
-    inherit (php) src version;
+      src = pkgs.fetchurl {
+        url = "https://github.com/bobthecow/psysh/releases/download/v${version}/psysh-v${version}.tar.gz";
+        sha256 = "0bzmc94li481xk81gv460ipq9zl03skbnq8m3rnw34i2c04hxczc";
+      };
 
-    pname = "pdo_oci";
-    sourceRoot = "php-${version}/ext/pdo_oci";
+      phases = [ "installPhase" ];
+      nativeBuildInputs = [ pkgs.makeWrapper ];
 
-    buildInputs = [ pkgs.oracle-instantclient ];
-    configureFlags = [ "--with-pdo-oci=instantclient,${pkgs.oracle-instantclient.lib}/lib" ];
+      installPhase = ''
+        mkdir -p $out/bin
+        tar -xzf $src -C $out/bin
+        chmod +x $out/bin/psysh
+        wrapProgram $out/bin/psysh
+      '';
 
-    postPatch = ''
-      sed -i -e 's|OCISDKMANINC=`.*$|OCISDKMANINC="${pkgs.oracle-instantclient.dev}/include"|' config.m4
-    '';
+      meta = with pkgs.lib; {
+        description = "PsySH is a runtime developer console, interactive debugger and REPL for PHP.";
+        license = licenses.mit;
+        homepage = "https://psysh.org/";
+        maintainers = with maintainers; [ caugner ];
+      };
+    };
   };
 
-  pdo_sqlsrv = buildPecl {
-    version = "5.8.0";
-    pname = "pdo_sqlsrv";
 
-    sha256 = "0z4vbyd851b4jr6p69l2ylk91iihndsm2qjb429pxcv8g6dqzqll";
 
-    buildInputs = [ pkgs.unixODBC ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ pkgs.libiconv ];
-  };
+  # This is a set of PHP extensions meant to be used in php.buildEnv
+  # or php.withExtensions to extend the functionality of the PHP
+  # interpreter.
+  extensions = {
+    apcu = buildPecl {
+      version = "5.1.18";
+      pname = "apcu";
 
-  php-cs-fixer = mkDerivation rec {
-    version = "2.16.1";
-    pname = "php-cs-fixer";
+      sha256 = "0ayykd4hfvdzk7qnr5k6yq5scwf6rb2i05xscfv76q5dmkkynvfl";
 
-    src = pkgs.fetchurl {
-      url = "https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v${version}/php-cs-fixer.phar";
-      sha256 = "1dq1nhy666zg6d4fkfsjwhj1vwh1ncap2c9ljplxv98a9mm6fk68";
+      buildInputs = [ pcre' ];
+      doCheck = true;
+      checkTarget = "test";
+      checkFlagsArray = ["REPORT_EXIT_STATUS=1" "NO_INTERACTION=1"];
+      makeFlags = [ "phpincludedir=$(dev)/include" ];
+      outputs = [ "out" "dev" ];
     };
 
-    phases = [ "installPhase" ];
-    buildInputs = [ pkgs.makeWrapper ];
+    apcu_bc = buildPecl {
+      version = "1.0.5";
+      pname = "apcu_bc";
 
-    installPhase = ''
-      mkdir -p $out/bin
-      install -D $src $out/libexec/php-cs-fixer/php-cs-fixer.phar
-      makeWrapper ${php}/bin/php $out/bin/php-cs-fixer \
-        --add-flags "$out/libexec/php-cs-fixer/php-cs-fixer.phar"
-    '';
+      sha256 = "0ma00syhk2ps9k9p02jz7rii6x3i2p986il23703zz5npd6y9n20";
 
-    meta = with pkgs.lib; {
-      description = "A tool to automatically fix PHP coding standards issues";
-      license = licenses.mit;
-      homepage = http://cs.sensiolabs.org/;
-      maintainers = with maintainers; [ jtojnar ];
+      buildInputs = [
+        php.extensions.apcu
+        pcre'
+      ];
     };
-  };
 
-  php-parallel-lint = mkDerivation rec {
-    version = "1.0.0";
-    pname = "php-parallel-lint";
+    ast = buildPecl {
+      version = "1.0.5";
+      pname = "ast";
 
-    src = pkgs.fetchFromGitHub {
-      owner = "JakubOnderka";
-      repo = "PHP-Parallel-Lint";
-      rev = "v${version}";
-      sha256 = "16nv8yyk2z3l213dg067l6di4pigg5rd8yswr5xgd18jwbys2vnw";
+      sha256 = "16c5isldm4csjbcvz1qk2mmrhgvh24sxsp6w6f5a37xpa3vciawp";
     };
 
-    buildInputs = [ pkgs.makeWrapper composer box ];
+    couchbase = buildPecl rec {
+      version = "2.6.1";
+      pname = "couchbase";
+
+      buildInputs = [
+        pkgs.libcouchbase
+        pkgs.zlib
+        php.extensions.igbinary
+        php.extensions.pcs
+      ];
+
+      src = pkgs.fetchFromGitHub {
+        owner = "couchbase";
+        repo = "php-couchbase";
+        rev = "v${version}";
+        sha256 = "0jdzgcvab1vpxai23brmmvizjjq2d2dik9aklz6bzspfb512qjd6";
+      };
+
+      configureFlags = [ "--with-couchbase" ];
+      internalDeps = [ php.extensions.json ];
+      patches = [
+        (pkgs.writeText "php-couchbase.patch" ''
+          --- a/config.m4
+          +++ b/config.m4
+          @@ -9,7 +9,7 @@ if test "$PHP_COUCHBASE" != "no"; then
+               LIBCOUCHBASE_DIR=$PHP_COUCHBASE
+             else
+               AC_MSG_CHECKING(for libcouchbase in default path)
+          -    for i in /usr/local /usr; do
+          +    for i in ${pkgs.libcouchbase}; do
+                 if test -r $i/include/libcouchbase/couchbase.h; then
+                   LIBCOUCHBASE_DIR=$i
+                   AC_MSG_RESULT(found in $i)
+          @@ -154,6 +154,8 @@ COUCHBASE_FILES=" \
+               igbinary_inc_path="$phpincludedir"
+             elif test -f "$phpincludedir/ext/igbinary/igbinary.h"; then
+               igbinary_inc_path="$phpincludedir"
+          +  elif test -f "${php.extensions.igbinary.dev}/include/ext/igbinary/igbinary.h"; then
+          +    igbinary_inc_path="${php.extensions.igbinary.dev}/include"
+             fi
+             if test "$igbinary_inc_path" = ""; then
+               AC_MSG_WARN([Cannot find igbinary.h])
+        '')
+      ];
+
+      meta.broken = isPhp74; # Build error
+    };
 
-    buildPhase = ''
-      composer dump-autoload
-      box build
-    '';
+    event = buildPecl {
+      version = "2.5.3";
+      pname = "event";
 
-    installPhase = ''
-      mkdir -p $out/bin
-      install -D parallel-lint.phar $out/libexec/php-parallel-lint/php-parallel-lint.phar
-      makeWrapper ${php}/bin/php $out/bin/php-parallel-lint \
-        --add-flags "$out/libexec/php-parallel-lint/php-parallel-lint.phar"
-    '';
-
-    meta = with pkgs.lib; {
-      description = "This tool check syntax of PHP files faster than serial check with fancier output";
-      license = licenses.bsd2;
-      homepage = https://github.com/JakubOnderka/PHP-Parallel-Lint;
-      maintainers = with maintainers; [ jtojnar ];
-    };
-  };
+      sha256 = "12liry5ldvgwp1v1a6zgfq8w6iyyxmsdj4c71bp157nnf58cb8hb";
 
-  php_excel = buildPecl rec {
-    version = "1.0.2";
-    pname = "php_excel";
-    phpVersion = "php7";
+      configureFlags = [
+        "--with-event-libevent-dir=${pkgs.libevent.dev}"
+        "--with-event-core"
+        "--with-event-extra"
+        "--with-event-pthreads"
+      ];
 
-    buildInputs = [ pkgs.libxl ];
+      postPhpize = ''
+        substituteInPlace configure --replace 'as_fn_error $? "Couldn'\'''t find $phpincludedir/sockets/php_sockets.h. Please check if sockets extension installed" "$LINENO" 5' \
+                                              ':'
+      '';
 
-    src = pkgs.fetchurl {
-      url = "https://github.com/iliaal/php_excel/releases/download/Excel-1.0.2-PHP7/excel-${version}-${phpVersion}.tgz";
-      sha256 = "0dpvih9gpiyh1ml22zi7hi6kslkilzby00z1p8x248idylldzs2n";
+      nativeBuildInputs = [ pkgs.pkgconfig ];
+      buildInputs = with pkgs; [ openssl libevent ];
+      internalDeps = [ php.extensions.sockets ];
+
+      meta = with pkgs.lib; {
+        description = ''
+          This is an extension to efficiently schedule I/O, time and signal based
+          events using the best I/O notification mechanism available for specific platform.
+        '';
+        license = licenses.php301;
+        homepage = "https://bitbucket.org/osmanov/pecl-event/";
+      };
     };
 
-    configureFlags = [ "--with-excel" "--with-libxl-incdir=${pkgs.libxl}/include_c" "--with-libxl-libdir=${pkgs.libxl}/lib" ];
-    meta.broken = true;
-  };
+    igbinary = buildPecl {
+      version = "3.0.1";
+      pname = "igbinary";
 
-  phpcbf = mkDerivation rec {
-    version = "3.5.3";
-    pname = "phpcbf";
+      sha256 = "1w8jmf1qpggdvq0ndfi86n7i7cqgh1s8q6hys2lijvi37rzn0nar";
 
-    src = pkgs.fetchurl {
-      url = "https://github.com/squizlabs/PHP_CodeSniffer/releases/download/${version}/phpcbf.phar";
-      sha256 = "1mrsf9p6p64pyqyylnlxb2b7cirdfccch83g7yhfnka3znffq86v";
+      configureFlags = [ "--enable-igbinary" ];
+      makeFlags = [ "phpincludedir=$(dev)/include" ];
+      outputs = [ "out" "dev" ];
     };
 
-    phases = [ "installPhase" ];
-    nativeBuildInputs = [ pkgs.makeWrapper ];
+    imagick = buildPecl {
+      version = "3.4.4";
+      pname = "imagick";
 
-    installPhase = ''
-      mkdir -p $out/bin
-      install -D $src $out/libexec/phpcbf/phpcbf.phar
-      makeWrapper ${php}/bin/php $out/bin/phpcbf \
-        --add-flags "$out/libexec/phpcbf/phpcbf.phar"
-    '';
+      sha256 = "0xvhaqny1v796ywx83w7jyjyd0nrxkxf34w9zi8qc8aw8qbammcd";
 
-    meta = with pkgs.lib; {
-      description = "PHP coding standard beautifier and fixer";
-      license = licenses.bsd3;
-      homepage = https://squizlabs.github.io/PHP_CodeSniffer/;
-      maintainers = with maintainers; [ cmcdragonkai etu ];
+      configureFlags = [ "--with-imagick=${pkgs.imagemagick.dev}" ];
+      nativeBuildInputs = [ pkgs.pkgconfig ];
+      buildInputs = [ pcre' ];
     };
-  };
 
-  phpcs = mkDerivation rec {
-    version = "3.5.3";
-    pname = "phpcs";
+    mailparse = buildPecl {
+      version = "3.0.3";
+      pname = "mailparse";
+      sha256 = "00nk14jbdbln93mx3ag691avc11ff94hkadrcv5pn51c6ihsxbmz";
 
-    src = pkgs.fetchurl {
-      url = "https://github.com/squizlabs/PHP_CodeSniffer/releases/download/${version}/phpcs.phar";
-      sha256 = "0y4nhsifj4pdmf5g1nnm4951yjgiqswyz7wmjxx6kqiqc7chlkml";
+      internalDeps = [ php.extensions.mbstring ];
+      postConfigure = ''
+        echo "#define HAVE_MBSTRING 1" >> config.h
+      '';
     };
 
-    phases = [ "installPhase" ];
-    buildInputs = [ pkgs.makeWrapper ];
-
-    installPhase = ''
-      mkdir -p $out/bin
-      install -D $src $out/libexec/phpcs/phpcs.phar
-      makeWrapper ${php}/bin/php $out/bin/phpcs \
-        --add-flags "$out/libexec/phpcs/phpcs.phar"
-    '';
-
-    meta = with pkgs.lib; {
-      description = "PHP coding standard tool";
-      license = licenses.bsd3;
-      homepage = https://squizlabs.github.io/PHP_CodeSniffer/;
-      maintainers = with maintainers; [ javaguirre etu ];
+    maxminddb = buildPecl rec {
+      pname = "maxminddb";
+      version = "1.6.0";
+
+      src = pkgs.fetchFromGitHub {
+        owner = "maxmind";
+        repo = "MaxMind-DB-Reader-php";
+        rev = "v${version}";
+        sha256 = "0sa943ij9pgz55aik93lllb8lh063bvr66ibn77p3y3p41vdiabz";
+      };
+
+      buildInputs = [ pkgs.libmaxminddb ];
+      sourceRoot = "source/ext";
+
+      meta = with pkgs.lib; {
+        description = "C extension that is a drop-in replacement for MaxMind\\Db\\Reader";
+        license = with licenses; [ asl20 ];
+        maintainers = with maintainers; [ ajs124 das_j ];
+      };
     };
-  };
 
-  phpstan = mkDerivation rec {
-    version = "0.12.14";
-    pname = "phpstan";
+    memcached = buildPecl rec {
+      version = "3.1.5";
+      pname = "memcached";
+
+      src = fetchgit {
+        url = "https://github.com/php-memcached-dev/php-memcached";
+        rev = "v${version}";
+        sha256 = "01mbh2m3kfbdvih3c8g3g9h4vdd80r0i9g2z8b3lx3mi8mmcj380";
+      };
+
+      internalDeps = [
+        php.extensions.session
+      ] ++ lib.optionals (lib.versionOlder php.version "7.4") [
+        php.extensions.hash
+      ];
+
+      configureFlags = [
+        "--with-zlib-dir=${pkgs.zlib.dev}"
+        "--with-libmemcached-dir=${pkgs.libmemcached}"
+      ];
+
+      nativeBuildInputs = [ pkgs.pkgconfig ];
+      buildInputs = with pkgs; [ cyrus_sasl zlib ];
+    };
 
-    src = pkgs.fetchurl {
-      url = "https://github.com/phpstan/phpstan/releases/download/${version}/phpstan.phar";
-      sha256 = "JAq1/+bVhTgKRR7oFusqZ/yBOYewaOM38ZoiCjirsTg=";
+    mongodb = buildPecl {
+      pname = "mongodb";
+      version = "1.6.1";
+
+      sha256 = "1j1w4n33347j9kwvxwsrix3gvjbiqcn1s5v59pp64s536cci8q0m";
+
+      nativeBuildInputs = [ pkgs.pkgconfig ];
+      buildInputs = with pkgs; [
+        cyrus_sasl
+        icu
+        openssl
+        snappy
+        zlib
+        pcre'
+      ] ++ lib.optional (pkgs.stdenv.isDarwin) pkgs.darwin.apple_sdk.frameworks.Security;
     };
 
-    phases = [ "installPhase" ];
-    nativeBuildInputs = [ pkgs.makeWrapper ];
+    oci8 = buildPecl {
+      version = "2.2.0";
+      pname = "oci8";
 
-    installPhase = ''
-      mkdir -p $out/bin
-      install -D $src $out/libexec/phpstan/phpstan.phar
-      makeWrapper ${php}/bin/php $out/bin/phpstan \
-        --add-flags "$out/libexec/phpstan/phpstan.phar"
-    '';
+      sha256 = "0jhivxj1nkkza4h23z33y7xhffii60d7dr51h1czjk10qywl7pyd";
+      buildInputs = [ pkgs.oracle-instantclient ];
+      configureFlags = [ "--with-oci8=shared,instantclient,${pkgs.oracle-instantclient.lib}/lib" ];
 
-    meta = with pkgs.lib; {
-      description = "PHP Static Analysis Tool";
-      longDescription = ''
-        PHPStan focuses on finding errors in your code without actually running
-        it. It catches whole classes of bugs even before you write tests for the
-        code. It moves PHP closer to compiled languages in the sense that the
-        correctness of each line of the code can be checked before you run the
-        actual line.
+      postPatch = ''
+        sed -i -e 's|OCISDKMANINC=`.*$|OCISDKMANINC="${pkgs.oracle-instantclient.dev}/include"|' config.m4
       '';
-      license = licenses.mit;
-      homepage = "https://github.com/phpstan/phpstan";
-      maintainers = with maintainers; [ etu ];
     };
-  };
 
-  pinba = if isPhp73 then pinba73 else pinba7;
+    pcov = buildPecl {
+      version = "1.0.6";
+      pname = "pcov";
 
-  pinba7 = assert !isPhp73; buildPecl {
-    version = "1.1.1";
-    pname = "pinba";
+      sha256 = "1psfwscrc025z8mziq69pcx60k4fbkqa5g2ia8lplb94mmarj0v1";
 
-    src = pkgs.fetchFromGitHub {
-      owner = "tony2001";
-      repo = "pinba_extension";
-      rev = "RELEASE_1_1_1";
-      sha256 = "1kdp7vav0y315695vhm3xifgsh6h6y6pny70xw3iai461n58khj5";
+      buildInputs = [ pcre' ];
     };
 
-    meta = with pkgs.lib; {
-      description = "PHP extension for Pinba";
-      longDescription = ''
-        Pinba is a MySQL storage engine that acts as a realtime monitoring and
-        statistics server for PHP using MySQL as a read-only interface.
-      '';
-      homepage = "http://pinba.org/";
-    };
-  };
+    pcs = buildPecl {
+      version = "1.3.3";
+      pname = "pcs";
 
-  pinba73 = assert isPhp73; buildPecl {
-    version = "1.1.2-dev";
-    pname = "pinba";
+      sha256 = "0d4p1gpl8gkzdiv860qzxfz250ryf0wmjgyc8qcaaqgkdyh5jy5p";
 
-    src = pkgs.fetchFromGitHub {
-      owner = "tony2001";
-      repo = "pinba_extension";
-      rev = "edbc313f1b4fb8407bf7d5acf63fbb0359c7fb2e";
-      sha256 = "02sljqm6griw8ccqavl23f7w1hp2zflcv24lpf00k6pyrn9cwx80";
+      meta.broken = isPhp74; # Build error
     };
 
-    meta = with pkgs.lib; {
-      description = "PHP extension for Pinba";
-      longDescription = ''
-        Pinba is a MySQL storage engine that acts as a realtime monitoring and
-        statistics server for PHP using MySQL as a read-only interface.
-      '';
-      homepage = "http://pinba.org/";
-    };
-  };
+    pdo_oci = buildPecl rec {
+      inherit (php) src version;
 
-  protobuf = buildPecl {
-    version = "3.11.2";
-    pname = "protobuf";
+      pname = "pdo_oci";
+      sourceRoot = "php-${version}/ext/pdo_oci";
 
-    sha256 = "0bhdykdyk58ywqj940zb7jyvrlgdr6hdb4s8kn79fz3p0i79l9hz";
+      buildInputs = [ pkgs.oracle-instantclient ];
+      configureFlags = [ "--with-pdo-oci=instantclient,${pkgs.oracle-instantclient.lib}/lib" ];
 
-    buildInputs = with pkgs; [ (if isPhp73 then pcre2 else pcre) ];
+      internalDeps = [ php.extensions.pdo ];
 
-    meta = with pkgs.lib; {
-      description = ''
-        Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data.
-      '';
-      license = licenses.bsd3;
-      homepage = "https://developers.google.com/protocol-buffers/";
+      postPatch = ''
+      sed -i -e 's|OCISDKMANINC=`.*$|OCISDKMANINC="${pkgs.oracle-instantclient.dev}/include"|' config.m4
+    '';
     };
-  };
 
-  psalm = mkDerivation rec {
-    version = "3.9.3";
-    pname = "psalm";
+    pdo_sqlsrv = buildPecl {
+      version = "5.8.0";
+      pname = "pdo_sqlsrv";
 
-    src = pkgs.fetchurl {
-      url = "https://github.com/vimeo/psalm/releases/download/${version}/psalm.phar";
-      sha256 = "KHm2n06y/yxN5B2rCVxT5ja7HxkyxAMsjZ5HLb3xr4M=";
-    };
+      sha256 = "0z4vbyd851b4jr6p69l2ylk91iihndsm2qjb429pxcv8g6dqzqll";
 
-    phases = [ "installPhase" ];
-    nativeBuildInputs = [ pkgs.makeWrapper ];
+      internalDeps = [ php.extensions.pdo ];
 
-    installPhase = ''
-      mkdir -p $out/bin
-      install -D $src $out/libexec/psalm/psalm.phar
-      makeWrapper ${php}/bin/php $out/bin/psalm \
-        --add-flags "$out/libexec/psalm/psalm.phar"
-    '';
-
-    meta = with pkgs.lib; {
-      description = "A static analysis tool for finding errors in PHP applications";
-      license = licenses.mit;
-      homepage = https://github.com/vimeo/psalm;
+      buildInputs = [ pkgs.unixODBC ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ pkgs.libiconv ];
     };
-  };
-
-  psysh = mkDerivation rec {
-    version = "0.9.12";
-    pname = "psysh";
 
-    src = pkgs.fetchurl {
-      url = "https://github.com/bobthecow/psysh/releases/download/v${version}/psysh-v${version}.tar.gz";
-      sha256 = "0bzmc94li481xk81gv460ipq9zl03skbnq8m3rnw34i2c04hxczc";
-    };
+    php_excel = buildPecl rec {
+      version = "1.0.2";
+      pname = "php_excel";
+      phpVersion = "php7";
 
-    phases = [ "installPhase" ];
-    nativeBuildInputs = [ pkgs.makeWrapper ];
+      buildInputs = [ pkgs.libxl ];
 
-    installPhase = ''
-      mkdir -p $out/bin
-      tar -xzf $src -C $out/bin
-      chmod +x $out/bin/psysh
-      wrapProgram $out/bin/psysh
-    '';
+      src = pkgs.fetchurl {
+        url = "https://github.com/iliaal/php_excel/releases/download/Excel-1.0.2-PHP7/excel-${version}-${phpVersion}.tgz";
+        sha256 = "0dpvih9gpiyh1ml22zi7hi6kslkilzby00z1p8x248idylldzs2n";
+      };
 
-    meta = with pkgs.lib; {
-      description = "PsySH is a runtime developer console, interactive debugger and REPL for PHP.";
-      license = licenses.mit;
-      homepage = https://psysh.org/;
-      maintainers = with maintainers; [ caugner ];
+      configureFlags = [ "--with-excel" "--with-libxl-incdir=${pkgs.libxl}/include_c" "--with-libxl-libdir=${pkgs.libxl}/lib" ];
     };
-  };
 
-  pthreads = if isPhp73 then pthreads32-dev else pthreads32;
+    pinba = let
+      version = if isPhp73 then "1.1.2-dev" else "1.1.1";
+      src = pkgs.fetchFromGitHub ({
+        owner = "tony2001";
+        repo = "pinba_extension";
+      } // (if (isPhp73) then {
+        rev = "edbc313f1b4fb8407bf7d5acf63fbb0359c7fb2e";
+        sha256 = "02sljqm6griw8ccqavl23f7w1hp2zflcv24lpf00k6pyrn9cwx80";
+      } else {
+        rev = "RELEASE_1_1_1";
+        sha256 = "1kdp7vav0y315695vhm3xifgsh6h6y6pny70xw3iai461n58khj5";
+      }));
+    in buildPecl {
+      pname = "pinba";
+      inherit version src;
+
+      meta = with pkgs.lib; {
+        description = "PHP extension for Pinba";
+        longDescription = ''
+          Pinba is a MySQL storage engine that acts as a realtime monitoring and
+          statistics server for PHP using MySQL as a read-only interface.
+        '';
+        homepage = "http://pinba.org/";
+      };
+    };
 
-  pthreads32 = assert (pkgs.config.php.zts or false); assert !isPhp73; buildPecl rec {
-    version = "3.2.0";
-    pname = "pthreads";
+    protobuf = buildPecl {
+      version = "3.11.2";
+      pname = "protobuf";
 
-    src = pkgs.fetchFromGitHub {
-      owner = "krakjoe";
-      repo = "pthreads";
-      rev = "v${version}";
-      sha256 = "17hypm75d4w7lvz96jb7s0s87018yzmmap0l125d5fd7abnhzfvv";
-    };
+      sha256 = "0bhdykdyk58ywqj940zb7jyvrlgdr6hdb4s8kn79fz3p0i79l9hz";
 
-    buildInputs = with pkgs; [ pcre.dev ];
-  };
+      buildInputs = with pkgs; [ pcre' ];
 
-  pthreads32-dev = assert (pkgs.config.php.zts or false); assert isPhp73; buildPecl {
-    version = "3.2.0-dev";
-    pname = "pthreads";
+      meta = with pkgs.lib; {
+        description = ''
+          Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data.
+        '';
+        license = licenses.bsd3;
+        homepage = "https://developers.google.com/protocol-buffers/";
+      };
+    };
 
-    src = pkgs.fetchFromGitHub {
-      owner = "krakjoe";
-      repo = "pthreads";
-      rev = "4d1c2483ceb459ea4284db4eb06646d5715e7154";
-      sha256 = "07kdxypy0bgggrfav2h1ccbv67lllbvpa3s3zsaqci0gq4fyi830";
+    pthreads = let
+      version = "3.2.0";
+      src = pkgs.fetchFromGitHub ({
+        owner = "krakjoe";
+        repo = "pthreads";
+      } // (if (isPhp73) then {
+        rev = "4d1c2483ceb459ea4284db4eb06646d5715e7154";
+        sha256 = "07kdxypy0bgggrfav2h1ccbv67lllbvpa3s3zsaqci0gq4fyi830";
+      } else {
+        rev = "v3.2.0";
+        sha256 = "17hypm75d4w7lvz96jb7s0s87018yzmmap0l125d5fd7abnhzfvv";
+      }));
+    in buildPecl {
+      pname = "pthreads";
+      inherit version src;
+
+      buildInputs = [ pcre'.dev ];
+
+      meta.broken = isPhp74;
     };
 
-    buildInputs = with pkgs; [ pcre2.dev ];
-  };
+    redis = buildPecl {
+      version = "5.1.1";
+      pname = "redis";
 
-  redis = buildPecl {
-    version = "5.1.1";
-    pname = "redis";
+      sha256 = "1041zv91fkda73w4c3pj6zdvwjgb3q7mxg6mwnq9gisl80mrs732";
 
-    sha256 = "1041zv91fkda73w4c3pj6zdvwjgb3q7mxg6mwnq9gisl80mrs732";
-  };
+      internalDeps = with php.extensions; [
+        json
+        session
+      ] ++ lib.optionals (lib.versionOlder php.version "7.4") [
+        hash ];
+    };
 
-  sqlsrv = buildPecl {
-    version = "5.8.0";
-    pname = "sqlsrv";
+    sqlsrv = buildPecl {
+      version = "5.8.0";
+      pname = "sqlsrv";
 
-    sha256 = "1kv4krk1w4hri99b0sdgwgy9c4y0yh217wx2y3irhkfi46kdrjnw";
+      sha256 = "1kv4krk1w4hri99b0sdgwgy9c4y0yh217wx2y3irhkfi46kdrjnw";
 
-    buildInputs = [ pkgs.unixODBC ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ pkgs.libiconv ];
-  };
+      buildInputs = [ pkgs.unixODBC ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ pkgs.libiconv ];
+    };
 
-  v8 = buildPecl {
-    version = "0.2.2";
-    pname = "v8";
+    v8 = buildPecl {
+      version = "0.2.2";
+      pname = "v8";
 
-    sha256 = "103nys7zkpi1hifqp9miyl0m1mn07xqshw3sapyz365nb35g5q71";
+      sha256 = "103nys7zkpi1hifqp9miyl0m1mn07xqshw3sapyz365nb35g5q71";
 
-    buildInputs = [ pkgs.v8_6_x ];
-    configureFlags = [ "--with-v8=${pkgs.v8_6_x}" ];
-    meta.broken = true;
-  };
+      buildInputs = [ pkgs.v8_6_x ];
+      configureFlags = [ "--with-v8=${pkgs.v8_6_x}" ];
+      meta.broken = true;
+    };
 
-  v8js = assert !isPhp73; buildPecl {
-    version = "2.1.0";
-    pname = "v8js";
+    v8js = buildPecl {
+      version = "2.1.0";
+      pname = "v8js";
 
-    sha256 = "0g63dyhhicngbgqg34wl91nm3556vzdgkq19gy52gvmqj47rj6rg";
+      sha256 = "0g63dyhhicngbgqg34wl91nm3556vzdgkq19gy52gvmqj47rj6rg";
 
-    buildInputs = [ pkgs.v8_6_x ];
-    configureFlags = [ "--with-v8js=${pkgs.v8_6_x}" ];
-    meta.broken = true;
-  };
+      buildInputs = [ pkgs.v8_6_x ];
+      configureFlags = [ "--with-v8js=${pkgs.v8_6_x}" ];
+      meta.broken = true;
+    };
 
-  xdebug = buildPecl {
-    version = "2.8.1";
-    pname = "xdebug";
+    xdebug = buildPecl {
+      version = "2.8.1";
+      pname = "xdebug";
 
-    sha256 = "080mwr7m72rf0jsig5074dgq2n86hhs7rdbfg6yvnm959sby72w3";
+      sha256 = "080mwr7m72rf0jsig5074dgq2n86hhs7rdbfg6yvnm959sby72w3";
 
-    doCheck = true;
-    checkTarget = "test";
+      doCheck = true;
+      checkTarget = "test";
 
-    zendExtension = true;
-  };
+      zendExtension = true;
+    };
 
-  yaml = buildPecl {
-    version = "2.0.4";
-    pname = "yaml";
+    yaml = buildPecl {
+      version = "2.0.4";
+      pname = "yaml";
 
-    sha256 = "1036zhc5yskdfymyk8jhwc34kvkvsn5kaf50336153v4dqwb11lp";
+      sha256 = "1036zhc5yskdfymyk8jhwc34kvkvsn5kaf50336153v4dqwb11lp";
 
-    configureFlags = [
-      "--with-yaml=${pkgs.libyaml}"
-    ];
+      configureFlags = [
+        "--with-yaml=${pkgs.libyaml}"
+      ];
 
-    nativeBuildInputs = [ pkgs.pkgconfig ];
-  };
+      nativeBuildInputs = [ pkgs.pkgconfig ];
+    };
 
-  zmq = assert !isPhp73; buildPecl {
-    version = "1.1.3";
-    pname = "zmq";
+    zmq = buildPecl {
+      version = "1.1.3";
+      pname = "zmq";
 
-    sha256 = "1kj487vllqj9720vlhfsmv32hs2dy2agp6176mav6ldx31c3g4n4";
+      sha256 = "1kj487vllqj9720vlhfsmv32hs2dy2agp6176mav6ldx31c3g4n4";
 
-    configureFlags = [
-      "--with-zmq=${pkgs.zeromq}"
-    ];
+      configureFlags = [
+        "--with-zmq=${pkgs.zeromq}"
+      ];
 
-    nativeBuildInputs = [ pkgs.pkgconfig ];
-  };
+      nativeBuildInputs = [ pkgs.pkgconfig ];
 
-  exts = let
+      meta.broken = isPhp73;
+    };
+  } // (let
     # Function to build a single php extension based on the php version.
     #
     # Name passed is the name of the extension and is automatically used
@@ -709,39 +736,67 @@ let
     mkExtension = {
       name
       , configureFlags ? [ "--enable-${name}" ]
+      , internalDeps ? []
+      , postPhpize ? ""
       , buildInputs ? []
       , zendExtension ? false
+      , doCheck ? true
       , ...
-    }: stdenv.mkDerivation {
-      pname = "php-ext-${name}";
+    }@args: stdenv.mkDerivation ((builtins.removeAttrs args [ "name" ]) // {
+      pname = "php-${name}";
+      extensionName = name;
 
       inherit (php) version src;
       sourceRoot = "php-${php.version}/ext/${name}";
 
       enableParallelBuilding = true;
       nativeBuildInputs = [ php autoconf pkgconfig re2c ];
-      inherit configureFlags buildInputs zendExtension;
-
-      preConfigure = "phpize";
-
+      inherit configureFlags internalDeps buildInputs
+        zendExtension doCheck;
+
+      preConfigure = ''
+        nullglobRestore=$(shopt -p nullglob)
+        shopt -u nullglob   # To make ?-globbing work
+
+        # Some extensions have a config0.m4 or config9.m4
+        if [ -f config?.m4 ]; then
+          mv config?.m4 config.m4
+        fi
+
+        $nullglobRestore
+        phpize
+        ${postPhpize}
+        ${lib.concatMapStringsSep "\n"
+          (dep: "mkdir -p ext; ln -s ${dep.dev}/include ext/${dep.extensionName}")
+          internalDeps}
+      '';
+      checkPhase = "echo n | make test";
+      outputs = [ "out" "dev" ];
       installPhase = ''
         mkdir -p $out/lib/php/extensions
-        cp modules/${name}.so $out/lib/php/extensions/ext-${name}.so
+        cp modules/${name}.so $out/lib/php/extensions/${name}.so
+        mkdir -p $dev/include
+        ${rsync}/bin/rsync -r --filter="+ */" \
+                              --filter="+ *.h" \
+                              --filter="- *" \
+                              --prune-empty-dirs \
+                              . $dev/include/
       '';
-    };
+    });
 
     # This list contains build instructions for different modules that one may
     # want to build.
     #
     # These will be passed as arguments to mkExtension above.
-    extensionData = let
-      pcre' = if (lib.versionAtLeast php.version "7.3") then pcre2 else pcre;
-    in [
+    extensionData = [
       { name = "bcmath"; }
       { name = "bz2"; buildInputs = [ bzip2 ]; configureFlags = [ "--with-bz2=${bzip2.dev}" ]; }
       { name = "calendar"; }
       { name = "ctype"; }
-      { name = "curl"; buildInputs = [ curl ]; configureFlags = [ "--with-curl=${curl.dev}" ]; }
+      { name = "curl";
+        buildInputs = [ curl ];
+        configureFlags = [ "--with-curl=${curl.dev}" ];
+        doCheck = false; }
       { name = "dba"; }
       { name = "dom";
         buildInputs = [ libxml2 ];
@@ -752,8 +807,9 @@ let
         buildInputs = [ enchant1 ];
         configureFlags = [ "--with-enchant=${enchant1}" ];
         # enchant1 doesn't build on darwin.
-        enable = (!stdenv.isDarwin); }
-      { name = "exif"; }
+        enable = (!stdenv.isDarwin);
+        doCheck = false; }
+      { name = "exif"; doCheck = false; }
       { name = "ffi"; buildInputs = [ libffi ]; enable = lib.versionAtLeast php.version "7.4"; }
       { name = "fileinfo"; buildInputs = [ pcre' ]; }
       { name = "filter"; buildInputs = [ pcre' ]; }
@@ -765,6 +821,7 @@ let
           "--with-external-gd=${gd.dev}"
           "--enable-gd-jis-conv"
         ];
+        doCheck = false;
         enable = lib.versionAtLeast php.version "7.4"; }
       { name = "gd";
         buildInputs = [ zlib gd libXpm ];
@@ -778,21 +835,22 @@ let
           "--with-zlib-dir=${zlib.dev}"
           "--enable-gd-jis-conv"
         ];
+        doCheck = false;
         enable = lib.versionOlder php.version "7.4"; }
-      ## gettext (7.2, 7.3, 7.4) -- configure: error: Cannot locate header file libintl.h
-      #{ name = "gettext";
-      #  buildInputs = [ gettext ];
-      #  configureFlags = "--with-gettext=${gettext}"; }
+      { name = "gettext";
+        buildInputs = [ gettext ];
+        postPhpize = ''substituteInPlace configure --replace 'as_fn_error $? "Cannot locate header file libintl.h" "$LINENO" 5' ':' '';
+        configureFlags = "--with-gettext=${gettext}"; }
       { name = "gmp";
-        buildInputs = [ gmp5 ];
-        configureFlags = [ "--with-gmp=${gmp5.dev}" ];
-        # gmp5 doesn't build on darwin.
-        enable = (!stdenv.isDarwin); }
+        buildInputs = [ gmp ];
+        configureFlags = [ "--with-gmp=${gmp.dev}" ]; }
       { name = "hash"; enable = lib.versionOlder php.version "7.4"; }
-      { name = "iconv"; configureFlags = if stdenv.isDarwin then
+      { name = "iconv";
+        configureFlags = if stdenv.isDarwin then
                            [ "--with-iconv=${libiconv}" ]
                          else
-                           [ "--with-iconv" ]; }
+                           [ "--with-iconv" ];
+        doCheck = false; }
       { name = "imap";
         buildInputs = [ uwimap openssl pam pcre' ];
         configureFlags = [ "--with-imap=${uwimap}" "--with-imap-ssl" ];
@@ -808,36 +866,110 @@ let
           "LDAP_DIR=${openldap.dev}"
           "LDAP_INCDIR=${openldap.dev}/include"
           "LDAP_LIBDIR=${openldap.out}/lib"
-        ] ++ lib.optional stdenv.isLinux "--with-ldap-sasl=${cyrus_sasl.dev}"; }
-      { name = "mbstring"; buildInputs = [ oniguruma ]; }
-      { name = "mysqli"; configureFlags = [ "--with-mysqli=mysqlnd" "--with-mysql-sock=/run/mysqld/mysqld.sock" ]; }
+        ] ++ lib.optional stdenv.isLinux "--with-ldap-sasl=${cyrus_sasl.dev}";
+        doCheck = false; }
+      { name = "mbstring"; buildInputs = [ oniguruma ]; doCheck = false; }
+      { name = "mysqli";
+        internalDeps = [ php.extensions.mysqlnd ];
+        configureFlags = [ "--with-mysqli=mysqlnd" "--with-mysql-sock=/run/mysqld/mysqld.sock" ];
+        doCheck = false; }
+      { name = "mysqlnd";
+        buildInputs = [ zlib openssl ];
+        # The configure script doesn't correctly add library link
+        # flags, so we add them to the variable used by the Makefile
+        # when linking.
+        MYSQLND_SHARED_LIBADD = "-lssl -lcrypto -lz";
+        # The configure script builds a config.h which is never
+        # included. Let's include it in the main header file
+        # included by all .c-files.
+        patches = [
+          (pkgs.writeText "mysqlnd_config.patch" ''
+            --- a/mysqlnd.h
+            +++ b/mysqlnd.h
+            @@ -1,3 +1,6 @@
+            +#ifdef HAVE_CONFIG_H
+            +#include "config.h"
+            +#endif
+             /*
+               +----------------------------------------------------------------------+
+               | Copyright (c) The PHP Group                                          |
+          '')
+        ];
+        postPhpize = lib.optionalString (lib.versionOlder php.version "7.4") ''
+          substituteInPlace configure --replace '$OPENSSL_LIBDIR' '${openssl}/lib' \
+                                      --replace '$OPENSSL_INCDIR' '${openssl.dev}/include'
+        ''; }
       # oci8 (7.4, 7.3, 7.2)
       # odbc (7.4, 7.3, 7.2)
-      { name = "opcache"; buildInputs = [ pcre' ]; zendExtension = true; }
+      { name = "opcache";
+        buildInputs = [ pcre' ];
+        # HAVE_OPCACHE_FILE_CACHE is defined in config.h, which is
+        # included from ZendAccelerator.h, but ZendAccelerator.h is
+        # included after the ifdef...
+        patches = lib.optional (lib.versionOlder php.version "7.4") [
+          (pkgs.writeText "zend_file_cache_config.patch" ''
+            --- a/zend_file_cache.c
+            +++ b/zend_file_cache.c
+            @@ -27,9 +27,9 @@
+             #include "ext/standard/md5.h"
+             #endif
+
+            +#include "ZendAccelerator.h"
+             #ifdef HAVE_OPCACHE_FILE_CACHE
+
+            -#include "ZendAccelerator.h"
+             #include "zend_file_cache.h"
+             #include "zend_shared_alloc.h"
+             #include "zend_accelerator_util_funcs.h"
+          '') ];
+        zendExtension = true;
+        doCheck = !(lib.versionOlder php.version "7.4"); }
+      { name = "openssl";
+        buildInputs = [ openssl ];
+        configureFlags = [ "--with-openssl" ];
+        doCheck = false; }
       { name = "pcntl"; }
-      { name = "pdo"; }
+      { name = "pdo"; doCheck = false; }
       { name = "pdo_dblib";
+        internalDeps = [ php.extensions.pdo ];
         configureFlags = [ "--with-pdo-dblib=${freetds}" ];
         # Doesn't seem to work on darwin.
-        enable = (!stdenv.isDarwin); }
+        enable = (!stdenv.isDarwin);
+        doCheck = false; }
       # pdo_firebird (7.4, 7.3, 7.2)
-      { name = "pdo_mysql"; configureFlags = [ "--with-pdo-mysql=mysqlnd" ]; }
+      { name = "pdo_mysql";
+        internalDeps = with php.extensions; [ pdo mysqlnd ];
+        configureFlags = [ "--with-pdo-mysql=mysqlnd" "PHP_MYSQL_SOCK=/run/mysqld/mysqld.sock" ];
+        doCheck = false; }
       # pdo_oci (7.4, 7.3, 7.2)
-      { name = "pdo_odbc"; configureFlags = [ "--with-pdo-odbc=unixODBC,${unixODBC}" ]; }
-      { name = "pdo_pgsql"; configureFlags = [ "--with-pdo-pgsql=${postgresql}" ]; }
-      { name = "pdo_sqlite"; buildInputs = [ sqlite ]; configureFlags = [ "--with-pdo-sqlite=${sqlite.dev}" ]; }
-      { name = "pgsql"; buildInputs = [ pcre' ]; configureFlags = [ "--with-pgsql=${postgresql}" ]; }
-      { name = "phar"; buildInputs = [ pcre' openssl ]; }
-      { name = "posix"; }
+      { name = "pdo_odbc";
+        internalDeps = [ php.extensions.pdo ];
+        configureFlags = [ "--with-pdo-odbc=unixODBC,${unixODBC}" ];
+        doCheck = false; }
+      { name = "pdo_pgsql";
+        internalDeps = [ php.extensions.pdo ];
+        configureFlags = [ "--with-pdo-pgsql=${postgresql}" ];
+        doCheck = false; }
+      { name = "pdo_sqlite";
+        internalDeps = [ php.extensions.pdo ];
+        buildInputs = [ sqlite ];
+        configureFlags = [ "--with-pdo-sqlite=${sqlite.dev}" ];
+        doCheck = false; }
+      { name = "pgsql";
+        buildInputs = [ pcre' ];
+        configureFlags = [ "--with-pgsql=${postgresql}" ];
+        doCheck = false; }
+      { name = "posix"; doCheck = false; }
       { name = "pspell"; configureFlags = [ "--with-pspell=${aspell}" ]; }
-      ## readline (7.4, 7.3, 7.2) -- configure: error: Please reinstall libedit - I cannot find readline.h
-      #{ name = "readline";
-      #  buildInputs = [ libedit readline ];
-      #  configureFlags = [ "--with-readline=${readline.dev}" ]; }
-      { name = "recode";
-        configureFlags = [ "--with-recode=${recode}" ];
-        # Removed in php 7.4.
-        enable = lib.versionOlder php.version "7.4"; }
+      { name = "readline";
+        buildInputs = [ libedit readline ];
+        configureFlags = [ "--with-readline=${readline.dev}" ];
+        postPhpize = lib.optionalString (lib.versionOlder php.version "7.4") ''
+          substituteInPlace configure --replace 'as_fn_error $? "Please reinstall libedit - I cannot find readline.h" "$LINENO" 5' ':'
+        '';
+        doCheck = false;
+      }
+      # recode (7.3, 7.2)
       { name = "session"; }
       { name = "shmop"; }
       { name = "simplexml";
@@ -849,21 +981,25 @@ let
         buildInputs = [ net-snmp openssl ];
         configureFlags = [ "--with-snmp" ];
         # net-snmp doesn't build on darwin.
-        enable = (!stdenv.isDarwin); }
+        enable = (!stdenv.isDarwin);
+        doCheck = false; }
       { name = "soap";
         buildInputs = [ libxml2 ];
         configureFlags = [ "--enable-soap" ]
           # Required to build on darwin.
-          ++ lib.optional (lib.versionOlder php.version "7.4") [ "--with-libxml-dir=${libxml2.dev}" ]; }
-      { name = "sockets"; }
+          ++ lib.optional (lib.versionOlder php.version "7.4") [ "--with-libxml-dir=${libxml2.dev}" ];
+        doCheck = false; }
+      { name = "sockets"; doCheck = false; }
       { name = "sodium"; buildInputs = [ libsodium ]; }
+      { name = "sqlite3"; buildInputs = [ sqlite ]; }
       { name = "sysvmsg"; }
       { name = "sysvsem"; }
       { name = "sysvshm"; }
-      { name = "tidy"; configureFlags = [ "--with-tidy=${html-tidy}" ]; }
+      { name = "tidy"; configureFlags = [ "--with-tidy=${html-tidy}" ]; doCheck = false; }
       { name = "tokenizer"; }
       { name = "wddx";
         buildInputs = [ libxml2 ];
+        internalDeps = [ php.extensions.session ];
         configureFlags = [ "--enable-wddx" "--with-libxml-dir=${libxml2.dev}" ];
         # Removed in php 7.4.
         enable = lib.versionOlder php.version "7.4"; }
@@ -871,7 +1007,8 @@ let
         buildInputs = [ libxml2 ];
         configureFlags = [ "--enable-xml" ]
           # Required to build on darwin.
-          ++ lib.optional (lib.versionOlder php.version "7.4") [ "--with-libxml-dir=${libxml2.dev}" ]; }
+          ++ lib.optional (lib.versionOlder php.version "7.4") [ "--with-libxml-dir=${libxml2.dev}" ];
+        doCheck = false; }
       { name = "xmlreader";
         buildInputs = [ libxml2 ];
         configureFlags = [ "--enable-xmlreader CFLAGS=-I../.." ]
@@ -887,12 +1024,21 @@ let
         configureFlags = [ "--enable-xmlwriter" ]
           # Required to build on darwin.
           ++ lib.optional (lib.versionOlder php.version "7.4") [ "--with-libxml-dir=${libxml2.dev}" ]; }
-      { name = "xsl"; buildInputs = [ libxslt libxml2 ]; configureFlags = [ "--with-xsl=${libxslt.dev}" ]; }
+      { name = "xsl";
+        buildInputs = [ libxslt libxml2 ];
+        doCheck = !(lib.versionOlder php.version "7.4");
+        configureFlags = [ "--with-xsl=${libxslt.dev}" ]; }
       { name = "zend_test"; }
-      { name = "zip"; buildInputs = [ libzip pcre' ];
+      { name = "zip";
+        buildInputs = [ libzip pcre' ];
         configureFlags = [ "--with-zip" ]
           ++ lib.optional (lib.versionOlder php.version "7.4") [ "--with-zlib-dir=${zlib.dev}" ]
-          ++ lib.optional (lib.versionOlder php.version "7.3") [ "--with-libzip" ]; }
+          ++ lib.optional (lib.versionOlder php.version "7.3") [ "--with-libzip" ];
+        doCheck = false; }
+      { name = "zlib";
+        buildInputs = [ zlib ];
+        configureFlags = [ "--with-zlib" ]
+          ++ lib.optional (lib.versionOlder php.version "7.4") [ "--with-zlib-dir=${zlib.dev}" ]; }
     ];
 
     # Convert the list of attrs:
@@ -909,5 +1055,5 @@ let
     }) (builtins.filter (i: i.enable or true) extensionData);
 
     # Produce the final attribute set of all extensions defined.
-  in builtins.listToAttrs namedExtensions;
-}; in self
+  in builtins.listToAttrs namedExtensions);
+}