谁能给我一个完整的例子,说明从连接到插入到选择以及错误处理的准备语句?
这个问题很老,但直到最近我才完成了一些研究,产生了一系列完全涵盖该请求的文章,所以你去吧:
连接
mysqli 连接的重要性经常被忽视,被贬低为一行。而正确的连接代码可以解决许多问题,从安全性到可用性。
鉴于您的代码是通常的 PHP 程序,这里有一个简单的 mysqli 连接代码将包含在您的脚本中:
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->set_charset($charset);
} catch (\mysqli_sql_exception $e) {
throw new \mysqli_sql_exception($e->getMessage(), $e->getCode());
}
unset($host, $db, $user, $pass, $charset); // we don't need them anymore
完整的解释可以在我的文章How to connect properly using mysqli 中找到(以及许多有用的提示),但只是一个小引用来突出最重要的部分:
- 为连接设置正确的字符集将消除整类错误,例如奇怪的字符/问号而不是您的数据、空的 json_encode() 输出、存储表情符号的问题等。
- 设置正确的错误报告模式将消除神秘的错误消息,如 mysqli_fetch_assoc() 需要参数... / 调用成员函数 bind_param()...,而是为您提供来自 MySQL 的实际错误消息。
- 安全性不是笑话,不应该有机会向外界泄露您的数据库详细信息
插入
Insert query比较简单,其他答案已经介绍过了。
您只需用问号替换查询中的所有变量(以及周围的引号!),然后准备查询,然后将所有变量及其类型推入bind_param(),最后执行查询。
只是一个快速提示:MySQL 很乐意将所有变量作为字符串接受,所以不要为某个变量寻找正确的类型,只需使用 "s" 即可。
所以基本上插入是这样的
$sql = "INSERT INTO users (name, email, password) VALUES (?,?,?)";
$stmt= $conn->prepare($sql);
$stmt->bind_param("sss", $name, $email, $password_hash);
$stmt->execute();
同样的原则也适用于所有其他查询类型,例如 UPDATE 或 DELETE。
选择
运行select query 几乎相同,但有一个小技巧。由于某些未知的原因,您不能在准备好的语句中使用熟悉的 fetch 函数。所以你需要先得到mysqli_result,然后才能使用fetch_assoc()、fetch_obj()等:
$sql = "SELECT * FROM users WHERE id=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch data
提示:绝对不需要熟悉的mysqli_num_rows() 函数。如果你想到了,你总是可以使用数据本身来查看你的查询是否返回了任何行:
$user = $result->fetch_assoc();
if ($user) {
// found!
}
多行也是如此,感谢
另一个提示:有一个方便的函数fetch_all() 可以一次性获取所有选定行的数组。例如,如果查询返回多行,您可以通过将最后一行更改为
来将它们放入数组中
$users = $result->fetch_all(MYSQLI_ASSOC); // fetch data
错误处理
错误处理是最重要但又有点令人惊讶的部分。尽管有许多文章和示例都说了,但作为一项规则,您根本不应该编写任何错误处理代码。这听起来绝对是疯狂的,但这正是事情必须要做的事情。大多数时候,您需要做的只是报告错误。并且 mysqli/PHP 已经可以为您完成,无需帮助。因此,您不应该编写任何验证查询执行结果的代码——如果出现错误,mysqli 会自动报告,这要归功于#Connection 部分中提到的mysqli_report() 函数调用。同样,这个原理的完整解释可以在另一篇文章中找到,献给将军PHP error reporting。
在极少数情况下,您确实需要处理错误,即在出现错误时执行一些操作,而不是仅仅报告错误,然后包装您的查询(es)try..catch。