Официальная документация PDO (PHP Data Object).
Как и в предыдущем примере, нам сначала нужно соединение с базой данных, которое выполняется путем создания нового объекта PDO - смотрите выше пример того, как это сделать, если вы не уверены.
Поскольку соединение с базой данных MySQL является объектом PDO, вы должны использовать различные методы PDO (любую функцию, которая является частью любого объекта) для подготовки и выполнения запросов. Методы объектов вызываются так:
$the_Object->the_Method();
PDO позволяет подготовить SQL-код перед его выполнением. SQL-запрос обрабатывается и исправляется перед выполнением.
Упрощенная атака SQL-инъекцией может быть выполнена просто путем ввода SQL-кода в поле на форме. Например:
// хакер пишет это в поле имени пользователя формы входа
john"; DROP DATABASE user_table;
// финальный запрос становится таким
"SELECT * FROM user_table WHERE username = john"; DROP DATABASE user_table;
Так как существует синтаксически корректный SQL-код, точка с запятой делает DROP DATABASE user_table
новым SQL-запросом, а ваша пользовательская таблица удаляется.
Подготовленные операторы не позволяют символам " и ; завершить исходный запрос, и вредоносная инструкция DROP DATABASE
никогда не будет выполнена.
Чтобы использовать подготовленные операторы, вы должны написать новую переменную, которая вызывает метод prepare()
объекта базы данных.
Переходим к правильному коду:
<?php
$servername = "mysql.hostinger.com";
$database = "u266072517_name";
$username = "u266072517_user";
$password = "buystuffpwd";
$sql = "mysql:host=$servername;dbname=$database;";
$dsn_Options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION];
// создание нового соединения с базой данных MySQL с помощью PDO, $my_Db_Connection - это объект
try {
$my_Db_Connection = new PDO($sql, $username, $password, $dsn_Options);
echo "Connected successfully";
} catch (PDOException $error) {
echo 'Connection error: ' . $error->getMessage();
}
// устанавливаем переменные для человека, которого мы хотим добавить в базу данных
$first_Name = "Test";
$last_Name = "Testing";
$email = "Testing@testing.com";
// здесь мы создаем переменную, которая вызывает метод prepare() объекта базы данных.
// SQL-запрос, который вы хотите выполнить, вводится как параметр, а заполнители записываются следующим образом: placeholder_name
$my_Insert_Statement = $my_Db_Connection->prepare("INSERT INTO Students (name, lastname, email) VALUES (:first_name, :last_name, :email)");
// теперь мы сообщаем скрипту, на какую переменную фактически ссылается каждый заполнитель, используя метод bindParam()
// первый параметр - это место в выражении выше - второй параметр - это переменная, к которой он должен относиться
$my_Insert_Statement->bindParam(:first_name, $first_Name);
$my_Insert_Statement->bindParam(:last_name, $last_Name);
$my_Insert_Statement->bindParam(:email, $email);
// выполните запрос, используя данные, которые мы только что определили
// метод execute() возвращает TRUE, если он успешен, и FALSE, если нет, позволяя писать свои собственные сообщения здесь
if ($my_Insert_Statement->execute()) {
echo "New record created successfully";
} else {
echo "Unable to create record";
}
// на этом этапе вы можете изменить данные переменных и повторить процедуру для добавления новых данных в базу данных
$first_Name = "John";
$last_Name = "Smith";
$email = "john.smith@email.com";
$my_Insert_Statement->execute();
// выполняем снова, когда переменные изменились
if ($my_Insert_Statement->execute()) {
echo "New record created successfully";
} else {
echo "Unable to create record";
}
В строках 28, 29 и 30 мы используем метод bindParam()
объекта базы данных. Также существует совершенно другой метод bindValue()
.
bindParam() - Этот метод оценивает данные при достижении метода execute()
. В первый раз, когда скрипт достигает метода execute()
, он видит, что $first_Name
соответствует "Test"
, связывает это значение и выполняет запрос.
Когда сценарий достигает второго метода execute()
, он видит, что $first_Name
теперь соответствует "John"
, связывает это значение и снова запускает запрос с новыми значениями. Важно помнить, что мы определили запрос один раз и повторно использовали его с разными данными в разных точках скрипта.
bindValue() - Этот метод оценивает данные, как только достигается bindValue()
. Поскольку значение $first_Name
было установлено на "Test"
при достижении bindValue()
, оно будет использоваться каждый раз, когда вызывается метод execute()
для $my_Insert_Statement
.
Обратите внимание, что мы повторно используем переменную $first_Name
и второй раз даем ей новое значение. Если вы проверите свою базу данных после выполнения этого скрипта, у вас есть оба определенных имени, несмотря на то, что в конце скрипта переменная $first_Name
равна "John"
. Помните, что PHP оценивает весь скрипт перед его фактическим выполнением.
Если вы обновите скрипт, чтобы заменить bindParam на bindValue, вы дважды вставите в MySQL "Test Testing"
в БД и "John Smith"
будет проигнорирован.