如果方法名称设置为空字符串,则将影响类的标志本身,而不是单个方法。这可以用来从类中删除“final”属性。
<?php
declare(strict_types=1);
final class MyClass { function mymethod() {} };
uopz_flags(MyClass::class, '', 0);
?>
注意:虽然没有记录在案,但将方法设置为 NULL 也会针对类标志,但是,由于开发人员的函数签名不正确,该语法与严格类型冲突。
(PECL uopz 2 >= 2.0.2, PECL uopz 5, PECL uopz 6, PECL uopz 7)
uopz_flags — 获取或设置函数或类的标志
在运行时获取或设置类或函数条目的标志
class
类的名称
function
函数的名称。如果提供了 class
并且将空字符串作为 function
传递,则 uopz_flags() 获取或设置类条目的标志。
flags
一组有效的 ZEND_ACC_ 标志。如果省略,则 uopz_flags() 充当 getter。
如果设置,则返回旧标志,否则返回标志
从 PHP 7.4.0 开始,如果传递了参数 flags
,则 uopz_flags() 会抛出 RuntimeException,如果启用了 OPcache,并且 class
的类条目或 function
的函数条目是不可变的。
版本 | 描述 |
---|---|
PECL uopz 5.0.0 | flags 参数现在是可选的。以前,必须传递 ZEND_ACC_FETCH 才能将 uopz_flags() 用作 getter。 |
示例 #1 uopz_flags() 示例
<?php
class Test {
public function method() {
return __CLASS__;
}
}
$flags = uopz_flags("Test", "method");
var_dump((bool) (uopz_flags("Test", "method") & ZEND_ACC_PRIVATE));
var_dump((bool) (uopz_flags("Test", "method") & ZEND_ACC_STATIC));
var_dump(uopz_flags("Test", "method", $flags|ZEND_ACC_STATIC|ZEND_ACC_PRIVATE));
var_dump((bool) (uopz_flags("Test", "method") & ZEND_ACC_PRIVATE));
var_dump((bool) (uopz_flags("Test", "method") & ZEND_ACC_STATIC));
?>
以上示例将输出
bool(false) bool(false) int(1234567890) bool(true) bool(true)
示例 #2 “取消最终化” 类
<?php
final class MyClass
{
}
$flags = uopz_flags(MyClass::class, '');
uopz_flags(MyClass::class, '', $flags & ~ZEND_ACC_FINAL);
var_dump((new ReflectionClass(MyClass::class))->isFinal());
?>
以上示例将输出
bool(false)
如果方法名称设置为空字符串,则将影响类的标志本身,而不是单个方法。这可以用来从类中删除“final”属性。
<?php
declare(strict_types=1);
final class MyClass { function mymethod() {} };
uopz_flags(MyClass::class, '', 0);
?>
注意:虽然没有记录在案,但将方法设置为 NULL 也会针对类标志,但是,由于开发人员的函数签名不正确,该语法与严格类型冲突。
澄清上述提示
“......类或函数的类条目是不可变的”
PHP 类或函数定义都没有任何“不可变”关键字 - 所以此注释令人困惑,因为它暗示 PHP 程序员可以控制这一点。实际上,提到的“不可变”状态是 OPcache 的内部控制优化/共享内存功能。
因此,如果需要通过“uopz_flags()”设置(更改)PHP 类或函数的标志,则有必要使用“opcache.blacklist_filename”INI 参数将引用的类或函数的 PHP 脚本从 OPcache 中排除。