Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Очень просто о PHP, от элементарных понятий до ООП


Это перевод восьмой статьи из обучающего курса по языку программирования PHP. Прочитав данный цикл статей, вы получите возможность легко писать программы на языке PHP. Лекция расскажет о возможностях PHP в работе с базами данных MySQL.

Итак, продолжим:


Совмещаем полезности

Одной из насущных вещей в PHP является его поддержка множества систем управления базами данных, включая MySQL, PostgreSQL, Oracle и Microsoft Access. В силу этой поддержки разработчики PHP могут создавать сложные Web-приложения, управляющие базами данных за долю затрат времени и средств, необходимых другим альтернативам. И нигде это не проявляется так чётко, как в поддержке MySQL - очень быстрой, надёжной и многофункциональной открытой СУБД.

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

Ну всё, хватит рекламы, давайте примемся за дело.

В этой части курса я покажу вам как использовать PHP для извлечения данных из базы данных и использовать эти данные для создания динамической веб-страницы. Для того, чтобы запускать примеры этой лекции, вам понадобится установленный дистрибутив MySQL, который вы можете взять с сайта http://www.mysql.com/. Если вы знаете SQL (Structured Query Language, язык для работы с сервером баз данных), вам это поможет, но на самом деле это несущественно.

Из кирпичиков - дом

Для использования связки MySQL+ PHP ваша версия PHP должна содержать поддержку MySQL. Для UNIX это достигается путём указания опции --with-mysql в скрипте настройки при сборке PHP и указывает PHP использовать клиентские библиотеки MySQL.

Для Windows клиентские библиотеки MySQL встроены в PHP 4 и активированы по умолчанию. В PHP 5 требуются скомпилированные файлы .dll, которые есть в дистрибутиве PHP для Windows. Узнайте больше об этом по адресу http://www.php.net/manual/en/ref.mysql.php.

Пользователи Unix должны знать, что PHP 4 поставляется с набором клиентских библиотек MySQL, которые активируются по умолчанию, а вот PHP 5 больше не включает эти библиотеки из-за особенностей лицензирования, так что вам требуется заполучить, установить и активировать их отдельно. Они есть в дистрибутиве MySQL и автоматически устанавливаются при установке MySQL. Для активации расширения MySQL, ext/mysql, добавьте опцию --with-mysql в скрипт конфигурирования PHP. Больше информации вы можете узнать об этом на странице http://www.php.net/manual/en/faq.databases.php#faq.databases.mysql.php5.

И наконец (если вы ещё не запутались), PHP 5 также поставляется с новым расширением MySQL, называемым ext/mysqli (MySQL Improved). Вы можете использовать новое расширение для доступа к новым возможностям MySQL 4.1.2 и получить улучшения в скорости и безопасности. Для активирования этого расширения на UNIX, добавьте опцию --with-mysqli в скрипт конфигурирования PHP и запустите программу mysql_config, которая поставляется с MySQL 4.1 и выше. Для пользователей Windows поставляется собранная версия расширения ext/mysqli в дистрибутиве PHP для win32.
Больше информации вы можете узнать на странице http://www.php.net/manual/en/ref.mysqli.php.

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

  • Если вы нуждаетесь в новых функциях в MySQL 4.1.2 или выше, или если вы используете старую версию MySQL, но хотите получить скорость/безопасность и улучшения в новом расширении,используйте ext/MySQLi.
  • Если вы не попали в одну из вышеперечисленных категорий, или не поняли что я говорю, используют обычное расширение ext/MySQL.

Если вам интересно, данный урок охватывает как ext/mysql, так и ext/mysqli, так что вы получаете два по цене одного. Продолжайте читать и позвольте мне представить вам MySQL.

Животный магнетизм

Каждая база данных MySQL состоит из одной или больше таблиц. Эти таблицы, которые располагают данные по строкам и колонкам, упорядочивают их. Обычная таблица выглядит так:

+----+-----------+----------+
| id | страна    | животное |
+----+-----------+----------+
|  1 | Америка   | орёл     |
|  2 | Китай     | дракон   |
|  3 | Англия    | лев      |
|  4 | Индия     | тигр     |
|  5 | Австралия | кенгуру  |
|  6 | Норвегия  | лось     |
+----+-----------+----------+

Как вы видите, таблица разделяет данные на строки с отдельной записью в каждой строке. Данные в каждой строке разделяются на ячейки (поля), каждая из которых содержит значение конкретного атрибута. Например, если вы найдёте строку со страной "Индия", то увидите, что строка поделена на два поля - название страны и её национальное животное. Строки в таблице не упорядочены ни в каком порядке - но они могут сортироваться по алфавиту, по номеру, по стране, или по любому критерию как вы укажете. Поэтому необходимо иметь способ определять конкретную запись в таблице. В примере выше записи идентифицируются по уникальному номеру. Это уникальное поле называется первичным ключом таблицы.

Для работы с сервером MySQL требуется использовать язык SQL, где вы сообщаете что надо создать таблицу, отметить поле как первичный ключ, вставить запись, получить записи, изменить запись и т.д. - в-общем всё, что включает в себя манипулирование данными или базой данных. Чтобы понять как это работает, давайте рассмотрим следующий запрос SQL, который создаёт описанную нами таблицу:

CREATE DATABASE testdb; 

CREATE TABLE `symbols` ( 
    `id` int(11) NOT NULL auto_increment, 
    `country` varchar(255) NOT NULL default '', 
    `animal` varchar(255) NOT NULL default '', 
    PRIMARY KEY  (`id`) 
) TYPE=MyISAM; 

INSERT INTO `symbols` VALUES (1, 'Америка', 'орёл'); 
INSERT INTO `symbols` VALUES (2, 'Китай', 'дракон'); 
INSERT INTO `symbols` VALUES (3, 'Англия', 'лев'); 
INSERT INTO `symbols` VALUES (4, 'Индия', 'тигр'); 
INSERT INTO `symbols` VALUES (5, 'Австралия', 'кенгуру'); 
INSERT INTO `symbols` VALUES (6, 'Норвегия', 'лось');

Вы можете вводить эти команды интерактивно или неинтерактивно с помощью программы-клиента MySQL, которую вы можете найти в папке mysql/bin, и запустив её или командой mysql, или
mysql имя_базы
если вы хотите выбрать уже существующую базу данных для работы с ней. Прочтите больше об использовании командной строки клиента MySQL на странице http://
dev.mysql.com/doc/mysql/en/mysql.html
, а также изучите урок по адресу http://www.melonfire.com/community/columns/trog/article.php?id=39 чтобы понять что делает каждая команда SQL выше. SQL очень похож на английский язык, так что вам не придётся долго его изучать (ага-ага). Только не путайте обратные кавычки ` с одинарными '.

После того как данные были внесены, запустите запрос SELECT, чтобы проверить это:

mysql> SELECT * FROM `symbols`;
+----+-----------+----------+
| id | страна    | животное |
+----+-----------+----------+
|  1 | Америка   | орёл     |
|  2 | Китай     | дракон   |
|  3 | Англия    | лев      |
|  4 | Индия     | тигр     |
|  5 | Австралия | кенгуру  |
|  6 | Норвегия  | лось     |
+----+-----------+----------+
6 rows in set (0.06 sec)

На человеческим языке запрос SELECT * FROM `symbols` означает "показать все записи из таблицы symbols". Если вы увидели такой-же вывод, как выше, у вас всё в порядке!

Привет, база!

Теперь давайте применим PHP чтобы сделать то-же самое действие. Вы можете использовать PHP чтобы создать базу данных 'testdb', но поскольку она уже есть у нас, мы выполним простой запрос SELECT и покажем результат на HTML-странице:

<html> 
<head>
<basefont face="Arial">
</head>
<body> <?php // устанавливаем переменные для доступа к серверу базы данных: $host = "localhost"; $user = "test"; $pass = "test"; $db = "testdb"; // открываем соединение $connection = mysql_connect($host, $user, $pass) or die ("Не могу подключиться к серверу!"); // выбираем базу данных mysql_select_db($db) or die ("Не могу выбрать базу!"); // создаём запрос $query = "SELECT * FROM symbols"; // выполняем запрос $result = mysql_query($query) or die ("Ошибка в запросе: $query. ".mysql_error()); // проверяем, получены-ли строки if (mysql_num_rows($result) > 0) { // да, получены // печатаем их одну за другой echo "<table cellpadding=10 border=1>"; while($row = mysql_fetch_row($result)) { echo "<tr>"; echo "<td>".$row[0]."</td>"; echo "<td>".$row[1]."</td>"; echo "<td>".$row[2]."</td>"; echo "</tr>"; } echo "</table>"; } else { // строки не получены // печатаем сообщение об этом echo "Не найдено ни одной строки в таблице!"; } // очищаем память от результата запроса mysql_free_result($result); // отключаемся от сервера mysql_close($connection); ?> </body>
</html>

Вот какой результат мы получим:

id страна животное
1 Америка орёл
2 Китай дракон
3 Англия лев
4 Индия тигр
5 Австралия кенгуру
6 Норвегия лось

Как видно, получение данных из базы заключается в нескольких шагах, каждый из которых - предопределённая функция PHP. Давайте обсудим каждый шаг:

  1. Во-первых, надо указать некоторую важную информацию, требуемую для подключения к серверу базы данных. Это имя сервера, имя пользователя и пароль для доступа к нему, а также имя базы данных. Эти значения мы устанавливаем как обычные переменные PHP.
    <?php
    
    // устанавливаем переменные для доступа к серверу базы данных: 
    $host = "localhost"; 
    $user = "test"; 
    $pass = "test"; 
    $db = "testdb"; 
    
    ?>
  2. Для начала обмена информации с сервером нам надо установить соединение с этим сервером. Всё общение с ним проходит через это соединение. Используем для этого функцию mysql_connect():
    <?php
    
    $connection = mysql_connect($server, $user, $pass);
    
    ?>

    Все параметры в функции mysql_connect() необязательны, но вам потребуется три указанных чтобы получить доступ к серверу вне вашей машины: имя сервера баз данных, имя пользователя и пароль. Если сервер баз данных и Web-сервер работают на одной машине, вы можете использовать в качестве имени сервера базы данных "localhost", вообще-то это значение в PHP по умолчанию.
    Функция mysql_connect() возвращает "идентификатор ссылки на соединение", который сохраняется в переменную $connection. Этот идентификатор используется при обмене данными с базой.

  3. Раз у нас есть соединение с базой данных, нам необходимо выбрать базу данных функцией mysql_select_db():
    <?php
    
    mysql_select_db($db) or die ("Не могу выбрать базу!"); 
    
    ?>

    Эта функция должна передать имя базы данных, которая будет использовать в последующих запросах. Возможен второй аргумент - идентификатор ссылки. Если он не указан, будет использован последний открытый идентификатор. Если у вас есть два или больше открытых одновременно соединений с базами данных, использовать идентификатор ссылки как второй аргумент для функции mysql_select_db() - хорошая идея, и аналогично для всех функций mysql_* в вашем скрипте. Теперь PHP не будет путаться какое соединения надо использовать.

  4. Следующий шаг - создать запрос и выполнить его. Это делается функцией mysql_query().
    <?php
    
    // выполняем запрос 
    $result = mysql_query($query)
    or die ("Ошибка в запросе: $query. ".mysql_error()); 
    
    ?>

    Этой функции также требуется два параметра: строка запроса и идентификатор соединения ссылки на подключение. И опять-же, если идентификатор ссылки не указан, будет использоваться последнее открытое подключение. В зависимости от того успешным был запрос или нет, функция возвращает истину или ложь (true или false), а ошибку можно перехватить с помощью обьявления ...or die() и функции mysql_error() для вывода описания ошибки.

  5. Если функция mysql_query() выполнилась успешно, возвращённый запросом набор результатов сохранится в переменной $result. Этот набор результатов может содержать одну или больше строк или колонок данных, в зависимости от вашего запроса. Вы можете получить конкретные подмножества из набора результатов различными функциями PHP, включая использованную нами mysql_fetch_row() - которая выбирает одну строку данных из массива $row. Поля в этой строке могут быть получены с помощью стандартной нотации для массивов PHP. Каждый раз когда вы вызываете mysql_fetch_row(), вам будет возвращена следующая запись результата. Это делает функцию mysql_fetch_row() удобной совместно с циклами while() или for().
    // проверяем, получены-ли строки 
    if (mysql_num_rows($result) > 0) { 
        // да, получены
        // печатаем их одну за другой 
        echo "<table cellpadding=10 border=1>"; 
        while($row = mysql_fetch_row($result)) { 
            echo "<tr>"; 
            echo "<td>".$row[0]."</td>"; 
            echo "<td>".$row[1]."</td>"; 
            echo "<td>".$row[2]."</td>"; 
            echo "</tr>"; 
        } 
        echo "</table>"; 
    }

    Отметим, что вызов mysql_fetch_row() заключён в условную проверку которая проверяет была-ли возвращёна хотя-бы одна строка. Эта информация доступна с помощью функции mysql_num_rows(), которая содержит количество строк, возвращённых запросом.
    Очевидно что вы можете использовать эту функцию с запросами, которые возвращают данные, такие как SELECT или SHOW и она не подходит к запросам с INSERT, UPDATE, DELETE или подобными.

  6. И, наконец, так как каждый набор результатов после выполнения запроса занимает память, хорошей идеей будет использовать mysql_free_result() чтобы очистить использованную память. После очистки результата и если больше запросов выполняться не будет, вы можете закрыть соединение с сервером MySQL функцией mysql_close():
    <?php
    
    // очищаем память от результата запроса 
    mysql_free_result($result); 
    
    // отключаемся от сервера
    mysql_close($connection);
    
    ?>

На вкус и цвет...

Для получения простого массива значений вы можете использовать функции PHP mysql_fetch_row() и list(), а затем назначить эти значения разным переменным - просто вариация техники, рассмотренной в предыдущей секции. Посмотрите (изменяется только цикл while()):

<html> 
<head>
<basefont face="Arial">
</head>
<body> <?php // устанавливаем переменные для доступа к серверу базы данных: $host = "localhost"; $user = "test"; $pass = "test"; $db = "testdb"; // открываем соединение $connection = mysql_connect($host, $user, $pass) or die ("Не могу подключиться к серверу!"); // выбираем базу данных mysql_select_db($db) or die ("Не могу выбрать базу!"); // создаём запрос $query = "SELECT * FROM symbols"; // выполняем запрос $result = mysql_query($query) or die ("Ошибка в запросе: $query. ".mysql_error()); // проверяем, получены-ли строки if (mysql_num_rows($result) > 0) { // да, получены // печатаем их одну за другой echo "<table cellpadding=10 border=1>"; while(list($id, $country, $animal) = mysql_fetch_row($result)) {
echo "<tr>";
echo "<td>$id</td>";
echo "<td>$country</td>";
echo "<td>$animal</td>";
echo "</tr>";
} echo "</table>"; } else { // строки не получены // печатаем сообщение об этом echo "Не найдено ни одной строки в таблице!"; } // очищаем память от результата запроса mysql_free_result($result); // отключаемся от сервера mysql_close($connection); ?> </body>
</html>

В этом случае функция list() используется для назначения элементов набора результатов переменным PHP, которые применяются при выводе страницы.

Вы можете использовать функцию mysql_fetch_assoc() чтобы получить каждую строку как ассоциативный массив с парами поле-значение - также незначительный вариант рассмотренного выше способа:

<html> 
<head>
<basefont face="Arial">
</head>
<body> <?php // устанавливаем переменные для доступа к серверу базы данных: $host = "localhost"; $user = "test"; $pass = "test"; $db = "testdb"; // открываем соединение $connection = mysql_connect($host, $user, $pass) or die ("Не могу подключиться к серверу!"); // выбираем базу данных mysql_select_db($db) or die ("Не могу выбрать базу!"); // создаём запрос $query = "SELECT * FROM symbols"; // выполняем запрос $result = mysql_query($query) or die ("Ошибка в запросе: $query. ".mysql_error()); // проверяем, получены-ли строки if (mysql_num_rows($result) > 0) { // да, получены // печатаем их одну за другой echo "<table cellpadding=10 border=1>"; while($row = mysql_fetch_assoc($result)) {
echo "<tr>";
echo "<td>".$row['id']."</td>";
echo "<td>".$row['country']."</td>";
echo "<td>".$row['animal']."</td>";
echo "</tr>";
} echo "</table>"; } else { // строки не получены // печатаем сообщение об этом echo "Не найдено ни одной строки в таблице!"; } // очищаем память от результата запроса mysql_free_result($result); // отключаемся от сервера mysql_close($connection); ?> </body>
</html>

Заметим, что в этом случае значения полей доступны по своему имени вместо номера поля.

Из всех вариантов, однако, мне нравится больше всего функция mysql_fetch_object (), которая возвращает каждую строку как объект (помните обьекты из седьмой лекции курса?) со свойствами, соответствующими именам полей:

<html> 
<head>
<basefont face="Arial">
</head>
<body> <?php // устанавливаем переменные для доступа к серверу базы данных: $host = "localhost"; $user = "test"; $pass = "test"; $db = "testdb"; // открываем соединение $connection = mysql_connect($host, $user, $pass) or die ("Не могу подключиться к серверу!"); // выбираем базу данных mysql_select_db($db) or die ("Не могу выбрать базу!"); // создаём запрос $query = "SELECT * FROM symbols"; // выполняем запрос $result = mysql_query($query) or die ("Ошибка в запросе: $query. ".mysql_error()); // проверяем, получены-ли строки if (mysql_num_rows($result) > 0) { // да, получены // печатаем их одну за другой echo "<table cellpadding=10 border=1>"; while($row = mysql_fetch_object($result)) {
echo "<tr>";
echo "<td>".$row->id."</td>";
echo "<td>".$row->country."</td>";
echo "<td>".$row->animal."</td>";
echo "</tr>";
} echo "</table>"; } else { // строки не получены // печатаем сообщение об этом echo "Не найдено ни одной строки в таблице!"; } // очищаем память от результата запроса mysql_free_result($result); // отключаемся от сервера mysql_close($connection); ?> </body>
</html>

Здесь создаётся обьект $row со свойствами, соответствующими именам полей в строке. Значения строки могут быть получены используя стандартную нотацию обьектов обьект->свойство.

Если вы из того типа людей, которые хотят гоняться за двумя зайцами, то вам подойдёт функция the mysql_fetch_array(), которая возвращает и ассоциативный массив, и массив с численными индексами - комбинация функций mysql_fetch_row() и mysql_fetch_assoc(). Почитайте об этом на сайте PHP: http://www.php.net/manual/en/function.mysql-fetch-array.php.

... товарищи есть!

Если вы используете PHP 5, вы можете делать те-же самые вещи, используя расширение ext/mysqli, которое представляет несколько новых возможностей. Это расширение может быть использовано двумя способами: процедурным (используя функции) и обьектно-ориентированным (используя методы и свойства класса). Рассмотрим следующий скрипт, иллюстрирующий использование ext/mysqli в процедурном стиле:

<html> 
<head>
<basefont face="Arial">
</head>
<body> <?php // установим переменные для доступа к серверу $host = "localhost"; $user = "test"; $pass = "test"; $db = "testdb"; // открываем соединение $connection = mysqli_connect($host, $user, $pass, $db) or die ("Не могу подключиться!"); // создаём запрос $query = "SELECT * FROM symbols"; // выполняем запрос $result = mysqli_query($connection, $query) or die ("Ошибка в запросе: $query. ".mysqli_error()); // проверяем, не были-ли возвращены строки if (mysqli_num_rows($result) > 0) { // были // печатаем их поочерёдно echo "<table cellpadding=10 border=1>"; while($row = mysqli_fetch_row($result)) { echo "<tr>"; echo "<td>".$row[0]."</td>"; echo "<td>".$row[1]."</td>"; echo "<td>".$row[2]."</td>"; echo "</tr>"; } echo "</table>"; } else { // строки возвращены не были // печатаем сообщение об этом echo "Не найдено ни одной строки!"; } // освобождаем память от набора результатов mysqli_free_result($result); // закрываем соединение mysqli_close($connection); ?> </body>
</html>

Как видно, это очень похоже на код для расширения ext/mysql. Единственная существенная разница - по крайней мере для невооружёного глаза - имена функций mysqli_* вместо mysql_*. Конечно, есть куча различий, невидимых нам: ext/mysqli быстрее, безопаснее и мощнее чем старое расширение ext/mysql, и также поддерживает подготовленные выражения, связанные наборы результатов, множества одновременных запросов, транзакции и целую кучу других крутых вещей.

Вы можете использовать расширение ext/mysqli обьектно-ориентированным способом, где каждое действие - подключение, запрос, разбор результата - является методом обьекта mysqli():

<html> 
<head>
<basefont face="Arial">
</head>
<body> <?php // установим переменные для доступа к серверу $host = "localhost"; $user = "test"; $pass = "test"; $db = "testdb"; // создаём обьект mysqli // открываем соединение $mysqli = new mysqli($host, $user, $pass, $db); // проверяем ошибки соединения if (mysqli_connect_errno()) { die("Не могу подключиться!"); } // создаём запрос $query = "SELECT * FROM symbols"; // выполняем запрос if ($result = $mysqli->query($query)) { // проверяем, возвращены-ли строки if ($result->num_rows > 0) { // да // печатаем из по одну за другой echo "<table cellpadding=10 border=1>"; while($row = $result->fetch_array()) { echo "<tr>"; echo "<td>".$row[0]."</td>"; echo "<td>".$row[1]."</td>"; echo "<td>".$row[2]."</td>"; echo "</tr>"; } echo "</table>"; } else { // строк нет // сообщаем об этом echo "Не найдено ни одной строки!"; } // освобождаем память от результата запроса $result->close(); } else { // печатаем сообщенеи об ошибке в запросе echo "Ошибка в запросе: $query. ".$mysqli->error; } // закрываем соединение $mysqli->close(); ?> </body>
</html>

Здесь мы использовали ключевое слово new для создания обьекта класса mysqli и передали конструктору обьекта информацию о подключении (включая имя базы данных). Полученный обьект, сохранённый в переменной $mysqli, имеет методы и свойства для работы с ним - запросов, получения и разбора ответов, перехвата ошибок.

Если вы присмотритесь внимательнее к скриптам выше, вы заметите сходство между именами функций и методов, а также структурами скрипта. Тем не менее, из двух лучше использовать обьектно-ориентированный метод, особенно в свете новой обьектной модели PHP 5.

Также вам следует в виду несколько других важных различий:

  • с ext/mysqli, вы можете включить имя базы данных в аргументах mysqli_connect () или в конструктор mysqli();
  • при вызове mysqli_query () или метода query() объекта mysqli идентификатор является обязательным, а не опциональным.

Продолжение читайте во второй части лекции.

 

Оригинал перевода статьи: http://www.figli-migli.org.ua/books/1070-php101-8a


В избранное