Php: работа с бд mysql

Введение

PDO_MYSQL — это драйвер, реализуюший интерфейс PHP Data Objects (PDO) и предоставляет доступ из PHP к базам данных MySQL.

Начиная с PHP 5.2.1, PDO_MYSQL по умолчанию использует эмулированную подготовку. Ранее PDO_MYSQL по умолчанию использовал нативную поддержку подготовленных запросов, пристутствущих в MySQL 4.1 и выше, и эмулировал их для более старых версий клиентских библиотек mysql.

MySQL 8

При запуске PHP до версии 7.1.16 или PHP 7.2 до 7.2.4, установите плагин пароля по умолчанию MySQL 8 Server в mysql_native_password, иначе вы увидите ошибки, похожие на The server requested authentication method unknown to the client , даже когда caching_sha2_password не используется.

Это связано с тем, что MySQL 8 по умолчанию использует caching_sha2_password, и плагин не распознается старыми версиями PHP (mysqlnd). Вместо этого измените это, установив default_authentication_plugin=mysql_native_password в my.cnf. Плагин caching_sha2_password будет поддерживаться в будущей версии PHP. Пока же расширение mysql_xdevapi поддерживает его.

Подключение к MySQL через одноименное расширение

Расширение MySQL появилось первым и долгое время не имело конкурентов. Сейчас считается устаревшим и в серьезных проектах не используется. На это есть ряд причин, основными из которых являются плохая оптимизация и безопасность, отсутствие многопоточности. Несмотря на это, оно ещё долго будет поддерживаться большинством хостингов.


Начиная с PHP версии 5.5 многие функции расширения стали устаревшими, а в PHP 7 и вовсе не поддерживаются.

Рассмотрим пример подключения к базе данных с комментариями.

// Подключаемся к серверу БД
$mysql = mysql_connect($db_server, $db_user, $db_password);
if (!$mysql) { die ('Connection error: ' . mysql_error()); }

// Выбираем БД
$db = mysql_select_db($db_name, $mysql);
if (!$db) { die ('Error select db : ' . mysql_error()); }

// Устанавливаем кодировку подключения
mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER SET 'utf8'");

// Запросы ...

// Отключаемся от базы
mysql_close($mysql);

В качестве запросов используется стандартный SQL. Рассмотрим простые примеры выборки и добавления записей.

// Составляем запрос
$sql = 'SELECT * FROM `books` WHERE `BAuthor`="Пушкин"';
$result = mysql_query($sql);

// Перебор результата
while($row = mysql_fetch_array($result)) {
    print $row . '<br>';
}

В примере производим простую выборку записей из таблицы «books». Результат представлен в качестве ассоциативного массива, поэтому его содержимое можно получить в обычном цикле. Если запрос не возвращает набор данных, то в качестве результата возвращается «false» или «true».

$sql = 'SELECT * FROM `books` WHERE `BAuthor`="Пушкин"';
$result = mysql_query($sql);

if ($result) { echo 'Выполнено!'; }
else { echo 'Ошибка: ' . mysql_error(); }

Два способа PHP-подключения к БД MySQL

Есть два метода подключения к базе данных MySQL с помощью PHP: MySQLi и PDO.

MySQLi расшифровывается как MySQL Improved. Это эксклюзивное расширение MySQL, которое добавляет новые функции в интерфейс базы данных. Функции MySQLi являются как процедурными, так и объектно-ориентированными, причём первую парадигму расширение унаследовало от более ранней версии MySQL.

Сама MySQL разбивает задачу на линейные, пошаговые процедуры, что затрудняет внесение изменений, поскольку вам приходится редактировать код сверху. Между тем MySQLi рассматривает данные как набор взаимозаменяемых объектов с функциями, позволяя пользователям легко добавлять или удалять данные.

PDO расшифровывается как PHP Data Object, или объект данных PHP. В отличие от MySQLi, PDO является только объектно-ориентированным методом. Он поддерживает ряд различных типов баз данных, использующих PHP, таких как MySQL, MSSQL, Informix и PostgreSQL.

Исходные функции mysql_ устарели. Их лучше не использовать, поскольку они небезопасны и больше не поддерживаются.

Одна из наиболее важных функций, которую поддерживают оба метода — это подготовленные выражения (prepared statements). Она сокращает время, необходимое MySQL для выполнения повторяемого запроса. Эта функция также используется для предотвращения SQL-инъекций при внесении изменений в базу данных.

Какой бы метод вы ни использовали, вам понадобится правильная информация для подключения к созданной вами базе данных MySQL. Здесь вам пригодятся ранее сохранённые данные БД.

Вам также потребуется правильное имя сервера, или имя хоста для конфигурации. Hostinger использует “localhost” в качестве имени хоста своего сервера MySQL. Это имя, которое вы будете использовать, если загрузите свой PHP-скрипт на тот же сервер, что и база данных.

С другой стороны, если вы подключаетесь к базе данных из удалённого места (например, со своего компьютера), вам придётся использовать IP-адрес MySQL-сервера. Чтобы получить дополнительную информацию, обратитесь к своему хостинг-провайдеру. Он предоставит вам актуальную информацию о том, какое имя использовать в качестве имени хоста.

Listing Tables and Databases

It is very easy to list down all the databases and the tables available with a database server. Your result may be null if you don’t have the sufficient privileges.

Apart from the method which is shown in the following code block, you can use SHOW TABLES or SHOW DATABASES queries to get the list of tables or databases either in PHP or in PERL.

PERL Example

# Get all the tables available in current database.
my @tables = $dbh->tables ( );

foreach $table (@tables ){
   print "Table Name $table\n";
}

PHP Example

<?php
   $con = mysql_connect("localhost", "userid", "password");
   
   if (!$con) {
      die('Could not connect: ' . mysql_error());
   }
   $db_list = mysql_list_dbs($con);

   while ($db = mysql_fetch_object($db_list)) {
      echo $db->Database . "<br />";
   }
   mysql_close($con);
?>

5 последних уроков рубрики «PHP»

Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных. Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак

В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода. Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение

В этой статье мы расскажем как улучшили процесс подключение нескольких модулей. Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке. Подборка PHP песочниц Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

PHP-подключение к БД MySQL с PDO

Другой метод подключения к БД MySQL с использованием PHP-скрипта — через PDO. В целом он похож на предыдущий, но с некоторыми особенностями:

  1. В public_html создайте файл с названием pdoconfig.php и вставьте следующий код. Как всегда, не забудьте заменить значения плейсхолдеров информацией из вашей базы данных. Сохраните и закройте его, когда закончите.
    <?php
        $host = 'localhost';
        $dbname = 'databasename';
        $username = 'username';
        $password = 'password';
  2. Создайте ещё один файл и назовите его databaseconnect.php в том же каталоге, но со следующим кодом. Если вы назвали предыдущий файл по-другому, не забудьте изменить значение после require_once.
    <?php
    require_once 'pdoconfig.php';
     
    try {
        $conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
        echo "Connected to $dbname at $host successfully.";
    } catch (PDOException $pe) {
        die("Could not connect to the database $dbname :" . $pe->getMessage());
    }

Объяснение Скрипта PDO

Для подключения к базе данных PDO необходимо создать новый объект PDO с именем источника данных (DSN), именем пользователя и паролем.

DSN определяет тип базы данных, имя базы данных и любую другую информацию, относящуюся к базе данных, если это необходимо. Это переменные и значения, указанные нами в файле dbconfig.php, на которые один раз ссылается строка require_once в файле databaseconnect.php.


В последнем примере вы найдёте код try… catch… Это означает, что скрипт попытается подключиться к MySQL, используя предоставленный код, но в случае возникновения проблемы будет выполнен код в разделе catch. Вы можете использовать блок catch для отображения сообщений об ошибках подключения или запустить альтернативный код в случае сбоя блока try.

Если соединение установлено успешно, вы увидите сообщение «Connected to $dbname at $host successfully». Однако, если попытка не удалась, код в блоке catch покажет простое сообщение об ошибке и завершит скрипт.

Should I Use MySQLi or PDO?

If you need a short answer, it would be «Whatever you like».

Both MySQLi and PDO have their advantages:

PDO will work on 12 different database systems, whereas MySQLi will only work with MySQL databases.

So, if you have to switch your project to use another database, PDO makes the process easy. You only have to change the connection string and a few queries. With MySQLi, you will need to rewrite the entire code — queries included.

Both are object-oriented, but MySQLi also offers a procedural API.

Both support Prepared Statements. Prepared Statements protect from SQL injection, and are very important for web application security.

Что?

Для соединения с базой данных MySQL имеется три разных API:

  • – MySQL Improved (улучшенная)
  • – PHP Data Objects (объекты данных PHP)

Традиционный API хорошо выполняет свою работу и получил широкое распространение благодаря тому, что делает процесс получения записей из базы данных очень простым. Например:

/*
 * Демонстрация старого способа работы с базой данных MySQL
 */
 
# Соединение
mysql_connect('localhost', 'username', 'password') or die('Could not connect: ' . mysql_error());
 
# Выбор базы данных
mysql_select_db('someDatabase') or die('Не могу выбрать базу данных');
 
# Выполнение запроса
$query = "SELECT * from someTable";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
 
# Фильтрация строк и вывод нужной информации
while ($row = mysql_fetch_object($result)) {
    echo $row->name;
}

Да, приведенный пример очень прост. Но у него есть существенные недостатки:

  • Устарел: хотя официально его не признают устаревшим, но для новых приложений и обучения лучше использовать другие API.
  • Очистка: процесс очистки ввода пользователя от ненужного кода ложится на плечи разработчика.
  • Гибкость: данный API не гибкий и  работает только с базой данных MySQL. А если нужно перейти на другую?

PDO (PHP Data Objects) предоставляет более мощный инструмент для использования. Не нужно думать о драйвере базы данных, можно использовать подготовленные выражения, исключаются инъекции кода SQL.

Подключение БД к PHP:

Для этого создаём файлы connect.php, index.php и checkin.php. Сначала мы в connect.php подключаемся к самой БД, для этого пишем код ниже.

PHP

1 2 3 4 5 6 7 8 9 10 11 12 13 14

<?php

$server=’localhost’;// Имя или адрес сервера

$user=’root’;// Имя пользователя БД

$password=»;// Пароль пользователя

$db=’authorization-system’;// Название БД

$db=mysqli_connect($server,$user,$password,$db);// Подключение

// Проверка на подключение

if(!$db){

// Если проверку не прошло, то выводится надпись ошибки и заканчивается работа скрипта

echo»Не удается подключиться к серверу базы данных!»;

exit;

}

Подключаем connect.php к index.php

Default

1 2

// Подключение БД

require_once’connect.php’;


Проверяем скрипт, для этого запускаем программу.

После того как проверили на работа способность, можете убрать вывод надписи «подключение к базе данных прошло успешно».

Obtaining and Using MySQL Metadata

There are three types of information, which you would like to have from MySQL.

  • Information about the result of queries − This includes the number of records affected by any SELECT, UPDATE or DELETE statement.

  • Information about the tables and databases − This includes information pertaining to the structure of the tables and the databases.

  • Information about the MySQL server − This includes the status of the database server, version number, etc.

It is very easy to get all this information at the MySQL prompt, but while using PERL or PHP APIs, we need to call various APIs explicitly to obtain all this information.

Установка соединения с базой данных SQLite

Сначала создайте новый файл в директории приложения и добавьте новый класс с именем следующим образом:

<?php
 
namespace App;
 
class Config {
 /**
  * path to the sqlite file
  */
  const PATH_TO_SQLITE_FILE = 'db/phpsqlite.db';

}

Константа используется для хранения пути к файлу базы данных sqlite, который находится в папке .

Во-вторых, создайте новый файл и добавьте класс следующим образом:

<?php
namespace App;
 
/**
 * SQLite connnection
 */
class SQLiteConnection {
  /**
   * PDO instance
  * @var type 
  */
  private $pdo;
 
  /**
  * return in instance of the PDO object that connects to the SQLite database
  * @return \PDO
  */
  public function connect() {
    if ($this->pdo == null) {
      $this->pdo = new \PDO("sqlite:" . Config::PATH_TO_SQLITE_FILE);
      if (!filesize(self::SQLITE_FILE))
          throw new \Exception('There are no tables in the database!');
      }
    return $this->pdo;
  }
}

Чтобы установить соединение с базой данных SQLite, нам нужно создать новый экземпляр класса и передать строку соединения конструктору объекта .

Предположим, что файл базы данных SQLite находится в папке , мы используем следующую строку подключения:

sqlite:db/phpsqlite.db

Поскольку мы храним путь к файлу базы данных sqlite в классе , мы просто используем его для построения строки подключения.

Обратите внимание, что когда PHP подключается к базе данных SQLite, если она не существует, PHP создаст новый файл базы данных SQLite. используется для хранения экземпляра объекта PDO

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

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

Если необходимо сгенерировать файла автозагрузки заново:

composer dump-autoload -o

Чтобы установить соединение с базой данных SQLite, мы используем следующий код в файле :

<?php
 
require 'vendor/autoload.php';
 
use App\SQLiteConnection;
 
$pdo = (new SQLiteConnection())->connect();
if ($pdo != null)
  echo 'Connected to the SQLite database successfully!';
else
  echo 'Whoops, could not connect to the SQLite database!';

Если вы проверите папку , вы увидите файл с именем .

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

Для обработки исключения вы можете использовать блок следующим образом:

try {
  $this->pdo = new \PDO("sqlite:" . Config::PATH_TO_SQLITE_FILE);
} catch (\PDOException $e) {
  // handle the exception here
}

В этом уроке я показал, как настроить структуру проекта PHP и установить соединение с базой данных SQLite.

Select Data With PDO (+ Prepared Statements)

The following example uses prepared statements.

It selects the id, firstname and lastname columns from the MyGuests table where the lastname is «Doe», and displays it in an HTML table:

Example (PDO)

<?phpecho «<table style=’border: solid 1px black;’>»; echo «<tr><th>Id</th><th>Firstname</th><th>Lastname</th></tr>»;class TableRows extends RecursiveIteratorIterator {   function __construct($it) {     parent::__construct($it, self::LEAVES_ONLY);   }  function current() {    return «<td style=’width:150px;border:1px solid black;’>» . parent::current(). «</td>»;   }  function beginChildren() {     echo «<tr>»;   }   function endChildren() {     echo «</tr>» . «\n»;   } } $servername = «localhost»; $username = «username»;$password = «password»;$dbname = «myDBPDO»; try {  $conn = new PDO(«mysql:host=$servername;dbname=$dbname», $username, $password);   $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  $stmt = $conn->prepare(«SELECT id, firstname, lastname FROM MyGuests WHERE lastname=’Doe'»);   $stmt->execute();  // set the resulting array to associative  $result = $stmt->setFetchMode(PDO::FETCH_ASSOC);   foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) {     echo $v;  }}catch(PDOException $e) {  echo «Error: » . $e->getMessage();}$conn = null;echo «</table>»;?>

Проверка Статуса Выполнения и Устранение Распространённых Ошибок

Если запрос, который мы выполнили и вставили в базу данных MySQL, был успешным, мы увидим следующее сообщение:

Connect Successfully
New record created successfully

Устранение Распространённых Ошибок

Если же запись содержит ошибку, вы увидите соответствующее сообщение. Но не волнуйтесь, есть множество вариантов, как можно устранить эти ошибки mySQL.

MySQLi

Если вы столкнулись с ошибкой, работая с MySQLi, причина скорее всего в неправильном синтаксисе. Для примера давайте сделаем одну синтаксическую ошибку в нашем коде. В результате мы увидим что-то вроде этого:

Connect successfully
Error: INSERT INTO students {name, lastname, email} VALUES ('Test', 'Testing', 'Testing@testing.com')
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{name, lastname, email} VALUES ('Test', 'Testing', 'Test@testingcom')' at line 1"

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

"Error: INSERT INTO Students {name, lastname, email} VALUES ('Thom', 'Vial', 'thom.v@some.com') You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{name, lastname, email} VALUES ('Thom', 'Vial', 'thom.v@some.com')' at line 1"

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

$sql = "INSERT INTO Students {name, lastname, email} VALUES ('Thom', 'Vial', 'thom.v@some.com')";

Мы использовали фигурные скобки вместо простых. Поскольку это неправильно, наш скрипт выдал синтаксическую ошибку.

PDO

В строке 7 подключения PDO, режим обработки ошибок установлен в «display all exceptions» (отображать все исключения). Если вы уберёте это из скрипта и запрос потерпит неудачу, вы не получите никакого сообщения об ошибке. Со включёнными исключениями, будут отображаться конкретные возникшие проблемы.

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

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE: Syntax error or access violation: 1064 You have an error in your SQL syntax; <code>check the manual that corresponds to your MySQL server version for the right syntax to use near '{name, lastname, email} VALUES ('Thom', 'Vial', 'thom.v@some.com')' at line 1"</code>

Другие проблемы, с которым вы можете столкнуться:

  • Неверно указаны столбцы (несуществующие столбцы или ошибки в написании названий).
  • Несоответствие типа значения типу столбца. Например, когда мы хотим присвоить числовое значение 47 полю Name, мы получим ошибку, потому что предполагается, что значение будет строкой. Но, если вы укажете число в кавычках, например, “47”, ошибки не будет, потому что наше число будет записано как строка в этот столбец.
  • Попытка ввести данные в таблицу, которой не существует или ошибка в написании названия таблицы.

Все эти ошибки могут быть исправлены, следуя руководствам по исправлению ошибок или журнала ошибок (англ.).

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


С этим читают