Mau*_*wer 8 php mysqli prepared-statement
我完全被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';
}
}
Run Code Online (Sandbox Code Playgroud)
另外,每次调用函数时,是否必须实例化mysqli?我假设他们不是像程序mysql那样持久的db连接.是的,我知道这是一个范围问题,并且我没有能够理解这个类变量的范围.当我在函数之外声明它时,当我进入函数时它不可用.
更新 如果我从以下位置更改第12行:
if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
Run Code Online (Sandbox Code Playgroud)
至:
$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';
Run Code Online (Sandbox Code Playgroud)
我没有准备好声明.现在我更困惑了....
更新: 我联系了我的托管服务提供商,显然支持mySQLi,并且存在mysqlnd驱动程序.也许有一种方法可以简单地测试一下?虽然他们过去通常给我很多知识渊博的答案.
更新...再次:我自己检查了我的服务器功能并发现,虽然存在mysqli和PDO,但mysqlnd却没有.因此,我理解为什么get_result()不起作用(我认为需要mysqlnd),我仍然不明白为什么准备好的语句本身不起作用.
Mau*_*wer 12
通过一些检查,即使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);
}
Run Code Online (Sandbox Code Playgroud)
我能想到的错误检查一样多,而且根本没有任何问题!
最终守则
function checkUsernameEmailAvailability($username, $email) {
$dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST;
$user = C_USER;
$password = C_PASS;
new PDO($dsn, $user, $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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13585 次 |
| 最近记录: |