在非对象 PHP 帮助中调用成员函数 prepare()
Posted
技术标签:
【中文标题】在非对象 PHP 帮助中调用成员函数 prepare()【英文标题】:Call to a member function prepare() on a non-object PHP Help 【发布时间】:2011-05-26 16:39:17 【问题描述】:我正在尝试编写一个 php 函数。这很简单。这只是一个查询数据库的准备好的语句,但我无法让它工作。我不断收到错误 Call to a member function prepare() on a non-object。这是代码:
$DBH = new mysqli("host", "test", "123456", "dbname");
function selectInfo($limit, $offset)
$stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
$stmt->bind_param("ii", $limit, $offset);
$stmt->execute();
selectInfo();
每当我调用该函数时,我都会收到该错误。有人可以帮忙吗?
【问题讨论】:
【参考方案1】:这是一个范围错误。您正在使 $DBH
成为全局变量。所以当你进入函数时,全局变量是不可用的。你有 5 个实物期权。
1.使用全局关键字
function doSomething()
global $DBH;
//...
这不是一个好主意,因为它使维护和测试成为 PITA。想象一下尝试调试该函数调用。您现在需要找出$DBH
的定义位置,以尝试弄清楚发生了什么...
2。将$DBH
设为函数的参数
function doSomething(MySQLi $DBH)
它的优点是明确。但这仍然不是很好,因为调用代码需要跟踪全局变量。
3。创建一个函数来“获取”$DBH
对象
function getDBH()
static $DBH = null;
if (is_null($DBH))
$DBH = new mysqli(...);
return $DBH;
function doSomething()
$DBH = getDBH();
这具有完全绕过全局变量问题的优势。但也很难有多个连接或将任何代码重用于其他连接。
4.创建一个类来包装数据库访问
class Database
public function __construct($host, $user, $pass)
$this->DBH = new MySQli($host, $user, $pass);
public function doSOmething()
$this->DBH->foo();
这为您封装了所有内容。所有数据库访问都将通过一个类进行,因此您无需担心全局变量访问或其他任何事情。
5.使用预构建的类/框架
这是最好的选择,因为您不必担心自己动手。
数据库访问类:
A quick google search to get you started Doctrine ORM - 具有完整 ORM(对象映射)的完整数据库访问库 ADODB - 与数据库无关的数据库访问库 Pear MDB2 - 另一个数据库访问库完整的框架:
Zend Framework Lithium Framework Code Igniter (真的还有很多,我不会再麻烦列出了,因为这是另一个问题......)真的,选择是无穷无尽的。找到你喜欢的东西,并坚持下去。它真的会让你的生活更轻松......
【讨论】:
它对我不起作用:***.com/questions/40080426/…【参考方案2】:$DBH
不在范围内。您要么想在函数中将$DBH
定义为全局:
$DBH = new mysqli("host", "test", "123456", "dbname");
function selectInfo($limit, $offset)
global $DBH;
$stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
$stmt->bind_param("ii", $limit, $offset);
$stmt->execute();
或者正如 ircmaxell 在他的出色回答中指出的那样,有一个函数可以返回 $DBH
的静态实例。
【讨论】:
谢谢。我将如何使其成为全球性的并且仍然保持安全?我会将连接包装在一个函数中,然后为其分配一个变量,例如 function connect() new myqsli("host", "test", "123456", "dbname") $DBH = new connect(); (连接变量实际上隐藏在另一个文件中。) 是的,我会做一些函数并从那里获取连接。 @ircmaxell 完成。你当然是对的。为每个方法调用建立新连接是个坏主意。【参考方案3】:尝试在函数中添加global $DBH;
,或者添加到函数的参数中。
【讨论】:
【参考方案4】:selectInfo($DBH);
function selectInfo($DBH,$limit, $offset)
$stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
$stmt->bind_param("ii", $limit, $offset);
$stmt->execute();
【讨论】:
【参考方案5】:这很简单。 $DBH
不存在于 selectInfo()
函数中。在全局范围内定义的变量在函数中不可见,反之亦然。在手册页上阅读有关 variables scope 的更多信息。
如何解决?将该变量作为函数的参数传递:
$dbh = new MySQLi(...);
function selectInfo(MySQLi $dbh, $limit, $offset)
$stmt = $dbh->prepare(...);
...
【讨论】:
【参考方案6】:确保连接成功。
$DBH = @new mysqli("host", "test", "123456", "dbname");
if ($DBH->connect_errno)
die('Connect Error: ' . $DBH->connect_errno);
或
$DBH = @mysqli_connect("host", "test", "123456", "dbname");
if (!$DBH )
die('Connect Error: ' . mysqli_connect_errno());
【讨论】:
【参考方案7】:使 $DBH 全局化并不健康... 除了您可以在类中保护您的 $DBH 并将其设置为 null .. 并使用它..
【讨论】:
【参考方案8】:class PDOconnect extends PDO
受保护的 $con=null;
public function __construct()
try
$this->con= new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD ); //our new PDO Object
$this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
$this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
echo "hi.. you are connected succcessfully...";
【讨论】:
以上是关于在非对象 PHP 帮助中调用成员函数 prepare()的主要内容,如果未能解决你的问题,请参考以下文章
PDO 致命错误:在非对象上调用成员函数 prepare()
PHP 致命错误:在第 45 行的 admin\includes\html\database.class.php 中的非对象上调用成员函数 prepare()
致命错误:在非对象 cakephp 上调用成员函数 save()
致命错误:在非对象上调用成员函数 fetch_array()