如果 slug 包含“和”,我的查询无法找到帖子

问题描述 投票:0回答:2

我在 Laravel 中遇到一个问题,其中某些关键字(例如电影标题中的

"AND"
)被解释为
where
子句中的 SQL 语法。当我尝试通过
slug
检索记录时,这会导致查询中断。这是我的查询的简化版本:

$listing = Post::where('slug', $slug)
    ->where('status', 'publish')
    ->where('type', 'movie')
    ->firstOrFail();

$slug
包含“AND”之类的关键字时,MySQL似乎会误解
slug
值,从而导致错误。以下是导致问题的原始 SQL 输出的示例:

SELECT * FROM `posts` WHERE `slug` = and-there-were-4 AND `status` = publish AND `type` = movie LIMIT 1

正如你在上面看到的,我使用了 Laravel Eloquentquery builder 但它返回的 sql 查询有错误,导致“尝试在 null 上读取属性“slug””,而 slug 可用,但它会将“and”识别为sql 查询的一部分而不是 slug

在这种情况下,

and-there-were-4

应被视为 slug 中的单个字符串,但 MySQL 将其解释为查询语法的一部分。

我已经尝试过了

$listingQuery = Post::where('slug', '=', $slug) ->where('status', '=', 'publish') ->where('type', '=', 'movie');
但是结果都一样

我希望

slug

 值被解释为单个字符串,而 MySQL 不会误解它可能包含的任何关键字。理想情况下,我希望 Laravel 在内部处理这个问题,而不需要手动调整 SQL。

php laravel eloquent slug
2个回答
-3
投票
MySQL 将 slug 中的“AND”解释为 SQL 关键字,而不是将整个 slug 视为文字字符串值。

<?php namespace App\Http\Controllers; use App\Models\Post; use Illuminate\Support\Facades\DB; class PostController extends Controller { /** * Using query parameters */ public function getPostBySlug($slug) { $listing = Post::where('slug', '=', DB::raw('?')) ->where('status', '=', 'publish') ->where('type', '=', 'movie') ->setBindings([$slug], 'where') ->firstOrFail(); return $listing; }
这是推荐的解决方案,因为,它..

    维护 Eloquent 的查询生成器功能
  • 正确转义 slug 值
  • 能够防止 SQL 注入
  • 保留模型事件和关系
要在代码中实现此功能,只需将当前查询替换为:

$listing = Post::where('slug', '=', DB::raw('?')) ->where('status', '=', 'publish') ->where('type', '=', 'movie') ->setBindings([$slug], 'where') ->firstOrFail();
这将确保您的 slug 被视为文字字符串值,无论它可能包含任何 SQL 关键字。


-3
投票
如果您怀疑 $slug 可能未正确清理,请确保它作为字符串传递。您可以使用addslashes()或mysqli_real_escape_string()手动确保该值正确转义(尽管Laravel应该自动处理这个):

$slug=addslashes($slug);

© www.soinside.com 2019 - 2024. All rights reserved.