Intereting Posts

Как преобразовать динамически построенный запрос ext / mysql в подготовленный отчет PDO?

Я конвертирую часть моего кода, который использовал функции ext / mysql ( mysql_*() ) для PDO и подготовленных операторов. Раньше, когда я динамически mysql_real_escape_string() запросы, я просто передавал свои строки через mysql_real_escape_string() и mysql_real_escape_string() их прямо в мой запрос, но теперь я считаю, что мне нужно передать значения в виде массива при выполнении запроса или привязать переменные до выполнения ,

Как я могу преобразовать старый код для использования нового драйвера базы данных?

Миграция ваших запросов из ext / mysql в подготовленные заявления PDO требует нового подхода к ряду аспектов. Здесь я расскажу о нескольких общих задачах, которые необходимо регулярно выполнять. Это ни в коем случае не является исчерпывающим, чтобы соответствовать любой возможной ситуации, оно просто предназначено для демонстрации некоторых методов, которые можно использовать при динамическом генерировании запросов.

Прежде чем мы начнем, нужно запомнить несколько вещей – если что-то не работает правильно, проверьте этот список, прежде чем задавать вопросы!

  • Если вы явно не отключите эмулированные подготавливаете, ваши запросы не безопаснее, чем использование mysql_real_escape_string() . См. Это для полного объяснения.
  • Невозможно объединить имена заполнителей и заполнители вопросительных знаков в одном запросе. Прежде чем вы начнете строить свой запрос, вы должны решить использовать один из другого, вы не можете переключаться на полпути.
  • Заполнитель в подготовленных операторах может использоваться только для значений, они не могут использоваться для имен объектов. Другими словами, вы не можете динамически указывать имена базы данных, таблицы, столбца или функции или любое ключевое слово SQL с использованием заполнителя. В общем, если вы обнаружите, что вам нужно это сделать, дизайн вашего приложения неверен, и вам нужно его повторно изучить.
  • Любые переменные, используемые для указания идентификаторов базы данных / таблицы / столбца, не должны поступать непосредственно из пользовательского ввода. Другими словами, не используйте $_POST , $_GET , $_COOKIE или любые другие данные, поступающие из внешнего источника, чтобы указать имена столбцов. Перед созданием динамического запроса необходимо предварительно обработать эти данные.
  • PDO с именем placeholders указываются в запросе как :name . При передаче данных для выполнения соответствующие ключи массива могут необязательно включать в себя ведущий : но это не требуется. Имя заполнитель должен содержать только буквенно-цифровые символы.
  • Именованные заполнители не могут использоваться более одного раза в запросе. Чтобы использовать одно и то же значение более одного раза, вы должны использовать несколько разных имен. Вместо этого попробуйте использовать заполнители вопросительных знаков, если у вас есть запрос со многими повторяющимися значениями.
  • При использовании заполнителей вопросительных знаков важна последовательность пройденных значений. Важно также отметить, что позиции замещающих элементов являются 1-индексированными, а не 0-индексированными.

Весь приведенный ниже примерный пример предполагает, что соединение с базой данных установлено и что соответствующий экземпляр PDO хранится в переменной $db .


Использование ассоциативного массива в виде списка столбцов / значений

Самый простой способ сделать это – с именами заполнителей.

С ext / mysql можно было бы избежать значений по мере создания запроса и поместить экранированные значения непосредственно в запрос. При построении подготовленного оператора PDO мы используем ключи массива, чтобы вместо этого указывать имена заполнителей, поэтому мы можем передать массив непосредственно в PDOStatement::execute() .

В этом примере мы имеем массив из трех пар ключ / значение, где ключ представляет имя столбца, а значение представляет значение столбца. Мы хотим выбрать все строки, в которых сопоставляется любой из столбцов (данные имеют отношение OR ).

 // The array you want to use for your field list $data = array ( 'field1' => 'value1', 'field2' => 'value2', 'field3' => 'value3' ); // A temporary array to hold the fields in an intermediate state $whereClause = array(); // Iterate over the data and convert to individual clause elements foreach ($data as $key => $value) { $whereClause[] = "`$key` = :$key"; } // Construct the query $query = ' SELECT * FROM `table_name` WHERE '.implode(' OR ', $whereClause).' '; // Prepare the query $stmt = $db->prepare($query); // Execute the query $stmt->execute($data); 

Использование массива для построения списка значений для предложения IN (<value list>)

Самый простой способ добиться этого – использовать заполнители вопросительных знаков.

Здесь у нас есть массив из 5 строк, которые мы хотим сопоставить с заданным именем столбца, и возвращаем все строки, где значение столбца соответствует хотя бы одному из пяти значений массива.

 // The array of values $data = array ( 'value1', 'value2', 'value3', 'value4', 'value5' ); // Construct an array of question marks of equal length to the value array $placeHolders = array_fill(0, count($data), '?'); // Normalise the array so it is 1-indexed array_unshift($data, ''); unset($data[0]); // Construct the query $query = ' SELECT * FROM `table_name` WHERE `field` IN ('.implode(', ', $placeHolders).') '; // Prepare the query $stmt = $db->prepare($query); // Execute the query $stmt->execute($data); не // The array of values $data = array ( 'value1', 'value2', 'value3', 'value4', 'value5' ); // Construct an array of question marks of equal length to the value array $placeHolders = array_fill(0, count($data), '?'); // Normalise the array so it is 1-indexed array_unshift($data, ''); unset($data[0]); // Construct the query $query = ' SELECT * FROM `table_name` WHERE `field` IN ('.implode(', ', $placeHolders).') '; // Prepare the query $stmt = $db->prepare($query); // Execute the query $stmt->execute($data); 

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

 // The array of values $data = array ( 'value1', 'value2', 'value3', 'value4', 'value5' ); // Temporary arrays to hold the data $placeHolders = $valueList = array(); // Loop the array and construct the named format for ($i = 0, $count = count($data); $i < $count; $i++) { $placeHolders[] = ":list$i"; $valueList["list$i"] = $data[$i]; } // Construct the query $query = ' SELECT * FROM `table_name` WHERE `field` IN ('.implode(', ', $placeHolders).') '; // Prepare the query $stmt = $db->prepare($query); // Execute the query $stmt->execute($valueList);