我在 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 Eloquent 或 query 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
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;
}
这是推荐的解决方案,因为,它..
$listing = Post::where('slug', '=', DB::raw('?'))
->where('status', '=', 'publish')
->where('type', '=', 'movie')
->setBindings([$slug], 'where')
->firstOrFail();
这将确保您的 slug 被视为文字字符串值,无论它可能包含任何 SQL 关键字。
$slug=addslashes($slug);