PDO返回空数组作为结果

I have a simple search form, which I use to send a POST request to my php script using AJAX. I want the script to search my database for the keyword in the title column, and return the rows where it finds it. The posted data looks like this "searchword=test1", where test1 in the content of my text input.

I have 2 rows in my database, one has a title of test1, and another of test2. If I do SELECT * FROM articles I can see the results fine. If I type SELECT * FROM articles WHERE title LIKE 'test1'; into console, I get the correct result, but my php script returns an empty array.

No idea what I'm doing wrong here, any help is appreciated.

my php:

try {
    $hostname = "localhost";
    $username = "root";
    $password = "";

    $db = new PDO("mysql:host=$hostname;dbname=topdecka_PTC",$username, $password);

    if (!empty($_POST["searchword"])) {
        $searchword = $_POST["searchword"];
        $query = $db->prepare("SELECT * FROM articles WHERE title LIKE %:seachword%");
        $query->execute(array(':searchword' => $searchword));

        $result = $query->fetchAll(PDO::FETCH_ASSOC);
        echo json_encode($result);
        die();
    } 
    else {
        $query = $db->prepare('SELECT * FROM articles');
        $query->execute();

        $result = $query->fetchAll(PDO::FETCH_ASSOC);
        echo json_encode($result);
        die();
    }
} catch (PDOException $e) {
    echo "Error!: " . $e->getMessage() . "<br/>";
    die();
}

Firstly, you forgot the $ sign for %:seachword% as per your assignment:

Sidenote: There's a typo that I just noticed in seachword which should read as searchword as per ':searchword' => $searchword

$searchword = $_POST["searchword"];

However, I'd do something like this instead:

LIKE :seachword

then

$query->execute(array(":searchword" => "%" . $searchword . "%"));

Example syntax:

$sqlprep = $conn->prepare("SELECT `column` FROM `table` WHERE `column` LIKE :word");
$sqlprep->bindValue(':word', '%value%');

Also make sure that your form does have a POST method and that your element is indeed named and no typos.

Add error reporting to the top of your file(s) which will help find errors.

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);

// rest of your code

Sidenote: Error reporting should only be done in staging, and never production.

  • Add $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); right after the connection is opened, to catch potential errors, if any.

The reason it isn't working is because the value for :searchname is being escaped. As a result,

SELECT * FROM articles WHERE title LIKE %:seachword%

is being interpreted as this:

SELECT * FROM articles WHERE title LIKE %"test1"%

which is an invalid query. You need to quote the entire string or use concat() to add the % in.

Your two options are: $query = $db->prepare("SELECT * FROM articles WHERE title LIKE :seachword"); $query->execute(array(':searchword' => "%" . $searchword . "%"));

or: $query = $db->prepare("SELECT * FROM articles WHERE title LIKE CONCAT('%', :seachword, '%')"); $query->execute(array(':searchword' => $searchword));

Personally, I prefer the option with CONCAT as it separates responsibilities better, in my opinion.