Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
713 views
in Technique[技术] by (71.8m points)

mysql - Writing a PDO search query from a PHP array

I'm building an application using PHP 7 and a PDO connection to a MySQL database.

One part of the application contains a search form which allows a user to search for a training course by 3 different fields: the course category, the course name, and a date.

The types of elements on the form are:

  1. Course category - dropdown, with numerical (int) ID's.
  2. Course name - text input
  3. Date - date picker (using HTML 5 type="date" parameter to get a calendar in the browser).

These fields can be used in conjunction, or on their own. This means a user could search, for example, just by (1), or (2 & 3), or all (1 & 2 & 3).

I've written the PHP to get the POST data and it's now in an array - for example:

$search_data = [
    'category' => 3,
    'name' => 'Hazard training',
    'date' => ''
]

I want to use this within a PDO query but I don't know what the best way to write it is because (1) and (3) would be an = query condition, whereas (2) is a LIKE. My solution was going to be looping through the search terms and then trying to construct a query, e.g.

$sql = ' WHERE ';
foreach ($search_data as $key => $value) {
    if ($key == 'category') {
        $sql .= ' category = ' . $value;
    }
    if ($key == 'course_name') {
        $sql .= ' course_name LIKE % ' . $value ' % ';
    }
    if ($key == 'date') {
        $sql .= ' date = ' . $value;
    }
}

The trouble with this is it doesn't work because of having to bind the parameters in PDO. It also doesn't work because I can't find a way to get the AND between each query (if there is a preceding statement).

I'm lost with this now and unsure what the best way to write this is.

Any help would be appreciated.

Edit: I realise that hardcoding the names, e.g. ($key == 'course_name') isn't ideal, but this is only being done because of the different query conditions (LIKE vs =). I assume that one could make $search_data multi-dimensional to say which type of query it was, but this is beyond my initial problem and probably another post.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here`s a simple solution to your problem:

$sql = 'SELECT ..... FROM ... WHERE 1 ';
$where = '';
$pdoData = [];

foreach ($search_data as $key => $value) {
    if(!$value) continue; // skip empty values

    if ($key === 'category') {
        $pdoData[':category'] = $value;
        $where .= ' AND category = :category ';
    }
    if ($key === 'course_name') {
        $pdoData[':course_name'] = '%'.$value.'%';
        $where .= ' AND course_name LIKE (:course_name) ';
    }
    if ($key === 'date') {
        $pdoData[':date'] = $value;
        $where .= ' AND date = :date ';
    }
}

$sql = $sql.$where;

$stmt = $this->ci->db->prepare($sql);
$stmt->execute($pdoData);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

And you have $pdoDate array holding the binded data.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...