получить именованные заполнители из подготовленного запроса mysql

Учитывая подготовленный оператор MySQL в PHP, как я могу выбрать из него именованные заполнители?

Например, если запрос, который я готовлю,

SELECT name, colour FROM fruit WHERE calories < :calories AND colour = :colour

or

INSERT INTO people (name, position, admin_level) VALUES (:name, :pos, 0) 

тогда я хотел бы в качестве вывода array(":calories",":colour") или array(":name",":pos").

Эта функция не указана на сайте PHP. Есть ли способ получить именованные заполнители из подготовленного оператора?


person user1111929    schedule 05.08.2014    source источник
comment
Бесполезно автоматически заполнять что-либо из массива $_POST, если только вы не хакер. Это будет НЕВЕРОЯТНО ОПАСНО, созданное для того, чтобы ловить новичков и помогать им разрабатывать сайты, которые ТАК ЛЕГКО ВЗЛОМАЕМЫ   -  person RiggsFolly    schedule 05.08.2014
comment
Не в этом дело. Текущий код также заполняет их данными из $_POST, это то, что делают формы, и вполне возможно сделать это безопасным способом. Все, что я спрашиваю, это как выбрать эти токены из запроса.   -  person user1111929    schedule 05.08.2014
comment
Хорошо, я увидел глупость, и это ослепило меня от реального вопроса.   -  person RiggsFolly    schedule 05.08.2014
comment
Хорошо, тогда я удалил эту часть, она была просто предназначена для иллюстрации варианта использования для этого.   -  person user1111929    schedule 05.08.2014


Ответы (1)


Вам придется использовать какие-то манипуляции со строками, чтобы сделать то, что, как я думаю, вы просите. Я не знаю стандартного механизма, который бы это делал. Итак, что-то вроде этого: -

$q = 'SELECT name, colour FROM fruit WHERE calories < :calories AND colour = :colour';

$res = preg_match_all('/:[a-z]+/',$q, $matches);

print_r($matches[0]);

Будет генерировать что-то вроде этого:

Array
    (
        [0] => :calories
        [1] => :colour
    )
)

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

После некоторых исследований я обнаружил

В качестве альтернативы, если вы хотите получить эту информацию после завершения

->prepare()
->bindParams()
->execute()

и сгенерировал дескриптор оператора, вы можете использовать: -

$stmt->debugDumpParams()

Ссылка на руководство по PHP, радикальная идея, которую я знаю, теперь мы оба кое-чему научились потому что я никогда не видел этого раньше либо.

person RiggsFolly    schedule 05.08.2014
comment
Да, таким образом его можно получить из запроса, но я надеюсь/предполагаю, что есть также способ напрямую получить его из подготовленного оператора. Как база данных вообще подготавливает оператор, если она не знает, какие заполнители должны быть назначены? - person user1111929; 05.08.2014
comment
Подготовка выполняется на сервере базы данных, а не в расширении php, и связана с вашим соединением. Чтобы вернуть его, потребуется какой-то запрос к серверу базы данных, чтобы вернуть его, что не имеет смысла и, следовательно, не существует. - person RiggsFolly; 06.08.2014
comment
Почему это не имеет смысла? Синтаксис PHP похож на $stmt = $db->prepare($query); $stmt->execute($params);, где фактический объект $stmt возвращается БД между подготовкой и выполнением. Так почему бы не использовать для этого метод $stmt->listofplaceholders()? - person user1111929; 06.08.2014
comment
О, вам нужна эта информация после того, как вы создали дескриптор оператора. Я думал, вы хотели этого до фазы bindParam(). См. ответ для получения дополнительной информации. - person RiggsFolly; 06.08.2014
comment
К сожалению, это функция отладки, которая выводит информацию прямо на экран, а не позволяет мне легче манипулировать ею. Так что я думаю, что это будет означать «нет» на мой первоначальный вопрос. Кроме того, не должна ли технически эта информация уже быть доступна после фазы prepare($query) и до фазы execute($params)? В подготовленном запросе (сразу после команды prepare($query)) уже должны быть просчитаны слоты для связываемых параметров, верно? - person user1111929; 06.08.2014
comment
Но, как я уже говорил, оператор prepare() отправляет необработанный текст вашего запроса вместе с :var или ? непосредственно на сервер, а сервер сам выполняет подготовку и сохраняет результат. Затем bindParams отправляет набор значений для привязки к подготовленному запросу (на сервере). Ничто не поддерживается локально для PHP расширения PDO. Итак, кто захочет добавлять дополнительные циклы к серверу базы данных, чтобы получить эти данные, когда вместо этого он может выполнять полезную работу. - person RiggsFolly; 06.08.2014
comment
Это правда. Я думал, что эти данные будут доступны в объекте $stmt без повторного обращения к базе данных, но я думаю, что нет. Спасибо за ответы! - person user1111929; 06.08.2014