0

假设有一个对象类,让我们以 User 为例。User 类包含它自己的规则,用于在提交之前验证它的数据。在保存到数据库之前,将检查规则并返回任何错误。否则更新将运行。

class User extends DBTable // contains $Rules, $Data, $Updates, and other stuff
{
    public __construct($ID)
    {
        parent::__construct($ID);
        // I'll only list a couple rules here...
        $this->Rules['Email'] = array(
            'Empty' => 'ValidateEmpty', // pre-written functions, somewhere else
            'Invalid' => 'ValidateBadEmail', // they return TRUE on error
            'Duplicate' => function($val) { return existInDatabase('user_table', 'ID_USER', '`Email`="'. $val .'" AND `ID_USER`!='. $this->ID);}
        );
        $this->Rules['Password'] = array(
            'Empty' => 'ValidateEmpty',
            'Short' => function($val) { return strlen($val) < 8; }
        );
        this->Rules['PasswordConfirm'] = array(
            'Empty' => 'ValidateEmpty',
            'Wrong' => function($val) { return $val != $this->Updates['Password']; }
        );
    }

    public function Save(&$Errors = NULL)
    {
        $Data = array_merge($this->Data, $this->Updates);
        foreach($this->Rules as $Fields => $Checks)
        {
            foreach($Checks as $Error => $Check)
            {
                if($Check($Data[$Field])) // TRUE means the data was bad
                {
                    $Errors[$Field] = $Error; // Say what error it was for this field
                    break; // don't check any others
                }
            }
        }
        if(!empty($Errors))
            return FALSE;

        /* Run the save... */

        return TRUE; // the save was successful
    }
}

希望我在这里张贴的足够多。所以你会注意到,在电子邮件的重复错误中,我想检查他们的新电子邮件对于除他们自己以外的任何其他用户是否不存在。PasswordConfirm还尝试使用 $this->Updates['Password'] 来确保他们两次输入相同的内容。

运行 Save 时,它​​会遍历规则并设置存在的任何错误。

这是我的问题:

Fatal error: Using $this when not in object context in /home/run/its/ze/germans/Class.User.php on line 19

我想使用 $this 的所有闭包都会出现此错误。

似乎数组中的闭包和类中的数组的组合导致了问题。这个规则数组的东西在类之外工作正常(通常涉及“使用”),AFAIK 闭包应该能够在类中使用 $this。

那么,解决方案?变通?

谢谢。

4

1 回答 1

2

问题出在Wrong验证器上。从这里调用验证方法:

if($Check($Data[$Field])) // TRUE means the data was bad

此调用不是在对象上下文中进行的(lambda 不是类方法)。因此$this,在 lambda 的主体内部会导致错误,因为它仅在对象上下文中存在。

对于 PHP >= 5.4.0,您可以通过捕获以下内容来解决问题$this

function($val) { return $val != $this->Updates['Password']; }

Updates在这种情况下,无论其可见性如何,您都可以访问。

对于 PHP >= 5.3.0,您需要复制对象引用并捕获它:

$self = $this;
function($val) use($self) { return $val != $self->Updates['Password']; }

但是,在这种情况下,您只能Updatespublic.

于 2013-01-30T01:01:52.217 回答