Skip to content

Commit

Permalink
PHP/8.4.1
Browse files Browse the repository at this point in the history
There is no more E_STRICT for error_reporting, and session.sid_length is gone.

The imap extension has moved to PECL.

No blackfire or newrelic extension builds yet with support for 8.4. The phalcon extension is incompatible with 8.4 (they always get new releases some time later), and pcov needs a fix and release first: krakjoe/pcov#111

The heroku-20 stack is not getting this version because the stack is already deprecated.

GUS-W-17226361
  • Loading branch information
dzuelke committed Nov 22, 2024
1 parent 09c1621 commit 8f336f3
Show file tree
Hide file tree
Showing 39 changed files with 227 additions and 31 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased]

### ADD

- PHP/8.4.1 [David Zuelke]

## [v259] - 2024-11-21

Expand Down
4 changes: 2 additions & 2 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,9 @@ composer validate --no-plugins --no-check-publish --no-check-all --quiet "$COMPO
status "Preparing platform package installation..."

if [[ $STACK == "heroku-20" ]]; then
HEROKU_PHP_DEFAULT_RUNTIME_VERSION="^7.3.0 | ^8.0.0 <8.4"
HEROKU_PHP_DEFAULT_RUNTIME_VERSION="^7.3.0 | ^8.0.0 <8.5"
else
HEROKU_PHP_DEFAULT_RUNTIME_VERSION="^8.0.0 <8.4"
HEROKU_PHP_DEFAULT_RUNTIME_VERSION="^8.0.0 <8.5"
fi
export HEROKU_PHP_DEFAULT_RUNTIME_VERSION
# extract requirements from composer.lock
Expand Down
1 change: 1 addition & 0 deletions bin/util/eol.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"8.1" => array("2023-11-25", "2025-12-31"),
"8.2" => array("2024-12-31", "2026-12-31"),
"8.3" => array("2025-12-31", "2027-12-31"),
"8.4" => array("2026-12-31", "2028-12-31"),
);

if(basename(__FILE__) != basename($_SERVER["PHP_SELF"])) return $eol; // we're being included, just return the data
Expand Down
18 changes: 18 additions & 0 deletions support/build/_conf/php/8/4/conf.d/000-heroku.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
; in line with Heroku dynos' TZ
date.timezone = UTC

; we want users to see E_DEPRECATED warnings, as it's not uncommon to accidentally run PHP series newer than on local dev
; PHP 8.4+ no longer has E_STRICT
error_reporting = E_ALL

; do not expose PHP via headers (just like we don't with web servers)
expose_php = Off

; legacy
short_open_tag = On

; dyno filesystems are ephemeral, so there is no point in checking for .user.ini changes
user_ini.cache_ttl = 86400

; we need environment variables included in superglobals, as they're used for configuration
variables_order = EGPCS
2 changes: 2 additions & 0 deletions support/build/_conf/php/conf.d/000-heroku.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ error_reporting = E_ALL & ~E_STRICT
expose_php = Off

; 32 or more is recommended and always has been the default for PHP 7+ on Heroku
; the production config we use as the baseline sets this to 26
; this setting is gone in PHP 8.4, so the more specific file for that version does not have this
session.sid_length = 32

; legacy
Expand Down
5 changes: 5 additions & 0 deletions support/build/extensions/no-debug-non-zts-20240924/amqp-2.1.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/amqp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/apcu
5 changes: 5 additions & 0 deletions support/build/extensions/no-debug-non-zts-20240924/ev-1.2.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/ev
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/event
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/imagick
23 changes: 23 additions & 0 deletions support/build/extensions/no-debug-non-zts-20240924/imap
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

dep_name=$(basename $BASH_SOURCE)

# we need these libs already installed
needed=( libc-client2007e libkrb5-3 libpam0g )
missing=$(comm -1 -3 <(dpkg-query -W -f '${package}\n' | sort) <(IFS=$'\n'; echo "${needed[*]}" | sort))
if [[ "$missing" ]]; then
echo "Error! Missing libraries: $missing"
exit 1
fi

# we need the headers for compilation
needed=( libc-client2007e-dev libkrb5-dev libpam0g-dev )
missing=$(comm -1 -3 <(dpkg-query -W -f '${package}\n' | sort) <(IFS=$'\n'; echo "${needed[*]}" | sort))
if [[ "$missing" ]]; then
apt-get update -qq || { echo "Failed to 'apt-get update'. You must build this formula using Docker."; exit 1; }
apt-get install -q -y $missing
fi

CONFIGURE_EXTRA="--with-imap-ssl --with-kerberos"

source $(dirname $BASH_SOURCE)/../pecl
5 changes: 5 additions & 0 deletions support/build/extensions/no-debug-non-zts-20240924/imap-1.0.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20240924/imap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/memcached
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/mongodb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/oauth
5 changes: 5 additions & 0 deletions support/build/extensions/no-debug-non-zts-20240924/pq-2.2.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*, extensions/no-debug-non-zts-20240924/raphf-2.*

source $(dirname $0)/../no-debug-non-zts-20180731/pq
5 changes: 5 additions & 0 deletions support/build/extensions/no-debug-non-zts-20240924/psr-1.2.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/psr
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/raphf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*, libraries/librdkafka-*

source $(dirname $0)/../no-debug-non-zts-20180731/rdkafka
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/redis
5 changes: 5 additions & 0 deletions support/build/extensions/no-debug-non-zts-20240924/uuid-1.2.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php
# Build Deps: php-8.4.*

source $(dirname $0)/../no-debug-non-zts-20180731/uuid
25 changes: 17 additions & 8 deletions support/build/php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ if [[ $dep_version == *alpha* ]] || [[ $dep_version == *beta* ]] || [[ $dep_vers
dep_url=https://downloads.php.net/~pierrick/${dep_archive_name}
elif [[ $dep_version == 8.3.* ]]; then
dep_url=https://downloads.php.net/~eric/${dep_archive_name}
elif [[ $dep_version == 8.4.* ]]; then
dep_url=https://downloads.php.net/~calvinb/${dep_archive_name}
fi
else
dep_url=https://www.php.net/distributions/${dep_archive_name}
Expand All @@ -40,8 +42,8 @@ curl -L ${dep_url} | tar xz

pushd ${dep_dirname}

# we need libgmp for GMP, libpam0g/libc-client for IMAP, libicu for intl, libsasl2/krb/ldap for LDAP, libreadline for PHP
needed=( libgmp10 libpam0g libc-client2007e libsasl2-2 libkrb5-3 )
# we need libgmp for GMP, libicu for intl, libsasl2/ldap for LDAP, libreadline for PHP
needed=( libgmp10 libsasl2-2 )
needed+=( libonig5 )
needed+=( libsodium23 )
if [[ $STACK == "heroku-20" ]]; then
Expand All @@ -60,14 +62,20 @@ else
needed+=( libreadline8t64 )
needed+=( libzip4t64 )
fi
if [[ $dep_version == 7.* || $dep_version == 8.[0-3].* ]]; then
needed+=( libc-client2007e libkrb5-3 libpam0g ) # the IMAP extension was bundled before PHP 8.4
fi
missing=$(comm -1 -3 <(dpkg-query -W -f '${package}\n' | sort) <(IFS=$'\n'; echo "${needed[*]}" | sort))
if [[ "$missing" ]]; then
echo "Error! Missing libraries: $missing"
exit 1
fi

# we need libgmp-dev for GMP, libpam0g-dev/libc-client-dev for IMAP, libicu-dev for intl, libsasl2/krb5/ldap2-dev for LDAP, libreadline-dev for PHP
needed=( libgmp-dev libpam0g-dev libc-client2007e-dev libicu-dev libsasl2-dev libkrb5-dev libldap2-dev libonig-dev libreadline-dev libsodium-dev libsqlite3-dev libzip-dev libwebp-dev )
# we need libgmp-dev for GMP, libicu-dev for intl, libsasl2/ldap2-dev for LDAP, libreadline-dev for PHP
needed=( libgmp-dev libicu-dev libsasl2-dev libldap2-dev libonig-dev libreadline-dev libsodium-dev libsqlite3-dev libzip-dev libwebp-dev )
if [[ $dep_version == 7.* || $dep_version == 8.[0-3].* ]]; then
needed+=( libc-client2007e-dev libkrb5-dev libpam0g-dev ) # the IMAP extension was bundled before PHP 8.4
fi
missing=$(comm -1 -3 <(dpkg-query -W -f '${package}\n' | sort) <(IFS=$'\n'; echo "${needed[*]}" | sort))
if [[ "$missing" ]]; then
apt-get update -qq || { echo "Failed to 'apt-get update'. You must build this formula using Docker."; exit 1; }
Expand Down Expand Up @@ -114,6 +122,10 @@ fi
if [[ $dep_version == 7.3.* ]]; then
configureopts+=("--with-libzip=/usr" "--with-onig=/usr") # PHP before 7.4 bundles these, so give explicit locations
fi
if [[ $dep_version == 7.* || $dep_version == 8.[0-3].* ]]; then
configureopts+=("--with-imap=shared" "--with-imap-ssl") # the IMAP extension was bundled before PHP 8.4
configureopts+=("--with-kerberos") # for IMAP and OpenSSL before PHP 8.4
fi

export PATH=${OUT_PREFIX}/bin:$PATH
# cannot be built shared: date, ereg, opcache (always), pcre, reflection, sockets (?), spl, standard,
Expand All @@ -129,7 +141,6 @@ export PATH=${OUT_PREFIX}/bin:$PATH
--with-pdo-mysql \
--with-mysqli \
--with-openssl \
--with-kerberos \
--with-password-argon2 \
--with-pgsql \
--with-pdo-pgsql \
Expand All @@ -142,8 +153,6 @@ export PATH=${OUT_PREFIX}/bin:$PATH
--enable-ftp=shared \
--with-gettext=shared \
--with-gmp=shared \
--with-imap=shared \
--with-imap-ssl \
--enable-intl=shared \
--with-ldap=shared \
--with-ldap-sasl \
Expand Down Expand Up @@ -220,7 +229,7 @@ if ! curl -sL https://composer.github.io/installer.sha384sum | sha384sum --quiet
exit 1
fi

php composer-setup.php --2.2 # https://github.com/composer/composer/issues/11046
php composer-setup.php

# first, read all platform packages (just "ext-" and "php-") that are already there; could be statically built, or enabled through one of the INIs loaded
platform_default=$(php composer.phar show --platform | grep -E '^(ext-\S+|php-\S+)' | sed s@^@heroku-sys/@ | tr -s " " | cut -d " " -f1,2 | sort)
Expand Down
4 changes: 4 additions & 0 deletions support/build/php-8.4.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/php

source $(dirname $0)/php
1 change: 1 addition & 0 deletions support/devcenter/generate.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
'8.1',
'8.2',
'8.3',
'8.4',
];
}

Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/ci/atoum/composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"require": {
"php": "*"
"php": "8.3.*"
},
"require-dev": {
"atoum/atoum": "^4.0"
Expand Down
4 changes: 2 additions & 2 deletions test/fixtures/ci/atoum/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions test/spec/blackfire_shared.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,28 @@
@app = new_app_with_stack_and_platrepo('test/fixtures/bootopts',
buildpacks: buildpacks,
config: credentials.merge({ "BLACKFIRE_LOG_LEVEL" => "4"}),
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-blackfire:*'") or raise "Failed to require PHP/ext-blackfire" }
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-blackfire:*'") or raise "Failed to require PHP/ext-blackfire" }
)
elsif mode == "without BLACKFIRE_SERVER_TOKEN"
# ext-blackfire is listed as a dependency in composer.json, but a BLACKFIRE_SERVER_TOKEN/ID is missing
@app = new_app_with_stack_and_platrepo('test/fixtures/bootopts',
buildpacks: buildpacks,
config: { "BLACKFIRE_LOG_LEVEL" => "4" },
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-blackfire:*'") or raise "Failed to require PHP/ext-blackfire" }
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-blackfire:*'") or raise "Failed to require PHP/ext-blackfire" }
)
elsif mode == "with default BLACKFIRE_LOG_LEVEL"
# ext-blackfire is listed as a dependency in composer.json, and BLACKFIRE_LOG_LEVEL is the default (1=error)
@app = new_app_with_stack_and_platrepo('test/fixtures/bootopts',
buildpacks: buildpacks,
config: credentials,
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-blackfire:*'") or raise "Failed to require PHP/ext-blackfire" }
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-blackfire:*'") or raise "Failed to require PHP/ext-blackfire" }
)
else
# a BLACKFIRE_SERVER_TOKEN/ID triggers the automatic installation of ext-blackfire at the end of the build
@app = new_app_with_stack_and_platrepo('test/fixtures/bootopts',
buildpacks: buildpacks,
config: credentials.merge({ "BLACKFIRE_LOG_LEVEL" => "4"}),
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*'") or raise "Failed to require PHP version" }
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*'") or raise "Failed to require PHP version" }
)
end
@app.deploy
Expand Down
8 changes: 4 additions & 4 deletions test/spec/newrelic_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@
# ext-newrelic is listed as a dependency in composer.json, and a NEW_RELIC_LICENSE_KEY is provided
@app = new_app_with_stack_and_platrepo('test/fixtures/bootopts',
config: { "NEW_RELIC_LOG_LEVEL" => "info", "NEW_RELIC_LICENSE_KEY" => "somethingfake" },
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" }
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" }
)
elsif mode == "without NEW_RELIC_LICENSE_KEY"
# ext-newrelic is listed as a dependency in composer.json, but a NEW_RELIC_LICENSE_KEY is missing
@app = new_app_with_stack_and_platrepo('test/fixtures/bootopts',
config: { "NEW_RELIC_LOG_LEVEL" => "info" },
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" }
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" }
)
elsif mode == "with default NEW_RELIC_LOG_LEVEL"
# ext-newrelic is listed as a dependency in composer.json, and NEW_RELIC_LOG_LEVEL is the default (warning)
@app = new_app_with_stack_and_platrepo('test/fixtures/bootopts',
config: { "NEW_RELIC_LICENSE_KEY" => "somethingfake" },
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" }
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" }
)
else
# a NEW_RELIC_LICENSE_KEY triggers the automatic installation of ext-newrelic at the end of the build
@app = new_app_with_stack_and_platrepo('test/fixtures/bootopts',
config: { "NEW_RELIC_LOG_LEVEL" => "info", "NEW_RELIC_LICENSE_KEY" => "thiswilltriggernewrelic" },
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*'") or raise "Failed to require PHP version" }
before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*'") or raise "Failed to require PHP version" }
)
end
@app.deploy
Expand Down
5 changes: 5 additions & 0 deletions test/spec/php-8.4_base_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require_relative "php_base_shared"

describe "A basic PHP 8.4 application", :requires_php_on_stack => "8.4" do
include_examples "A basic PHP application", "8.4"
end
5 changes: 5 additions & 0 deletions test/spec/php-8.4_boot-apache2_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require_relative "php_boot_shared"

describe "A PHP 8.4/Apache application for testing boot options", :requires_php_on_stack => "8.4" do
include_examples "A PHP application for testing boot options", "8.4", "apache2"
end
5 changes: 5 additions & 0 deletions test/spec/php-8.4_boot-nginx_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require_relative "php_boot_shared"

describe "A PHP 8.4/Nginx application for testing boot options", :requires_php_on_stack => "8.4" do
include_examples "A PHP application for testing boot options", "8.4", "nginx"
end
5 changes: 5 additions & 0 deletions test/spec/php-8.4_concurrency-apache2_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require_relative "php_concurrency_shared"

describe "A PHP 8.4/Apache application for testing WEB_CONCURRENCY behavior", :requires_php_on_stack => "8.4" do
include_examples "A PHP application for testing WEB_CONCURRENCY behavior", "8.4", "apache2"
end
5 changes: 5 additions & 0 deletions test/spec/php-8.4_concurrency-nginx_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require_relative "php_concurrency_shared"

describe "A PHP 8.4/Nginx application for testing WEB_CONCURRENCY behavior", :requires_php_on_stack => "8.4" do
include_examples "A PHP application for testing WEB_CONCURRENCY behavior", "8.4", "nginx"
end
5 changes: 5 additions & 0 deletions test/spec/php-8.4_sigterm-apache2_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require_relative "php_sigterm_shared"

describe "A PHP 8.4 application with long-running requests", :requires_php_on_stack => "8.4" do
include_examples "A PHP application with long-running requests", "8.4", "apache2"
end
5 changes: 5 additions & 0 deletions test/spec/php-8.4_sigterm-nginx_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require_relative "php_sigterm_shared"

describe "A PHP 8.4 application with long-running requests", :requires_php_on_stack => "8.4" do
include_examples "A PHP application with long-running requests", "8.4", "nginx"
end
Loading

0 comments on commit 8f336f3

Please sign in to comment.