Извлечение строки
Для построчного извлечения данных нужно заменить цикл из примера 4 кодом, выделенным в примере 5 полужирным шрифтом, и обнаружится, что будет получен точно такой же результат, который был показан на рис. 1.
Переделанный файл можно сохранить под именем fetchrow-mysqli.php.
Рис. 1. Результат запуска на выполнение кода примера 4
Пример 5. Построчное извлечение результатов с помощью mysqli
< ?php //fetchrow-mysqli.php require_once 'login.php';
$connection =
new mysqli($db_hostname, $db_username, $db_password, $db_database); if ($connection->connect_error) die($connection->connect_error);
$query = "SELECT * FROM classics";
$result = $connection->query($query); if (!$result) die($connection->error); $rows = $result->num_rows;
for ($j = 0 ; $j < $rows ; ++$j)
{
$result->data_seek($j);
$row = $result->fetch_array(MYSQLI_ASSOC);
echo 'Author: ' . $row['author'] . '<br>'; echo 'Title: ' . $row['title'] . '<br>'; echo 'Category: ' . $row['category'] . '<br>'; echo 'Year: ' . $row['year'] . '<br>';
Запросы к базе данных MySQL с помощью mysqli
echo 'ISBN: ' . $row['isbn'] . '<br><br>'; }
$result->close();
$connection->close();
?>
В этом измененном коде к объекту $result делается только одна пятая часть обращений, а при каждом проходе цикла в объекте осуществляется только один поиск, поскольку посредством метода fetch_array каждая строка извлекается целиком. В результате одна строка данных возвращается в виде массива, который затем присваивается массиву $row.
Метод fetch_array в зависимости от переданного ему значения может возвращать три типа массивов.
Ѓ MYSQLI_NUM -- числовой массив. Каждый столбец появляется в массиве в порядке его определения при создании (или изменении) в таблице. В нашем случае нулевой элемент массива содержит столбец Author, первый элемент содержит Title и т. д.
Ѓ MYSQLI_ASSOC -- ассоциативный массив. Каждый ключ является названием столбца. Поскольку ссылка на элементы данных производится по названию столбца (а не по номеру индекса), используйте этот вариант в своем коде везде, где это возможно, чтобы упростить отладку и помочь другим программистам управиться с вашим кодом.
Ѓ MYSQLI_BOTH -- ассоциативный и числовой массив.
Ассоциативные массивы обычно полезнее числовых, поскольку на каждый столбец можно ссылаться по названию, например $row['author'], вместо того чтобы пытаться вспомнить, где он находится в порядке следования столбцов. Поэтому в данном сценарии используется ассоциативный массив, что заставляет нас передать MYSQLI_ASSOC.
Закрытие подключения
Со временем, после завершения работы сценария, PHP вернет память, распределенную под объекты, поэтому при небольших по размеру сценариях обычно не приходится волноваться об освобождении памяти своими силами. Но если распределено большое количество объектов с результатами обращения к базе или извлечен большой объем данных, было бы неплохо освободить задействованную память, чтобы избежать возможных будущих проблем в своем сценарии.
В частности, важность такого освобождения возрастает для страниц с высоким трафиком, поскольку объем памяти, затрачиваемый в сеансе, может быстро возрастать. Поэтому в предыдущих сценариях не забывайте вызывать методы close объектов $result и $connection, как только минует надобность в каждом из объектов.
В идеале нужно закрывать каждый объект с результатами по окончании его использования, а затем, когда ваш сценарий больше не будет обращаться к MySQL, закрывать и объект подключения к базе данных.
Такой подход обеспечит возвращение ресурсов в систему как можно скорее, чтобы сохранить оптимальный режим работы MySQL, и устранит сомнения насчет возвращения со стороны PHP неиспользуемой памяти ко времени возникновения новой потребности в ней.
Практический пример
Теперь перепишем процедурную программу sqltest.php из предыдущей главы с использованием mysqli. Переделка не представляет особого труда, в чем можно убедиться, просмотрев код примера 6 (который нужно сохранить в файле mysqlitest.php, если вы собираетесь его протестировать, поскольку он постоянно вызывает сам себя).
Пример 6. Вставка и удаление с помощью mysqlitest.php
< ?php // mysqlitest.php require_once 'login.php';
$connection =
new mysqli($db_hostname, $db_username, $db_password, $db_database); if ($connection->connect_error) die($connection->connect_error);
if (isset($_POST['delete']) && isset($_POST['isbn']))
{
$isbn = get_post($connection, 'isbn');
$query = "DELETE FROM classics WHERE isbn='$isbn'";
$result = $connection->query($query);
if (!$result) echo "Сбой при удалении данных: $query<br>" .
$connection->error . "<br><br>";
}
if ( isset($_POST['author']) && isset($_POST['title']) && isset($_POST['category']) && isset($_POST['year']) && isset($_POST['isbn']))
{
$author = get_post($connection, 'author');
$title = get_post($connection, 'title');
$category = get_post($connection, 'category');
$year = get_post($connection, 'year');
$isbn = get_post($connection, 'isbn'); $query = "INSERT INTO classics VALUES" .
"('$author', '$title', '$category', '$year', '$isbn')";
$result = $connection->query($query);
if (!$result) echo "Сбой при вставке данных: $query<br>" .
$connection->error . "<br><br>";
} echo <<<_END
Практический пример
<form action="mysqlitest.php" method="post"><pre>
Author <input type="text" name="author">
Title <input type="text" name="title">
Category <input type="text" name="category">
Year <input type="text" name="year">
ISBN <input type="text" name="isbn">
<input type="submit" value="ADD RECORD">
</pre></form>
_END;
$query = "SELECT * FROM classics";
$result = $connection->query($query); if (!$result) die ("Сбой при доступе к базе данных: " . $connection->error); $rows = $result->num_rows;
for ($j = 0 ; $j < $rows ; ++$j)
{
$result->data_seek($j);
$row = $result->fetch_array(MYSQLI_NUM);
echo <<<_END
<pre>
Author $row[0]
Title $row[1]
Category $row[2]
Year $row[3]
ISBN $row[4]
</pre>
<form action="mysqlitest.php" method="post">
<input type="hidden" name="delete" value="yes">
<input type="hidden" name="isbn" value="$row[4]">
<input type="submit" value="DELETE RECORD"></form>
_END;
}
$result->close();
$connection->close();
function get_post($connection, $var)
{
return $connection->real_escape_string($_POST[$var]);
}
?>
В первых двух строках внедряется код из login.php и создается объект $connection для получения доступа к базе данных. Затем идет код для удаления записи, в котором просто выдается команда DELETE для объекта $connection с использованием метода query, и, в случае возникновения проблемы, возвращается сообщение об ошибке.
Затем, если новые данные отправляются программе, выдается команда INSERT и опять для объекта $connection используется метод query. В обоих экземплярах кода результат данной операции получает объект $result, значением которого может быть либо TRUE, либо FALSE.
В конце основной части программы осуществляется извлечение данных из базы данных и отображение их с помощью методов data_seek и fetch_array объекта $result. Но в отличие от кода примера 5, в котором возвращается ассоциативный массив, здесь методу fetch_array передается значение MYSQLI_NUM, следовательно, возвращается числовой массив. Соответственно, ссылки на ячейки имеют числовую основу
(например, $row[0] для автора). Затем результат выводится на экран при каждом проходе цикла, а после этого объект с результатом и подключение закрываются.
Здесь также была изменена функция get_post, чтобы можно было использовать новый метод real_escape_string объекта подключения, поэтому теперь ей передаются два значения (подключение и строковое значение).
Процедурное использование mysqli
Если хотите, можете для доступа к mysqli воспользоваться альтернативным набором функций в процедурном (а не в объектно-ориентированном) режиме.
Вместо создания следующего объекта $connection:
$connection = new mysqli($db_hostname, $db_username, $db_password, $db_database); можно воспользоваться таким кодом:
$link = mysqli_connect($db_hostname, $db_username, $db_password, $db_database);
Чтобы проверить успешность подключения и управлять им, можно воспользоваться следующим кодом: if (mysqli_connect_errno()) die(mysqli_connect_error());
А для выдачи MySQL-запроса воспользуйтесь таким кодом:
$result = mysqli_query($link, "SELECT * FROM classics");
После возвращения управления данные будут содержаться в $result. Количество возвращенных строк можно определить с помощью следующего кода:
$rows = mysqli_num_rows($result));
В $rows будет возвращено целочисленное значение. Построчное извлечение фактических данных можно получить следующим способом, при котором возвращается числовой массив:
$row = mysqli_fetch_array($result, MYSQLI_NUM);
В этом примере в $row[0] будут содержаться данные первого столбца, в $row[1] -- второго и т. д. Как уже объяснялось в примере 5, строки также могут быть возвращены в виде ассоциативных массивов или в виде массивов обоих типов, в зависимости от значения, переданного в качестве второго аргумента.
Вопросы. При использовании mysqli в процедурном режиме обезвреживание содержимого строк производится с помощью следующего кода: $escaped = mysqli_real_escape_string($link, $val);
Получить все подробности использования mysqli в процедурном режиме (и описание всех других аспектов mysqli ) можно по адресу http://tinyurl.com/usingmysqli.
После изучения интеграции PHP с MySQL несколькими различными способами в следующей главе мы перейдем к созданию удобных в использовании форм и к обработке отправляемых из них данных.
Задания к работе
1. Напиши рассылщик почты. Вот ТЗ ( с применением чего делать) рассылка через смтп или имап (здесь наследование, и забыл как шаблон называется, типа стратегия. Делаешь интерфейс/абстрактный класс с общими красивыми методами, и две реализации)
2. Напиши рассылщик почты. Вот ТЗ ( с применением чего делать) ) Чтоб группы адресов, адреса, списки рассылки хранились в бд, могли произвольно загружаться из csv (можно взять ORM DAPPER)
3. Напиши рассылщик почты. Вот ТЗ ( с применением чего делать)
4. рассылка через смтп или имап (здесь наследование, и забыл как шаблон называется, типа стратегия. Делаешь интерфейс/абстрактный класс с общими красивыми методами, и две реализации)
5. Напиши рассылщик почты. Вот ТЗ (с применением чего делать) ) многопоточная рассылка. Чтоб интерфейс при процессе не блокировался, а какой-нить грид писался лог рассылки (тут тебе и делегаты, и многопоточная, и очередь, и блокировки)
6. Напиши рассылщик почты. Вот ТЗ (с применением чего делать)
7. повтор неразосланных (организация данных)
8. Напиши рассылщик почты. Вот ТЗ (с применением чего делать)
9. ведение лога (в файл или базу, можно взять NLog)
10. Напиши рассылщик почты. Вот ТЗ (с применением чего делать)
11. максиальная настраиваемость (хошь в конфиг только, а хошь, еще и в интерфейс выведи)
12. Напиши рассылщик почты. Вот ТЗ (с применением чего делать)
13. можешь захреначить на winforms, wpf. Или вообще бомба сделать промежуточный слой, ядро, которое будет рассылать, а интерфейс - хоть мобильные Оси))
14. Напиши рассылщик почты. Вот ТЗ (с применением чего делать)сохранить и выполнить заполнение таблиц
15. Напиши рассылщик почты. Вот ТЗ (с применением чего делать) максиальная настраиваемость (хошь в конфиг только, а хошь, еще и в интерфейс выведи)
16. Напиши рассылщик почты. Вот ТЗ (с применением чего делать) сохранить и выполнить заполнение таблиц.
17. Напиши рассылщик почты. Вот ТЗ (с применением чего делать)ведение лога (в файл или базу, можно взять NLog)