skip to Main Content

I’m experiencing an issue in Laravel where certain keywords (e.g., "AND" in a movie title slug) are being interpreted as SQL syntax within a where clause. This causes the query to break when I try to retrieve a record by its slug. Here’s a simplified version of my query:

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

When $slug contains keywords like "AND," MySQL seems to misinterpret the slug value, causing errors. Here’s an example of the raw SQL output that’s causing issues:

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

As you can see above I used Laravel Eloquent or query builder but the sql query it return it have Error causing "Attempt to read property "slug" on null" while slug available but it recognize "and" as part of sql query instead of slug

In this case, and-there-were-4 should be treated as a single string in slug, but instead, MySQL interprets it as part of the query syntax.

I have tried


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

But the outcome become the same

I expect the slug value to be interpreted as a single string without MySQL misinterpreting any keywords it may contain. Ideally, I would like Laravel to handle this internally without manual SQL adjustments.

2

Answers


  1. MySQL is interpreting the "AND" in your slug as an SQL keyword rather than treating the entire slug as a literal string value.

    <?php
    
    namespace AppHttpControllers;
    
    use AppModelsPost;
    use IlluminateSupportFacadesDB;
    
    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;
        }
    
    

    This is a the recommended solution because, it..

    • Maintains Eloquent’s query builder functionality
    • Properly escapes the slug value
    • Is secure against SQL injection
    • Preserves model events and relationships

    To implement this in your code, simply replace your current query with:

    $listing = Post::where('slug', '=', DB::raw('?'))
        ->where('status', '=', 'publish')
        ->where('type', '=', 'movie')
        ->setBindings([$slug], 'where')
        ->firstOrFail();
    

    This will ensure that your slug is treated as a literal string value, regardless of any SQL keywords it might contain.

    Login or Signup to reply.
  2. If you suspect that $slug might be getting improperly sanitized, make sure it is being passed as a string. You can manually ensure that the value is correctly escaped using addslashes() or mysqli_real_escape_string() (although Laravel should handle this automatically):

    $slug = addslashes($slug);

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search