Как запросить таблицу на основе до 17 различных переменных? - PullRequest
1 голос
/ 15 мая 2011

У меня есть таблица MySQL, которую я хочу искать через форму POST. Проблема в том, что существует около 17 переменных, которые конечный пользователь может пожелать запросить по отдельности или в комбинации. Это приводит к слишком большому количеству возможностей для выражений else-if. Спросив здесь, я построил следующий запрос:

$query = "SELECT * FROM profiles"; 

$postParameters = array("name","height","gender","class","death","appro","born","tobiano","modifier","adult","birth","sire","dam","breeder","owner","breed","location");
$whereClause = " WHERE 1 = 1";
foreach ($postParameters as $param) {
    if (isset($_POST[$param]) && !empty($_POST[$param])) {
        switch ($param) {
            case "name":
                $whereClause .= " AND ProfileName='".$_POST[$param]."' ";
                break;
            case "height":
                $whereClause .= " AND ProfileHeight='".$_POST[$param]."' ";
                break;
            case "gender":
                $whereClause .= " AND ProfileGenderID='".$_POST[$param]."' ";
                break;
            case "class":
                $whereClause .= " AND ProfileBreedClassID='".$_POST[$param]."' ";
                break;
            case "death":
                $whereClause .= " AND ProfileYearOfDeath='".$_POST[$param]."' ";
                break;
            case "appro":
                $whereClause .= " AND ProfileYearApproved='".$_POST[$param]."' ";
                break;
            case "born":
                $whereClause .= " AND ProfileYearOfBirth='".$_POST[$param]."' ";
                break;
            case "tobiano":
                $whereClause .= " AND ProfileTobianoTest='".$_POST[$param]."' ";
                break;
            case "modifier":
                $whereClause .= " AND ProfileColourModifier='".$_POST[$param]."' ";
                break;
            case "adult":
                $whereClause .= " AND ProfileAdultColourID='".$_POST[$param]."' ";
                break;
            case "birth":
                $whereClause .= " AND ProfileBirthColourID='".$_POST[$param]."' ";
                break;
            case "sire":
                $whereClause .= " AND ProfileSireReg='".$_POST[$param]."' ";
                break;
            case "dam":
                $whereClause .= " AND ProfileDamReg='".$_POST[$param]."' ";
                break;
            case "breeder":
                $whereClause .= " AND ProfileBreederID='".$_POST[$param]."' ";
                break;
            case "owner":
                $whereClause .= " AND ProfileOwnerID='".$_POST[$param]."' ";
                break;
            case "breed":
                $whereClause .= " AND ProfileBreedID='".$_POST[$param]."' ";
                break;
            case "location":
                $whereClause .= " AND ProfileLocationCountryID='".$_POST[$param]."' ";
                break;
        }
    }
}
$query .= $whereClause;

$result = mysql_query("$query");
    while ($row = mysql_fetch_array($result)) {
        echo $row['ProfileName'] . '<br/>';
    }

Спасибо Сагги Малахи за этот метод!

Ответы [ 4 ]

1 голос
/ 15 мая 2011

Другой способ, немного более гибкий.

<?php

// Use $ to indicate variable name, $ will be stripped when getting data from $_POST.
// The $variable will then be replaced with the data from the form.
// This way you setup the entire condition in the array, more flexible.
$set_data = array(
    'ProfileHeight >= $height',
    'ProfileGenderID = $gender',
    'ProfileTobianoTest LIKE %$tobiano%',
    'ProfileOwnerID = $owner',
);

$where = '';
foreach ($set_data as $str) {
    // Get variable name from str.
    if (!preg_match('/\$([a-zA-Z0-9_]+)/', $str, $matches))
        die('Invalid settings.');

    $name = $matches[1];

    if (!isset($_POST[$name]))
        continue;

    $data = trim($_POST[$name]);

    if ($where != '')
        $where .= ' AND ';
    $where .= str_replace('$' . $name, mysql_real_escape_string($data), $str);
}

if ($where != '') {
    $query = 'SELECT * FROM profiles WHERE ' . $where;
    print "$query\n";
}
1 голос
/ 15 мая 2011

Лучшим подходом было бы определение массива со всеми возможными параметрами POST, а затем запуск по ним при построении предложения WHERE с помощью оператора переключения PHP.

<?php
$postParameters = array("name","height","gender");
$whereClause = " WHERE 1 = 1";
foreach ($postParameters as $param) {
    if (isset($_POST[$param]) && !empty($_POST[$param])) {
        switch ($param) {
            case "name":
                $whereClause .= " AND ProfileName='".$_POST[$param]."' ";
                break;
            case "height":
                $whereClause .= " AND ProfileHeight='".$_POST[$param]."' ";
                break;
            // more cases....  
        }
    }
}
$query .= $whereClause;
0 голосов
/ 15 мая 2011

Если вы готовы сделать несколько модификаций:

$query = "SELECT * FROM profiles"; 
$parameters = "";

foreach ($params as $param => $value)
{
    // Important! validate the content of $value to avoid SQL injections

    if (!empty(param))
    {
         $parameters .= "AND $param LIKE '%" . $value . "%' ";
    }
}
if (!empty($parameters))
{
    $parameters = preg_replace("/^AND/", "WHERE", $parameters, 1); 
}

Для этого необходимо:

  1. Переименуйте ваши параметры в точные имена столбцов
  2. Соберите все данные в массив вместо отдельных переменных Кстати, похоже, что вы не проверяете переменные параметров для внедрения SQL. Если они отправлены пользователем, вам следует.
  3. Сделайте все свои сравнения, используя "LIKE". Если это проблема, вы можете сделать пару особых случаев, чтобы позаботиться о параметрах "LIKE".

Если вы готовы внести эти изменения, это намного чище.

Кстати, вы спрашиваете о PHP, но ваш код выглядит как C #. Что дает?

0 голосов
/ 15 мая 2011

Верхняя часть выглядит так, как будто она будет работать должным образом.

Вы проверяли их?

В первой была опечатка: "ProdileHeight" должен быть "ProfileHeight", я полагаю

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...