Php 致命错误:对中的非对象调用成员函数query()
我正在使用pdo,并在配置文件中设置了连接字符串,如Php 致命错误:对中的非对象调用成员函数query(),php,pdo,Php,Pdo,我正在使用pdo,并在配置文件中设置了连接字符串,如 $db = new PDO("mysql:host=localhost;dbname=mydbname", 'root', 'pass'); 我在一个类中,在一个方法/函数中有这个查询 $query = $db->query("select aUsername,aPassword,aOnline,aLastlogin from tbl_admins where aUsername = '$username'"); 当我运行我的站点时
$db = new PDO("mysql:host=localhost;dbname=mydbname", 'root', 'pass');
我在一个类中,在一个方法/函数中有这个查询
$query = $db->query("select aUsername,aPassword,aOnline,aLastlogin from tbl_admins where aUsername = '$username'");
当我运行我的站点时,我得到了这个错误。$db对象是否可能不是全局对象?这不是一种很好的方法,但您应该能够通过向方法/函数中添加全局对象使其工作:
function get_user($username) {
global $db;
$query = $db->query("select aUsername,aPassword,aOnline,aLastlogin from tbl_admins where aUsername = '$username'");
...
}
以这种方式使用全局变量时,您需要非常小心,不要在任何时候覆盖变量。这不是一种很好的方法,但您应该能够通过向方法/函数中添加全局变量来使其工作:
function get_user($username) {
global $db;
$query = $db->query("select aUsername,aPassword,aOnline,aLastlogin from tbl_admins where aUsername = '$username'");
...
}
以这种方式使用全局变量时,您需要非常小心,不要在任何时候覆盖变量。如果您在全局范围(或函数/方法以外的任何范围)中声明/安装了
$db
,并尝试在函数/方法中使用它,则它将不起作用
如果PDO对象未能实例化或在方法调用之前未设置,则也可能收到此错误。尝试var_dump(is_object($db))代码>和/或变量转储($db)代码>以进行检查
您需要执行以下操作之一:
在方法中实例化PDO对象(可能不实用或最佳选项):
在全局范围内实例化PDO对象,并使用global
关键字将其导入方法:
$db = new PDO( ... );
function foo () {
global $db;
$query = $db->query( ... );
}
在全局作用域中实例化PDO对象,并使用超全局$GLOBALS
数组访问它
$db = new PDO( ... );
function foo () {
$query = $GLOBALS['db']->query( ... );
}
在全局范围内实例化PDO对象,并将其作为参数传递给方法
$db = new PDO( ... );
function foo ($db) {
$query = $db->query( ... );
}
foo($db);
在全局范围内实例化PDO对象,并将其作为属性传递到对象中
$db = new PDO( ... );
class foo {
public $db;
public function bar ($db) {
$query = $this->db->query( ... );
}
}
$foo = new foo;
$foo->db = $db;
$foo->bar($db);
如果您在全局作用域(或函数/方法以外的任何作用域)中声明/安装了$db
,并试图在函数/方法中使用它,则它将不起作用
如果PDO对象未能实例化或在方法调用之前未设置,则也可能收到此错误。尝试var_dump(is_object($db))代码>和/或变量转储($db)代码>以进行检查
您需要执行以下操作之一:
在方法中实例化PDO对象(可能不实用或最佳选项):
在全局范围内实例化PDO对象,并使用global
关键字将其导入方法:
$db = new PDO( ... );
function foo () {
global $db;
$query = $db->query( ... );
}
在全局作用域中实例化PDO对象,并使用超全局$GLOBALS
数组访问它
$db = new PDO( ... );
function foo () {
$query = $GLOBALS['db']->query( ... );
}
在全局范围内实例化PDO对象,并将其作为参数传递给方法
$db = new PDO( ... );
function foo ($db) {
$query = $db->query( ... );
}
foo($db);
在全局范围内实例化PDO对象,并将其作为属性传递到对象中
$db = new PDO( ... );
class foo {
public $db;
public function bar ($db) {
$query = $this->db->query( ... );
}
}
$foo = new foo;
$foo->db = $db;
$foo->bar($db);
我建议使用一个名为的好模式。
以及一个简单的PHP实现:
abstract class Registry {
private static $_tools = array();
public static function set($name, $value) {
self::$_tools[$name] = $value;
}
public static function get($name) {
return (isset(self::$_tools[$name]) ? self::$_tools[$name] : null);
}
}
用法:
$db = new PDO("mysql:host=localhost;dbname=mydbname", 'root', 'pass');
Registry::set('db', $db);
//In some other part of code
$query = Registry::get('db')->query("select aUsername,aPassword,aOnline,aLastlogin from tbl_admins where aUsername = '$username'");
我建议使用一个名为的好模式。
以及一个简单的PHP实现:
abstract class Registry {
private static $_tools = array();
public static function set($name, $value) {
self::$_tools[$name] = $value;
}
public static function get($name) {
return (isset(self::$_tools[$name]) ? self::$_tools[$name] : null);
}
}
用法:
$db = new PDO("mysql:host=localhost;dbname=mydbname", 'root', 'pass');
Registry::set('db', $db);
//In some other part of code
$query = Registry::get('db')->query("select aUsername,aPassword,aOnline,aLastlogin from tbl_admins where aUsername = '$username'");
可能地任何上下文都很难说。它是全局的,否则您将收到一个未识别的变量错误。这可能不是PDO的一个实例,为什么或者如何-我不知道。如果错误报告设置为不显示此类警告,您是否在$db=new PDO(…)
之后重新声明$db
,但在$db->query
之前。它可能是未定义的,假设NULL
,因此是非对象。我会说,您的配置文件实际上应该只包含连接字符串/参数(“mysql:host=localhost;dbname=mydbname”、“root”、“pass”),并且您应该在别处(或需要时)创建PDO对象。可能的话。任何上下文都很难说。它是全局的,否则您将收到一个未识别的变量错误。这可能不是PDO的一个实例,为什么或者如何-我不知道。如果错误报告设置为不显示此类警告,您是否在$db=new PDO(…)
之后重新声明$db
,但在$db->query
之前。它可能是未定义的,假设NULL
,因此是非对象的。我会说,您的配置文件实际上应该只包含连接字符串/参数(“mysql:host=localhost;dbname=mydbname”、“root”、“pass”),您应该在别处(或需要时)创建PDO对象。+1使用设计模式。但是,如果在PHP中不能同时使用abstract final
,除非在以后的版本中可以?这会在PHP5.2中触发一个解析错误。您不需要将类声明为abstract
,而需要一个私有的_construct()方法。祝贺您,您刚刚演示了如何使用设计模式实现全局变量。+1。但是,如果在PHP中不能同时使用abstract final
,除非在以后的版本中可以?这会在PHP5.2中触发一个解析错误。与其将类声明为abstract
,您还需要一个私有的_construct()方法。恭喜,您刚刚演示了如何实现一个全局变量。哇,您的权利,我尝试了var_dump(is_object($db));在函数中,它显示为false,但在函数外,它显示为true。有点糟糕,就是这样。但愿我能让它全球化。现在我会像你说的那样在函数中实例化,直到我找到一个更好的方法。@Sarman不幸的是,由于Zend引擎的限制,PHP没有提供声明你自己的超全局的方法,这一点在互联网上已经被讨论过了$GLOBALS
是最接近可定制超全局的(您可以修改$\u get
、$\u POST
等,但不建议这样做),但它确实会使您的代码更混乱。我有时会做的事情(真正的OO程序员现在把目光移开)是从$GLOBALS
将数据提取到构造函数中对象的属性中,这样我就不必记得把它作为参数传入了;在函数中,它显示为false,但在