必须掌握SELECT、INSERT、UPDATE、DELETE、CREATE五类SQL语句及预处理防注入;PHP不执行SQL,仅传递给数据库解析,ORM底层仍是SQL。

PHP增删改查绕不开SQL,不学不行
PHP本身没有内置数据库操作能力,mysqli、PDO这些扩展只是“管道”,真正执行数据操作的是底层数据库(如MySQL)。你写$pdo->query("SELECT * FROM user"),实际是把字符串发给MySQL服务器去解析执行——这意味着,哪怕用ORM(如Eloquent),底层生成的仍是SQL。跳过SQL直接写CRUD,等于让别人替你写句子却不懂语法,出错时连报错信息都看不懂。
必须掌握的5类SQL语句及其典型PHP调用场景
不是所有SQL都要精通,但以下五类必须手写过、调试过,不能只靠生成器或文档复制粘贴:
-
SELECT:带WHERE、ORDER BY、LIMIT是高频需求;JOIN在关联查询(如“查用户+对应订单”)中无法避免 -
INSERT INTO ... VALUES:单条插入用VALUES,多条建议用INSERT INTO ... VALUES (),(),()减少IO -
UPDATE ... SET ... WHERE:漏写WHERE是线上事故高发原因(比如全表密码重置) -
DELETE FROM ... WHERE:同上,没WHERE就是清空表;软删除应优先用UPDATE设is_deleted=1 -
CREATE TABLE:建表语句要自己写,尤其字段类型(VARCHAR(255)vsTEXT)、索引(INDEX)、外键约束
PHP里最容易踩的SQL坑:参数拼接与预处理混淆
新手常把变量直接拼进SQL字符串,比如"SELECT * FROM user WHERE id = " . $_GET['id'],这等于敞开SQL注入大门。正确做法是用预处理(prepared statement):
try {
$stmt = $pdo->prepare("SELECT * FROM user WHERE status = ? AND created_at > ?");
$stmt->execute([1, '2024-01-01']);
$users = $stmt->fetchAll();
} catch (PDOException $e) {
// 注意:不要把$e->getMessage()直接输出给前端
}关键点:
立即学习“PHP免费学习笔记(深入)”;
- 问号
?或命名参数:status由PDO自动转义,不依赖手动过滤 -
execute()传入的数组值,类型由PDO根据字段元数据推断,不用自己cast - 不要用
mysql_real_escape_string()(已废弃)或addslashes()替代预处理
WHERE条件写错导致查不到数据?先看NULL和类型隐式转换
常见现象:SELECT * FROM user WHERE email = 'a@b.com'返回空,但数据明明存在。可能原因:
- 字段定义为
email VARCHAR(100) NOT NULL DEFAULT '',但实际存了NULL——WHERE email = NULL永远为false,得写WHERE email IS NULL - 字段是
INT类型,但PHP传入字符串'123',MySQL会做隐式转换,但某些严格模式下会报错或不匹配 - 字符集不一致:表用
utf8mb4,连接没设SET NAMES utf8mb4,中文条件查不到
验证方法:在PHP里用$pdo->getAttribute(PDO::ATTR_ERRMODE)确保开启异常模式,再用echo $pdo->lastInsertId()或$stmt->rowCount()确认影响行数,比肉眼盯SQL更可靠。











