不能。Eloquent ORM 不执行原生 SQL,需用 DB 门面(如 DB::select())配合参数绑定;DB::raw() 仅作原生片段用于 Query Builder,不可直接执行;写操作须用 DB::insert/update/delete 并绑定 ? 占位符;原生 SQL 不触发模型事件与访问器。

不能。Eloquent ORM 本身不执行原生 SQL —— 它是对象关系映射层,所有查询最终都经由 Query Builder 或 PDO 转译。你真正需要的是 DB 门面配合参数绑定,而不是“用 Eloquent 执行原生 SQL”。
DB::select() 是读取原生 SQL 的唯一安全入口
它专为 SELECT 设计,自动使用 PDO 预处理,返回 stdClass 对象数组。命名绑定和问号绑定都支持,但注意:命名绑定只在 DB::select() 中可用,DB::insert() 等写操作方法不支持命名占位符。
- 正确写法:
DB::select('SELECT * FROM users WHERE role = :role', ['role' => 'admin']) - 错误写法:
DB::insert('INSERT INTO logs (msg) VALUES (:msg)', ['msg' => 'ok'])→ 会报错或静默失败 - IN 子句不能直接写
WHERE id IN (?),必须动态生成占位符:DB::raw(implode(',', array_fill(0, count($ids), '?'))),再把$ids全部展开传入绑定数组
DB::raw() 不是执行 SQL 的方式,只是构建器里的“原生片段”
它只在 Query Builder 链式调用中生效,比如 User::select(DB::raw('MD5(email) as hash'))。它不会触发 SQL 执行,也不会做任何安全校验——如果把它拼进字符串再丢给 DB::statement(),就等于手动拼接 SQL,彻底绕过绑定机制。
- 安全用法:
User::whereRaw('created_at > ?', [$date])->get()(仍走绑定) - 危险用法:
DB::statement('UPDATE users SET name = ' . $unsafe . '')(SQL 注入高危) -
DB::raw()里不能放用户输入,只能放固定函数、字段别名、排序表达式等静态内容
写操作必须用 DB::insert/update/delete,而非 DB::statement()
DB::statement() 底层调用 PDO::exec(),对 SELECT 语句直接报错;而 DB::insert() 等方法才真正适配写操作语义,且强制要求参数绑定(只支持 ? 占位符)。
-
DB::insert('INSERT INTO posts (title) VALUES (?)', [$title])→ 返回布尔值 -
DB::update('UPDATE posts SET title = ? WHERE id = ?', [$newTitle, $id])→ 返回影响行数 - 要获取自增 ID,得在事务里调用
DB::getPdo()->lastInsertId(),DB::insert()本身不返回 ID
最易被忽略的一点:原生 SQL 查询默认不参与 Eloquent 的模型事件(creating、saving 等),也不触发访问器/修改器。如果你依赖这些逻辑,要么重构成 Eloquent 模型操作,要么手动补全对应行为。


















