继续获得致命错误:调用未定义的方法DB :: prepare()

时间:2014-10-31 21:54:30

标签: php mysql pdo

这是Reflection::export(new ReflectionClass($this));

的回复
Class [ class Users extends Crud ] { 
    @@ C:\xampp\htdocs\classes\Users.php 5-76 
- Constants [0] { 
} 

- Static properties [0] { 
} 

- Static methods [0] {
} 

- Properties [7] {
    Property [ protected $table ]
    Property [ private $username ]
    Property [ private $email ]
    Property [ private $password ]
    Property [ private $passwordRepeat ] 
    Property [ private $nickname ] 
    Property [ private $permission ] 
} 
- Methods [20] {
    Method [ public method setUsername ] {
    @@ C:\xampp\htdocs\classes\Users.php 15 - 17 
- Parameters [1] { 
    Parameter #0 [ $username ] 
} 
} Method [ public method setEmail ] {
    @@ C:\xampp\htdocs\classes\Users.php 19 - 21 
- Parameters [1] {
    Parameter #0 [ $email ] 
} 
} Method [ public method setPassword ] {
    @@ C:\xampp\htdocs\classes\Users.php 23 - 28 
- Parameters [2] { 
    Parameter #0 [ $password ] 
    Parameter #1 [ $passwordRepeat ] 
}
} Method [ public method setNickname ] { 
    @@ C:\xampp\htdocs\classes\Users.php 30 - 32 
- Parameters [1] { 
    Parameter #0 [ $nickname ] 
} 
} Method [ public method setPermission ] {
    @@ C:\xampp\htdocs\classes\Users.php 34 - 36 
- Parameters [1] { 
    Parameter #0 [ $permission ] 
} 
} Method [ public method checkUsername ] {
    @@ C:\xampp\htdocs\classes\Users.php 38 - 49 
- Parameters [2] {
    Parameter #0 [ $username ] 
    Parameter #1 [ $email ] 
} 
} Method [ public method insert ] {
    @@ C:\xampp\htdocs\classes\Users.php 51 - 64
} Method [ public method update ] {
    @@ C:\xampp\htdocs\classes\Users.php 66 - 75 - Parameters [1] {
Parameter #0 [ $id ] 
} 
} Method [ public method find ] {
    @@ C:\xampp\htdocs\classes\Crud.php 12 - 18 
- Parameters [1] {
    Parameter #0 [ $id ] 
} 
} Method [ public method findAll ] {
    @@ C:\xampp\htdocs\classes\Crud.php 20 - 26 
} Method [ public method delete ] { 
    @@ C:\xampp\htdocs\classes\Crud.php 28 - 33 
- Parameters [1] {
    Parameter #0 [ $id ] 
} 
} /** * Create a new DB object for the specified database type but don't * connect to the database * * @param string $type the database type (eg "mysql") * @param array $options an associative array of option names and values * * @return object a new DB object. A DB_Error object on failure. * * @see DB_common::setOption() */ 
Method [ public method &factory ] {
    @@ C:\xampp\php\pear\DB.php 447 - 480 
- Parameters [2] {
    Parameter #0 [ $type ] 
    Parameter #1 [ $options = false ] 
} 
} /** * Create a new DB object including a connection to the specified database * * Example 1. * * require_once 'DB.php'; * * $dsn = 'pgsql://user:password@host/database'; * $options = array( * 'debug' => 2, * 'portability' => DB_PORTABILITY_ALL, * ); * * $db =& DB::connect($dsn, $options); * if (PEAR::isError($db)) { * die($db->getMessage()); * } * * * @param mixed $dsn the string "data source name" or array in the * format returned by DB::parseDSN() * @param array $options an associative array of option names and values * * @return object a new DB object. A DB_Error object on failure. * * @uses DB_dbase::connect(), DB_fbsql::connect(), DB_ibase::connect(), * DB_ifx::connect(), DB_msql::connect(), DB_mssql::connect(), * DB_mysql::connect(), DB_mysqli::connect(), DB_oci8::connect(), * DB_odbc::connect(), DB_pgsql::connect(), DB_sqlite::connect(), * DB_sybase::connect() * * @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError() */ 
Method [ public method &connect ] {
    @@ C:\xampp\php\pear\DB.php 518 - 567 
- Parameters [2] {
    Parameter #0 [ $dsn ] 
    Parameter #1 [ $options = Array ] 
} 
} /** * Return the DB API version * * @return string the DB API version number */ 
Method [ public method apiVersion ] {
    @@ C:\xampp\php\pear\DB.php 577 - 580 
} /** * Determines if a variable is a DB_Error object * * @param mixed $value the variable to check * * @return bool whether $value is DB_Error object */

Method [ public method isError ] {
    @@ C:\xampp\php\pear\DB.php 592 - 595 
- Parameters [1] {
    Parameter #0 [ $value ] 
} 
} /** * Determines if a value is a DB_ object * * @param mixed $value the value to test * * @return bool whether $value is a DB_ object */ 
Method [ public method isConnection ] {
    @@ C:\xampp\php\pear\DB.php 607 - 612 
- Parameters [1] {
    Parameter #0 [ $value ] 
} 
} /** * Tell whether a query is a data manipulation or data definition query * * Examples of data manipulation queries are INSERT, UPDATE and DELETE. * Examples of data definition queries are CREATE, DROP, ALTER, GRANT, * REVOKE. * * @param string $query the query * * @return boolean whether $query is a data manipulation query */ 
Method [ public method isManip ] {
    @@ C:\xampp\php\pear\DB.php 628 - 639 
- Parameters [1] {
    Parameter #0 [ $query ] 
} 
} /** * Return a textual error message for a DB error code * * @param integer $value the DB error code * * @return string the error message or false if the error code was * not recognized */ 
Method [ public method errorMessage ] {
    @@ C:\xampp\php\pear\DB.php 652 - 694 
- Parameters [1] {
    Parameter #0 [ $value ] 
} 
} /** * Parse a data source name * * Additional keys can be added by appending a URI query string to the * end of the DSN. * * The format of the supplied DSN is in its fullest form: * * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true * * * Most variations are allowed: * * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 * phptype://username:password@hostspec/database_name * phptype://username:password@hostspec * phptype://username@hostspec * phptype://hostspec/database * phptype://hostspec * phptype(dbsyntax) * phptype * * * @param string $dsn Data Source Name to be parsed * * @return array an associative array with the following keys: * + phptype: Database backend used in PHP (mysql, odbc etc.) * + dbsyntax: Database used with regards to SQL syntax etc. * + protocol: Communication protocol to use (tcp, unix etc.) * + hostspec: Host specification (hostname[:port]) * + database: Database to use on the DBMS server * + username: User name for login * + password: Password for login */ Method [ public method parseDSN ] { @@ C:\xampp\php\pear\DB.php 733 - 850 - Parameters [1] { Parameter #0 [ $dsn ] } } /** * Returns the given DSN in a string format suitable for output. * * @param array|string the DSN to parse and format * @param boolean true to hide the password, false to include it * @return string */ 
Method [ public method getDSNString ] {
    @@ C:\xampp\php\pear\DB.php 862 - 926 
- Parameters [2] {
    Parameter #0 [ $dsn ] 
    Parameter #1 [ $hidePassword ] 
}}}} 

使用Reflection::export(new ReflectionClass('DB')); 我收到了以下回复:

Class [ class DB ] { 
    @@ C:\xampp\htdocs\classes\DB.php 5-30 

- Constants [0] { 
} 

- Static properties [1] { 
    Property [ private static $instance ] 
} 

- Static methods [2] { 
    Method [ static public method getInstance ] {
        @@ C:\xampp\htdocs\classes\DB.php 9 - 24 
} 

    Method [ static public method prepare ] { 
        @@ C:\xampp\htdocs\classes\DB.php 26 - 28 - Parameters [1] { 
            Parameter #0 [ $sql ] 
        } 
    } 
} 

- Properties [0] {
 } 

- Methods [0] { 
} }

所以,我是PHP的新手,我正在尝试学习一点PDO。 我有这个代码,它一直显示这条消息:

  

致命错误:在第22行的C:\ xampp \ htdocs \ classes \ Crud.php中调用未定义的方法DB :: prepare()

这是我的DB.php:

<?php

require_once 'cfg.php';

class DB{

private static $instance;

public static function getInstance(){

    if(!isset(self::$instance)){

        try {
            self::$instance = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
            self::$instance->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }

    }

    return self::$instance;
}

public static function prepare($sql){
    return self::getInstance()->prepare($sql);
}

}
?>

Crud.php:

<?php

require_once 'DB.php';

abstract class Crud extends DB {

protected $table;

abstract public function insert();
abstract public function update($id);

public function find($id) {
    $sql = "SELECT * FROM $this->table WHERE ID = :id";
    $qry = DB::prepare($sql);
    $qry->bindParam(':id', $id, PDO::PARAM_INT);
    $qry->execute();
    return $qry->fetch();
}

public function findAll() {
    $sql = "SELECT * FROM $this->table";
    $qry = DB::prepare($sql);
    $qry->execute();
    return $qry->fecthAll();
}

public function delete($id) {
    $sql = "DELETE FROM $this->table WHERE ID = :id";
    $qry = DB::prepare($sql);
    $qry->bindParam(':id', $id, PDO::PARAM_INT);
    return $qry->execute();
}
}
?>

然后,当我尝试从代码中获取任何函数时,我收到了该消息。 例如,如果我尝试:

<?php

$crud = new Users();
$crud->findAll();

?>

Users.php:

<?php

require_once 'Crud.php';

class Users extends Crud {

protected $table = 'bloggy_user';
private $username;
private $email;
private $password;
private $passwordRepeat;
private $nickname;
private $permission;

public function setUsername($username) {
    $this->username = $username;
}

public function setEmail($email) {
    $this->email    = $email;
}

public function setPassword($password, $passwordRepeat) {
    if ($password == $passwordRepeat) {
        $cryptedPass    = password_hash($password, PASSWORD_BCRYPT, ['cost' => 10, 'salt' => '1234567890123456789011']);
        $this->password = $cryptedPass;
    }
}

public function setNickname($nickname) {
    $this->nickname = $nickname;
}

public function setPermission($permission) {
    $this->permission = $permission;
}

public function checkUsername($username, $email) {
    $sql = "SELECT * FROM $this->table WHERE username = :username OR email = :email";
    $qry = DB::prepare($sql);
    $qry->bindParam(':username', $username);
    $qry->bindParam(':email', $email);
    $qry->execute();
    if ($qry->fetchColumn() == 0) {
        return true;
    } else {
        return false;
    }
}

public function insert() {
    $sql = "INSERT INTO $this->table (username, email, password, nickname) VALUES (:username, :email, :password, :nickname)";
    $qry = DB::prepare($sql);
    $qry->bindParam(':username', $this->username);
    $qry->bindParam(':email', $this->email);
    $qry->bindParam(':password', $this->password);
    $qry->bindParam(':nickname', $this->nickname);
    if ($this->checkUsername($this->username, $this->email)) {
        return $qry->execute();
    } else {
        echo "Esse usuário já existe";
        return false;
    }
}

public function update($id) {
    $sql = "UPDATE $this->table SET email = :email, password = :password, nickname = :nickname, permission = :permission WHERE ID = :id";
    $qry = DB::prepare($sql);
    $qry->bindParam(':email', $this->email);
    $qry->bindParam(':password', $this->password);
    $qry->bindParam(':nickname', $this->nickname);
    $qry->bindParam(':permission', $this->permission);
    $qry->bindParam(':id', $id); 
    return $qry->execute();
}
}


?>

它确实显示错误消息。 Idk如果我让自己足够清楚,但我真的是PDO的菜鸟,所以如果有人能帮助我,我会很感激。

1 个答案:

答案 0 :(得分:2)

当我更正其他错误(见下文)时,代码适用于我。我想知道你的require_once是否找到了另一个名为DB.php的文件?我会通过在DB.php中添加类似print "Hello!";但在类定义之外的行来测试它。然后运行您的脚本,看看您的打印消息是否出现。

如果消息没有出现,那么你的脚本正在从require_once找到的某个不同文件中扩展一个DB类,然后才能找到你当前的DB.php。如果你有相同代码的多个副本,并且你没有仔细管理你的PHP include_path,那么这种错误就会一直发生。

如果可以,那么你必须有一个不知何故没有static function prepare()的DB类。您可以将此代码添加到脚本中,以找出它认为具有的方法:

    Reflection::export(new ReflectionClass('DB'));

或者在findAll()方法中调用prepare()之前测试实际的Crud对象:

    Reflection::export(new ReflectionClass($this));

好的,我从反射导出中看到了你的输出,我注意到了这一点:

/** * Create a new DB object for the specified database type but don't * connect to the database * * @param string $type the database type (eg "mysql") * @param array $options an associative array of option names and values * * @return object a new DB object. A DB_Error object on failure. * * @see DB_common::setOption() */ 
Method [ public method &factory ] {
    @@ C:\xampp\php\pear\DB.php 447 - 480 
- Parameters [2] {
    Parameter #0 [ $type ] 
    Parameter #1 [ $options = false ] 
} 

请注意,factory()方法表明它最初是在C:\xampp\php\pear\DB.php中定义的。数据库类的getInstance()和prepare()方法都不在反射导出中!

所以你的class Crud extends DB实际上是在找到你自己的DB类之前找到了梨DB.php。

这就是PHP支持namespaces的原因,因此您可以确保您的类具有唯一标识符,即使基类名称与其他类冲突也是如此。

或者您也可以将数据库类重命名为myDBDBconnection等类似的内容。

或者您可以更改include_path,以便在梨文件之前找到您的项目文件。

这也解释了为什么代码在我的环境中工作,因为我没有使用XAMPP或其他任何安装PEAR类的东西。


其他错误:

  • 您的PDO连接可能会失败,例如由于获取主机名或用户/密码错误。

  • 如果您不打算纠正根本原因或返回失败,请不要catch()例外。当您的连接在getInstance()中失败时,您会回显错误,但无论如何都要返回实例。

  • getInstance()->prepare()无法返回PDO对象时,请勿调用getInstance()。将其分为两个调用,on以获取实例,第二个调用prepare(),如果实例作为有效的PDO对象返回。

    $instance = self::getInstance();
    if ($instance instanceof PDO) {
        return $instance->prepare($sql);
    } else {
        throw new Exception("Not a PDO");
    }
    
  • 您在fetchAll()函数中fecthAll()拼错了findAll()

  • 您致电findAll(),但未将结果分配给变量。

  • 编辑:我认为"$this->table"不起作用,但事实证明我不正确,它确实有效。但是你可能仍然需要知道在字符串中的变量周围使用花括号来表示其他类型的表达式,比如选择数组元素。