Лістинг 6.8. results.php - витягання результатів запиту і форматування їх
<html><head><title>Book Search Results by Mikle</title></head> <body>
<hl>Book Search Results</hl> <?
trim($searchterm);
if (!$searchtype || !$searchterm) {
echo "You have not entered search details. Please go back and try again.";
exit; }
$searchtype = addslashes($searchtype);
$searchterm = addslashes($searchterm);
@$db = mysql_pconnect("localhost", "bookorama", "bookorama");
if (!$db) {
echo "Error: Could not connect to database. Please try again later.";
exit; }
mysql_select_db("books");
$query = "select * from books where ".$searchtype." Like '%".$searchterm."%'";
$result = mysql_query($query);
$num_results = mysql_num_rows($result);
echo "<p>Number of books found: ".$num_results."</p>";
for ($i = 0; $i <$num_results; $i ++) {
$row = mysql_fetch_array($result);
echo "<p><strong>".($i+l).". Title:";
echo htmlspecialchars( stripslashes($row["titie"]));
echo "</strong><br>Author: ";
echo htmlspecialchars (stripslashes($row["author"]));
echo "<br>ISBN:
echo htmlspecialchars (stripslashes($row["isbn"]));
echo "<br>Price: " ;
echo htmlspecialchars (stripslashes($row["price"] ));
echo "</p>"; }
?>
</body> </html>
Основні кроки виконання запитів до бази даних через Web. У будь-якому сценарії, який забезпечує доступ до бази даних з Web, є декілька базових кроків:
1. Перевірка і фільтрація даних, витікаючих від користувача.
2. Установка з'єднання з необхідною базою даних.
3. Передача запиту в базу даних.
4. Здобуття результатів.
5. Представлення результатів користувачеві.
Те ж саме робить і сценарій results.php, і зараз ми досліджуємо кожен з цих етапів.
Перевірка і фільтрація даних, витікаючих від користувача.Спочатку необхідно прибрати всі зайві пропуски по краях слова, які міг випадково набрати користувач. Впоратися з цим допоможе функція trim(), вживана до $searchterm (критерій пошуку).
trim($searchterm);
Наступний етап — переконатися, що користувач вказав критерій і типа пошуку. Відмітьте, це перевіряється лише тоді, коли критерій пошуку не містить зайві пропуски. Якщо поміняти ці етапи місцями, може виникнути ситуація, коли критерій начеб і введений, повідомлення про помилку бути не повинно, проте критерій містить лише пропуски, які повністю віддаляються функцією trim():
if (!$searchtype || !$searchterm) {
echo "You have not entered search details. Please go back and try again.";
exit; }
В цьому випадку видається повідомлення про те, що критерій пошуку не введений.
Ми перевірили змінну $searchtype навіть у тому випадку, коли вона поступає з оператора SELECT. Вас може зацікавити, навіщо перевіряти вхідні дані. Не забувайте, що база даних може мати не один інтерфейс. Наприклад, Amazon має в своєму розпорядженні велику кількість філій, які використовують свої пошукові інтерфейси. Унаслідок того, що користувачі можуть заходити з різних робочих станцій, виникає і потенційна загроза безпеці.
В разі задіювання даних, які вводять інші користувачі, необхідно ретельно фільтрувати дані, що вводяться, від символів, що управляють. Якщо записувати дані, введені користувачем, в базу даних типа MYSQL, слід викликати addslashes(), а при поверненні користувачеві вихідних даних — stripslashes().
У нашому випадку до критерію пошуку застосовується функція addslashes():
$searchterm = addslashes ($searchterm);
До даних, витікаючих з бази, застосовується stripslashes(). Введені дані не містять косих ліній, так само як і символів, що управляють. Тобто виклик stripslashes() не допоможе. При побудові Web-интерфейса для бази даних великі шанси того, що потрібно буде вносити дані про нові книги, а деталі, внесені користувачем, можуть містити спеціальні символи. Зберігаючи їх в базі даних, ми звертаємося до addslashes(), а це означає, що при витяганні даних необхідно буде викликати stripslashes().
Функцію htmlspecialchars() застосовують для кодування символів, які в HTML мають особливе значення. У наших тестових даних немає амперсандів (&), знаків "менше" (<), "більше" (>), подвійних лапок ("), проте в назвах багатьох чудових книг може зустрітися амперсанд. Використання цієї функції страхує від грядущих помилок.
Установка з'єднання. Для підключення до сервера MYSQL в сценарії є такий рядок:
@ $db = mysql_pconnect("localhost", "bookorama", "bookorama");
Для підключення до бази даних використовується функція mysql_pconnect() з прототипом:
int mysql_pconnect ([string host [:port] [:/socketpath]],
[string user], [string password]);
Потрібно буде вказати ім'я вузла (host), на якому розміщений сервер MYSQL, ім'я користувача (user), аби увійти до нього, і пароль (password). Все це необов'язково і якщо не вказати все вищеперелічене, функція скористається значеннями за замовчуванням — локальна машина замість вузла, ім'я користувача, під яким запущений РНР, і порожній пароль.
При успіху функція поверне ідентифікатор зв'язку з базою даних (який слід зберегти для подальшого використання), а при невдачі — значення false. Результат не варто ігнорувати, оскільки без з'єднання з базою даних робота неможлива. Це робить наступний код:
if (!$db) {
echo "Error: Could not connect to database. Please try again later."; exit; }
Як альтернативу, можна використовувати іншу функцію, яка робить практично те ж саме, — mysql_connect(). Єдина відмінність полягає в тому, що mysql_connect() встановлює постійне з'єднання з базою даних.
З'єднання з базою даних закривається, коли сценарій завершує своє виконання або коли звертається до функції mysql_close(). Постійне з'єднання залишається відкритим і після того, як сценарій виконаний, а функцією mysql_close() його закрити не можна.
Може виникнути питання, для чого це потрібно. Відповідь така: з'єднання з базою даних передбачає деякі непродуктивні витрати, що вимагає часу. Коли викликається mysql_pconnect(), перш ніж вона спробує підключитися до бази даних, вона автоматично перевірить, чи немає вже відкритого постійного з'єднання. Якщо є, вона не стане відкривати нове. Це і час економить, і запобігає перевантаженню сервера.
Проте якщо РНР виконується як CGI, то постійне з'єднання виявиться не таким вже і постійним. (Кожен виклик сценарію РНР запускає нову копію механізму РНР і закриває її, коли сценарій завершує свою роботу. Це, у свою чергу, також закриває будь-яке постійне з'єднання.)
Кількість з'єднань в MYSQL, які існують одночасно, обмежена. Кордон встановлює параметр max_connections. Його завдання (як і родинного йому параметра Apache MaxClients) — змусити сервер відкидати нові запити на з'єднання, коли ресурси вузла зайняті або коли програмне забезпечення не функціонує.
Значення цих параметрів можна змінювати, редагуючи файл конфігурації. Аби набудувати MaxClients в Apache, слід правити файл httpd.conf. Налаштування max_connections в MYSQL здійснюється за рахунок редагування файлу my.conf.
Якщо ви користуєтеся постійними з'єднаннями, і практично кожній сторінці на вашому сайті потрібний доступ до бази даних, вам, мабуть, знадобиться постійне з'єднання для кожного процесу Apache. Якщо ж використовуються значення параметрів, прийняті за замовчуванням, можуть виникнути певні складнощі. За замовчуванням Apache допускає до 150 з'єднань, а MYSQL — лише 100. У особливо напружений час з'єднань може не вистачити. Тому краще всього набудувати параметри так, щоб в кожного процесу Web-сервера було своє з'єднання, звичайно, з оглядкою на технічні можливості вживаних апаратних засобів.
Вибір бази даних.Працюючи з MYSQL, необхідно вказувати, яка база даних потрібна. Це може зробити РНР-функиія mysql_select_db():
mysql_select_db("books");
Прототип цієї функції виглядає так:
int mysql_select_db(string database [int database_connection]);
В результаті використовуватиметься база даних з ім'ям database. Можна також використовувати з'єднання з базою даних, для якого потрібно виконати цю операцію (у нашому випадку $db), проте, якщо його не вказати, використовуватиметься останнє відкрите з'єднання. Якщо відкрите з'єднання не існує, воно відкривається за замовчуванням, неначебто викликалася mysql_connect().
Виконання запиту до бази даних.Аби здійснити запит, можна скористатися функцією mysql_query(). Проте раніше запит необхідно набудувати:
$query = "select * from books where ".$searchtype." like '%".$searchterm."%'";
В цьому випадку відшукуватиметься значення, введене користувачем ($searchterm), в полі, яке вказав користувач ($searchtype). Зверніть увагу на те, що ми спожили like, віддавши йому перевагу перед equal — толерантність ніколи не буває зайвою. Не забувайте, що запит, що відправляється вами в MYSQL, не вимагає в кінці крапки з комою, на відміну від запиту, який вводиться в середовищі монітора MYSQL.
Тепер можна виконати запит:
$result = mysql_query ($query);
Прототип функції mysql_query() такий:
int mysql_query(string query [int database_connection]);
У функцію передається запит, який має бути виконаний; можна також передати ще і з'єднання з базою даних (у нашому випадку $db). Якщо його не вказати, використовуватиметься останнє відкрите з'єднання. Якщо такого немає, функція відкриє з'єднання точно так, як і при виконанні mysql_connect().
Замість цього можна скористатися функцією mysql_db_query() Розглянемо її прототип:
int mysql_db_query(string database, string query
[int database_connection]);
Тут можна вказати базу даних, в якій потрібно проводити пошук. У якомусь сенсі це комбінація функцій mysql_select_db() і mysql_query(). Обоє функції повертають ідентифікатор результату (що дозволяє отримати результати пошуку) в разі успіху і значення false в разі невдачі. Ідентифікатор результату слід зберегти (так само, як в нашому випадку з $result), аби отримати з нього деяку користь.
Здобуття результатів запиту.Різноманітність функцій дає можливість отримати результат різними способами. Ідентифікатор результату — це ключ доступу до рядків, поверненим запитом, яких може бути нуль, одна і більш.
У нашому прикладі використовувалися дві функції: mysql_numrows() і mysql_fetch_array().
Функція mysql_numrows() повідомляє кількість рядків, які повертає запит В неї слід передати ідентифікатор результату:
$num_results = mysql_num_rows($result);
Це корисно знати, якщо планується обробляти або відображувати результати. Знаючи їх кількість, можна організувати цикл:
for ($i=0; $i <num_results; $i++)
{ // обробка результатів
}
На кожній ітерації циклу відбувається виклик mysql_fetch_array() Цикл не виконуватиметься, якщо немає рядків. Ця функція бере кожен рядок із списку результату і повертає його у вигляді асоціативного масиву, з ключем як ім'ям атрибуту і значенням як відповідним значенням масиву.
$row = mysql_fetch_array($result);
Маючи $row у асоціативному масиві, можна пройти кожне поле і відображувати його:
echo "<br>ISBN: ";
echo stripslashes($row["isbn"]);
Як уже згадувалося, stripslashes() викликають для того, щоб "підчистити" значення, перш ніж відображувати його користувачеві.
Існують декілька варіантів здобуття результату з ідентифікатора результату. Замість асоціативного масиву можна скористатися нумерованим масивом, застосувавши mysql_fetch_row():
$row = mysql_fetch_row($result);
Значення атрибутів зберігатимуться в кожному порядковому значенні $row[0], $row[l] і так далі
За допомогою функції mysql_fetch_object() можна вибрати рядок всередину об'єкту:
$row = mysql_fetch_object ($result);
Після цього до атрибутів можна дістати доступ $row->title, $row->author і так далі
Кожен з цих варіантів має на увазі вибірку рядка за раз. Інший варіант — дістати доступ, використовуючи mysql_result() Для цього потрібно буде вказати номер рядка (від 0 до кількості рядків мінус 1) і назву поля, наприклад
$row = mysql_result($result, $i, "title");
Назву поля можна задати у вигляді рядка (або у формі "title" або у формі books.title") або номером (як в mysql_fetch_row()). He варто змішувати mysql_result() з іншими функціями вибірки.
Рядково-орієнтовані функції вибірки набагато ефективніші, ніж mysql_result(), отже краще використовувати одну з них
Від'єднання від бази даних.Для закриття непостійного з'єднання застосовується функція:
mysql_close(database_connect±on);
Проте в цьому немає особливої необхідності, оскільки із завершенням виконання сценарію з'єднання закриється автоматично.
Внесення нової інформації до бази даних.Внесення нової інформації дуже схоже на здобуття що існує. Потрібно пройти ті ж кроки — встановити з'єднання, відправити запит і перевірити результати. Лише в даному випадку замість SELECT використовуватиметься INSERT. Хоч все і просто, але поглянути на приклад ніколи не перешкодуть.
Дата добавления: 2016-04-02; просмотров: 617;