aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-rpc/php/worker.php
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe-php-rpc/php/worker.php')
-rw-r--r--crates/shirabe-php-rpc/php/worker.php134
1 files changed, 124 insertions, 10 deletions
diff --git a/crates/shirabe-php-rpc/php/worker.php b/crates/shirabe-php-rpc/php/worker.php
index 15b38770..578c30d0 100644
--- a/crates/shirabe-php-rpc/php/worker.php
+++ b/crates/shirabe-php-rpc/php/worker.php
@@ -455,6 +455,77 @@ ShirabeRpcRuntime::$stubAutoloader = static function (string $class): void {
};
spl_autoload_register(ShirabeRpcRuntime::$stubAutoloader, true, true);
+/**
+ * Port of Composer\Platform\Runtime, whose runtime queries feed the `platform` payload. Its
+ * parseHtmlExtensionInfo() has no counterpart here: the worker is always the CLI SAPI, so
+ * getExtensionInfo() never takes the branch that reformats phpinfo()'s HTML output.
+ */
+final class ShirabePlatformRuntime
+{
+ /** The constants the `platform` payload reports, named ltrim($class.'::'.$constant, ':'). */
+ public const CONSTANTS = [
+ 'PHP_VERSION',
+ 'PHP_DEBUG',
+ 'PHP_ZTS',
+ 'PHP_INT_SIZE',
+ 'AF_INET6',
+ 'GD_VERSION',
+ 'GMP_VERSION',
+ 'ICONV_VERSION',
+ 'INTL_ICU_VERSION',
+ 'LIBXML_DOTTED_VERSION',
+ 'MB_ONIGURUMA_VERSION',
+ 'OPENSSL_VERSION_TEXT',
+ 'PCRE_VERSION',
+ 'PGSQL_LIBPQ_VERSION',
+ 'RD_KAFKA_VERSION',
+ 'SODIUM_LIBRARY_VERSION',
+ 'LIBXSLT_DOTTED_VERSION',
+ 'ZipArchive::LIBZIP_VERSION',
+ 'ZLIB_VERSION',
+ ];
+
+ /** The extensions whose info() output the `platform` payload reports when they are loaded. */
+ public const EXTENSION_INFO = [
+ 'amqp',
+ 'bz2',
+ 'curl',
+ 'date',
+ 'fileinfo',
+ 'gd',
+ 'intl',
+ 'ldap',
+ 'mbstring',
+ 'memcached',
+ 'mongodb',
+ 'mysqlnd',
+ 'pcre',
+ 'pdo_mysql',
+ 'pdo_pgsql',
+ 'pdo_sqlite',
+ 'pgsql',
+ 'pq',
+ 'sqlite3',
+ 'ssh2',
+ 'xsl',
+ 'yaml',
+ 'zlib',
+ ];
+
+ /** The classes the `platform` payload reports the existence of. */
+ public const CLASSES = ['ResourceBundle', 'IntlChar'];
+
+ public static function getExtensionInfo(string $extension): string
+ {
+ $reflector = new ReflectionExtension($extension);
+
+ ob_start();
+ $reflector->info();
+
+ return (string) ob_get_clean();
+ }
+}
+
// Port of Composer\XdebugHandler\XdebugHandler::setXdebugDetails(), which the diagnose payload
// reports as `xdebug_active`.
$xdebug_active = static function (): bool {
@@ -491,9 +562,6 @@ $xdebug_active = static function (): bool {
ShirabeRpcRuntime::$dispatch = [
'constant' => static fn($args) => defined($args[0]) ? constant($args[0]) : null,
- 'inet_pton' => static fn($args) => @inet_pton($args[0]),
- 'curl_version' => static fn($args) => function_exists('curl_version') ? (curl_version()['version'] ?? null) : null,
- 'get_loaded_extensions' => static fn($args) => get_loaded_extensions(),
'get_all_ini_files' => static function ($args) {
$paths = [(string) php_ini_loaded_file()];
$scanned = php_ini_scanned_files();
@@ -502,14 +570,60 @@ ShirabeRpcRuntime::$dispatch = [
}
return $paths;
},
- 'extension_info' => static function ($args) {
- if (!extension_loaded($args[0])) {
- return '';
+ 'platform' => static function ($args) {
+ $extensions = get_loaded_extensions();
+
+ $extension_versions = [];
+ foreach ($extensions as $extension) {
+ $version = phpversion($extension);
+ $extension_versions[$extension] = $version !== false ? $version : '0';
}
- $re = new ReflectionExtension($args[0]);
- ob_start();
- $re->info();
- return (string) ob_get_clean();
+
+ $extension_info = [];
+ foreach (ShirabePlatformRuntime::EXTENSION_INFO as $extension) {
+ if (in_array($extension, $extensions, true)) {
+ $extension_info[$extension] = ShirabePlatformRuntime::getExtensionInfo($extension);
+ }
+ }
+
+ // Only the defined constants carry a value; `constant_names` tells the Rust side which
+ // names were looked up, so a name it reads but this list omits is an error rather than a
+ // silently undefined constant.
+ $constants = [];
+ foreach (ShirabePlatformRuntime::CONSTANTS as $constant) {
+ if (defined($constant)) {
+ $constants[$constant] = constant($constant);
+ }
+ }
+
+ $classes = [];
+ foreach (ShirabePlatformRuntime::CLASSES as $class) {
+ $classes[$class] = class_exists($class, false);
+ }
+
+ // The values below stand in for the PHP objects and calls PlatformRepository reaches
+ // through Composer\Platform\Runtime::invoke()/construct(), reduced to the entries it reads.
+ $resource_bundle = null;
+ if ($classes['ResourceBundle']) {
+ $bundle = ResourceBundle::create('root', 'ICUDATA', false);
+ if ($bundle !== null) {
+ $resource_bundle = ['Version' => $bundle->get('Version')];
+ }
+ }
+
+ return [
+ 'extensions' => $extensions,
+ 'extension_versions' => $extension_versions,
+ 'extension_info' => $extension_info,
+ 'constant_names' => ShirabePlatformRuntime::CONSTANTS,
+ 'constants' => $constants,
+ 'classes' => $classes,
+ 'curl_version' => extension_loaded('curl') ? curl_version() : null,
+ 'inet_pton_ipv6' => @inet_pton('::'),
+ 'resource_bundle' => $resource_bundle,
+ 'intl_char_unicode_version' => $classes['IntlChar'] ? IntlChar::getUnicodeVersion() : null,
+ 'imagick' => extension_loaded('imagick') ? (new Imagick())->getVersion() : null,
+ ];
},
'diagnose' => static function ($args) use ($xdebug_active) {
$extensions = [];