理解如何在php中引用父类的问题

时间:2016-08-02 13:28:47

标签: php oop

OOP的新手很抱歉,如果这很明显。

我有一个班级和一个子班级

class dBConnect {

private $host, $username, $password, $database, $input;

public function __construct($host, $username, $password, $database){
    $this->host        = $host;
    $this->username    = $username;
    $this->password    = $password;
    $this->database    = $database;


    $this->dbConnect = new mysqli( $this->host, $this->username, $this->password, $this->database);
    /* check connection */
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
        }
    return true;
}

public function setCharacterSet($charSet = 'utf8'){
   if(!$this->dbConnect->set_charset($charSet)){
    printf("Error loading character set ".$charSet.": %s\n", $this->dbConnect->error);   
    };
    return true;
    }


   public function sanitizeSQL($input){
   return(mysqli_real_escape_string($this->dbConnect, $input));
   }

   public function runQuery($query) {
     $result = $this->dbConnect->query($query);
       if (!$result) die('Invalid query: ' . mysql_error($this->dbConnect));
      return $result;
      }

public function __destruct() {
    mysqli_close($this->dbConnect)
        OR die("There was a problem disconnecting from the database.");

   }

 }

 class newUser extends dBConnect {

    public static function login($userName=NULL, $password=NULL) {

       $sql = "SELECT * FROM db26541116_farmFile.users WHERE userName = '".$userName."' AND password = '".$password."' LIMIT 0,1";
       $result=parent::runQuery($sql);
      $numRows = $result->num_rows;
    $result->close();
    if($numRows > 0){
      return false;
    }else{
    $sql = "INSERT INTO db26541116_farmFile.users (userName, password) VALUES  ('$userName', '$password')"; 
    $result=parent::runQuery($sql);
    $result->close();
    return true;    
    }

    throw new RuntimeException("NULL string found in cleanPostString");

}

}

我可以创建对象

      $db = new dBConnect("localhost", "userName", "password", "database");
      $db->setCharacterSet('utf8'); 

没有问题,但是当我使用子类时,我遇到了问题

    if(newUser::login($userName,$passWord)){
//send to site
}else{
//try again 
}

我得到错误非静态方法dBConnect :: runQuery()不应该静态调用。我该如何从newUser中调用父类。

感谢您的期待。

4 个答案:

答案 0 :(得分:0)

$result=parent::runQuery($sql);

错误就在这一行。您已将runQuery定义为公共函数,因此您应使用$this->调用它。如果您已将其定义为公共静态,则可以将其称为parent::

此行上会出现同样的错误:

$result=parent::runQuery($sql);

您不应该在静态中调用非静态方法。相反的情况并非如此 - 您可以在非静态方法中调用静态方法。您应该阅读php文档以获取更多信息。

答案 1 :(得分:0)

您应该实例化newUser类而不是父类。并使用其对象登录用户。

$newUser = new newUser("localhost", "farmFile01", "NheuYyjadk3hdCga", "db26541116_farmFile"); // will use the construct of the parent class
$newUser->setCharacterSet('utf8'); 
if(newUser->login($userName,$passWord)){
//send to site
}else{
//try again 
}

或者更好,不是扩展数据库类,而是像这样传递数据库对象。

$newUser = new newUser($db);

结合使用
class newUser extends dBConnect {
  private $db;
  public function __construct($db){
  $this->db = $db;
  }
}
// and to run a query use 
$result=$this->db->runQuery($sql); 

答案 2 :(得分:0)

您可以像这样更改您的代码:

if(newUser::login($userName,$passWord,$db)){
//send to site
}else{
//try again 
}

在您的newUser类中,您需要像这样更改

public static function login($userName=NULL, $password=NULL,newUser $newUser) {
 $result=$newUser->runQuery($sql);
}

然后你的代码就可以了。

答案 3 :(得分:0)

除了您的代码中的一些错误,以解决此问题,下面应该概述问题,并为您提供一个去处。

你调用你创建的方法的方式实际上是这样的:

//No instantiation needed ie $newUser = new newUser()
//It is static so you can just call it.
newUser::login();

但是您会收到错误Non-static method dBConnect::runQuery() should not be called statically

这是因为要调用dbConnect的{​​{1}},您必须实例化该对象的实例。 runQuery($sql)扩展它,从技术上讲,你需要创建它。

newUser

但是你会再次收到错误$newUser = new newUser('host','user','pass','db'); //Notice this is dbConnects constructor. $newUser->login(); ,因为你仍在静态方法中调用它。

因此解决方法很简单,从方法Non-static method dBConnect::runQuery() should not be called statically中删除static标识符。从技术上讲,您可以暂时不管它,但您可能希望将login更新为parent::runQuery($sql);,因为调用$this->runQuery($sql);会获得parent的{​​{1}}并让比如有一天你需要在dbConnect中覆盖它,你将会遇到一个错误并且不知道原因。

注意事项runQuery($sql)是此对象实例的缩写,不适用于静态方法。静态方法不是实例的一部分,而是对象本身。由于您不必具有使用该方法的对象的实例化,因此没有此实例。