Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add php 8.4 compatibility #1255

Merged
merged 36 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ae53f5d
Add php 8.4 compatibility
julien-maurel Dec 30, 2024
8783302
Fixed missing comma in composer.json
intuibase Jan 10, 2025
39efe94
Merge branch 'main' into php84
intuibase Jan 10, 2025
a602406
Removed deprecated E_STRICT
intuibase Jan 10, 2025
3271798
Updated phpstan
intuibase Jan 10, 2025
e0c0b2a
Downgraded phpstan to latest supporting php 7.2
intuibase Jan 10, 2025
f63e5e2
Fixed issues reported by phpstan
intuibase Jan 10, 2025
af86418
Fixed issues reported by phpstan
intuibase Jan 10, 2025
092327f
Adapted expected stack trace to PHP 8.4
SergeyKleyman Jan 13, 2025
2fc39b7
Fixed static checks
SergeyKleyman Jan 13, 2025
1ff3ded
Fixed assert missing in older PHPUnit
SergeyKleyman Jan 13, 2025
3af4114
Fixed StackTraceUtilTest
SergeyKleyman Jan 13, 2025
3dbe743
Revert AssertMessageStack back to enabled by default
SergeyKleyman Jan 13, 2025
449e12e
Merge branch 'z_TEMP_Fix_PHP_84' into php84
SergeyKleyman Jan 13, 2025
eda4ad6
Fixed docker-compose label
intuibase Jan 13, 2025
6dfdbcb
Merge branch 'php84' into Fix_AssertMessageStack
SergeyKleyman Jan 14, 2025
f006303
Fixed test failures related to AssertMessageStack
SergeyKleyman Jan 14, 2025
8fd385f
Merge branch 'php84' into z_TEMP_Fix_PHP_84
SergeyKleyman Jan 14, 2025
3cd10d1
Merge branch 'Fix_AssertMessageStack' into z_TEMP_Fix_PHP_84
SergeyKleyman Jan 14, 2025
ce88255
Upgrade php-ds to 1.5.0
SergeyKleyman Jan 14, 2025
04b3467
Added PHP ds extension
SergeyKleyman Jan 14, 2025
c1ff432
Fixed component tests failing because of deprecation notices
SergeyKleyman Jan 14, 2025
13d75d1
Fixed issue with mysqli::ping being deprecated since PHP 8.4
SergeyKleyman Jan 14, 2025
aa08130
Disable deprecation notices starting from PHP 8.4
SergeyKleyman Jan 15, 2025
231ebbb
Reverted changes to ErrorComponentTest
SergeyKleyman Jan 15, 2025
9d505bc
Fixed WordPressAutoInstrumentationTest
SergeyKleyman Jan 15, 2025
a8fdf47
Fixed order in zendAstKindToString
SergeyKleyman Jan 15, 2025
9082469
Merge branch 'z_TEMP_Fix_PHP_84' into php84
SergeyKleyman Jan 15, 2025
3f1e282
Remove CentOS/latest PHP from testing agent upgrade
SergeyKleyman Jan 15, 2025
5b9b836
Merge branch 'z_TEMP_Fix_PHP_84' into php84
SergeyKleyman Jan 15, 2025
188bb16
Fixed GenerateUnpackScriptsTest
SergeyKleyman Jan 15, 2025
99ad6fa
Merge branch 'z_TEMP_Fix_PHP_84' into php84
SergeyKleyman Jan 15, 2025
1b04a28
Removed ds extension
SergeyKleyman Jan 15, 2025
61a4ac8
Merge branch 'z_TEMP_Fix_PHP_84' into php84
SergeyKleyman Jan 16, 2025
de5c1bf
Run PHP 8.4 tests on Fedora
intuibase Jan 16, 2025
0e48087
Added missing ps to fedora image
intuibase Jan 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .ci/generate_package_lifecycle_test_matrix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,13 @@ function generateAgentUpgradeRows () {
local testingType=agent-upgrade
local appHostKindShortName=all
local testsGroup=smoke
for phpVersion in 7.4 ; do
for linuxPackageType in rpm ; do
echo "${phpVersion},${linuxPackageType},${testingType},${appHostKindShortName},${testsGroup}"
done
done
for phpVersion in 7.4 "$(latestSupportedPhpVersion)" ; do
for linuxPackageType in deb rpm ; do
for linuxPackageType in deb ; do
echo "${phpVersion},${linuxPackageType},${testingType},${appHostKindShortName},${testsGroup}"
done
done
Expand Down
3 changes: 2 additions & 1 deletion .ci/packer_cache.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ php:8.0-fpm
php:8.1-fpm
php:8.2-fpm
php:8.3-fpm
php:8.4-fpm
ruby:2.7.1-alpine3.12
ubuntu:20.04
"
Expand All @@ -26,7 +27,7 @@ if [ -x "$(command -v docker)" ]; then

# Make sure list of PHP versions supported by the Elastic APM PHP Agent is in sync.
# See the comment in .ci/shared.sh
for version in 7.2 7.3 7.4 8.0 8.1 8.2 8.3
for version in 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4
do
PHP_VERSION=${version} make -f .ci/Makefile prepare || true
DOCKERFILE=Dockerfile.alpine PHP_VERSION=${version} make -f .ci/Makefile prepare || true
Expand Down
2 changes: 1 addition & 1 deletion .ci/shared.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ set -e
# *) docker-compose.yml in packaging/test

#
export ELASTIC_APM_PHP_TESTS_SUPPORTED_PHP_VERSIONS=(7.2 7.3 7.4 8.0 8.1 8.2 8.3)
export ELASTIC_APM_PHP_TESTS_SUPPORTED_PHP_VERSIONS=(7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4)

export ELASTIC_APM_PHP_TESTS_SUPPORTED_LINUX_NATIVE_PACKAGE_TYPES=(apk deb rpm)
export ELASTIC_APM_PHP_TESTS_SUPPORTED_LINUX_PACKAGE_TYPES=("${ELASTIC_APM_PHP_TESTS_SUPPORTED_LINUX_NATIVE_PACKAGE_TYPES[@]}" tar)
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/loop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
- "8.1"
- "8.2"
- "8.3"
- "8.4"
dockerfile:
- "Dockerfile"
- "Dockerfile.alpine"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/phpt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
- "8.1"
- "8.2"
- "8.3"
- "8.4"
steps:
# - uses: actions/checkout@v4
# - name: Fetch and extract latest release of apm-agent-php
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jobs:
- "8.1"
- "8.2"
- "8.3"
- "8.4"
data: ${{ fromJson(needs.setup-build-matrix.outputs.matrix-combinations).include }}
env:
PHP_VERSION: ${{ matrix.php-version }}
Expand Down Expand Up @@ -90,6 +91,7 @@ jobs:
- "8.1"
- "8.2"
- "8.3"
- "8.4"
dockerfile:
- "Dockerfile"
- "Dockerfile.alpine"
Expand Down
3 changes: 2 additions & 1 deletion agent/native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ include(elastic_conan_debugsymbols)

# Install project dependencies

set(_supported_php_versions 72 73 74 80 81 82 83)
set(_supported_php_versions 72 73 74 80 81 82 83 84)

function(get_php_api_from_release php_version ret_val)
block(SCOPE_FOR VARIABLES)
Expand All @@ -54,6 +54,7 @@ function(get_php_api_from_release php_version ret_val)
set(_php_release_81 20210902)
set(_php_release_82 20220829)
set(_php_release_83 20230831)
set(_php_release_84 20240924)

set(${ret_val} ${_php_release_${php_version}})
return(PROPAGATE ${ret_val})
Expand Down
37 changes: 37 additions & 0 deletions agent/native/building/dependencies/php84/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: "php-headers-84"
version: "1.0"
php_source_version: 8.4.1

sources:
7.2.34:
linux:
- url: "https://www.php.net/distributions/php-7.2.34.tar.gz"
contentsRoot: "php-7.2.34"
7.3.33:
linux:
- url: "https://www.php.net/distributions/php-7.3.33.tar.gz"
contentsRoot: "php-7.3.33"
7.4.33:
linux:
- url: "https://www.php.net/distributions/php-7.4.33.tar.gz"
contentsRoot: "php-7.4.33"
8.0.28:
linux:
- url: "https://www.php.net/distributions/php-8.0.28.tar.gz"
contentsRoot: "php-8.0.28"
8.1.18:
linux:
- url: "https://www.php.net/distributions/php-8.1.18.tar.gz"
contentsRoot: "php-8.1.18"
8.2.5:
linux:
- url: "https://www.php.net/distributions/php-8.2.5.tar.gz"
contentsRoot: "php-8.2.5"
8.3.2:
linux:
- url: "https://www.php.net/distributions/php-8.3.2.tar.gz"
contentsRoot: "php-8.3.2"
8.4.1:
linux:
- url: "https://www.php.net/distributions/php-8.4.1.tar.gz"
contentsRoot: "php-8.4.1"
56 changes: 56 additions & 0 deletions agent/native/building/dependencies/php84/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os
import shutil

from conans import tools, ConanFile, AutoToolsBuildEnvironment

class PhpHeadersForPHP81Conan(ConanFile):
description = "PHP headers package required to build Elastic APM agent without additional PHP dependencies"
license = "The PHP License, version 3.01"
homepage = "https://php.net/"
url = "https://php.net/"
author = "pawel.filipczak@elastic.co"

settings = "os", "compiler", "build_type", "arch"
platform = "linux"

def init(self):
self.name = self.conan_data["name"]
self.version = self.conan_data["version"] # version of the package
self.php_version = self.conan_data["php_source_version"] # version of the PHP to build
self.source_temp_dir = "php-src"

def requirements(self):
self.requires("libxml2/2.9.9")
self.requires("sqlite3/3.29.0")

def source(self):
for source in self.conan_data["sources"][self.php_version][self.platform]:

if "contentsRoot" in source:
# small hack - it can't contain custom fields, so we're removing it from source (got an unexpected keyword argument)
contentRoot = source["contentsRoot"]
del source["contentsRoot"]
tools.get(**source)
os.rename(contentRoot, self.source_temp_dir)
else:
self.output.error("Could not find 'contentsRoot' in conandata.yml")
raise Exception("Could not find 'contentsRoot' in conandata.yml")

def build(self):
with tools.chdir(os.path.join(self.source_folder, self.source_temp_dir)):
buildEnv = AutoToolsBuildEnvironment(self)
envVariables = buildEnv.vars
envVariables['ac_cv_php_xml2_config_path'] = os.path.join(self.deps_cpp_info["libxml2"].rootpath, "bin/xml2-config")
envVariables['LIBXML_LIBS'] = os.path.join(self.deps_cpp_info["libxml2"].rootpath, self.deps_cpp_info["libxml2"].libdirs[0])
envVariables['LIBXML_CFLAGS'] = "-I{}".format(os.path.join(self.deps_cpp_info["libxml2"].rootpath, self.deps_cpp_info["libxml2"].includedirs[0]))
envVariables['SQLITE_LIBS'] = os.path.join(self.deps_cpp_info["sqlite3"].rootpath, self.deps_cpp_info["sqlite3"].libdirs[0])
envVariables['SQLITE_CFLAGS'] = "-I{}".format(os.path.join(self.deps_cpp_info["sqlite3"].rootpath, self.deps_cpp_info["sqlite3"].includedirs[0]))
self.run("./buildconf --force")
buildEnv.configure(args=[""], vars=envVariables, build=False, host=False)

def package(self):
source = os.path.join(self.source_folder, self.source_temp_dir)
self.copy("*.h", src=source, dst='include', keep_path=True)

def package_id(self):
del self.info.settings.compiler.version
7 changes: 6 additions & 1 deletion agent/native/ext/AST_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,16 @@ String zendAstKindToString( zend_ast_kind kind )
ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_TYPE_INTERSECTION );
#endif


#if PHP_VERSION_ID >= ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 3, 0 ) /* if PHP version from 8.3.0 */
ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_MODIFIER_LIST );
#endif

#if PHP_VERSION_ID >= ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 4, 0 ) /* if PHP version from 8.4.0 */
ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_PARENT_PROPERTY_HOOK_CALL );
ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_PROPERTY_HOOK );
ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_PROPERTY_HOOK_SHORT_BODY );
#endif

default:
return NULL;
}
Expand Down
42 changes: 34 additions & 8 deletions agent/native/ext/AST_instrumentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,25 +181,47 @@ bool isZendAstListKind( zend_ast_kind kind )
}

/**
* zend_ast_create and zend_ast_create_ex allowed up to 4 child* parameters for version before PHP v8
* and the limit was increased to 5 in PHP v8
* Max number of children for AST nodes is
* 4 for PHP before 8.0
* 5 for PHP from 8.0 but before 8.4
* 6 for PHP from 8.4
*
* @see ZEND_AST_SPEC_CALL_EX
*
* When adding support for a new PHP version:
* - Make sure g_astNodeMaxChildCount is correct
* - If g_astNodeMaxChildCount changed then update createAstEx()
* - Make sure zendAstKindToString() in AST_debug.cpp includes all the enum cases from enum _zend_ast_kind in <php-src>/Zend/zend_ast.h
* - Increment minor part of PHP version in static_assert below
*/
static size_t g_maxCreateAstChildCount =
static_assert(
PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 5, 0 ),
"Make sure g_astNodeMaxChildCount is correct. See max number of children in enum _zend_ast_kind in <php-src>/Zend/zend_ast.h"
);
static constexpr size_t g_astNodeMaxChildCount =
#if PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 0, 0 )
4 // PHP before 8.0
#elif PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 4, 0 )
5 // PHP from 8.0 but before 8.4
#else
6 // PHP from 8.4
#endif
;
static constexpr size_t g_zendKindWithLargestChildNodesCount =
#if PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 0, 0 )
4
ZEND_AST_FOR // PHP before 8.0
#else
5
ZEND_AST_PARAM // PHP from 8.0
#endif
;
static_assert(g_zendKindWithLargestChildNodesCount == (g_astNodeMaxChildCount << ZEND_AST_NUM_CHILDREN_SHIFT));

zend_ast* createAstEx( zend_ast_kind kind, zend_ast_attr attr, ZendAstPtrArrayView children )
{
char txtOutStreamBuf[ELASTIC_APM_TEXT_OUTPUT_STREAM_ON_STACK_BUFFER_SIZE];
TextOutputStream txtOutStream = ELASTIC_APM_TEXT_OUTPUT_STREAM_FROM_STATIC_BUFFER( txtOutStreamBuf );

ELASTIC_APM_ASSERT_LE_UINT64( children.count, g_maxCreateAstChildCount );
ELASTIC_APM_ASSERT_LE_UINT64( children.count, g_astNodeMaxChildCount );
ELASTIC_APM_ASSERT( ! isZendAstListKind( kind ), "kind: %s", streamZendAstKind( kind, &txtOutStream ) );

switch( children.count )
Expand All @@ -218,6 +240,10 @@ zend_ast* createAstEx( zend_ast_kind kind, zend_ast_attr attr, ZendAstPtrArrayVi
case 5:
return zend_ast_create_ex( kind, attr, children.values[ 0 ], children.values[ 1 ], children.values[ 2 ], children.values[ 3 ], children.values[ 4 ] );
#endif
#if PHP_VERSION_ID >= ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 4, 0 )
case 6:
return zend_ast_create_ex( kind, attr, children.values[ 0 ], children.values[ 1 ], children.values[ 2 ], children.values[ 3 ], children.values[ 4 ], children.values[ 5 ] );
#endif
default: // silence compiler warning
return nullptr;
}
Expand All @@ -227,9 +253,9 @@ ResultCode createAstExCheckChildrenCount( zend_ast_kind kind, zend_ast_attr attr
{
ResultCode resultCode;

if ( children.count > g_maxCreateAstChildCount )
if ( children.count > g_astNodeMaxChildCount )
{
ELASTIC_APM_LOG_ERROR( "Number of children is larger than max; children.count: %u, g_maxCreateAstChildCount: %u", (unsigned)children.count, (unsigned)g_maxCreateAstChildCount );
ELASTIC_APM_LOG_ERROR( "Number of children is larger than max; children.count: %u, g_astNodeMaxChildCount: %u", (unsigned)children.count, (unsigned)g_astNodeMaxChildCount );
ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE_EX( resultFailure );
}

Expand Down
2 changes: 1 addition & 1 deletion agent/native/ext/tests_util/tests_util.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

declare(strict_types=1);

error_reporting(E_ALL | E_STRICT);
error_reporting(E_ALL);

function elasticApmOnAssertFailure(string $condDesc, string $expr, $actual, $expected)
{
Expand Down
5 changes: 3 additions & 2 deletions agent/native/loader/code/phpdetection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ bool isThreadSafe() {

std::tuple<std::string_view, int, bool> getZendModuleApiVersion(std::string_view zendVersion) {
using namespace std::string_view_literals;
constexpr size_t knownVersionsCount = 16;
constexpr size_t knownVersionsCount = 17;

constexpr std::array<std::tuple<std::string_view, int, bool>, knownVersionsCount> knownPhpVersions {{
{"4.4"sv, 20240924, true}, // PHP 8.4
{"4.3"sv, 20230831, true}, // PHP 8.3
{"4.2"sv, 20220829, true}, // PHP 8.2
{"4.1"sv, 20210902, true}, // PHP 8.1
Expand Down Expand Up @@ -91,4 +92,4 @@ std::tuple<std::string_view, int, bool> getZendModuleApiVersion(std::string_view



}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public function setOpt(int $option, $value): bool

public function asInt(): int
{
/** @phpstan-ignore-next-line */
return is_resource($this->curlHandle) ? intval($this->curlHandle) : spl_object_id($this->curlHandle);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ private function discoverStartTime(float $requestInitStartTime): float
return $requestInitStartTime;
}

/** @phpstan-ignore-next-line */
$serverRequestTimeInSeconds = floatval($serverRequestTimeAsString);
$serverRequestTimeInMicroseconds = $serverRequestTimeInSeconds * TimeUtil::NUMBER_OF_MICROSECONDS_IN_SECOND;
if ($requestInitStartTime < $serverRequestTimeInMicroseconds) {
Expand Down
1 change: 1 addition & 0 deletions agent/php/ElasticApm/Impl/Config/IniRawSnapshotSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ private static function iniValueToString($iniValue): string
return $iniValue ? 'true' : 'false';
}

/** @phpstan-ignore-next-line */
return strval($iniValue);
}
}
13 changes: 8 additions & 5 deletions agent/php/ElasticApm/Impl/InferredSpansManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,14 @@ private function onNewCurrentTransactionHasBegun(Transaction $transaction): void
($assertProxy = Assert::ifEnabled())
&& $assertProxy->that($this->onCurrentSpanChangedCallback === null)
&& $assertProxy->withContext('$this->onCurrentSpanChangedCallback === null', ['this' => $this]);
$this->currentTransaction->onCurrentSpanChanged->add(
$this->onCurrentSpanChangedCallback = function (?Span $span): void {
$this->onCurrentSpanChanged($span);
}
);

if ($this->currentTransaction !== null) {
$this->currentTransaction->onCurrentSpanChanged->add(
$this->onCurrentSpanChangedCallback = function (?Span $span): void {
$this->onCurrentSpanChanged($span);
}
);
}

$this->builder = new InferredSpansBuilder($this->tracer);
$this->state = self::STATE_RUNNING;
Expand Down
1 change: 1 addition & 0 deletions agent/php/ElasticApm/Impl/Log/LoggableToJsonEncodable.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public static function convert($value, int $depth)
return self::convertObject($value, $depth);
}

/** @phpstan-ignore-next-line */
return [LogConsts::TYPE_KEY => DbgUtil::getType($value), LogConsts::VALUE_AS_STRING_KEY => strval($value)];
}

Expand Down
19 changes: 10 additions & 9 deletions agent/php/ElasticApm/Impl/Util/ArrayUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,18 @@ final class ArrayUtil
use StaticClassTrait;

/**
* @param string $key
* @param array<mixed> $array
* @param mixed $valueDst
* @template TKey of array-key
* @template TValue
*
* @return bool
* @param TKey $key
* @param array<TKey, TValue> $array
* @param TValue &$valueDst
*
* @template T
* @phpstan-param T[] $array
* @phpstan-param T $valueDst
* @param-out TValue $valueDst
*
* @return bool
*/
public static function getValueIfKeyExists(string $key, array $array, &$valueDst): bool
public static function getValueIfKeyExists($key, array $array, /* out */ &$valueDst): bool
{
if (!array_key_exists($key, $array)) {
return false;
Expand All @@ -54,7 +55,7 @@ public static function getValueIfKeyExists(string $key, array $array, &$valueDst
}

/**
* @template TKey of string|int
* @template TKey of array-key
* @template TValue
*
* @param TKey $key
Expand Down
Loading
Loading