From 26a538680f726ada48d73dc7a15ea6472579496e Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 2 Jun 2026 16:33:42 +0800 Subject: [PATCH] =?UTF-8?q?refactor(php):=20=E5=B0=86=20stream=5Fcast=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=9B=BF=E6=8D=A2=E4=B8=BA=20toStream=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 stream_cast 全局函数实现 - 将 stream_cast($stream) 调用转换为 $stream->toStream() 方法调用 - 更新编译器中的流类型识别逻辑,移除对 stream_cast 的特殊处理 - 修改标准容器解析器中的 unsafePtr 为 boxExpr 属性 - 更新相关测试文件中的调用方式和断言 - 替换不安全指针转换为标准容器转换方法 --- .../universal-method-stream-cast-no-arg.php | 2 +- ...universal-method-stream-unknown-method.php | 2 +- src/Php/CompilerBase.php | 17 ++++++-------- src/Php/Parser/StdContainerParser.php | 8 +++---- src/polyfills.php | 4 ---- tests/aot/stream_method/stream_cast.phpt | 22 +++++++++---------- 6 files changed, 24 insertions(+), 31 deletions(-) diff --git a/phpunit/code/universal-method-stream-cast-no-arg.php b/phpunit/code/universal-method-stream-cast-no-arg.php index e0a87dfa..77688714 100644 --- a/phpunit/code/universal-method-stream-cast-no-arg.php +++ b/phpunit/code/universal-method-stream-cast-no-arg.php @@ -3,5 +3,5 @@ function main() { $tmpfile = tempnam(sys_get_temp_dir(), 'aot'); $fp = fopen($tmpfile, 'w'); - stream_cast()->write('data'); + $fp->toStream()->write('data'); } diff --git a/phpunit/code/universal-method-stream-unknown-method.php b/phpunit/code/universal-method-stream-unknown-method.php index 22987551..e5f29280 100644 --- a/phpunit/code/universal-method-stream-unknown-method.php +++ b/phpunit/code/universal-method-stream-unknown-method.php @@ -2,5 +2,5 @@ function main() { $tmpfile = tempnam(sys_get_temp_dir(), 'aot'); - stream_cast(fopen($tmpfile, 'w'))->unknownMethod(); + fopen($tmpfile, 'w')->toStream()->unknownMethod(); } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 358b4a51..8822bb52 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2506,7 +2506,7 @@ class CompilerBase extends \PhpAot\Core\Translator return self::TYPE_BIGFLOAT; } } - if (in_array($name, self::STREAM_FUNCTIONS) || $name === 'stream_cast') { + if (in_array($name, self::STREAM_FUNCTIONS)) { return self::TYPE_STREAM; } if (count($expr->args) === 1 and $this->isPlaceholderExpr($expr->args[0])) { @@ -3466,9 +3466,6 @@ class CompilerBase extends \PhpAot\Core\Translator if (in_array($name, Constants::UNSUPPORTED_FUNCTIONS)) { $this->fatalError($expr, 'Unsupported function: `' . $name . '`'); } - if ($name === 'stream_cast') { - return $this->parseExpr($expr->args[0]->value); - } $nativeFn = $this->findNativeFunction($name); if ($nativeFn) { $expr->setAttribute('nativeCall', $nativeFn); @@ -6366,8 +6363,8 @@ class CompilerBase extends \PhpAot\Core\Translator $code .= $this->getIndent(); if ($type === self::TYPE_STD_ARRAY) { $info = $this->context->stdArrays[$name]; - if (isset($info['unsafePtr'])) { - $code .= 'auto &' . $name . '_ref = php_unsafe_cast<' . $info['decl'] . '>(' . $info['unsafePtr'] . ', ' . $info['typeId'] . ');'; + if (isset($info['boxExpr'])) { + $code .= 'auto &' . $name . '_ref = php::toStdContainer<' . $info['decl'] . '>(' . $info['boxExpr'] . ', ' . $info['typeId'] . ');'; } else { $containerType = 'php::StdContainerBox<' . $info['decl'] . '>'; $code .= 'php::Var ' . $name . ' = php::Var(new ' . $containerType . '(' . $info['typeId'] . '));' . PHP_EOL; @@ -6375,8 +6372,8 @@ class CompilerBase extends \PhpAot\Core\Translator } } elseif ($type === self::TYPE_STD_VECTOR) { $info = $this->context->stdContainers[$name]; - if (isset($info['unsafePtr'])) { - $code .= 'auto &' . $name . '_ref = php_unsafe_cast<' . $info['decl'] . '>(' . $info['unsafePtr'] . ', ' . $info['typeId'] . ');'; + if (isset($info['boxExpr'])) { + $code .= 'auto &' . $name . '_ref = php::toStdContainer<' . $info['decl'] . '>(' . $info['boxExpr'] . ', ' . $info['typeId'] . ');'; } else { $containerType = 'php::StdContainerBox<' . $info['decl'] . '>'; if ($info['size'] !== null) { @@ -6389,8 +6386,8 @@ class CompilerBase extends \PhpAot\Core\Translator } } elseif ($type === self::TYPE_STD_MAP || $type === self::TYPE_STD_UNORDERED_MAP) { $info = $this->context->stdContainers[$name]; - if (isset($info['unsafePtr'])) { - $code .= 'auto &' . $name . '_ref = php_unsafe_cast<' . $info['decl'] . '>(' . $info['unsafePtr'] . ', ' . $info['typeId'] . ');'; + if (isset($info['boxExpr'])) { + $code .= 'auto &' . $name . '_ref = php::toStdContainer<' . $info['decl'] . '>(' . $info['boxExpr'] . ', ' . $info['typeId'] . ');'; } else { $containerType = 'php::StdContainerBox<' . $info['decl'] . '>'; $code .= 'php::Var ' . $name . ' = php::Var(new ' . $containerType . '(' . $info['typeId'] . '));' . PHP_EOL; diff --git a/src/Php/Parser/StdContainerParser.php b/src/Php/Parser/StdContainerParser.php index 52ba7318..7bf14028 100644 --- a/src/Php/Parser/StdContainerParser.php +++ b/src/Php/Parser/StdContainerParser.php @@ -617,8 +617,8 @@ trait StdContainerParser if ($containerType === 'array') { $this->addLocalVar($var, self::TYPE_STD_ARRAY); $this->parseStdArray($var, $fakeCall); - $this->context->stdArrays[$var]['unsafePtr'] = $sourceVar; - return '// php_unsafe_cast<' . $this->context->stdArrays[$var]['decl'] . '>(' . $sourceVar . ')'; + $this->context->stdArrays[$var]['boxExpr'] = $sourceVar; + return '// StdContainer<' . $this->context->stdArrays[$var]['decl'] . '>(' . $sourceVar . ')'; } if ($containerType === 'vector') { @@ -631,8 +631,8 @@ trait StdContainerParser $this->addLocalVar($var, self::TYPE_STD_UNORDERED_MAP); $this->parseStdUnorderedMap($var, $fakeCall); } - $this->context->stdContainers[$var]['unsafePtr'] = $sourceVar; - return '// php_unsafe_cast<' . $this->context->stdContainers[$var]['decl'] . '>(' . $sourceVar . ')'; + $this->context->stdContainers[$var]['boxExpr'] = $sourceVar; + return '// StdContainer<' . $this->context->stdArrays[$var]['decl'] . '>(' . $sourceVar . ')'; } protected function parseStdMapKeyType(NodeAbstract $expr, string $owner): string diff --git a/src/polyfills.php b/src/polyfills.php index aa515931..fb16acdf 100644 --- a/src/polyfills.php +++ b/src/polyfills.php @@ -89,7 +89,3 @@ function any(mixed $var): mixed return $var; } -function stream_cast($stream) -{ - return $stream; -} diff --git a/tests/aot/stream_method/stream_cast.phpt b/tests/aot/stream_method/stream_cast.phpt index 6d2718d2..d2246325 100644 --- a/tests/aot/stream_method/stream_cast.phpt +++ b/tests/aot/stream_method/stream_cast.phpt @@ -1,5 +1,5 @@ --TEST-- -stream_cast() pseudo-function for stream type casting +toStream() keyword method for stream type casting --FILE-- write("hello world"); $fp->seek(0); - $data = stream_cast($fp)->read(5); + $data = $fp->toStream()->read(5); var_dump($data); $fp->close(); - // Test 2: stream_cast on array elements where type isn't known + // Test 2: toStream() on array elements where type isn't known $pipes = []; $pipes[0] = fopen($tmpfile, 'w'); - $w = stream_cast($pipes[0]); + $w = $pipes[0]->toStream(); $w->write("test data from pipe"); $w->close(); $pipes[1] = fopen($tmpfile, 'r'); - $r = stream_cast($pipes[1]); + $r = $pipes[1]->toStream(); $data2 = $r->read(1024); var_dump($data2); $r->close(); - // Test 3: stream_cast in expression context (method chaining) + // Test 3: toStream() in expression context (method chaining) $fp2 = fopen($tmpfile, 'w'); - stream_cast($fp2)->write("chain test"); - stream_cast($fp2)->close(); + $fp2->toStream()->write("chain test"); + $fp2->toStream()->close(); $fp3 = fopen($tmpfile, 'r'); - var_dump(stream_cast($fp3)->read(10)); - stream_cast($fp3)->close(); + var_dump($fp3->toStream()->read(10)); + $fp3->toStream()->close(); unlink($tmpfile); echo "OK\n";