在PHP中引用对象变量会引发语法错误

克里斯

我正在尝试清理我的一个类中的代码,但这带来了一些问题。

我想做的是将类方法中的所有SQL查询放入属性,这些方法可以根据需要引用这些属性。当SQL查询不依赖任何变量时,此方法工作正常,但是当我尝试将变量合并到查询中时,它将引发错误。

可能更容易显示代码来解释。

class Assignment {

  //Properties

  public $courseID;
  public $userID;
  public $date;

  //SQL query as property

  private $releaseAssignmentSQL = "UPDATE StudentCourses SET released = '1', dateReleased = '" . $this -> date . "' WHERE courseID = '".$this -> courseID."' AND userID = '".$this -> userID."'";

  //Method

  public function releaseAssignment(){
      global $db;
      $query = $db -> query($this -> releaseAssignmentSQL);
  }


}

然后使用以下方法调用该方法:

$assignment = new Assignment();

$assignment -> courseID = $db -> escape_value($_POST['courseID']);
$assignment -> userID = $db -> escape_value($_POST['userID']);
$assignment -> date = date("Y-m-d H:i:s");

echo $assignment -> releaseAssignment();

我的问题是,当我第一次加载页面(包括对该类的其他引用)时,它崩溃并显示以下错误:

Parse error: syntax error, unexpected '$this' (T_VARIABLE) in ... class.assignment.php on line 19

第19行指的是上述$releaseAssignment财产的声明

谁能解释为什么会这样?似乎不可能声明一个引用其他属性的新字符串属性,但是我不敢相信这是真的-还是吗?

埃里亚斯·范·奥特格姆(Elias Van Ootegem)

这行是问题所在:

private $releaseAssignmentSQL = "UPDATE StudentCourses SET released = '1', dateReleased = '" . $this -> date . "' WHERE courseID = '".$this -> courseID."' AND userID = '".$this -> userID."'";

$this变量引用当前实例。因为您仍在声明属性,所以没有要引用的实例(因此,no $this)。可以在类的生存期内为属性分配不同的值,因此这样的表达式可能行不通。

要么硬编码值(可能不是您想要的值),要么定义一个构造函数并在那里初始化private属性:

public function __construct()
{
    $this->releaseAssignmentSQL = "UPDATE StudentCourses SET released = '1', dateReleased = '" . $this -> date . "' WHERE courseID = '".$this -> courseID."' AND userID = '".$this -> userID."'";
}

再加上那,据我所知,在性能$date$courseID并且$userID没有一个值(null),这可能不会工作。您真正想做的是初始化这些属性(在构造函数中或使用setters),然后初始化字符串:

public function __construct($date, $course, $user)
{
    $this->date = $date;
    $this->userID = $user;
    $this->courseID = $course;
    $this->releaseAssignmentSQL = "UPDATE StudentCourses SET released = '1', dateReleased = '" . $this -> date . "' WHERE courseID = '".$this -> courseID."' AND userID = '".$this -> userID."'";
}

尽管如此,由于属性可以在实例的生存期内更改,因此,将它们的值串联起来可能不是您想要的。我在这里要做的是定义一个带有占位符的常量,以及一个返回带有填充的属性值的字符串的方法:

const REASSIGNMENT_QUERY = "UPDATE StudentCourses SET released = 1, dateReleased = '%s' WHERE courseID = %d AND userID = %d";

public function getQuery()
{
    return sprintf(
        self::REASSIGNMENT_QUERY,
        $this->date,
        $this->courseID,
        $this->userID
    );
}

看起来已经好多了。但是在查询中使用变量时,学习如何使用准备好的语句确实值得。

附带说明一下:global如果要编写OO代码,将class与with一起使用是最糟糕的事情。对象应该是独立的,并且永远不要依赖全局状态来完成其工作


解释为什么$this在声明属性时没有提示

简而言之,当您声明一个类时,您只是在描述实例(实际对象)的外观。这些属性描述了实例将保存的数据,而方法则描述了实例可以执行的工作/动作。
当类需要访问其包含的数据或调用其自己的方法之一(私有/受保护的方法)时,您必须告诉PHP在哪里寻找该数据。因为您在类中,所以您告诉PHP查看当前对象:$this

$this->date像这样读取属性访问语句():“在'this'实例中,为我获取'date'的值”,或“在'this'内,查找'date',并给我其值”

就像我说的$this是指对象,类的实例。该对象的布局和功能由类定义,但是实际数据由实例而非类拥有。
因此,类声明未链接到实例。为什么?因为单个类可以实例化无数次。$this在声明属性时,PHP无法知道您的意思。

简而言之,这是一个类,在这里您可以使用$this

class Foo
{
    private $declaration = 'This is part of the description, not an instance, no this';

    public function __construct()
    {
        //__construct is called when a new instance is created,
        //$this references our new instance
        //what happens here only affects this one instance
        $this->declaration = 'Not applicable anymore';
    }
}//end of declaration

因此,您只能$this在方法中使用,因为方法仅在实例存在时才会生效。方法之外的方法$this不起作用。曾经。

额外的信息

如果要让类声明设置影响所有实例的数据怎么办?好吧,如果该数据是不可变的(即字符串),则可以声明一个常量:

class Foo
{
    const THIS_CANNOT_CHANGE = 123;

    public $instanceProperty = null;

    public function __construct()
    {
        $this->instanceProperty = self::THIS_CANNOT_CHANGE;
    }
}

PHP也有static关键字,但是看到您还在学习中,我就不用说了,因为它static容易被滥用,尤其是那些仍然对OOP概念有所了解的人。最重要的是,如果您使用PHP编写类并使用static,请退后一步。9/10次,这意味着您犯了一个错误,或者即将犯错。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章