PHP -致命错误:无法访问以“\0”开头的属性

ghg1uchk  于 2023-09-29  发布在  PHP
关注(0)|答案(4)|浏览(118)

这是我在jsut上遇到的最奇怪的错误之一,因为在另外两个系统上完全相同的代码都能正常工作。
让我解释一下我的设置以及它是如何工作的。首先,我使用的是zend框架,错误是在第300行的Zend/View/Abstract类中抛出的。
Windows系统运行PHP 5.3.3 -在这里工作正常。Linux Centos 5.5系统运行PHP 5.3.3 -在这里工作正常。Linux Centos 5.5系统运行PHP 5.3.6 -这个系统给了我致命的错误。
PHP -致命错误:无法访问以“\0”开头的属性
看了看设置,我第一次认为这一定是PHP中的一个bug,但我不太确定。我首先安装了PHP 5.3.5并升级到5.3.6,但这没有帮助。
抛出错误的代码也应该工作,所以我完全搞不懂为什么我在这个系统上得到错误,而不是其他两个。
抛出错误的代码是:

$this->$key = $val;

以下列方法定位:

public function __set($key, $val)
{
        if ('_' != substr($key, 0, 1)) {
            $this->$key = $val;
            return;
        }

        require_once 'Zend/View/Exception.php';
        $e = new Zend_View_Exception('Setting private or protected class members is not allowed');
        $e->setView($this);
        throw $e;
}

任何帮助将不胜感激。
我做了一些进一步的调试,它不是我的变量导致的错误。我发现当$key变量被设置为Zend_View_useViewStream时,会抛出致命错误,所以我在它被字符串修剪之前和之后对它进行了vardump。

KEY string(25) "Zend_View_useViewStream" 
TRIMMED string(24) "Zend_View_useViewStream"

正如你所看到的字符串长度是1个字符长的变量时,没有修剪,但他们似乎对我一样??我猜是nul-byte [“\0”(ASCII 0(0x 00)),NULL字节。]是被剥夺与修剪,但为什么它被添加到这个系统,而不是其他?

kgqe7b3p

kgqe7b3p1#

__set()是一个魔术方法,当你尝试设置一个不存在的属性时会调用它。如果它在Zend_View_Abstract中抛出错误,那么您的某个视图正在尝试设置不存在的示例属性,并且该示例属性以空字符开头。

$this->$property = $value;

你可以试着把财产

$property = trim($property);
$this->$property = $value;

我有一种感觉,有人试图错误地修改$this。你能在你的视图中找到代码吗?

enyaitl3

enyaitl32#

我会说这是一个地方的事情了。但这似乎已经在当前的PHP版本中得到了巩固:

if (Z_STRVAL_P(member)[0] == '\0') {
            if (!silent) {
                    if (Z_STRLEN_P(member) == 0) {
                            zend_error(E_ERROR, "Cannot access empty property");
                    } else {
                            zend_error(E_ERROR, "Cannot access property started with '\\0'");
                    }
            }
            return NULL;

所以我们可以推断这是在PHP 5.3.3到5.3.6左右引入的。(我的版本是5.3.2,效果相同,但可能是一个backported补丁)。在更新日志中找不到任何指示原因的内容。
无论如何,如果不确保它们不以NUL开头,就不能使用二进制属性名。

PHP 5.0.0和PHP 5.1.0之间已经发生了变化:

我怀疑这就是原因:

if (prop_info_name[0] == '\0' && prop_info_name[1] != '*' && !(property_info->flags & ZEND_ACC_PRIVATE)) {
    /* we we're looking for a private prop but found a non private one of the same name */
    return FAILURE;
}

我还没有看过这个,但从那个片段中,我假设\0字节最初用于不同的东西,后来被禁止了。

hts6caw3

hts6caw33#

我不确定,但我假设$key是以"\0"开头的字符串。

643ylb08

643ylb084#

这可能会帮助到某人。我试图访问一个对象,因为LazyLoading没有完全初始化。请确保在访问对象之前对其进行了初始化。在我的例子中,我必须从数据库中加载对象并完全初始化它。

相关问题