PHP执行SQL需先连接数据库(mysqli或PDO),再查询;直接写SQL会报错;mysqli须先connect再query;PDO必须用prepare+execute防注入;WHERE条件引号与类型要明确;查询后必须检查结果。

PHP 本身不直接执行 SQL 查询,必须通过数据库扩展(如 mysqli 或 PDO)连接并发送语句;裸写 SELECT * FROM users 是无效的,会报错或被当成字符串。
用 mysqli_query() 执行查询必须先建立连接
常见错误是跳过连接步骤,直接调用 mysqli_query(),结果返回 Warning: mysqli_query(): Couldn't fetch mysqli 或 null。
正确流程是:
- 先用
mysqli_connect()创建连接资源(推荐面向对象写法:new mysqli($host, $user, $pass, $db)) - 检查连接是否成功(
$mysqli->connect_error不为空则失败) - 再用
$mysqli->query($sql)发送查询 - 对
SELECT类查询,需用fetch_assoc()、fetch_all()等读取结果集
示例:
立即学习“PHP免费学习笔记(深入)”;
$mysqli = new mysqli('localhost', 'root', '', 'test');
if ($mysqli->connect_error) die('连接失败: ' . $mysqli->connect_error);
$result = $mysqli->query("SELECT id, name FROM users WHERE status = 1");
while ($row = $result->fetch_assoc()) {
echo $row['id'] . ': ' . $row['name'] . "\n";
}PDO 查询更安全,但 prepare() 不是可选而是必需
很多人以为 PDO::query() 和 mysqli_query() 一样能直插变量,结果写出严重 SQL 注入漏洞。例如:$pdo->query("SELECT * FROM users WHERE id = $id") —— 这属于高危写法。
正确做法是:
- 一律使用
prepare()+execute()组合 - 参数用占位符(
:name或?),避免拼接字符串 - 即使只查一条记录,也别省略
fetch()步骤;query()返回的是PDOStatement对象,不是数据
示例:
立即学习“PHP免费学习笔记(深入)”;
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->prepare("SELECT name, email FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id'] ?? 1]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);WHERE 条件里数字和字符串的引号不能靠经验猜
MySQL 对类型隐式转换很“宽容”,但 PHP 层面不处理类型转换。比如 WHERE status = 1 和 WHERE status = '1' 在某些字段类型下行为不同(如 status 是 VARCHAR 时,前者可能全表扫描)。
更关键的是:预处理绑定时,PDO 默认把所有参数当字符串传给 MySQL,除非显式指定类型。所以:
- 整数字段建议用
PDO::PARAM_INT显式绑定:$stmt->bindValue(':id', $id, PDO::PARAM_INT) - 时间字段用
PDO::PARAM_STR即可,但值必须是标准格式(如'2024-05-20'),不能是time()返回的时间戳 - 布尔值在 PHP 中传
true/false,MySQL 接收为1/0,但字段类型应为TINYINT(1)而非BOOLEAN(后者只是别名)
最易被忽略的一点:查询后没检查结果是否为空或出错。mysqli->query() 对语法错误返回 false,PDOStatement->execute() 出错默认静默失败(除非开启 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)。不加判断就直接 fetch(),程序会崩得毫无提示。











