我有一个db.php文件,其中包含以下内容:
// db.php file
// creates connection to database
// DATABASE CONNECTION FUNCTION
function sql_con(){
try{
$dbh = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
// log error to file and display friendly error to user
ExceptionErrorHandler($e);
exit;
}
}
我有一个注册页面,我想检查用户名是否已经存在,所以我事先调用我的sql_con();
函数连接到数据库然后执行以下查询
// connect to database
sql_con();
$stmt = $dbh->prepare("SELECT `user_login` FROM `users` WHERE `user_login` = ? LIMIT 1");
$stmt->execute(array($username));
if ( $stmt->rowCount() > 0 ) {
$error[] = 'Username already taken';
}
我是PDO的新手,上面我得到了以下错误:
注意:未定义的变量:第64行的C:\ wamp \ www \ signup.php中的dbh
致命错误:在非对象中调用成员函数prepare() 第64行的C:\ wamp \ www \ signup.php
可能是非常愚蠢的事情,我似乎把自己与PDO混为一谈,因为我处于初学阶段。谁能告诉我我做错了什么?此外,我不确定这是否是正确的方式,因为我是PDO的新手,所以如果有更有效的方式进行用户名查询,请告诉我。
答案 0 :(得分:3)
这是因为$dbh
对象仅限于try catch
块内部和sql_con()
功能,因为范围。
正确的解决方案是删除try catch
阻止, 返回$dbh
末尾的sql_con()
变量功能 强>
然后:
try {
$dbh = sql_con();
$stmt = $dbh->prepare("SELECT `user_login` FROM `users` WHERE `user_login` = ? LIMIT 1");
$stmt->execute(array($username));
if ( $stmt->rowCount() > 0 ) {
$error[] = 'Username already taken';
}
}
catch (PDOException $e) {
//Do stuff with $e
}
答案 1 :(得分:2)
一旦函数执行完毕,$dbh
变量就会被销毁。
您可以尝试返回句柄:
function sql_con() {
// your connection code
return $dbh;
}
然后在你的注册页面中:
$dbh = sql_con();
根据您的需求,更好的选择是使用DI容器。
答案 2 :(得分:0)
你在函数中定义了一个不可见的ist。
function sql_con(){
try{
$dbh = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh; //this
} catch (PDOException $e) {
// log error to file and display friendly error to user
ExceptionErrorHandler($e);
exit;
}
}
$dbh = sql_con();
如果为pdo抽象创建一个类会更好。
$dbh = DB::getInstance();