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

时间:2016-03-04 17:22:05

标签: php oop

我试图在我的某个课程中清理代码,但它会引发一些问题。

我想要做的是将我的类方法中的所有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属性的声明

任何人都可以解释为什么会这样吗?看起来似乎无法声明引用其他属性的新字符串属性,但我不能相信这是真的 - 或者是它?

3 个答案:

答案 0 :(得分:2)

这一行是问题所在:

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

$this变量引用当前实例。由于您仍然声明属性,因此没有要引用的实例(因此,没有$this)。在课堂上可以为属性分配不同的值。一生,所以这样的表达可能无法奏效。

要么对值进行硬编码(可能不是你想要的),要么定义构造函数并在那里初始化私有属性:

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

除此之外,AFAIK,属性$date$courseID$userID没有值(null),这可能会赢得&#39 ;或者工作。你真正想做的是初始化这些属性(在构造函数中或使用setter),然后然后初始化字符串:

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
    );
}

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

旁注:如果要编写OO代码,使用带global的类是最糟糕的事情。对象应该是独立的,永远不要依赖全局状态来完成它们的工作

解释在声明属性

时没有$this的原因

嗯,简而言之,当你宣布一个类时,你只是描述了什么样的实例(实际的对象)。这些属性描述了实例将包含哪些数据,这些方法描述了实例可以执行的工作/操作类型 当一个类需要访问它包含的数据,或者调用它自己的一个方法(私有/受保护的方法)时,你必须告诉PHP在哪里查找该数据。因为你在课堂上,所以你告诉PHP查看当前对象:$this

阅读属性访问语句($this->date),如下所示:" From' this'例如,让我了解' date'" " Inside' this',查找' date&# 39;,并给我它的价值"

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

简单地说,这是一个班级,您可以在这里使用$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次,这意味着你犯了一个错误,或者即将制造一个。

答案 1 :(得分:0)

你不能在php类

中的方法或函数之外引用$ this
 private $releaseAssignmentSQL = "UPDATE StudentCourses SET released = '1', dateReleased = '" . $this -> date . "' WHERE courseID = '".$this -> courseID."' AND userID = '".$this -> userID."'";

尝试使用类中的方法构建SQL查询:

public function makeQuery () {

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

}

然后在__construct函数中调用它:

function __construct() {
     $this->makeQuery();
}

或者您可以在收到查询之前在其他地方执行此操作。

答案 2 :(得分:0)

关键字$this始终指向当前实例化的对象(对象上下文)。
在实例化对象后,您可以访问$this
更改您的代码,如下所示:

class Assignment {

  public $courseID;
  public $userID;
  public $date;
  private $releaseAssignmentSQL;

  public function __construct()
  {
      // setting other properties
      // ....
      $this->releaseAssignmentSQL = ($this->date && $this->courseID && $this->userID)? "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);
  }


}