我对MysqLi感到很困惑.虽然我多年来一直在使用过程式
mysql调用,但我想习惯为它提供的db security / MysqL注入保护制作预备语句.我正在尝试编写一个简单的select语句(是的,我知道为此提供性能增强的程序调用).在运行时,我得到了所有的回声,直到我点击$result = $stmt-> get_result();零件.对我来说这一切看起来都相当简单,但是在MysqLi上阅读手册后,我感到很茫然.任何想法为什么会失败?
*注意:这是一个测试环境,虽然没有对字符进行消毒/转义,但我只将有效内容传递给变量$username和$email.而且,我已经看了很多,以找到我的问题的解决方案.
function checkUsernameEmailAvailability($username,$email) { //Instantiate MysqLi connection @$MysqLi = new MysqLi(C_HOST,C_USER,C_PASS,C_BASE) or die("Failed to connect to MysqL database..."); if (!$MysqLi) { echo 'Error: Could not connect to database. Please try again later...'; exit; } else { echo 'MysqLi created'; } /* Create a prepared statement */ if($stmt = $MysqLi -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) { echo '<br />MysqLi: '; /* Bind parameters s - string,b - boolean,i - int,etc */ $stmt -> bind_param("ss",$username,$email); echo '<br />paramsBound...'; /* Execute it */ $stmt -> execute(); echo '<br />Executed'; $result = $stmt->get_result(); echo '<br />Result acquired'; /* now you can fetch the results into an array - NICE */ $myrow = $result->fetch_assoc(); echo '<br />Fetched'; /* Close statement */ /$stmt -> close(); echo '<br />Done MysqLi'; } }
另外,每次调用函数时,是否必须实例化MysqLi?我假设他们不是像程序MysqL那样持久的db连接.是的,我知道这是一个范围问题,并且我没有能够理解这个类变量的范围.当我在函数之外声明它时,当我进入函数时它不可用.
UPDATE
如果我改变第12行:
if($stmt = $MysqLi -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
至:
$stmt = $MysqLi->stmt_init(); if($stmt = $MysqLi -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) { if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
我没有准备好声明.现在我更加困惑……
更新:
我联系了我的托管服务提供商,显然支持MysqLi,并且存在MysqLnd驱动程序.也许有一种方法可以简单地测试一下?虽然他们过去通常给我很多知识渊博的答案.
更新…再次:我自己检查了我的服务器功能并发现,而MysqLi和PDO存在时,MysqLnd不是.因此,我理解为什么get_result()不起作用(我认为需要MysqLnd),我仍然不明白为什么准备好的语句本身不起作用.
通过一些检查,即使MysqLi安装在我的主机上,显然MysqLnd驱动程序不存在.因此,不能使用get_result()(PHP手册将get_result定义为依赖于MysqLnd),而是需要进行额外编码以按照我希望的方式处理我的结果.
因此,我决定尝试学习PDO如何工作,并在几分钟内,瞧!
function checkUsernameEmailAvailability($username,$email) { echo 'pdo about to be created'; $dsn = 'MysqL:dbname='.C_BASE.';host='.C_HOST; $user = C_USER; $password = C_PASS; try { $dbh = new PDO($dsn,$user,$password); } catch (PDOException $e) { echo 'Connection Failed: ' . $e->getMessage(); } $params = array(':username' => $username,':email' => $email); try{ $sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email '); } catch(PDOException $e) { echo 'Prepare Failed: ' . $e->getMessage(); } try{ $sth->execute($params); } catch(PDOException $e) { echo 'Execute Failed: ' . $e->getMessage(); } $result = $sth->fetch(PDO::FETCH_ASSOC); print_r($result); }
尽可能多地进行错误检查,并且没有任何问题首先破解它!
最终守则
function checkUsernameEmailAvailability($username,$email) { $dsn = 'MysqL:dbname='.C_BASE.';host='.C_HOST; $user = C_USER; $password = C_PASS; new PDO($dsn,$password); $params = array(':username' => $username,':email' => $email); $sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email '); $sth->execute($params); $result = $sth->fetch(PDO::FETCH_ASSOC); print_r($result); }