如果将方法名称设置为一个空字符串,那么将影响类的标志,而不是单个方法的标志。这可用于从类中删除“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 也将针对类的标志,但是,由于开发人员的函数签名不正确,该语法将与严格类型冲突。
为了澄清上面的提示
"...class 的类条目或 function 的函数条目是不可变的"
PHP 类或函数定义都没有任何“不可变”关键字 - 所以这个注释很令人困惑,因为它暗示 PHP 程序员可以控制它。实际上,提到的“不可变”状态是 OPcache 的内部控制的优化/共享内存功能。
因此,如果需要通过“uopz_flags()”来设置(更改)PHP 类或函数的标志,则有必要使用“opcache.blacklist_filename”INI 参数将引用类的 PHP 脚本或函数从 OPcache 中排除。