Разбор заполнители в качестве аргументов в SQL в PHP


Я пытаюсь найти хороший способ обработки аргументов в SQL, как я делаю это сейчас кажется, что он может использовать большое улучшение. Я пытаюсь преобразовать аргументы, которые разделены друг от друга ', & <= =>' из строки в аргументах SQL, такие как имя = 'АБВ' или name ='Имярек'.

Так

parseSQLOperators('dan,john&steven', 'username');

Создаст

WHERE username= 'dan' OR username = 'john' AND username ='steven'

У меня есть пример, как это делается ниже, но я интересно, если есть лучший способ для этого. Я знаю, что этот код-это некрасиво и я пытался вещи, как preg_splits но безрезультатно.

public static function parseSQLOperators($string, $content_term, $encapsulate = TRUE) {

        $string = trim($string);
        $length = strlen($string);

        $ADD_PREFIX = true;
        $output = '';
        for ($i = 0; $i < $length; $i++) {

            if ($string[$i] == '!') {

                $output .= ' ' . $content_term . '!=\'';

                if ($i == 0) {
                    $ADD_PREFIX = false;
                }
            } else if ($string[$i] == '+') {
                if (@$string[$i + 1] != '!') {
                    $output .= ' AND ' . $content_term . '=\'';
                } else {
                    $output .= ' AND ';
                }
            } else if ($string[$i] == ',') {
                if (@$string[$i + 1] != '!') {
                    $output .= ' OR ' . $content_term . '=\'';

                } else {
                    $output .= ' OR ';
                }

            }

            if ($string[$i] != '!' && $string[$i] != '+' && $string[$i] != ',') {

                $output .= $string[$i];

                if (@$string[$i + 1] == ',' || @$string[$i + 1] == '+' || @$string[$i + 1] == '!' || $i == $length || $i == $length - 1) {
                    $output .= '\'';
                }
            }
        }//end for

        if ($ADD_PREFIX == true) {
            $output = $content_term . '=\'' . $output;
        }

        if ($encapsulate) {
            $output = '(' . $output . ')';
        }

        return $output;
    }//end parseSQLOperator


307
3
задан 19 ноября 2011 в 06:11 Источник Поделиться
Комментарии
3 ответа

Если это все в SQL класс рода, то, я думаю, вы можете улучшить ваш дизайн немного. Что, если вы хотите, чтобы люди, которые не архивируются и имена соответствуют определенные вещи? Дэн,Джон и Стивен', 'логин' не работает. Вам нужно что-то более похожее:

$sql
->select(...)
->from(...)
->where('=dan|=john&=steven', 'username')
->andWhere('>0', 'archived')
->execute();

Обратите внимание, что я не использовал грамматику. Я бы рекомендовал следующее сокращенное обозначение грамматики:

//& means AND
//| means OR
//~ means LIKE

//operator means &, |
//comparator means things like !=, =, <>, <, >, <=, >=, ~
//identifier means things like dan, john, or jo%

//The pseudo regular expession:
//{comparator} {identifier} ({operator} {comparator} {identifier})*

Делая это, вы можете обратиться: '=Джон | !=Джемисон & =Джеймс | ~%jo_n' в имя = 'Джон' или name != 'Джеймисон' и имя = 'Джеймс' или имя как '%jo_n' довольно легко:

    function parse($string, $name) {
//add in quote marks
$string = preg_replace('/[A-Za-z0-9%_-]+/', "'$0'", $string);

//add in name:
$string = preg_replace('/\=|\!\=|<>|<|<=|>|>=|~/', "$name $0 ", $string);

//replace ~ with LIKE
$string = str_replace('~', 'LIKE', $string);

//expand '&' and ',' to ' AND '
$string = preg_replace('/\&|\,/', ' AND ', $string);

//expand '|' to ' OR '
$string = str_replace('|', ' OR ', $string);

return $string;

}

Также обратите внимание, что вы должны быть в состоянии защитить вещи правильно. Мы не хотим, чтобы SQL-инъекции происходит вокруг здесь! Я бы порекомендовал следующий синтаксис:

where('=? | =? & =?', array('dan', 'john', 'steven'), 'username')

Функция I может быть легко изменен, чтобы сделать это. Вы просто использовать в mysqli или PDO двигателя, чтобы сделать замена. Вы просто должны хранить аргументов в вашу структуру, так что вы можете сделать ее правильной.

4
ответ дан 20 ноября 2011 в 09:11 Источник Поделиться

Вы уверены, что вам нужен этот пользовательский формат (и анализа) на всех?

С помощью некоторых вспомогательных функций будет легче, например:

$sql->select(...)
->from(...)
->where(
or(
eq('dan', 'username'),
and(eq('john', 'username'),
eq('steven', 'username')
)
)
)
->execute();

Некоторые доказательство концепции реализации:

function eq($value, $col) {
return " ('$value' = $col) ";
}

function or($arg1, $arg2) {
return " ($arg1 OR $arg2) ";
}

function and($arg1, $arg2) {
return " ($arg1 AND $arg2) ";
}

Может быть, рамки с подобным функционалом уже существует.

0
ответ дан 20 декабря 2011 в 04:12 Источник Поделиться

Рассмотрим это читается решение, которое позволяет легко использовать подготовленные операторы:

$condition = array('username = :u and password =:p', array(':u' => $user, ':p' => $pass));
$result = $database->fetch_row('users', $condition);

0
ответ дан 18 февраля 2012 в 09:02 Источник Поделиться