I am trying to do a small search engine for a website.
This is the simple code
if ( Input::issetGet('q') ) {
        $q = Input::get('q');
        if ( !empty($q) ) {
            $keywords = explode(' ', $q);
            $findPhones = $dbh->prepare("
                SELECT 
                    p.id AS pId, p.name AS pName, p.original_price, p.price, p.img, p.brand, p.model, p.color, p.o_s, p.status, p.description,
                    b.id, b.name AS bName, 
                    m.id, m.name AS mName
                FROM phones AS p
                LEFT JOIN brands AS b ON p.brand = b.id
                LEFT JOIN phone_models AS m ON p.model = m.id
                WHERE p.name LIKE '%" . implode("%' OR p.name LIKE '%", $keywords) . "%'  
                OR p.description LIKE '%" . implode("%' OR p.description LIKE '%", $keywords) . "%' 
                OR b.name LIKE '%" . implode("%' OR b.name LIKE '%", $keywords) . "%'  
                ORDER BY p.id DESC
            ");
            $findPhones->execute();
            $phones = $findPhones->fetchAll();
        }
    }
Let me quickly explain. If I search for samsung, this query will check if the p.name, p.description or b.name contain this word. If I search for samsung computers the query will check if p.name, p.description or b.name contain either the word samsung or computers and so on for more search terms.
The problem is that I can't find a way to bind $keywords, I would like not to hardcode it like in the query, but to pass it when I execute the query.
I tried with ? and :keyword, but none worked. If I dump the query, the LIKE statements are empty, "".
My guess is that the problem lays in the implode function which is inside the query, it won't allow me to parameterize the array $keywords.
At this point I simply query the database without binding values and I am open for SQL Injection.
Q: How can I bind the array keywords, and if not possible, what's the best way to protect from SQL Injection in this case ?
Thank you
