Изучаем php и mysql(мировой компьютерный 2010 part 001

Page 1


МИРОВОЙ КОМПЬЮТЕРНЫЙ БЕСТСЕЛЛЕР


Head First РНР & MySQL

Lynn Beighley Мichael

Morrison

Q'REILLY® Beijing • Cambridge • Кбln • Sebastopo/ • Taipei • Tokyo


МИРОВОЙ КОМПЬЮТЕРНЫЙ БЕСТСЕЛЛЕР

Изучаем РНР и

MySQL

JIиннБейли и майк.л Моррисон

Как оыло Оы хорошо, еслu Оы суuщ:т(;о(;ала KHU(a о fНP u MySQt., которая nо:?(;олuла

Оы сuелать rазrаоотку nрuложе.нuU с uсnользо(;анuем оаз ианных

u cep(;erHO(O nроrpаммuрo(;анuя такои, дуито (;се ~тo npoucxouum на неОесах. На(;ерно, это (;се(о лuшь меЧта

~ЭКСМО Москва

2010

...


УДК ББК

004.45 32.973.26-018.2 Б35

Перевод с английского и редакция ЧП «Айдиономикс»

БейпиЛ.

Б

35

Изучаем РНР и MySQL англ.]. - М. : Эксмо, 2010. бестселлер).

/ Линн Бейли, Майкл Моррисон; [пер. с - 800 с. : ил. - (Мировой компьютерный

ISBN 978-5-699-44494-6 Вы хотите уметь создавать не только статичные, но и динамичные, связанные с ба­ зами данных сайты? Тогда вам не обойтись без знания РНР и

MySQL.

Эта книга является

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

ческого опыта, создав целый ряд приближенных к реальным проектов (от рейтинговой системы до сайта знакомств). Вы освоите в деле все важнейшие концепции программи­ рования на РНР и под

MySQL:

верификацию форм, работу с сессиями, эффективные за­

просы к базе данных, операции с файлами и многое другое. УДК 004.45 ББК 32.973.26-018.2

Все названия программных продуктов ЯJWh'Р{&:t'.~~<<!.-"·-

марками cpp~.z:~(<tI(«<<.. ""

~Соответствующих фирм .

'.

. т~"'-,,"mI~~~ зарегистрированны"ми торговыми

Никакая часть настоящего издания ни в каких целях не может быть воспроизведена в

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

письменного разрешения OOD .И;щатеЛЬСТ80 «Зксма •.

158Н 978-5-699-44494-6

Authorized RussiBn trBn51ation of Head Fir5t РНР & MySQL ISBN 9780596006303 @ 2008, Lynn Beighley, MichBel Morrison. Thi5 tran5'ation 15 pubIi5hed and so'd Ьу регm;НiОЛ 01 O'Rei ••y Med.a, 'пс./ tbe ОWЛl1Г 013// rights fo pubfish and 5е" the аате. @ ЧП «ДЙДИономикс" перевод на русский язык, 2010 С Мздatмe на русском IlЗЫке, оформление. 000 .Издательство .Эксмо., 201 О


Orламeнuе (кратко) Вступление

25

1 2 3 4 5 6 7

Она жива: Вдохните жизнь в ваши статичные страницы

37 95 139 195 259

71/2

Совместное использование значит забота: Устранение дублирования кода

8 9 10 11 12 1 11 III

Сбор урожая данных: Управляйте сво'I.I.МИ данн'ЫМи, управляйте окружающ'I.I.М вас миром

Как все это согласуется между собой: Соединение с MySQL

Создание ваших собственных данных: Создание и заполнение базы данных Ваше веб-приложение: Реальные и nрактичеcкuе nрuложения

Когда просто базы данных недостаточно: Работа с данн'ЫМи, сохранен'Н'ЫМи в файлах Считайте, что все они намерены воспользоваться вашими слабостями: Защита вашею npuложения

331 381

Вы меня помните? Создание nepСО1lШluзupоваННОlО веб-nрuлoжения

453 463 537 597 641 693 749 767 785

Функции облегчают жизнь: Текстовые строки и пользовательские функции Правила замены: Регулярные выражения

Динамическое создание изображений: Визуализация ваших данных... и более! Связь с миром: Распространение информации и веб-сервисы Десять основных тем (которые мы не затронули): Дополнения

Место, где разворачиваются события: Настройка среды разработки

Добейтесь еще большего: Расширьте возможности своею РНР

Orламeнtle (nogposяо) .стуn"еИllе Ваш мозг ocмыcnивaer рнр и МYSQI...

В то время, когда вы стараетесь

изучить что-то! ваш мозг пытается оказать вам услугу, убеждая вас, что все это не имеет значения. Ваш мозг думает: «Надо лучше сосредоточиться на том,

как избежать встречи со свирепым хищником, или подумать, действительно ли подводная йога такая полезная вещь». Так как же убедить мозг в том, что ваша жизнь зависит от знания РНР и Для

MySQL?

KOro эта книга?

Кому, скорее вcero, следует отложить эту книгу в сторону? Мы знаем, о чем вы думаете Мы знаем, о чем думает ваш мозг

Метапознание: мысли о мыслях Вот что мы делаем

А вот то, что вы можете сделать, чтобы ваш мозг слушался вас

Read те (Прочти меня) Команда техническнх рецензентов

Блаroдарность

26 26 27 27 29 30 31 32 34 35

5


Ag'oXlfU,'t1uG ~u,дlfЬ ~ ~a\U.u, с1h.a1h,u,ЧlfЫс c1h,falfu,~bl Она _1I8а

1

вы создали эомечarenьную веб-араниц~ используя НТМL. и украсили ее

с помощью

CSS. но эаметили, что внешний вид вашего сайта не идет дальше того,

чтобы пассивно покаэывать свое содержимое. Информация передается только

в одну сторону, и вам хотелось бы иэменить такое положение вещей. По сути, вам хотелось бы энать, о чем думает ваша аудитория . Но для этого вы должны

предоставить посетителям воэможность вносить данные в веб-форму. Вам также необходимо, чтобы эта информация была обработана и передана вам. Похоже, вам нужно больше, чем просто

HTML, чтобы

поднять ваш сайт на уровень выше.

HTML статичен и скучен РНР оживляет ве6-сч>аницы Собаки в космосе Форма помоraет Оуэну разобраться в этой истории Формы пишyrcя на НТМL у НТМL-формы имеются проблемы НТМL-код интерпретируется на клиентской программе РНР действует на сервере РНР-сценарии интерпретируются на сервере Используйте РНР для доступа к данным формы

РНР-сценарий должен размещаться на сервере Поместите свои РНР-сценарии на сервер

Сервер преобразует РНР в

HTML

Разбор РНР-сценария Оуэна Несколько РНР-правил кодирования Поиск допустимых имен для переменных

Данные содержатся в переменных сценария

$ _POST - специальная переменная, содержащая данные формы $_POST передает данные формы вашему сценарию Построение содержания электронного письма в РНР

.

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

Оуэн начинает терять электронные письма

6

38 39 40 41 42 44 46 47 48 52 54 55 58 60 61 62 67 69 70 80 82 83 84 85 86 89 90


огnавленuе

соС8ц,lfGlfц,G с лtr&JtlL Как все ато corllacyeTc• •eJКAY со60Й

2

Перед тем как начинать соэдание системы, очень важно понимать, как

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

формы больше вас устраивать не может. Вам необходим способ, позволяющий сохранять эти результаты так долго, как это вам необходимо. С другой стороны, этот

способ должен позволять вам обращаться к данным по мере необходимости. Хорошо известная система управления базами данных

MySQL может надежно хранить ваши

данные. Но вам необходимо как-то подключить ваш сценарий к этой системе, чтобы воспользоваться теми возможностями, которые она предоставляет.

РНР-форма Оуэна работает хорошо. Слишком хорошо...

96

замечательное средство для хранения данных

Оуэну необходима база данных

97 98

РНР управляет движением данных формы

100 103 106 109 110

Соединение с вашей базой данных из РНР

112

MySQL -

MySQL Создание базы данных и таблицы в MySQL Запрос INSERT в действии Используйте SELECT, чтобы извлечь данные из таблицы Пусть РНР обрабатывает эти утомительные запросы SQL

Добавление данных с помощью РНР-сценария

113

Используйте РНР'функции для соединения с базой данных

114 116 121 122 123 127 132 134

Открытие соединения с помощью функции шуsqli_connectO Построение запроса

INSERT в РНР MySQL из РНР Закрытие соединения с помощью функции mysqli_closeO $_ POST передает данные формы Оуэну необходима помощь в .просеивании~ ero данных Выполнение запроса к базе данных

Оуэн на пути обнаружения Фэнга Но&.. Й СLЩiаl"uii I"Momaem x0I"0uJo,

• ),1

но я сmaл !1Олучаmь СЛUIllКОМ

MHOfO

3ЛfКmI"ОИН ..х nuceм. Я не СМО1)' Пl"uняmь

сmоЛЬКО K"'f'euHa. чm"""l"а~ООl"аmься МСОЛЮmНо со &сем.

~

iI,l,


огЛQвnенuе

co~aJfu,e u, дrl110J\Jfеlfu,е 8rlдЫ 8rllflfblX Соэдание ваших со6ственных "аннь.х

3

у вое не вcerAo будyr необходимые вам данные. Иногда вам придется создавать данные, прежде чем вы сможете их использовать. А иногда вам придется создавать таблицы, чтобы хранить эти данные. А иногда вам придется создавать

базу данных, чтобы хранить данные, которые вам нужно создавать, прежде чем

вы сможете их использовать. 3апутались? Разберетесь! При готовьтесь узнать, как создавать свои собственные базы данных и таблицы. И после всего этого вы создадите свое первое РНР- и MySQL-приложение . Магазин « Элвис~ открыт

Элмеру необходимо приложение Визуализированная структура приложения Элмера

Все начинается с таблицы

Еще один контакт с MySQL'c~pBepoM баз данных Создайте базу данных для электронных писем Эл мера

Создайте таблицу в базе данных Нам необходимо указать типы наших данных Познакомьтесь с некоторыми типами данных

MySQL

Создайте вашу таблицу с помощью запроса Таблица впереди базы данных Выполните запрос

Запрос

USE перед использованием базы DESCRIBE показывает структуру таблицы

Элмер готов заносить данные

Создайте сценарий

addemail.php

Другая сторона приложения Элмера Колесики и винтики сценария

«Отправка электронной почты»

(sendemail.php) - извлечение данных mysqlUetch_arrayO

В первую очередь

Функция

извлекает результаты запроса

Повторение операции в цикле

while Обработка данных в цикле while Вы получили письмо... от Элмера!

о

Иногда люди хотят удалиться

Удаление данных с помощью запроса

DELETE WHERE

Использование ограничивающего условия

no~ ..... ~-6~ 8'f'OPOА 6ec:nJJ11тио l Ocт&JI~ ТOnblto '!tIМ JOUIIl

8

150 153 155 156 159 161 162 169 170 171 172 175 176 181 182 183

для удал ения определенных данных

184

Минимиза цня риска случайного удаления

185 190 191

MakeMeElvis.com - это веб-приложение Кроссворд РНР и MySQL ине :)а6w..ай:nо~еаа. о­

140 141 142 145 146 147 148 149


огЛDsnенuе

rt~ЛЫfЫ' ц, 11rч~'th,ц,Чtс~ц,t 11rц,J\о~tlf14.Я Ваше be6-nРИIIОJКение

4

Иногда надо реально смотреТЬ на вещи и менять свои планы . Или планировать более внимательно с самого начала. После загрузки

приложения на веб-сервер вы, возможно, обнаружите, что спланировали его недостаточно хорошо. Некоторые решения, которые, как вы предполагали,

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

и переместится в Интернет. По пути мы познакомим вас с примерами более важного кода РНР и

SQL.

у Элмера появились раздраженные покупатели

Требуйте достоверных данных, вводимых в форму

196 199 200

Логика в проверке на достоверность данных формы «Отправка электронной почты~

201

Защита Элмера от... Элмера

~EL.vj$.C()toI

=--=::,:':.~::...

=-.5:, :~~~., ("""'"""-9

Ваш код может принимать решения,

испольэуя управляющую конструкцию

if

Про верка на достоверность

В управляющей конструкции

if может осуществляться

проверка не только на тождественность данных

Логика в проверке на достоверность данных формы .Отправка электронной почты. РНР-функции для проверки переменных Множественная про верка на достоверность с помощью логических операторов AND и OR

Форме ввода данных необходима обратная связь Необходим простой вход в РНР и выход из него Испольэуйте флаг для· предотвращения повторения кода

Испольэуйте повторный код НТМL-формы только один раз

Форма ввода данных, которая ссылается на себя Передайте атрибуту action имя сценария Проверка: была ли форма отправлена на сервер Некоторые покупатели все еще сердятся

Записи таблицы должны уникально идентифицироваться Первичные ключи обеспечивают уникальность От кнопок с независимой фиксацией к идентификаторам покупателей

_._---

Прохождение по элементам массива в цикле foгeach

202 203 204 207 208 215 219 229 230 231 235 236 238 242 244 246 251 252

~~Lvj$.C:OМ

::::=II=:'~IWY8"""'" с д..IiIIIfa ......,р ........ ---~ O м,.~1 1. l' .c ~ .......... 1 .. с.) QDм . . . . "цф.

!~)

"111"'-

9


frlБо~ с grllflfЫМц" coXfrllftlflfbJMu, ~ Фrli1,J\ЧХ

KorAa просто 6аз ... данных недостато"но

s

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

но как обстоят дела с бинарными данными? Скажем, такими как изображения

в формате JPEG или документы в формате РОЕ Есть ли смысл в том, чтобы хранить, например, картинки, изображающие коллекции редких гитарных медиаторов,

в таблице базы данных? Чаще всего нет. Данные подобного типа обычно сохраняются в виде файлов, и будет лучше, если мы оставим их в этих файлах. В этой главе рассказывается, как совместно использовать данные, сохраненные в файлах и базах

данных, для того чтобы создавать РНР-приложения, забитые под завязку бинарными данными.

Виртуальным гитаристам нравится соревноваться

Доказательство подлинности

-

в изображении

Приложению необходимо сохранять изображения Планирование загрузки изображений на сервер

~Гитарные войны»

267

База данных рейтингов должна быть изменена

268

Как получить файл изображения от пользователя?

272 274 275 280

Добавление имени файла изображения в базу данных Определение имени загружаемого файла Куда деваются загружаемые на сервер файлы?

Создание места для загруженных файлов изображений

284

Общие данные должны использоваться совместно

290

Совместные данные включаются в сценарий в тот момент, когда они требуются Рассматривайте выражение

Распределение по порядку

-

require_опсе как ~вставить~ это все, когда речь идет о рейтингах

Награды самым лучшим гитарным воинам

Форматирование списка рейтингов с помошью

HTML и CSS

Допускаются только небольшие файлы изображений Проверка парамеуров файлов во время загрузки

делает сценарий БОлее надежным

ПЛан создания страницы ~ Админ~ Создание на странице ~Админ~ гиперссылки для удаления рейтинга

291 292 294 297 298 303 304 308

Определение рейтинга для удаления

311 312 314 316 319

Установка предельного количества удаляемых записей с помощью выражения LIMIТ

320

Сценарии могут обмениваться друг с другом информацией ОGЕТиРОSТ

GET, POST и удаление рейтинга

10

260 261 262


оглавленuе

д~\ц'u,'t11,~ ~~\{LCgO lIru,i\o~clfl4.ff

6

С"итаiте, ..то все они намерен ... восnо,.ьэоватьс. вашими CIIа60CТRМИ Ваши родители были праВЫ: никоrда не paэrоваривайте с неэнокомыми людьми. Или, по крайней мере, не доверяйте им. Ну и, конечно же, не давайте

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

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

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

Кудаделисьрейтинги?

Защита от нашествия банд злоумышленников

C'IPIIWe ВОЙНЫ. Администрирование ре~iтинroi)( ' - : .-с-~peiтN.IUVII ~ ..r88ptWC:~.

~~-~~~.~.~.~.~~.~~: -.....А с:..,.,а. 2008-OS-OJ ZO:~6;4S 38У740

Y.uun,

--.. ~ -. ~

2OOW5-01 20:16:0'1. 282А70 .Y~ :IOМ-OS-Ol 26:.)8:23 243260 ~

... ~ ~........,..

1003-05-01 20;37:40 186'110 2OO8-Os..o1 20:37;2' 127650

---

--

Защита страницы .Администрирование рейтингов~ приложения сГитарные войны~

НТТР-аутентификации требуются НТТР-заголовки НТТР'заголовок: пристальный взгляд

Работа с НТТР-заголовками в РНР Аутентификация с использованием НТТР-заголовков Создание сценария сАутентификация. сГитарные воЙны~. Эпизод

11: атака

рейтинговых клонов

Вычитание сложением

Безопасность требует присутствия человека

План арбитража в приложении сГитарные войны. Предоставьте место для санкций с помощью SQL-запроса ALTER Несанкционированные рейтинги недостойны внимания Хакерская атака в миллион очков Все зависит от модеририрования?

как именно она сделала это? о

Манипуляции сервером баз данных с помощью комментариев Форма .Добавление рейтинга. была подвергиута атаке сВнедрение SQL-кода. Защитите свои данные от атаки .Внедрение SQL-кода.

Более безопасный запрос

INSERT

332 333 335 336 338 340 341 342 350 354 355 356 357 358 363 366 367 369 370 371 372

(с использованием имен колонок)

373

Проверка данных dюрмы на ДOCTo~epHOCTЬ никогда не может быть чрезмернои

375

Пожар потушен!

377

11


CO~~lfu,c '\1сrсоlf~лu,зu,rо~~lflfоgо ~сБ-'\1ru,ЛО~Сlf14fI

1

....

мен.

nOMHlIl'e?

Никому не нравится, когда о нем эабыващ особенно это не любят

пользователи веб-приложениЙ. Если приложение ориентировано на работу с пользователями как с членами своего рода сообщества и пользователи

обмениваются с ним информацией в определенной степени личного характера, такое приложение должно помнить своих пользователей. Вам определенно

не понравилось бы представляться своей семье каждый раз, появляясь на пороге дома. Вам нет необходимости делать это, потому что у всех членов вашей семьи есть такая замечательная штука, как память. Но веб-приложение не запоминает

людей автоматически. Это забота толкового разработчика приложения, использующего доступные средства (может быть, РНР и

My5QL?), -

создавать

персонализированные веб-приложения, способные запоминать пользователей. [оворят, противоположности сходятся

Все эти несоответствия являются, по существу, личными данными

Пользователям приложения ~Несоответствия ~ необходимо

войти в приложение, прежде чем они получат доступ к профилям

Более детальная разработка плана для входа пользователей в приложение

Подготовка базы данных к процедуре входа в приложение Создание интерфейса для входа пользователя в приложение Шифрование пароля с помощью функции

SHAO

Сравнение паролей

добавление места для зашифрованного пароля Аутентификация пользователей с помошью НТТР

Вход пользователей в приложение с использованием

НТТР-аутентификации

Форма для создания учетных записей для новых пользователей Дайте пользователю возможность создать учетную запись Иногда все, что вам нужно,

-

это куки

Что такое куки? Использование куки в РНР Переосмысление процедуры входа в приложение

Вход в приложение с использованием куки Вход в приложение Выход из приложения означает удаление куки

Сессия не зависит от клиента

Сессия Использование данных сессии

Обновление приложения «Несоответствия ~ путем использования сессий

~, ш"ntт:; '

ФIb'8ll"J'8+•• :

••11:

'" . ••мu..:

11.,,,

Выход из приложения при использовании в нем сессии Завершение перехода к сессиям Пол ьзователи не чувствуют гостеприимства Сессии живут недолго ...

... а куки могут сушествовать вечно! Сессии

12

+ куки

~ исключительное постоянство существования данных

382 383 384 385 387 389 390 391 391 394 397 401 406 410 411 412 415 416 418 421 425 426 427 428 429 434 440 442 443 445


оглавление

j'C'th,fr1Jfertu,e 8tБJ\u,fО~r1.rtL4JI ~ogrl

7t1 2 /

Совмecrиое ИСnOllьзоваНИ8 зна .. иr за6cna

ЗоНТИК - не единcrвeнная вещь, которой МОЖНО ПОЛЬЗОватЬСЯ совместно. в любом веб-приложении вы можете столкнуться с ситуацией,

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

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

-

исключение дублирования кода путем

его совместного использования. Говоря другими словами, вы размещаете

в каком-то одном месте код, необходимый в нескольких местах, а затем просто ссылаетесь на него, когда у вас возникает в этом необходимость. Составные части приложения .Несоответствия~

457

Пре06разование приложения «Несоответствия~ с использованием шаблонов

458

Преобразуйте приложение «Несоответствия~

с использованием шаблонов

460

Приложение «Несоответствия~ снова завершено ... и гораздо лучше. организовано

462

.'---- 3d~ОЛ()€ОI( 110Я€ляе11\С9.. "" € к.а.Чctле nоЧm,u. Kq;JV':90U С11\РФ'.u.v,bt I1рu.лож.еКIJ.9..

~:~~~~~~~

«НеСОО'У!\€е11\С11\€ЦЯ ", э еJл,ОКС11\РЦРУЯ К<\3(S'dнuе I1рu.ложеНilЯ, .90I"\олн.енкое

НдJ€ФШем l(ofU(pe11\J-I.OU С11\ pqНilU,bL

c:mpdн.u.u,e I"\Рu.лож.е~u.я.

«НеСОО11\€е11\С11\€u.я. »

,,-еодхо.9Wo\ 1(03 «j$xoq g- nрu.лож.ен.u.е»,

'lm,о$"bI. 011\слeJtШ.€d11\Ь СОС11\оя.н.u.е t\OлЬJО€G\11\еЛ>l

НG\€ЦС',Qu,цо"-l-l.Oе. Мен.)()

t)о.я.€ляе11\СЯ cpdJj Jq Jd.~ОЛо€I(ОМ

ц I1р еЭ ОС11\qеля.е'!l1 €ce.M

С11\РФМJ.,<J.М t)рU.лож.ен.uЯ

«JiеСОО11\€еm, с-m€u.я» еэu.н.oО~Р<:IJк()е Mefl)() ЭЛЯ t)epex0.9<.\ межэу Кu.мц.

в ре3'JлЬ11\G\11\е u.СI"\ОЛЬ,3o€"'НilЯ 11\(\КОС',О ~олЬщо~о колu.ЧеС11\€q зо~q€ляемЬ!.х ClA,eк.a.pue€ щеК4рЩQ il"\<{eX,re ОС1l\dе11\СЯ mолы(o сосреЭО'!l10ЧЦ-m.Ься к4 c€oeц e.9u.,,-c.11\€e~,,-ou ролц, КО11\ОРdЯ 3 d I(Л)()'-Idе'УГIС9.. е €bI.€0.ge l"\еречf'.Я rШ€bu< чле,,-о€ coodUJ.,eCYf)€d.

13


оглавленuе

J11f~l\}Iii,11t,G c~ou,Mu, 8C1JftfblMU" J11f~l\}Iii,11t,G оtkf~ruo\ц'u,м. ~~c MU,f0лt

8

С60Р урожа. Аанных Это не что иное, КОК осенний сбор урожая донных. Перед вами огромное количество информации, которую нужно получить, отсортировать, сравнить, скомбинировать и вообще сделать все то, что необходимо для вашего потрясающего веб-приложения. Это выполнимо? Да. Но, как и при настоящем

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

которые призывают к действию ... данных, которые обогаща.qт. Поэтому чего вы ждете? Заводите свой MySQL-комбайн и принимайтесь за работу!

Создание идеального несоответствия Несоответствия

-

это все данные

Классификация данных приложения «Несоответствия» Моделирование базы данных с помощью схемы Свяжите друг с другом несколько таблиц Внешние ключи в действии

Таблицы MOryT связываться между собой по принципу ~OДHa запись одной таблицы соответствует одной записи другой таблицы» Одна запись ведет ко многим Связь типа многие-ко-многим Создание анкеты приложения «Несоответствия»

Добавление признаков несоответствия в базу данных Данные MOryт управлять созданием формы

Говоря об эффективности ... Создание формы «Анкета» приложения «Несоответствия»

, ,

Теперь данные управляют формой Стремитесь к нормализации

)

В процессе нормализации думайте об атомизации Кому, в конце концов, нужна эта нормализация

Три этапа нормализации базы данных

Изменение структуры базы данных приложения «Несоответствия» Итак, действительно ли база данных приложения «Несоответствия» нормализована? Запрос в запросе в запросе ... Соединим наши таблицы Соедините с помошью точек

В действительности мы можем делать еще больше, используя внутренние объединения Упрощение выражения

ON с помощью ключевого слова USING

Альтернативные имена для таблиц и колонок Объединения повышают эффективность lasLname

birft1dote

Любовь

-

это игра цифр

Пять этапов нахождения успешного несоответствия Подготовка к поиску несоответствий Испытание пользователей на несоответствие

Все, что нам необходимо,

14

-

это цикл

for

Завершение приложения «Несоответствия»

464 465 466 467 472 473 474 475 476 481 482 486 491 492 496 498 499 500 501 505 506 508 509 510 511 512 513 514 520 521 522 523 524 527


огЛDsnенuе

1h,t}:;c11t.o~blt c11t.f0}:;U, U, '\10J\Ъдо~а.1h,tJ\ъс}:;u,t фj't(}:;~u,u, _УНКЦIIII 06l1er..alOT _IIЗН"

9

ФунI<ЦИИ nepeвoдят ваше пpилoжeн.ote на COВePWetН> новый ypoвet ... Вы уже использовали встроенные РНР-функции для решения определенных задач. Наступило время рассмотреть еще несколько исключительно полезных

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

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

Хорошую рискованную работу не так легко найти l'

_

Запрос на поиск не прощает никакой ошибки

,.

SQL-запросы могут стать более гибкими при использовании в них оператора LIKE Разбейте строку на отдельные слова

Функция

. ._ _ _

",oe~. По.а

implodeO создает строку из подстрок

Предварительная обработка поисковой строки Замените ненужные для поиска символы

Зап\?ОСу необходимо условие поиска с деиствительными критериями

Копирование непустых элементов массива в новый массив Иногда вам достаточно только части строки Извлечение подстрок с другого конца Несколько запросов позволят нам сортировать результаты нашего поиска

Функции дают вам возможность использовать код повторно Создание запроса с использованием пользовательской функции

-

Пользовательская функция : близкий взгляд Управляющая конструкция SWIТCH выбирает нужное решение из значительно большего набора возможных вариантов, чем IF Дайте функции

build_ queгyO возможность сортировать данные

Мы можем разбить результат поиска на страницы Извлекайте столько записей, сколько вам необходимо,

•••••• =.. . =............

_

используя запрос с выражением LIMIТ

Управляйте гиперссылками на страницы,

..

с-1234Ф

~

-_;~

'-

Our-.

541 546 549 555 556 560 561 564 565 568 572 573 574 578 581 584 585

используя выражение LIMIТ

586

результатов поиска на отдельные страницы

587

Создание переменных, необходимых для разбиения результатов поиска на страницы

588

~-ВW:l!I\lШiiril• • • • •iiiiiIliIjk, Отслеживайте данные, необходимые для разбиения

- - - , . . . . . . . ., ......... Pny.if..11IТ.мara

538 540

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

Создание навигационных гиперссылок

Сборка законченного сценария поиска Окончательный вариант сценария поиска, продолжение ...

589 590 593 594

15


огЛQвление

rezJМftfble ~bjr~~etfL4JI

10

ПраВИllа замень. ФунКЦИИ ДЛЯ обрабоТJ(И строк

-

похоже, очень неnnохое средство,

но в то же Время ОНИ достаточно оrpоничены в своих возможностях.

Конечно, они могут определить длину вашей строки, укоротить ее и заменить

отдельные символы другими . Но иногда у вас возникает необходимость делать более сложные преобразования текстовых строк. Здесь вам на помощь приходят регулярные выражения . Используя их, вы можете выполнять

достаточно сложные преобразования текстовых строк, основываясь на группе правил, а не на каком-то одном критерии.

Приложение ~Рискованные работы~ дает пользователям возможность загружать свои резюме

Определите, как должны выглядеть ваши данные

Создание шаблона для номера телефона Проверка соответствия шаблону

с использованием регулярных выражений

Создание шаблонов с использованием метасимволов Тонкая настройка шаблонов с помощью символьных классов

Проверка соответствия с помошью функции

preg_matchO

Стандартизируйте номера телефонов Удалите ненужные символы Создать шаблон адреса электронной почты имя:ДжимМИ

задача нетривиальная

ФёlМИЛИЯ: СВИфТ Адрес электРОННОЙ почты: Js@sim-u-duck.com Телефон: 636 4652 ЖеЛёlеМёlЯ pёl6oTёI: НИНДЗЯ

Доменные суффиксы везде Используйте РНР дЛЯ проверки доменов

Проверка адреса электронной почты: весь процесс полностью

о

ИМЯ:дЖИММИ

ФёlМИЛИЯ: Свифт Адрес электронной почты: JS@sim-u-duсk.соm

Телефон:

(555) 636 4652

ЖеЛёlеМёlЯ pёl6oTёI: НИНДЗЯ

16

-

598 602 605 606 608 615 620 627 628 632 634 635 636


д..на....еское СО3AQи.е .306ра_ен •• Конео8-ю, все мы ЭНОЕ!М ширсжие В03МOЖНOCJИ грамотно составленного

3а1ЮОО, пpeдocтaвnяющего великолепные реэу11ЬТОТЬ1. Но результаты

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

игра. Но в качестве источника данных для построения изображений в вашем

приложении может выступать не только информация, сохраненная в базе данных. !"""'~..r'- ~'.:ЕЬ: !XZo.OnUНi_ ~''''''.''' "'~..r-: ~•..f:h: ~\.k1r

..-k:;80

.........~ _ .... ___.:r':

~'---;3b: ~:.mLЖ,.._

Например, знаете ли вы, что вполне возможно защитить форму от занесения в нее данных программой-роботом по распространению спама (спам-ботом) с помощью

динамически генерируемых изображений? Перезагрузка приложения «Гитарные войны~: восстание роботов Любая веб-форма подвержена риску

Нам необходимо отличать людей от машин Мы можем победить автоматизацию с помощью автоматизации Создание текста идентификационной фразы САРТСНА

Вывод изображения САРТСНА

Внутри функций графической библиотеки Функции графической библиотеки

GD.

GD

Продолжение...

Использование в тексте шрифтов Тгие Туре

Создание случайного изображения САРТСНА Приведение в порядок приложения «Гитарные войны~

Включение САРТСНА в сценарий «Добавление рейтинга~ Пять уровней противопоставления Составление гистограммы распределения несоответствий по категориям Сохранение данных гистограммы

Гистограмма: близкий взгляд От одного массива к другому Создание массива для признаков несоответствия

Разработка плана операции по созданию гистограммы Перемалывание категорий CmratlHO. у Meн~ нет HUKaKOU в.О3МQжносmu MoueruroBamb Все. 3mu

rwmuнщ ООЛbl.JJuнстбо U3 которь,х upальсucj>uцuru~аны. Я "аже не )наю,

~~=?:-'::5r:::~о:~,,,:::ч;mо такое. <<'XMyt'blU смаuлuк))!

642 643 644 647 649 650 652 654 656 659 661 663 666 667 668 671 672 674 675 676

Проведение математической обработки категорий

677

Основы процесса построения гистограмм

680

Создание и вывод гистограммы распределения несоответствий по категориям

683

Индивидуальные изображения гистограмм

распределения несоответствий по категориям для всех

686

Пользователи при,южения «Несоответствия~ углубились в изучение гистограмм распределений признаков несоответствий по категориям

689

17


оглавление

12

С ••3 .. С миром Вокруг нас оrpoмный мир, И наше веб-приложение не может позволить себе иrнорировоть его. ХОТЯ, может быть, правильнее сказать, ДЛЯ вас было бы лучше, если окружающий вас мир не игнорировал бы ваше веб-приложение. Один из исключительно эффективных способов при влечь

внимание мира к вашему веб-приложению

-

это сделать ваши данные

доступными ДЛЯ распространения, что означает предоставить пользователям

возможность получать на свой компьютер новости вашего сайта, вместо того

чтобы они посещали его непосредственно в надежде узнать эти новости. И не только это. Ваше приложение может взаимодействовать с другими

приложениями через различные веб-сервисы и использовать информацию этих приложений. Оуэну необходимо поведать миру о Фэнге РаспространениесообlЦений о ПОХИlЦеtlИИ космическими пришельцами

RSS используется для распространения содержания сайта RSS - это не что иное, как XML (еХtепsiblе Markup Laпguаgе, J(ftC~.lIчесК1lt приwе..:t .. qw IIОIНща.:18

расширяемый язык разметки (гипертекста»

Mrl••

~~:::~;':..~:,~~-''Ц~ »'''''~-'''-'~-__ <'tw.''_О(>lk'')<''' , ''''''''''''''"~'~~''~? • ... , .. :.О .............. " .... 'К

От базы данных к программе чтения новостей

.._ . _ _._.........,"-...

Визуализация RSS RSS: близкий взгляд

~f!(>-*"Of. :ll;~.. II(:>I ..(' . ..

=~·_~~~·i:~::О!~:=:~'~·~~~;~.'~f'~i«<Ц<

~_!:

Динамическое создание RSS-документа

f~€;~~~f.::::.:~~~_. ~~"-~, ~.~ж·· ~= ~

Ссылка на RSS-канал

_< ••••

Видео красноречивее миллиона слов

~~.:::~~~!t;::~~a;,.~~~~'.,~_.~"_~~A . . ~'- ...,._ ,:-~:

Извлечение содержания из других веб-ресурсов

:.=,~~ ~~~~:c::.~~j;:~:'~IЬ~_ ~:~'~'II._~~"'~:t.!!'~>$. .: :--~

Распространение видеозаписей сайта УоиТиЬе Создание видеозапроса к серверу УоиТиЬе Оуэн готов создать RЕSТ-запрос

He.oтopwe lIUIиеМfW ~ICI'pOMнoA по

УоиТиЬе разговаривает на

........

noмep*M80801' pocnpocтpotteMII8 содер.ан",

саЙТО., "03.0"•• 8ОМ пonyч~ "ИOlUleНМ8

XML

Разбор XML-ответа сервера УоиТиЬе

XML XML с ПОМОlЦью объектов От элементов XML - к объектам РНР Извлечение данных XML из объекта Визуализация видеоданных

Доступ к данным

МН0nt8 06wчн", 6роуир ... ,о

....

"p8дocro8ll8Кn ВОМ 8OJМO.м0Ch npocмcnpмecrn pocnponpaи.емое содержание,

::::::::'": е

p83Y"lt1'01'e ...ro

МЭМ8М8ммА на соАте.

До••

ycrpoAcno

M06мnbltolii

помеРЖМ80t01'

paatpocтpoN8HM8 маме"_""" содер_он

...

на им

"0II.,,8НН8.

28

СОЙ1'О, КО1'Орме

..еClOt п.ре. .~ ycrpoAC1'8CI no мере

ОlПOМотм

Работа с видеозаписями свидетельствами наблюдения Фэнга

-

на подъеме

РазмеlЦение видеозаписей для просмотра

"у_ Форматирование видеоданных для вывода на дисплей

асе. пocnе"имх

(88""

Только с учетом пространства имен!

694 695 696 697 702 705 707 708 712 714 716 717 718 722 726 730 731 732 733 734 735 737 738 739


tnЛQ8Ленuе

g01)Ol\Jf сIiU$ ДеСАТЬ основных тем

(которые мы не ЭQТРОНУIIИ)

1

Даже поспе всего изпожеНН9ГО есть еще некоторые вещи, которые, как

мы думаем, вам нужно знать. Мы были бы не правы, игнорируя их, хотя они и требуют только краткого упоминания. Поэтому перед тем, как отложить книгу в сторону, обратите внимание на эти краткие, но важные детали, касающиеся РНР и

MySQL. Кроме того,

осталось,

-

раз уже вы дочитали до этого места, все, что вам

это несколько коротких дополнений ... и алфавитный указатель ...

и, возможно, немного рекламы ... и вот тогда книга действительно закончится. м

1.

Модификация кода этой книги для поддержки функций РНР 4 и

М

2. 3. 4. 4. 5. 5. 6. 6. 7. 7.

Права пользователей

М

N2 N2 N2 N2 N2 N2 М

N2

N2 8. N2 9. N210.

MySQL MySQL Сообщения об ошибках MySQL Обработка исключений (Exceptions) в РНР Обработка исключений (Exceptions) в РНР (продолжение) Объектно-ориентированный РНР

Объектно-ориентированный РНР (продолжение) Защита вашего РНР-приложения Защита вашего РНР-приложения (продолжение)

Защита вашего приложения от межсайтовоro скриптинга Защита вашего приложения от межсайтового скриптинга (продолжение) Приоритеты операторов В чем заключается разница между РНР 5 и РНР

6

Использование РНР-приложений, написанных другими

750 752 754 755 756 757 758 759 760 761 762 763 764 766

19


оглавление

rr~C1h,roii,X~ cregbl rrlдr~Бо1h,Хu,

n

Место,

rAe

развора .. иваIOТС. со6ь.ти.

Вам необходимо место, где вы могли бы пракrиковоться В рнр и

MySQL

и при этом не допуСтить уязвимости ваших данных. Очень полезно найти безопасное место ДЛЯ разработки своих РНР-приложений, прежде чем

предоставлять к ним доступ из Интернета. Приложение 11 содержит инструкции, как установить веб-,

MySQL- или

РНР-сервер для создания безопасного места

для работы. Создание среды разработки РНР·приложениЙ Определите, что у вас есть

Серверный

Есть ли у вас веб·сервер?

компьютер

У вас есть РНР? Какая версия? У вас есть

MySQL?

Какая версия?

Начало установки веб-сервера Установка

Apache ... завершение

Установка РНР Стадии установки РНР Стадии установки РНР ... завершение

Установка

MySQL MySQL на Windows Активация РНР на Мас OS Х Стадии установки MySQL на Мас OS Х Стадии установки

Перенесите приложение с локального компьюте.l?а

на постоянное место, где оно будет доступно IIЗ Интернета

Создайте дамп ваших данных (и таблиц) Подготовка к использованию дампа ваших данных

Перенесите данные на сервер в Интернете, используя дамп Подключитесь к вашему серверу вИнтернете

20

768 768 769 769 770 771 772 772 773 773 774 775 778 778 780 781 781 782 783


оглавление

ш

r~c\Uu,rb't1bt ffiОдМо~lfос'th,u, cffioe,zo уЬу До6ейтесь еще 60llьwеrо Да, вы можете создавать отличные приложения с использованием рнр

и

MySQL

Но вы знаете, что должно быть что-то, что позволит делать это

еще лучше. В этом коротком приложении мы покажем вам, как установить такие расширения языка, как

mysqli

и графическая библиотека

GD.

Затем мы упомянем еще несколько расширений РНр, которые вас, возможно,

также заинтересуют. Потому что иногда хорошо хотеть большего. Расширение возможностей вашего РНР ИнаМас ...

786 789

rn>1!i~f'''''­

~JI;~~

'1o~b­

!74~~~ "llII8/op;1Gt-~­

'l1Q"~I':c-­ ~~~b_

l2'i>1!i~~. fiJlI3 .......jor.~

bl>l~~_·

125a:~--­

,,аэI0~"""Ь"""" ~\IZ~'~ n>2l~~

~3Ja ~.e.-. UHIjj~~' :U1<I!i~f"~ '!IIr.;~.,;or.~

21


Моим родителям, которые часто пользуются

веб-приложениями, и всегда из-за меня. Линн Бейли

Расмусу Лердофу, в одиночку создавшему язык, который в конечном счете превратился в то, что мы

знаем теперь как РНР. Неутомимая энергия

-

вот что

позволило этому человеку повести нас по новому, более плодотворному пути.

Майкл Моррисон


Автор(ы) книги с<Изучаем РНР и

",lинн Бейли

-

писатель, сменивший

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

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

вычислительной техники Линн работала под псевдонимами

MySQL»

NRL и LANL. Затем создала

свой первый бестселлер. Она переехала в Силиконовую долину как раз перед кризисом.

Проработала несколько лет в Yahoo! и написала несколько книг и учебных пособий. Наконец,

Майкл Моррисон стал большим энтузиастом Интернета, с тех пор как вел

BBS на своем

~Koммoдope 64\> в те давние времена, когда быть компьютерным фанатиком еще не было так круто, как в наше компьютеризированное время. Сейчас,

когда скорости передачи информации возросли

на порядки, он не устает восхищаться тем, как быстро и как далеко мы продвинулись в этой области. Майкл больше не ведет

BBS, но продолжает с энтузиазмом

работать с современными эквивалентами этой системы. Большую часть своего ~официального\>

\"Ступив своим творческим наклонностям

времени он проводит за разработкой различных

где получила степень магистра изящных искусств

или соавтора более пятидесяти книг на темы,

~исателя, она переехала в Нью- Йорк,

веб-технологиЙ. Он создал в качестве автора

как писатель. Ее магистерская диссертация

простирающиеся от программирования игр для

Head First была очень хорошо принята

мобильных телефонов до

преподавателями и студентами, и, получив

книг Head Fiгst начиная с книги

степень, девушка закончила книгу

Head First SQL и почти закончила книгу ~Изучаем РНР

н ~1ySQL\>. Вот как!

.lинн любит путешествовать, писать и составлять

исключительно обоснованные истории о совершенно незнакомых людях. Она немного

боится НЛО.

XML Он попал в мир серии Head FiгstJavaScгipt

и остается в этом мире до сих пор.

Майкл является также основателем

Stailfish

Labs (www.stalefishlabs.com) -

компании,

специализирующейся на играх и интерактивном медиа. А еще хорошо известно, что у него есть

занятия вне Интернета (не удивляЙтесь!).

Скейтборд, хоккей ... Он любит также посидеть возле бассейна с карпами вместе со своей женой Машид. И даже время от времени ложится поспать.

23


Всryпnение

25


как nОЛЬ30ВQться этой книгой

Для кого эта книга? Если вы ответите <!;да!> на все эти вопросы: Являетесь ли вы веб-разработчиком с опытом использования

или

HTML XHTML и желаете ли вы повысить уровень ваших страниц?

Хотите ли вы двигаться дальше создания простых НТМL-страниц, изучить, понять и запомнить, как использовать РНР и

MySQL

ДЛЯ разработки веб-припожений? Предпочитаете ли вы стипь непринужденной беседы за обеденным стопом стипю сухой и скучной академической пекции?

тогда эта книга для вас.

Кому, скорее всего, следует отложить эту книгу в сторону? Если вы ответите <!;да!> на любой из этих вопросов: Вы COBepweHHO незнакомы с такими базовыми понятиями проrраммирования, как переменные и цикnы?

(Но даже если никогда не программировали до этого, то, скорее

всего, сможете получить из этой книги необходимые вам

• •

ключевые понятия.)

Вы опытный разработчик веб-приложений, ищущий справочник по РНР? Боитесь ли вы пробовать что-нибудь отпичающееся от того, к чему вы привыкли? (читаете ли вы, что

техническая книга не может быть серьезной, если

в ней идет речь о создании базы данных о похищениях космическими пришельцами?

тогда эта книга не для вас .

26

вступление


вступление

Мы зиаем, о чем вы думаете «Насколько эта книга о РНР и

MySQL серьезна?»

«Зачем вся эта графика?»

«Смогу ли я изучить материл, подаваемый в таком виде?»

Мы зиаем, о чем думает Baw МО3Г Ваш мозг жаждет нового. Он все время что-то ищет, изучает, ожидает чего-то необычного. Он так устроен, и это помогает вам в жизни. Итак, что делает ваш мозг со всеми этими рутинными, обычными, нормальными вещами, с которыми вы сталкиваетесь? Все, что

он может сделать, чтобы предотвратить их влияние на свою важную работу, - это сохранить то, что имеет значение. Он не утруждает себя сохранением скучных вещей, они не идут дальше фильтра под названием «это не имеет никакого значения».

Как же ваш мозг оnределяеm, что имеет значение? Предположим, вы отправились на прогулку и неожиданно прямо перед вами

выпрыгнул тигр. Что произойдет в вашем мозгу, да и во всем теле?

Нейроны вспыхнут. Чувства обострятся до предела. Концентрация адреналина в крови начнет зашкаливать. Вот так ваш мозг и определяет ...

Это очень ва_ноl Не эабуAltте этоl А теперь представьте, что вы дома или в библиотеке. В этой зоне, свободной от всяких там тигров, безопасно и тепло. Вы занимаетесь.

Готовитесь к экзаменам. Или пытаетесь разобраться со сложным

техническим вопросом, на решение которого, по мнению вашего u

начальника, вам нужна неделя или, от силы, десять днеи.

Вот только одна проблема. Ваш мозг пьпается оказать вам

большую услугу. Он старается принять все меры, чтобы все это

не имеющее никакого значения содержание не забивало и без

~ш. ,лоу" '-\m0 c'4v.-mo.e-m' .....

c-mОU:щ 110 \-\.е'-\mo'&~ ez'o ~°2,О, :mb .

y1nO~

\

того небезграничные ресурсы. Ресурсы, которые необходимы для сохранения действительно важных вещей. Таких как

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

И не существует просто способа сказать вашему мозгу: «Эй, мозг, спасибо тебе, конечно, но независимо от того, насколько эта книга скучна и насколько низок сейчас мой

эмоциональный уровень по шкале Рихтера, мне крайне

необходимо, чтобы ты сохранил всю эту информацию».

]3v..9eo3d l1u.cb I1рu...3 е м.лен.u.я. НЛО м '10иТи/,е, н.eCOfi\Н.eкн.o uKYf\epec.M .9ЛЯ '

долее

€dшег.о мозг.d, Чем ~ Л1ОddЯ J<ОМt)Ь)OYl1ермя кн.uг.d .

8ЬlзоеСh •

27


как nОЛЬЗ0ватЬСR этой книгой

Мы paccмaтpuвaeM чumamе.лs серии KНUГ

Head First

как ОБ~ающег0С9

Тоща что же необходимо для того, чтобы научиться чему-нибудь? Для начала материал должен

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

Мы знаем, как мобили30ВОТЬ ваш мозг. Вот некоторые принципы обучения, реализованные в серии Head First. Используйте изображения . Изображения запоминаются значительно лучше простых слов и делают процесс обучения более эффективным (повышение эффективности тестов на запоминание до

89 %). Кроме того,

изображения более понятны . Помещайте слова внутри или около

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

Испольэуйте раэrоворный и персоналиэированный стиль. Как следует из последних исследований, улучшение результатов контрольных тестов учащихся достигает

40 %, если

книга обращается непосредственно к читателю, материал подается внеформальном, разговорном стиле. Вместо чтения лекций рассказывайте истории . Говорите

неофициальным языком. Не держитесь слишком серьезно. Что больше при влечет ваше внимание: непринужденная беседа за столом или сухая лекция?

Соэдавайте все условии ДЛИ более rлубокоrо осмыслении материала

обучаемым. Иначе говоря, пока вы активно не возбудите его нейроны, ничего не произойдет в его

О

голове. Читатель должен быть взволнован, увлечен, удивлен и заинтересован в решении проблемы .

О

Он должен делать выводы и получать новые знания . А чтобы достичь этого, вам необходимы задачи, упражнения, провокационные вопросы

-

все, что вовлекает в работу обе половины мозга и множество

чувств .

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

совершенно неожиданно . Новые технические темы совсем необязательно должны подаваться в скучном формальном стиле . Ваш мозг воспримет гораздо больше и быстрее, если это не так. Эатраrивайте эмоции. Мы знаем, что способность запоминать что-либо в значительной степени зависит от эмоционального состояния . Вы запоминаете то, что для вас важно. Вы запоминаете тогда,

когда ваши чувства обострены . Мы не имеем в виду душещипательные истории о мальчике и его собаке. Мы говорим о таких чувствах, как удивление, любопытство, чувствах, вызывающих смех или вопрос «Что это? .», чувстве глубокого удовлетворения, возникающем после решения сложной головоломки или осознания того, что многие считают слишком трудным для понимания. Что вы узнали то, чего не знает

Боб из инженерного отдела, постоянно дающий вам понять: «Я технически грамотнее, чем ты».

l'

qэн.о r::е~оЛЬщое jYJ10ЧН.ен.u.е. Н(\ с(\МОМ эеле

' - - - - f5.J'i\Ou. кн.аг.е

eC"YI'\b Э'ушещu.t"j(\"YI'\елЬн.С\Я

U. С"'l1l о рu.Я

о t1C\pНoe u. ег.о СОдФ{ е. ВЬ. дуэе."'I1Iе. \iOMoZC\"YI'\b .J1'rIОJ;',ч tjc\prtro € \JOu.cKe ег.о tjU."YI'\OMUf.\, tjохu.щенн.ог.о " КОСМltЧескu.мu. \Jрu.шелfл.у:\}.-\u.!

28

вступление


вступление

МетаПОJиаиие: МЫCJIИ О МЫСЛЯХ Если вы действительно хотите изучить что-либо и стремитесь сделать этот процесс быстрым и более глубоким, обратите внимание на то, как вы обращаете внимание на что-то. Подумайте о том, как вы думаете. Изучите то, как вы изучаете. Большинство из нас в течение своей жизни не изучают метапознание, или теорию обучения. Считается, что мы это и так знаем, и редко когда изучаем это как дисциплину.

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

как с помощью РНР и

MySQL создать сайт, управляемый базой данных. И вам, скорее

Q О

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

А ДlIЯ этого нужно понять все это. Для того чтобы получить максимум от прочтения этой, любой другой книги или от обучения, необходимо управлять своим мозгом. Направить свой мозг на изучаемое содержание .

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

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

сохранения этой информации.

Так как, смо_ете вы убедить свой мозr рассматривать РНР и

My5QL

n_РОТОРОАи.uaето .ом

так _е. как

ronop..Horo

тиrра.

AOPory"t

Имеется два пути: один медленный и нудный, другой значительно более быстрый и эффективный. Медленный путь заключается в простой зубрежке. Вы, очевидно, знаете, что можете заучить и запомнить наиглупейшее содержание, если будете долго и монотонно вбивать его в свой мозг. После достаточно длительного повторения мозг скажет себе: «Это не выглядит имеющим для него значение, но он продолжает и продолжает это повторять. Похоже, это все же важно!>.

Быстрый путь использует все, что повышает активность .мозга, особенно различные виды его активности. Перечисленное на предыдущей странице составляет значительную

часть решения. Использование этих приемов поможет организовать работу мозга

о

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

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

Разговорный стиль изложения материала помогает потому, что люди придают большее

значение информации, когда они обмениваются ею с другими. Удивительно то, что ваш мозг совершенно необязательно рассматривает эту беседу как ",беседу» с книгой! С другой стороны, если стиль книги формален и сух, ваш мозг чувствует себя так же, как чувствуете себя вы, сидя на лекции в огромной аудитории, полной пассивных слушателей. Нет особой необходимости бодрствовать.

Но использование изображений и разговорный стиль изложения материала -это только начало

... вы здесь

29


как пользоваться этой книгой

ВОТ ЧТО мы делаем Мы используем изображения потому, что мозг предпочитает изображения тексту. Ваш мозг убежден, что изображение стоит тысячи слов. А когда мы используем изображения вместе с текстом, мы встраиваем этот текст в изображение потому, что мозг работает более эффективно, когда текст находится вн,утри того, что он описывает, а не в заголовке или где-либо еще на странице. Мы используем избыточность, повторяя одни и те же вещи разн,ыми способами и с разных точек зрен,ия, чтобы увеличить шансы попадания информации более чем в одну

область вашего мозга.

Мы подаем понятия и изображения в неожиданном виде потому, что ваш мозг обращает внимание на все новое. И мы стараемся придать изображениям и понятиям

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

мозг более восприимчив, когда он считает, что вы участвуете в беседе, чем когда

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

Мы включили более

80 nрактичес1CUX упражнений потому, что ваш мозг лучше

воспринимает информацию, когда вы что-то делаете, чем когда вы читаете о том,

как это делается. И мы делаем упражнения хотя и СЛОЖНЬП\1И, но выполнимыми, потому что это мобилизует людей на их решение. Мы используем разнообразные способы обучения потому, что вы, возможно,

вначале понять общую картину, а третьему лучше просто разобрать практический предпочитаете изучать материал шаг за шагом, в то время как кто-то другой хочет

при мер. Но, независимо от предпочтений, любой человек выиграет от подачи материала разными способами.

--./fio;f08cff!, 11ЬС f;U I1 311\:01

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

изучения может быть более продуктивным в течение более продолжительного времени .

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

Мы включили nроблемн,ые задачи и вопросы, которые не всегда имеют прямое и простое решение, потому что ваш мозг настроен на лучшее понимание и запоминание, когда

он должен поработать над чем-либо. Подумайте об этом. Вы не сможете обрести фигуру атлета, н,аблюдая за людьми в тренажерном зале. Поэтому мы приложили все усилия

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

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

Мы описывали людей в историях, упражнениях, изображениях и т. п. потому, что ...

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

30

вступление


вступление

А вот то, что вы можете сделать,

чт06ы ваш MOJr слуwался вас Итак, мы свое дело сделали. Остальное

-

за вами. Эти советы

-

начало

пути; прислушивайтесь к своему мозгу и старайтесь понять, что

он воспринимает хорошо, а что

/3btре ЖЬYf\е ЭYf\О tA flрщлейYf\е

-

не очень. Пробуйте разные способы .

___ ._I__I_I_I_I_I_'_~__~~~~_~_~~~:~~_~о~~э~~~~к~~ ________________________________________ _ Не спеwите. Чем 60nItwe в... будете

понимать, тем

MeHItwe

вам придетс.

Разговор возбуждает разные области мозга.

эапоминать.

Если вы пытаетесь понять или запомнить что-либо,

Не ограничивайтесь только чтением. Делайте

проговаривайте это вслух. Еще лучше, если

перерывы, чтобы обдумать прочитанное. Если вам

вы попытаетесь объяснить это кому-нибудь. В этом

встречается вопрос , не смотрите сразу ответ на него.

случае усвоение материала пойдет значительно

Попробуйте представить, что кто-то действительно

быстрее. Более того, не исключено, что вы совершенно

задает вам вопрос. Чем лучше вы заставите свой мозг

неожиданно поймете что-то, о чем и не подозревали,

думать, тем больше у вас шансов понять и запомнить материал.

В",поnн.Йте все упражнени •• Деnайте свои

собственн ... е примечани •• Мы вставили примечания, но если вы не будете делать

своих, это будет так, как будто кто-то другой делает вашу работу. И не ограничивайтесь простым чтением упражнений. Возьмите в руки карандаш. Имеется множество свидетельств в пользу того, что физическая

• •

активность в nроцессе обучения повышает степень восприимчивости.

Читайте раэдеn ... «Не б ... вает

когда просто читали этот материал

.

Приспуwивайтесь к своему моэry. Старайтесь понять, не перегрузился ли ваш мозг. Если вы начинаете замечать, что <1скользите>.>

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

сделать перерыв. Вы не сможете воспринять больше того, что способны. И простое механическое добавление материала сверх допустимой нормы не улучшит этот процесс, а вот повредить ему может вполне .

Привпекайте свои чувства.

rnyn ...x

Вашему мозгу необходимо знать, что это имеет

вопросов».

значение. Почувствуйте себя участником историй,

Все они имеют большое значение. Это не просто

приведенных в книге . Придумайте новые названия

примечания на полях. Это часть основного

к изображениям . Испытать неприятные чувства

содержания! Не пропускайте эти разделы.

от плохой шутки все же лучше, чем не испытывать

Старайтесь, чтоб... чтение книrи б ...nо

никаких чувств вообще.

поспедним ваwим деnом, перед тем как

Пиwите

в ... nожитесь спать. Иnи, по крайней мере,

Существует единственный способ научиться

поспедним деnом, требуlOЩИМ YMCТBeHHoro

программировать - проrpaммиpoвать, и как можно больше.

напр.жени

MHoro

кода!

И это как раз то, что вы будете делать на протяжении

•.

Часть процесса усвоения материала (особенно передача

Обсуждайте прочитанное вспух.

чтения всей этой книги. Проrpaммиpoвание сродни

его в долговременную память) происходит после

искусству, и единственный способ преуспеть в Э'юй о(тасти

того, как вы отложили книгу в сторону. Вашему мозгу

:заключается в обширной практике. Мы предоставим

необходимо какое-то время для обработки полученной

вам множество практических примеров. В каждой

информации. Если в течение этого процесса вы дадите

главе есть упражнения, имеющие проблемы в решении.

ему какие-либо новые данные, процесс прервется

Не ограничивайтесь простым чтением этих упражнений.

и часть информации 6удетпотеряна.

Вы многого добьетесь в процессе их вьmолнения.

Пейте воду. MHoro вод... ,

Мы вКJIIOЧИ.lIИ решение для каждого из упражнеl!ИЙ.

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

снижает способность мозга к усвоению информации. РН Р

М.

.

О.

Не бойтесь бpocmъ быcrpый взrляд на 3'п1 решеЮ!Я, если у вас возникли затруднения! Часто бывает достаmчно зацешпься за 'IT()-нибудь незначительное. Но старайтесь

решать задания полностью и самостоятельно, прежде чем переходить к следующим разделам книги.

yS L Эd.wYr\ еам gОjМО.ж.н.ос"УТ\Ь coa9a€a"YТ\b €е~-t)РUJ10.ж.ен.tAЯ ""А. tAМe)OW,tAe t)Р~К"УТ\l... Ческое jНJ.:IЧен.tле. Не задbt€ай"ут\е 3d.ZР)'Жd.Yf\Ь '~ вы здесь ~ , tA

w<

НJ.:I Рd.dОЧtAu eeд-cep€ep

tA

Iiро€еря"УТ\ь, о"УТ\крbt.€d.Я g ~рd.Jзере.

31


как nОЛЬЗ0ваться этой книгой

Read

те (Прочти меня)

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

И мы хотим подчеркнуть: начинайте сначала, потому что считается, что материал, изложенный в предыдущих главах, вам уже знаком.

Мы начинаем с изучения проаых проrраммных реwений и основных приемов работ... с базами данных. Затем мы рассматриваем бопее CJ10жные функции РНР и запросы

MySQL,

а в самом конце переходим к реwению наибопее CJ10ЖНЫХ задач.

Хотя очень важно создавать приложения, которые позволяют пользователям добавлять в него данные и извлекать их, прежде чем вы сможете делать это, вам необходимо разобраться с синтаксисом и РНР,

!1 MySQL.

Поэтому мы даем вам выражения РНР и

MySQL, которые вы можете проверить на практике. MySQL,

Таким образом, вы сразу же сумеете делать что-нибудь практическое, используя РНР и

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

MySQL.

Хотя мы смогли бы включить все выражения, функции, ключевые слова И запросы РНР и

MySQL,

мы подумали, что вы предпочтете иметь относительно подъемную книгу, которая научит вас

использованию наиболее важных выражений, функций, ключевых слов и запросов. Мы даем те из них, которые вам необходимо знать и которые вы будете использовать

95 % времени .

А когда вы закончите

изучать эту книгу, сможете вполце уверенно найти любую функцию, необходимую для включения

в ваше сногсшибательное приложение, к которому вы приступили.

f'/\btможем

Мы поддерживаем РНР

5

и

~_---- u.С\J ОЛЬ 3 0 €О:"tТ\Ь ?Н?4 \JPu. u.з~че.k:" егали применения любого

MySQL 5.0.

Так как многие продолжают пользоваться РНР

4 ,ы из 4, 5 и 6 кода, где это возможно. Мы рекомендуем вам 6 и MySQL 5 или 6 при работе с этой книгой . При этом

.71У\оо. ЮU.l.iЩ

специфического дЛЯ РНР

использовать РНР

5 или

вы должны

учитывать, что наш код совместим с более ранними версиями этого программного

€н.еся. н.еdолЬUlu.~ u.з ме н.ен.u.Я.

обеспечения.

€ liрu.€ез екнbtil € н.еЙ КОЗ·

Вам необходим веб-сервер, поддерживающий РНР.

oap(\1Y\t).1Y\ecb

Код РНР выполняется на веб-сервере. Вам необходимо установить

Кl(\.3зел~

Apache или

#<

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

MySQL или получить доступ к нему. 11 и 111 за инструкциями по установке и настройке веб-сервера РНР и сервера MySQL.

Обратитесь к приложениям с поддержкой

Мы испоп"уем

MySQL.

Хотя существует стандартный

SQL (Structured

Queгy

Language -

язык структурированных

запросов), в этой книге мы сосредоточились на конкретной его реализации для

32

вступление

MySQL.

С самыми

t)рu.лож е н.u.9.


вступление

незначительными изменениями код этой книги может быть использован в запросах к Oracle,

MS SQL Server, PostgreSQL, DB2 и другим RDBMS (Relational Database Management Systemсистемы управления реляционными базами данных). Если у вас возникнет необходимость соединения с одной из этих баз данных, вы сможете найти соответствующие функции и описание

синтаксиса РНР. Если бы мы поставили себе задачу описать все варианты синтаксиса для работы со всеми базами данных, объем этой книги был бы намного больше. Поэтому мы сосредоточились тС>Лько на

MySQL.

Практические эадания НЕ являются дополнительным материалом. Упражнения и другие практические задания не являются каким-то дополнительным материалом.

Это часть содержания книги. Одни из них даны, чтобы улучшить запоминание, другие - чтобы улучшить понимание, третьи помогут применить то, что вы изучили. Не пропускайте практические задаffИЯ: СдИffствешюе, что вы не должны делать,

-

это разгадывать кроссворды, но их решение

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

Избыточность не случайна и важна.

Одна из особенностей серии книг

Head First заклюtlается в том, что мы поставили себе задачу,

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

цели запоминание изложенного в них материала, но это не справочник

- это книга для обучения,

поэтому вы увидите, что некоторые понятия возникают на ее страницах чаще одного раза.

nримеры, приведенные в книrе, наcrолько малы по объему, насколько это возмож~ Наши читатели говорят, что их смущает необходимость пробираться через

200 строк

tJ ек 011') о pbt.e

' кода в поисках двух строк, которые им нужно понять. Большинство примеров в этой

lA.з Ilpu.Мefo€

книге настолько малы по объему, насколько это возможно для того, чтобы та часть,

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

Я€ЛЯ}O'rТjся. €tlолн.е Jd.€е.рще.н.н.btми.

€5'ед-tlри.ло,жен.u.ЯМlA, сtlосоанbt.Ми.

€bt.t)олн.я.уr\Ь

Мы поместили коды всех примеров и приложений на сайт, чтобы вы имели

эо€ольн.о сло,жн.bt.е

воаможность скопировать фрагменты из них в файлы своих сценариев, используя

Jd.Эd.'-!и..

текстовый редактор, или выполнить запросы в MySQL-терминале. Вы также можете

ваrpузить их на свой веб-сервер для тестирования. Вы найдете их в Интернете по адресу:

http://www.headfirstlabs.com/books/hfphp Упражнения под названием «Сила мысли» оставлены нами без ответа. Для некоторых из этих упражнений правильного ответа просто не существует, а для других часть

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

вы здесь ~

33


KOMDHaD технических рецензентов

Команда технических рецензентов

Джереми Ален является веб-разработчиком высокого уровня и обладает опытом создания веб-приложений с использованием самых современных технологий. Более девяти лет

он использует в своих разработках РНР,

MySQL, а также множество других языков программирования, программных интерфейсов,

средств разработки и операционных систем. Давид Брисгс

-

автор технической литературы

и специалист по локализации программного

обеспечения. Живет в Бирмингеме, Англия.

Когда он свободен от тщательного, педантичного разъяснения пользователям особенно сложных программистских приемов, для него нет ничего лучше, чем погулять по местному парку вместе

с женой Паулеттой и их собакой Клео. Уил Харрис проводит свой день, управляя отделом информационных технологий,

предоставляющим услуги на

4 континентах.

11

компаниям

Он является вице-президентом

филиала ассоциации PASS (Professional Association for SQL Server - Профессиональная ассоциация пользователей SQL-сервера),

Если Стив Милано не пишет код для компании

ТЬе Оау Job™ или не исполняет панк-рок со своей группой Onion Flavored Rings ( <!Цветущие кольца лука» ) в каком-нибудь душном подвале, он, скорее всего, про водит время дома со своим ноутбуком, не уделяя никакого внимания кошачьей компании в лице Ральфа и человечьей

-

в лице Бьянки.

Харви Квимен променял карьеру компьютерного программиста на академическую жизнь

с постоянными перелетами в окружении толп

папарацци. Он сейчас адъюнкт-профессор

университета Альберты, где читает курсы

лекций по киберкультуре, литературе ХХ века и веб-разработке, включая РНР и MySQL.

Лас- Вегас. Он любит проводить время с женой

Крис Шифлет

Хитер, своими прелестными дочками Марой

компании

и Элли, а также собакой Свайпером.

специалистом в вопросах безопасности. Крис

Стефани Лиз

признанный лидер в области безопасности РНР- и веб-приложений, известный блосгер

-

инструктор и веб-разработчик

в Сакраменто, Калифорния. Когда она

не расхваливает достоинства кода, разработанного в соответствии с требованиями стандартов, или не отлаживает компоновку найти ее за занятием йогой.

34

вступление

CSS, вы сможете

на сайте

- технический директор OmniTI, где он является ведущим

shiftlett. org,

-

популярный докладчик

на различных конференциях и основатель РНР

Security Consortium. Он автор книг Essential РНР Security (О'Рейли) и НТТР Developer's Handbook.


вступление

Гiiiiiiiiiiiiiiiiiiii;;;;;;;;;;;;;;;=~

_____

&лагодарность Наши реоакторы: Множество благодарностей Бретry Маклафлину за его бесценные архивные материалы, которые направили нас на правильный путь, и за его жесткую приверженность

к когнитивному обучению.

Эта книга не увидела бы свет, если бы не героизм, терпение и постоянство Саидерса КлеЙнфельда. Мы исключительно

благодарны ему за то, что ему всегда удавалось подхватывать мячи (или это были кошки?), которыми мы жонглировали, при случайном падении одного из них (а то и трех!). Мы надеемся, у него появился шанс положить ноги на стол на пару дней, перед тем как он возьмется за другой проект, не менее сложный, чем этот.

Команоа О 'Реили: Множество благодарностей Лу Барр за ее феноменальные дизайнерские

способности, которые придали этой книге такой вид.

Мы благодарим также Британи Смит за ее тяжелую работу в самую последнюю минуту и Катрин Маккаллоф за установку и настройку саЙтов. И Лори Петрики за ее веру в то, что мы сможем написать

еще одну замечательную книгу из этой серии.

ЛУ~FР И еще:

Наконец, огромная благодарность Элвису Уилсону за сбор и при ведение в порядок всех видеозаписей о похищении космическими пришельцами

на УоuТuЬе для главы

12. Великолепная работа! Особенно если принять во внимание, что он самый обыкновенный, пещерный главный художник

8ыздесь ~

35


J MoX}fU,1h,~

~U,З]-fЬ

~ ~~\U,u, с1h,~1h,u,Ч]-fЫ~ с1h,f~]-fU,Llbl -t-

'*

-+ Она жива

Вы создали замечательную веб-страницу, используя ее с помощью

CSS, но заметили, что внешний

HTML,

и украсили

вид вашего сайта не идет дальше того,

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

бы энать, о чем думает ваша аудитория. Но для этого вы должны предоставить посетителям возможность вносить данные в веб-форму. Вам также необходимо,

чтобы эта информация была обработана и передана вам. Похоже, вам нужно больше, чем просто

HTML, чтобы

поднять ваш сайт на уровень выше.

это новая глава

37


иногда одного HTML недостаточно

НТМL статичен и скучен Как мы хорошо знаем,

HTML исключительно удобен для создания

веб-страниц. Но как быть, если нам необходимы не просто веб-страницы, а такие, которые делают что-то? Предположим, вам необходим поиск в базе данных или отправка электронного письма ... Как быть в таких случаях? HTML терпит неудачу, потому что это в значительной степени статичный язык, разработанный, чтобы отображать информацию, которая никогда не меняется.

HTML uскл)Очu:mелЬн.о :i9 06е к.. есЛU €b!. XO"'il\U"IТ\e~ "- - - ~ce~o ЛUw.Ь 1l 0 KdJd"lТ\b

ФО"'il\О2.Рdq:JЩО c€oe~o

llu"Y!)OM~, н.о н.е слuw.ком IIОЭХОЭU"У!), есЛU

€b!. xo"Y!)u"Y!)e 1l0 0dЩd"У!)ЬСя.

с t\Oсе"У!)U"IТ\еля.мu €аw.е~о cdi1"'i1\d.

HTML-K0.9 ..7'Yr)иx С'Yr)fdн.цu, дbr.л

Сфор.муЛUРО€dн., KOZ.9<:1 €еd-llроzр~uс'Yr) СО.3.9d fJ'С\Л их.

13e.-cep€er

OZp<l""Чек Тf\~

чу!\О може"у!) ОдРd~d"У!)Ь1Йd"lТ\Ь

HTML-С"lТ\Рdк.tAu,bt "IТ\ОЛЬКО " _ \')ослеЭО€d"lТ\елЬн.о, оэi-tу за эруzоu.. Во многом проблема веб-сервера при обработке статичных НТМL-страниц заключается в том, что в этом случае он выступает в роли простого передаточного

механизма, и не более того. Браузер запрашивает страницу, сервер предоставляет ее , и на этом все

заканчивается. Чтобы превратить сайт в диалоговое

веб-приложение, веб-сервер должен выступить в новой, более динамичной роли, которую ему может обеспечить РНР .

38

глава 1

Нмes gело с чuстым tlfML, сервер npocmо 06раватывает статuчную

tlfML-cmранuuу

u,

таким 06разом. только

отosражает ее cogержанuе.

------


вдохните жизнь в ваши статичные страницы

~ С н.еdольшой

РНР оживляет веб-страНИ11Ы ..

t]О~ЩЦЬ}О

серберct.

РНР позволяет вам манипулировать содержанием

Вместе с РНР вes-cepвep

веб-страницы на сервере непосредственно перед тем, как она будет отправлена браузеру. Это происходит следующим

CnОСОБеН guнамuческu

образом: в процессе интерпретации РНР-сценария сервер

может изменить или создать любой НТМL-код. После этого

~gaвatnb

НТМL-страница отправляется браузеру, который не знает и не придает значения тому, что в модификации кода

ИfМL-cmраНUlJbl

HTML

на сервере принимал участие РНР.

?НР ~eH.epu.pje'W\ НТМ L-K03 .flrjLI.X c'W\pctн.u.u,

г

u. Може'W\ u.jMeKu.'W\b ег.о € jct€u.cu.мoc'W\u. 0'W\ лог.цки.

€еd-t1ри.ложен.u.Я.

. 'f~ ?Н ~ -cu,eн.ctpu.u. соэерJI(Д'W\ К4К tПМL-коэ, 'Yr\Q.K _

u. коэ ?НР. 1l0 слеэн.u.u.

дцн.ctМи. Ческu.е

НТМ L-с'W\рctн.u.u.,bt

О\1р€.эеля.е'Yr\, К4ки.е

и.,3Мен.5l}O'W\с5t

~

€ соо'W\€е'W\с'W\€и.u. . с I1p0ZPctММн.oU лог.u.коU

PHP-cцeКdpцe~ Ч'YI)о t)Оj€ол5t€.'W\ з оd и.'W\Ьс5t и.СКЛ}ОЧи.'W\елЬн.оU

~u.dl{oc'W\u.,

6аза даннь.х

MySQL

Мclн.u.\1УЛя.u,u.и. н.еодхоэu.МО I1рou.зеес"l'l\U. с НТМL-коэом.

РН? МОЖе"lY1 СОХр4КЯ"lY1Ь 34н.н.bte € dQj'y и. (А.J€лекct'W\Ь Щ, 4 'fТ\ctкЖе gс'W\ctgл5t'W\Ь

34 KKbte, и.J€ле Чен.н.bt.е u.j dQjbt, g HTML- K03,

KO'fТ\0pbtu он. г.ен.ерu.руе'lТ\. выздесь ~

39



вдохните жизнь в ваши статичные страницы

Форма помогает Оуэну разоОраться в этой истории Цель нового сайта Оуэна Al iensAbductedМe. сот (ПришельцыПохищалиМеня. сот)

-

связать Оуэна с теми, кого похищали пришельцы и кто мог бы пролить свет на исчезновение Фэнга. Оуэн знает, что ему необходима НТМL-форма, чтобы запрашивать у посетителей

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

I\oeмвчetкве првme.льцы ПОIИШIJIВ мео- с_щепе О ПОlИШеивв Расскажите вашу историю похищеиИ!l космическими приmельцами: Ими:

I')оле эЛ5l dЭресо.

лек"«\роkКОU l')оЧYtibt.

Фa.>otвnвJI:

Ваш адрес электроннОЙ пОЧТЫ:

Korдa это ПРОВЗО1DJlО? как дOJIl'O вы отсутствовали? СII>ЛЫro их было?

t'!ос е.,,«\u.,,«\е.Л5l.

~,.;;;=,.;;;=,--,.;;;=~~---&::-IТ---- Оуэн.у н.ужн.о

ot'ju.co.н.u.e. €н.ешн.е.г.о

оnиmиreих:

Что онн делали с вами?

Видели ли вы мою собаку Фэиrа?

€цзa. I(ОСМu.ЧескW< да е Нет е

1'1 рu.шельu,еg. оуэн. н.о.эее.,,«\с5l, Ч"Ir\О

K,,«\0-н.u.d.'i9 b o,,«\€e.,,«\ц,,«\

«эо.» н.ct gQl1?OC.

н.е €u.эе.л лu. он. Ф Эн.г.о. н.ct космu.чеСI(ОМ КОРd.дле t'\рu.шельu,е€.

L .. _ . . _ ..._" . __·...J) - - - - . - Л)Оdbt.е. 30t)олн.u.'У!1елЬНbtе t)°зроdн.ос'У!1Ц Можн.о ,3<::tll uc o.'Y!1b С)О3С\· хоЧе-rn \\олуЧU1У\Ь \')0 элек"«\рон.н.оU r,оЧm,е у€еЭО}"J1ен.uе, КаК 'VY\олЬко l')осе'VY\u.'VY\елЬ Caй'fТ\c!. O"«\l')pa.€u.,,«\

3d.\!олн.ен.н.у!О форму ко. cep€ep.

Что выдумаете по поводу HTML-формы Оуэна? Как вы думаете, может ли Оуэн столкнуться с какими-либо проблемами, пытаясь получить данные о похищениях космическими пришельцами, используя эту форму? Действуйте, изложите свои

соображения.

выздесь ~

41


НТМL-форма Оуэна

tСЛLt €aм н..еодхоэu..м.о €ct)oMtW:Yf\b, КаК СО.3Эd)O'Yf\Ся. HTM\..-форМbL,оdРФl\LtYl\есЬ

Формы пиwутся на НТМL Форма Оуэна «Сообщение О похищении»созданас использованием

К гла€е 1.4 юw.l.Lt Hea~

исключительно одних тегов и атрибутов HTML В ней имеются текстовые поля 11ТМ\.. with CSS & ХНТМ\...

firs-t:

для болышrnства вопросов, кнопки с зависимой фиксацией, 'Побы узнать, видел ли

Фэнга посетитель сайта, и область ввода текста для дополнительных подробностей. Оуэк. 11 0 ЛУ ЧLt"iY1.9 Ф-u-tb!.е, Форма также предусматривает отправку данных на адрес электронной по'Пы Оуэна. €fJе..9 е н.нl:я,е € q:юрму,

t:

()

«YI\аiЯ-t:о» -" ЭYl\О ilРОYl\ОКОЛ, ilо.3~оля.)OW.,Ltu.

ОYl\l')ра€ля.YI\Ь 1')0 элекYI\РОн.к.оu. t10Ч'Yf\е эак.н.bt.е, €€e.geк.н.bt.e g форм})

НCI Э"n) О"iY1 ~pec Эле.кYrIрок.к.оu.

I10~b!.. ИJмен.u."iY1е ег.о кd. c€Oй, ког..9а dY.9e."iY1 e "iY1eC"iY1Ltpo€a"iY1b

форму.

<р>Расскажите историю О похище~вас космическими при:mельц </Р>3НАче~е Э'Yr\ог.о t)araмe~ ~ < orm method="post ~tiOn="mailtO"owen@aliensubductedme. сот"> г,о€орLtYl\ серверу, каК / /

<label <input <label <input

fоr="firstnате">Имя:</lаЬеl> type="text" id="firstnaтe" name="firstnaтe" /><br /> for=" lastname" >Фамилия: </label> type="text" id=" lastnaтe" naтe=" lastnaтe" /><br />

<label

fоr="еmаil">Ваш адрес электронной почты:</lаЬеl>

<input type="text" id=" email" <label

naтe="

email" /><br />

ОYl\t)равля.YI\6 эак.н.bt.е.

Он..мо.ж,еYl\ I')РШ'i.tLМdYl\Ь

JНАчеJ-Ф.Я. «~st»

IAЛLt «эеi:». Ь1.0dъя.с~ D.-I7.~lJ\J МеЖЭУ ~Lt ,'V-7,)

н..е.м.rtol.О l')o.3эк.е е .

Тег.Lt (i l1 put>

fоr="whеnithарреnd">когда это произошло?</lаЬеl>

<inp~tYPe="text"

id=" whenithappend"

<label for="howlong">KaK

долго

fоr="hоwmаnу">Сколько

<input

ty~"text"

<label for="

whenithappend" /><br />

ВЫ отсутствовали?</lаЬеl>

<input type="text" id=" howlong" <label

naтe="

naтe="

howlong" /><br />

их было?</lаЬеl>

id=" howmany"

naтe="

СООдЩа)ОУ!) форме,

Ч'Yf\О J.g ecb ду.9У"1У1 €€O.9 Lt"iY1bc 51. .9aннbte .

A-tnРLtdУ"1У1 type СООдЩа е"iY1 форме, Ч'Yf\О JэесЬ dY.g e "iY1

€€еэен.. 'Yf\e.KC'Yf\ (t1PLt ег,о 3Нс1Чен.u.Lt «text»'), аliеndеsсriрtiОn"·sizе="З2" /><br />

howmany" /><br />

аliеndеsсriрtiоn">Опишите их:</lаЬеl>

<input type="text" id=" aliendescription" <label fоr="whаtthеуdid">Что они делали

naтe=" с

вами?</lаЬеl>

<input type="text" id="whattheydid" naтe="whattheydid" sizе="З2" /><br /> <label fоr="fаngsроttеd">Видели ли ВЫ мою собаку Фэнга?</lаЬеl> Да Нет

<input id=" fangspotted"

naтe="

<input id=" fangspotted"

naтe="

fangspotted" type="radio" value="yes"/> fangspotted" type="radio" value="no"/><br />

<img src="fang.jpg" width="100" height="175" аlt="Моя похишенная

<label

собака Фэнг.">

fоr="оthеr">Дополнительная информация:</lаЬеl>

<textarea id=" other"

naтe="

other" /></textarea><br />

</f:~:~; type="sabmit" vаluе="СООбще~ о похищении" naт\submit" />

Фор.мс. ог,ран.u.чеНcl 'Yf\eг.aМLt 42

<for'Yf\>.

глава 1

Кн.Оt)Кd «Сооdщек.Ltе о t)ОXl.tщек.LtLt»

{

O'Yf\Kpbt.€a)OW.,u..м. Lt .3d.KpbL€ajOi..JJ..u..м. НLtкаlЩХ н..еОЖlA.9а к.к.оС'Yf\ео. э'Yf\О .100%-0. КО.9

HTMU

-

соо~щае"iY1 форме, ~o

к.ео хоэ~о 06pa60"iY1a"iY1b u. O"iY1t)Pd~u."iY1b .9aнн.bLe кd. cep€ep.


вдохните жизнь в ваши CmDтu.,HbIe CтPDHuqbI

eCT-.lI.райВ----ИcnыrаЙТ8 форму «Сообщение О похищении». Загрузите страницы .Сообщение о похищении~ с сайта по адресу

;,-.,-w. headfirstlabs . com/books/hfphp. Этот код находится в каталоге chapterOl. Этот же каталог содержит файл ::eport . html с веб-формой Оуэна, а также каскадные таблицы стилей (style. css) и изображение Фэнга (fang. jpg). Откройте файл

report . html

в текстовом редакторе и измените

.ирес электронной почты Оуэна на свой. Затем откройте

страницу в браузере, введите в форму какую-нибудь информацию Q похищении космическими пришельцами и нажмите кнопку 4

-

Сообщение о похищении •.

..

---

....

~

д

..

"

~

;.:

~..

=

""........."""

:<"

... .,.,

~

};{<:,«;':'

,

,

-::;,

~8WCQ_D. .~.~~~ п~е~~~

-.-:

........ -:

..., .... ..-1

'-_"~? ~-= _ _ c.-t

~

l8E8 _ .. _Ca6IaY Ф31n?

Дао H~$

ФctК'VY\uЧескu OlY\t'\Pd€Kct Оуэк.у к.е. СОС'VY\оu1Т\СЯ ЭО

'VY\ex

IIOР. I10ка

t'\осе'VY\u1Т\еJb CdU'VY\ct €ручк.уto

к.е 01Т\t'\Рd€U1Т\ Э'tт\u эоgольк.о С'VY\pctк.к.о €btzляэящuе Эdкн.btе. Итак, как вы думаете, придут ли даиные обработки формы в виде электронного письма на ваш почтовый ЯЩИК?

вы здесь ~


отправка по электронной почте

=плохая идея

у НТМL-формы имеются ПРО(iлемы Форма Оуэна «Сообщение о похищеНИИ$> выполняет свою задачу, но он не получает достаточно информации от посетителей саЙта.

Может быть, похищение Фэнга является исключительным случаем ... или что-то не так с формой? Давайте посмотрим , что говорят посетители саЙта.

110сле mofo как Я нажала кнопку, открыласl> МОЯ nочто"ая

о

О

о

nРО'1'амма Outl.ook. Но " HeU не Оыло нцчеfо mOfO, что Я ""оицла " 9'JOрму " теченце nослeUнц)( 15 мцнут.

у меня открылось иля заnолненця

о

пустое электронное nцсьмо. ~ce мои от"еты, которые Я так старательно ""оицл

"форму, оылц nроцnюрцро"аны.110)(ОЖе,

.

......-~--- ~~.-

..

..........-:

~ """,~-.~-- --

-...

кто-то nо)(цтuл эту fЛупую форму.

s-,..ос. -'jICOCIOCIiI _:

1(fc;o. Y.~"""'_?

о

КaIt}Що') "';nCJ:'~

<,_ .. 6,.a::I'!

НuчеfО не nроц;мuло, потому что

.......:

у Moefo ораузера нет nочтО"ОfО клцента по умолчанцю

...

что 01>1 это нц 0значзло.

о

Что происходит? Есть ли у вас какие-нибудь соображения о том, как исправить форму?

44

глава 1


вдохните жизнь в ваши статичные страницы

о Q

Да. Код НТМL-формы безукоризнен, но

mailto

не является

удачны M способом передачи данных формы. Форма Оуэна абсолютно совершенна до тех пор, пока посетитель сайта не нажмет кнопку «Сообщение о похищении». С этого момента вы полагаетесь на

mailto

в вопросе включения данных

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

И уж совсем неожиданный поворот событий ... Посетитель должен сам отправить это письмо, чтобы данные попали к вам! Таким образом, вы не в состоянии управлять процессом отправки электронной почты, в результате чего данные могут успешно пройти свой путь из вашей

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

неудачу. Не слишком-то хорошо.

Вам необходимо управлять процессом передачи данных, введенных в веб-форму. А конкретней, вам нужно, чтобы РНР упаковал данные в электронное письмо и подтвердил факт их отправки. Это требует переключения вашего внимания от клиентской программы

mailto

(HTML,

и т. п.) К серверу (РНР).

'\

Форм Fd.oo!1\d.e!1\

;:m ан ....... с...а

............ _-.,.-.,

Iipekpd.Cl-lO, tl0Kd. к.е НджмеYf\е KttOt)KY

ebt,

«Соодщек.u.е о t)охu.щек.u.u.».

~~~;~~~~~ :~~~. ~ ~~ ........ , --. _ _ _ : ...

...

...

.... .... "

вblздесь ~

45


исполнение кода на клиенте против исполнения кода на сервере

НТМL-КОА интерпретируется на клиентской программе Форма Оуэна написана на чистом

HTML с атрибутом act ion,

имеющим значение

mai 1 to,

в результате чего после обработки формы осуществляется попытка отправить данные через

электронную почту. И хотя веб-страница report . html приходит d d.ei'l) с веб-сервера, данные вносятся в нее и обрабатываются исключительно 3э есЬ рс!. Oi'l) на браузере посетителя саЙта. I\ро~рdММJ-lOе ОdеСf)еЧекuе

11

о. 111'

eea-cepee~c!. О\JЭн.d., , .) d. же u. eCi'I)к.o e

Ul.lJлum пожал йста .

е, о У,

~eE-cтpaHицy уэна

//;. <'

о Браузер запрашивает веб-страницуi'l) К Оуэна, которая включает форму.

,..

,,\...UooU.\etiueo noxuU.\eHuu),.

" ••3

8 11...,. vbI зuесь.

О,ш""'М

I\~ н.d......,·,eк.O{)<..\T,"",,," U"CD ~ VL.I.

О

О

nPO~PQ.ММd.­ др~~зе.р,

PddOi'l)d. }ОШ,dя. Нс!. еС\ще.м KOMllbfOYt\e.pe., u.,3ee.c"Yr\f{d. "Yr\С\КЖе t"jo.9 Н.I~зgd.н.u.е.jЛ КЛИIН1

Сервер присьшает НТМL-код этой страницы.

Посетитель сайта заполняет форму и оmравляет ее .

программу электронной почты, установленную на компьютере

посетителя саЙта .

Программа электронной почтысоздаетсооб"-ение

Ce.p€ep

с данными формы, но только сам

к.е IIpu.к..u..м.cIe"Yr\

пользователь компьютера может

КUKd.KO~O Y'-Id.С"Yr\u.я.

послать это сооб"-ение Оуэну.

€ Odpd.dO"Yr\Ke

Роль сервера в этом случае сводится лишь к передаче веб-страницы браузеру.

Когда посетитель передает формы на обработку, браузер (клиент!) использует программное обеспечение компьютера, на котором он установлен, чтобы решить вопрос, как отослать данные через электронную почту . Сам клиент не имеет

возможности пересылать данные

46

глава 1

-

это работа сервера.

Эd.нН.bu< €eд-cpopMb!. с d.i'I)pU.dj"Yr\OM d.ctiOIl:· u.Ме}ОШ,u.М .3н.d. Чекuе

i'l)d.i~tO.


вдохните жизнь в ваши статичные страницы

РНР действvет на сервере ?нр дает возможность манипулировать данными, введенными в форму =осетителем сайта, отправляя их вам через электронную почту совершенно

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

'2.Жимает кнопку ~Сообщение о похищении. - и все готово! РНР-код :'L1З..]ает электронное письмо, отправляет его вам и генерирует веб-страницу

:

:Ю.1Тверждением отправки для посетителя саЙта.

>-

о Браузер запрашивает веб-страннцу Оуэна, которая ВКJIIOчает форму.

l1PUUJлumе, t10жалуuсmа, ~е8"-сmrаиuц Оуэна «CoooU.\e.t1ue о t1oxuU.\e.t1uu)).

00

Сервер прнсылает НТМL-код этой страницы.

о Посетитель сайта заполняет форму н передает ее на обработку РНР-сценарию

<form action = "report.php" . ..

о

с подтверждением

Сервер оmравляет НТМL-страннцу

с подтверждением браузеру.

0 . ..,.1'8 noзициlO, соответcrвующую учаcrнику "iopcwwy принaд.nеJКИТ РНР-сценарий:

D Клиент

[]

Сервес

D Оба

процесса,

D Ни тот, ни другой

-

и оmравляет данные Оуэну

.

Оуэн..~ г.~р~н.lТ\u.ро€~к.оу I)олуче.н.u.е хорошо

ОlТ\ФОРМQlТ\u.РО€~НJ-\.Oг.о элекmрон.н.ог.о l)u.cbМct.

выздесь.

47


РНР -

это серверный я3ы K

РНР-сценарии интерпретируются на сервере РНР-код интерпретируется на сервере . Он сохраняется в РНР-сценариях, которые чаще

всего имеют расширение имени файла РНР. Эти сценарии часто выглядят так же, как и обычный

HTML-

и сss-код. Фактически результатом процесса интерпретации сервером

РНР-кода является чистый

HTML-

и сss-код. Поэтому каждый РНР-сценарий в конечном

счете после окончания исполнения его на сервере преобразуется в

HTML и css.

Давайте посмотрим внимательнее, как РНР-сценарий изменяет порядок обработки веб-формы Оуэна.

Брауаер аапрашивает НТМL-страницу, в данном случае

-

форму Оуэна ~Сообщение о похищении •.

------~------~ reporthlml

О Сервер прнсылает HtML-страницу.

НctЖ4)'!]u.е кн..ОI1Кu. «Соодщен.u.е

_•••~~'! О'У!)t)рctеля.е'У!) .9ctн.нЬt.e фоР,N'.l:я . t)охu.Щен.u.u.» 11 0.9'У!)ееРЖ.9ctе'У!)

PHP-сu,ен.ctрu.1О н.ct се.рее.ре.

О Посетитель сайта ааполняет форму и подтверждает это нажатием кнопки

~Сообщение о похищении., в реаультате чего брауаер передает данные РНР-сценарию на сервере.

48

глава 1


вдохните жизнь в ваши статичные страницы

РНР

-

это серверньш ~ nporpaммupooaНU9.

Сченарuu. нanucaHHble на нем. uнmepnpemuруюmсэ на 5е5-СеРВеРе. о Сервер присылает НТМL-страницу, сгенернрованную РНР-сценарием.

о Браузер отображает веб-страницу подтверждения.

hц .... - -• ....,.-Оt08.~fМ)II\:~'~II_

Qw~IП:

.......

........... _COIIII8I)I.~н.с-. -..........-:~-

1l0сеYl\U,YI\елЬ cctu.YI\ct У о Сервер ннтерпретирует РНР-сценарий, который оmравляет

€u,эu,YI\ €ед-СYI\ Pd.Ku'u,~ I)0ЭYl\€е ржэе.к.u.я.·

3.1ектронное письмо и генерирует

НТМL-страницу с подтверждением.

Электронное письмо поступает

в почтовый

ящик Оуэна.

Оуэк. t)олуЧctе1'Т)

Эле К1'Т)роиное ~ t)tAcbMo.

выздесь ~

49


атри6ут формы o<tion

Атрибут форм...

action обеспечивает е•• з.. форм... • .,.•• е.. тем Эllементом, котор",й сценарий, KorAa форма передаете.

с РНР-еценарием,

запуекает

на обработку. Формы создаются с использованием

HTML-Tera <form>,

и у каждого тега <form> имеется атрибут action. Имя файла, которое вы присваиваете в качестве значения атрибута action, используется сервером для обработки формы после подтверждения ее заполнения. Поэтому если имя РНР-сценария Оуэна

report . php, то атрибут act iоп-тега < form>,

который связывает

сценарий с формой, будет выглядеть так:

method = "post">

<form action =

Когда посетитель сайта нажмет на форме кнопку «Сообщение о похищении~, установленное значение атрибута формы

приведет к тому, что файл

report. php будет запущен

для обработки данных.

<р>Расскажите историю о Похищении вас космическими n~~ми~<~(~р>~==~~~___________ <formmethod=*post .. action- "report. PhPO;;:> <. а е

for-·firstпamе">Имя</lаЬеl>

r----

<~nput type="text" id="firstname* narne="firstname"

50

глава 1

I><br />

action

на сервере


вдохните жизнь в ваши стати.,ные CтptlHUqbI

lf~ 8ыi~'t1l,

gV't1blX ~0't1l'0CO~ 1}: Что означает РНР? О: РНР - это аббревиатура, которая вначале 0значала Personal Home Pages (персональные домашние страницы). Позднее значением этой Hypertext Preprocessor (РНР: обработчик

аббревиатуры стало РНР:

гипертекста). Последняя аббревиатура рассматривается как рекурсивная, так как она ссылается на саму себя

-

аббревиатура

в аббревиатуре. Умно? Запутано? Решайте сами!

1}:Даже несмотря на то, что мой брауэер показывает, что ИМJI

~ веб-страницы оканчивается на .php, она все равно явпяется HTML-страницеЙ. Как такое может быть?

О: ЭТО возможно потому, что страница первоначально создана как РНР-код на сервере, но пре06раэована в

HTML-KOA перед тем, как

была отправлена на браузер. Таким обраЗ0М, сервер интерпретирует РНР-код и конвертирует его в НТМL-код перед тем, как оmравить его

браузеру для просмотра. Это 0значает, что хотя .PHP-фаЙЛ содержит РНР-код, браузер никогда не видит этого; он видит только HTML-KOA, который появляется в результате исполнения РНР-кода на сервере.

1}:Но ра38е не все веб-страницы со3ДI1OТCЯ на сервере, даже страницы на чистом НТМL в HTML-фаЙllах?

О: Все файлы сайта сохранены на серверах HTML-, (55-, РНР-серверах и т. п. Но не все они интерпретируlOТCЯ на

этих серверах. НТМL- и (55-файлы, так же как файлы изображений, сервер пересылает браузеру непосредственно, не обращая ни малейшего внимания на то, что в действительности в них

содержится. РНР-файлы отличаются тем, что они содержат код, который интеpnретируется на сервере. Брауэеру отправляется не сам РНР-код, а реаупьтат его исполнения, который является чистым

HTML и (55.

8ыздесь ~

51


вDШ первый РНР·сченарuU

Мспользуйте РНР ДЛЯ доступа к данным формы Итак, Оуэну необходим РНР-сценарий, чтобы процесс получения

:7mO 6'r:олн.е

данных формы о похищении Ilришельцами был более надежным, чем при

ЭОliУС)'ljlAJ\l\О ЗЛ5/.

использовании та i

1>HP-сu,е.МрlA5t -

1 to.

Давайте создадим его. Не беспокойтесь, если что-то

6'КЛ}оЧd)'ljЬ одbtЧн.btе.

вам пока не понятно. Мы разберемся.

HTML-)'Ijezu. u. C\mpu.dYl1lbt.

~<html> РНР-I(О.9 Чо.с1Т\О

НдЧu.Нде1Т\С5/. 1Т\оЧн..о

)'IjC\K

j

<head>

<tit lе >Космические пришельцы похищали меня -

сообщение

о п охищении </tit lе >

ВесЬ

~e, каК

</head>

НТМL~pctкuup.

Cl.l,e.Mpu.9_ -

<body>

J)'IjO

< h 2>Космические

пришельцы

похищали

меня

-

о похищении</h2>

сообщение

J)'IjO)'lj

дЛОК

?JЧP -КОЗ···

Все. ОС1Т\(1ЛЬкое

одbtчкbtй

~

..-

IOML.

в J)'IjOM

Bo)'lj д.9есЬ

Фро.zмен.)'Ijе.

ндЧu.НД}O't!JС5/.

Pt1P- коэс\

u.K)'Ijepe.cн.bte

с Чu.)'IjbtЕ;'d /Oi'I1 С51

6'ещu.: Ji'r)O

.9dHHbte. ФорМbt., 'hr\ Одь!, о н.u. Моzлu. dbt)'ljb 6'bt6'e:g e Hbt k.C\ эк рС\н. КаК

НДЧС\ЛО

PHP-КОЗс.\·

ЧQСi'r)Ь С)'ljРС\k.Ш;,to_

t)ОЗ'YrI 6'ер.ж.зе.н.u.51. 3зесЬ МЬ!. u.Сt)ОЛЬ.31е.м.

рнр, 'hr\Odbt

сzекерu.рo6'Ф"f\Ь HTML-K0.9 u.,3 .9C\к.н..bt.x форМbt.. </body> </html >

~_ ТС\к.же КаК u. оdbtЧН,d5(

€еct-сmрdн.u.up,J)'IjО)'lj ?H?-сu,емрu.u.

jdкС\н,Чu.6'С\е1Т\С5( .3С\крbt1Т\u.е..А'\ O·i!'!Kpl'?1..)'Ijbt,x НТ/Ч.-)'Ijег.о€.

52

глава

1


вдохните жизнь в ваши статичные страницы

--Тест-драйв Внесите изменения в форму Оуэна с испоnltзованием РНР

ДАя обработки данных формы. Создайте новый текстовый файл с именем

report . php и введите весь

текст предыдущей страницы. Это сценарий, который будет обрабатывать веб-форму Оуэна. РНР-сценарий пока не подключен к форме, поэтому откройте файл

::-eport . html в текстовом редакторе и измените атрибут формы act ion с :nai 1 to на report . php. <form action

method

=

"post">

Откройте страницу report . html в браузере, введите в форму

какие-нибудь данные о похищении пришельцами и нажмите кнопку .Сообшение о похищении!>.

~ ,3d.€u.Сш.\ОС"Yr)u. o"'tТj €d.ше.г.о д~d.,'jзер'd. €b!. МоЖе"'tТjе. yts"u.зе."'tТjЬ €еd-С"'tТjрd.l-lliu,у с Кd.I{ш.\-"'tТjО C"'tТjpd.кн..bt.м

I8cмJlчеасм Dр.lIeJIbl~IoII10111D11J111--~ 0 " " " p~ вашу нcropиlOl1OXIIIЦCIIИI~ ~

"'tТje.Kc"'tТjOM u..лu., gозможк.о,

Эd..же. "poc"'tТjO repor·t.f*'p сu,е.Нdрu.я..

И",,: Фами.'IIII:

Ваш адрес элcю:poнкoIi DО'ПЫ;

Когда m> npowooшo? как дoпro вы oтcyrcnoвanн? clloJlыll IП бblJlO'! 0maпиIc"";

Чro оки ДCDaJUI с IIIDOI? ВJЩeJIИ JIН ... JIOIO ooбaJ<y Фэига'/

Как вы думаете, так и должен интерпреmроваться РНР-сценарий? Напишите, почему да или почему нет, и что, по-вашему, происходит.

выздееь ~

53


размещение РНР-сценария на сервере

РНР-сценарий должен размещаться на сервере

Если на вашем локальном компьютере нет работающего ~ Еслu. кд €ctшем

сценарий report . php не будет исполняться, когда вы нажмете кнопку «Сообщение о похищении>.> на форме. Не забывайте: РНР - это язык программирования, и ему необходимо окружение, в котором он будет интерпретироваться. Этим окружением является веб-сервер с поддержкой РНР. ДЛЯ того чтобы РНР-сценарий делал то, для чего он предназначен, он и веб-страницы, которые используют его, должны

лок<UJbк.ом KOМllb)01\')epe

'уС'Yl1ctн.о€лен. €eд-cep€ep u. 011. 1'l0.9.9ер.жи.€ctе'Yl1 рнр, 'YI10 ~bt МОЖе'Yl1е 11 PO'Yl1eC'Yl1u.po€ct1'f1b PHP-сu,е Н4 РШJ..

размещаться на реальном веб-сервере. Непосредственное открытие сценария в вашей локальной файловой системе в отсутствие веб-сервера не приведет к ожидаемому результату.

~ О'Yl1 л u.Чu.е. 01Т\ HTML-с1Т\Рctrшu,.

КО1Т\орbLe мог.'j"fI дbt1Т\Ь 01Т\крbt1Т\bt лоКctЛЬt-W

. dpctYJe.pe., PHP-c~e.кapu._u

€сег.,9Q 90лж.ен. «О1Т\крbtИQ1Т\Ь(51))

&раузер ничеrо

<.Jер ез VRL ка c.ep€epe..

не знает О РНР и поэтому не имеет возможности интерпретировать

РНР-сценарии.

для dрct'уз е рct _____ .7'Y110'Y1J PHP-сu,е Н4 рu.й €c.eгo лu.Lt.(!; Н4дОр dессМL"'Lсленн.ог.о K0.9Q•

~eд-c.e.p€ep t)ol-lU,Мctе1Т\

.7'У1101Т\ РНР-КО,9 ~

u. мож.е1Т\ €btI"\ОЛrtU.'YI1Ь с~е.каршl.

Ве6-сервер... с поддержкой РНР MOryт интерпретиро.атlt РНР-сценарии

и пре"разо .....атlt их в НТМL-страницw, пон.тн ... е

Дn. 6рауэера.

PНP~puu gоАжны1 Uнm.epnpemup058.tnbCS

- sygym

на ~ uначе oнu не

-~-----5bтOA1ВtТ1b

С6ОЮ функ:uuю.

54

глава

1


вдохните жизнь в воши статичные страницы

Поместите {(вои РНР-сценарии на сервер Совершенно нормально, если вы создаете и редактируете свои

РНР-сценарии на локальном компьютере. Но вам необходимо переместить файлы на веб-сервер, где они будут интерпретироваться. РНР-файлы часто размещают на сервере вместе с НТМL~файлами,

и в этом нет ничего таинственного. Для загрузки файлов на веб-сервер требуется соответствующая утилита, например

FTP.

БоЛЬwцн.с1Тl€О РН Р -cu,el-ld.pue€

ОI(4,3Ьt€сно'll'\Ся.

РcIJМещеННbt.м.ц

I-ld.

€eд-cep€epe

€Mec1Тle с .9Pyг.u.мu.

фctйммЦ.

Одной только загрузки ваших РНР-сценариев

недостаточно. Этот веб-сервер должен также поддерживать РНР. Некоторые серверы включают такую поддержку по умолчанию, некоторые

-

нет.

Не 8ы~аИh,

Z'if11blX ~011YOCO~ 'f?: Как я узнаlO, ycтaHoвneH РНР на моем сервере ияи нет? О: ВЫ можете спросить веб-администратора - своего или хостинговой

о

t~~

ЕслнРНР не установлен на вашем

веб-сервере, обратитесь к Прнложенню

В нем вы найдете инструкции,

компании либо провести тест самостоятельно. Создайте текстовый файл

как установить и запустить РНР

с именем

на вашем веб-сервере.

t es t . php и введите в него следующий

код:

<?php phpinfo();

11.

Не дqдуэ.Ь"Yl\е Y.9cV1U"Yl\b cu,eкo.puu r+-о.il1fоО 110 окон.чаtшц €ащег.о

?>

А теперь загрузите файл test. php на свой веб-сервер и введите его URL ~~С"Yl\u.ОО€Qки.Я., Ч"YI\одbt. tшК"YI\О в адресную строку вашего браузера. Если на вашем сервере установлен г.ой' н.е смОг. €ОСI1 0лЬ,30€а"Yl\ЬС51

РНр, вы увидите большое количество детальной информации о РНр,

включая его версию. Вы сделали зто!

"..;:-

-

эру

• ' - - ~"YI\Ou u.l-lrhоОМdu,u.еu .

.,. ,

выэдесь.

55


проведите тест-драйв своего РНР-сценария

-Тесу-драйв Эаrрузите фаЙn ... «Сообщение о похищении» на веб-сервер и попытайтес .. открыт .. форму ••• опят ... Загрузите

report. html, report. php, style. css

и

на веб-сервер, который поддерживает РНР. Введите

fang. jpg

URL страницы

report. html в адресную строку своего браузера, занесите в форму данные о похищении космическими пришельцами инажмите

кнопку <iСообщение о похищении!>.

Хоеоческве upllJllUWlbl JЮIl1щалв неа - еоо6щеnе е вв_щеn. Рассta)Jl;Иro вашу иcrop!JЮ ПОХfllllCllllJl КОСМИЧСCJQIМИ nPИШeJJЬоамн: И".: Фа_и:

ваш адрес эnепронноll ПOЧThl:

Кorдa:rro npoюoшnо'!

Ка. ДQJ\lo вы oтcyrctIOвa1lll'l сlOПЪJф IU. РЫдО? Qnишнтеих:

Что они дeJI8.'П! С вами'!

в_ ли вы""Ю собаку Фзиrа?

K_.'IeCIClle ПР.DJев~1IЫ ПОIНЩIJПI иен -

сообщев __ о ПОП_ВIIJI

вы были II<IIOIЩeJIЫ В IЮIбpe I1p01WIОЮ года И orСУn:Т808аЛИ в течение '11 часОВ. 0nи1lDfГe юс:

lIидеnв Л. вы IoЮЮ собаку Фэнra? [fet

118,. IIJtpeC :mcrrpoмвоЯ ""',.,'Ы: "1ti:t@1hC}'llOlllygreen.com

56

глава 1


вдохните жизнь в ваши статичные страницы

l<pymo!f"el1erb (1,се, чmо (1,ам нужно, - зmо mолько UОда(1,цть HeмHOrO fНP-KOUa, который 110~отцтС51 о "ересылке uанных срормы 110 злекmrонноu 110чmе.

Правияьно. В сценарии

report.php

все еще

отсутствует код пересь.яки по эяектронной почте

Оуэну данных о похищении космическими пришеяьцами.

Но это не проблема, так как РНР предлагает функцию (встроенный в язык фрагмент многократно используемого кода), которую вы можете использовать для отправки

электронного письма. Все, что вам необходимо,

-

это определить, что это сообщение должно содержать, а затем создать и отправить его с помощью РНР .

1l0cmoume! Мы, mолком eu.le не ,на51, как раО'отает l1ер(1,оначальныu (1,arl,aHm сценаРЦ51 rep0rt·rhr, ~eraeм ~erw, (1, Одласmь отl1ра(1,кц злекmrонноrо I1цсьма. Не СЛUUJКом лu мы mOrOl1UMC5l1?

Это верно. Решение бояее СЯОJКных задач с помощыо РНР требует 6ояее

rяубокоrо

ero

изучени".

Поэтому, чтобы добаlJИТЬ к сценарию Оуэна

report . php функцию

отправки электронных

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

вы здесь ~

57


как РНР-код nрео6разуетСR в

HTML

Сервер прео6разует РНР в НJML Для того чтобы взять в толк, как работает РНР-сценарий, нужно понять, что с ним происходит, когда он интерпретируется на сервере.

Большинство РНР-сценариев содержат как РНР-, так и НТМL- код .

РНР интерпретируется и преобразуется в отправляет законченную работу (в

HTML перед тем, как сервер HTML) браузеру. В сценарии Оуэна

report . php РНР-код генерирует большую часть HTML-контента в теге <body> страницы подтверждения. НТМL-код вне этого тега остается без изменения.

Cep€e?, u.Нo'"I'I\epllpe'"l'l\u.pye'"l'l\ .7'"1'1\0'"1'1\ РНР-КОЭ

сс·')бщ(.:ЕИf:~

u. г.ен.ерируе.;n НТМL.-КОЭ, соэер.ж.аw,u.u Эd~,

KO'"l'l\0pbte дbtЛu. €€еэен.bt. € форМ} .

$when_it_happened = $_POST['whenithappened']; $how_l ong = $_POST['howlong']; $alien_description = $_POST['description']; $fang_spotted = $_ POST['fangspotted']; $email = $_POST['email']; echo echo echo echo echo

'Спасибо за заполнение формы. <Ьr /> '; 'Вы были похищены ' . $when_it_happened; ' и отсутствовали в течение' . $how_long . ' <br /> ';

'Опишите их: ' . $alien_description . ' <br /> '; 'ВИдели ли вы МОЮ собаку Фэнга? ' . $fang_spotted . '<br /> ';

echo 'Ваш адрес электронной почты:

58

глава

1

'

. $email;


воохните жизнь в ваши статичные страницы

Дu.к.ctМu. чнbtCi

1(0.9 -

С'Yr\d'Yr\u.ЧнbtCi 1(0.9 01-\. не u.,3Мен..я.е'Yr\Ся..

< }'.:.2 :'-КОС:.М1I"Х\,.:.'{.:КН\:?

nР~~Ш!:::'Ji.i:~·ЦЬ:

.i:':.!.;Х:ИЩ;.:;:. nИ

u.,3Мен.я.е"У!)ся.

I(dЖ:9bt.Ci

Pc:IJ, I(ог..9а

1("Y!)0-к.u.S.'j9Ь €l-\.ece"Y!) .9aк.нbte fГ<

!'':':"?l·i9.

..- \:;(:~(;б'щС';:;.и(.? ;.;

<.ih2;·,

Спасибо

за

заполнение формы.<Ьr

/>

Вы были похищены в ноябре прошлого года

11

часов

и отсутствовали в течени е

. . <Ьг />

Опишите ИХ:

. <Ьг

/>

Видели ли вы мою собаку Фэнга?

Нет . <Ьг

Ваш

a1fn@theyreallygreen.com

адрес электронной почты:

/>

<.:.t··..y.1y:> -.: /r1!:. n:}:~

ВuI!wJDr _

llIOIII!fIC ПJIOIII'I'<O rou и Cm:YtC11IOOI>IМ ........... 11 .....,..

Qmruпneвх:

В................ ooбuy ФэIn? нcr

Вошupcc """"'1'OJIИ """"" ~Y8l='·c:om

вь, зоесь

..

59


анатомuя РНР-сценарuя Оуэна

PaJ60p

РНР-сценария Оуэна

Сценарий report . рЬр запускается в работу при нажатии кнопки

<lСообщение о похищеНИИi>, и его задача (на текущий момент) - прочитать данные формы и сгенерировать веб-страницу подтверждения. Давайте посмотрим, как это происходит. Первый фрагмент кода

-

это чистый

HTML. Он просто конфигурирует страницу,

которую мы создаем, и включает несколько HTML-тегов, необходимых для любой веб-страницы.

дс:\, Э!'riо"Yr\ НТМL-ко.э н.е.f)ОЛОк.: g u.эес:\ле

<html> <head> <titlе>Космические

-

пришельцы похишали меня

.3эе.СЬ ЭОЛЖн.bt

сообщение

11 pu.cyrt\ c"YI)eogc:\"YI)b "YI)e.z.u. DОСПРЕ (1Т\е.1с:\ > u."YI). t).,

о похищении</titlе>

</head> <body> <h2>Космические приmельцы похищали меня о

-

сообщение

н.О мЬ.. н.е. t) рu.еоэu.м u.x эля t",рос1Т\О"Yl)bL.

похищении</h2>

Дальше становится интереснее. Здесь мы прерываем НТМL-код

и входим В РНР. Тег <?рЬр открывает раздел сценария, содержащий

Нс:\Чu.н.ctЯ С Э1Т\Ог,о

РНР-код: все, что следует за этим тегом, является чистым PHP-КОдОМ.

моN,ен.1Т\с:\ мЬ.

<?рЬр

-<

Этот код читает данные формы и присваивает их значения индивидуальным переменным. Появляется простая возможность получить доступ к значениям u

этих переменных в дальнеишем.

РНР

-переменные позволяют вам сохранять

данные любого типа, будь то числа, текст или что-нибудь иное.

$when_i t_happened = $_POST [ 'wheni thappened ' ]; $how_long = $_POST [ 'howlong' ] ; $alien_description = $_POST [ , description' ] ; $fang_spotted = $_POST['fangspotted']; $email = $_POST['email'];

u.}I,e.eM

эело с РНР-коэом...

-

\')0

краЙн.е.Й мере, \')Око.

,,1_ I

JY\\01"

r ..

н'!~ОС"Yr\u.г,н.е.,т\

,3ctкр

I

ct)ОЩеzо

'1 "Yr\ez.c:\ . >.

Kct:k-э ctЯ С"У!)РОКС:\

~ РНР -КОЭС:\ "pu.cgc:\u.gc:\e"y!) н.oei:1t.м t)epeMeн.н.btм эctННbt.е еgе.эе~е

g t)олЯ фОD.мL."'l.

А теперь мы сообщаем посетителю сайта о результатах обработки формы. в этом месте

ЭmОI'r, ?НР-КОЭ gС"Yr\d.еля.е"Yr\

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

.3н.ctчен.u.я.

их значения в динамически генерируемый НТМL-код. Выводом команды есЬо

lle.peMe~

является НТМL-код, который непосредственно передается браузеру.

Тег

'Спасибо

есЬо

'Вы были похищены

за

заполнение

'

содержащий РНР-код. С этого момента мы возвращаемся в НТМL-раздел.

?>

~

А теперь закончим страницу, закрыв НТМL-теги, которые мы открыли ранее .

</body> </html>

60

g ТПМL-,коэ·

~ KO"Yr\0pbLu формы.<Ьr />'; . $when_it_happened; t)е.реэctе"Yr\Ся. есЬо ' и отсутствовали в течение' . $how_long . '<br / > ' ; Jрctуз е ру. есЬо 'Опишите их: ' . $alien_description . '<br />'; есЬо 'Видели ли вы мою собаку Фэнга? ' . $fang_spotted . '<br />'; есЬо 'Ваш адрес электронной почты: ' . $email; 39 есЬ 'зс:\l{ctн.Чt;.gс:\е"у!)ся. ?>, соответствующий тегу <?рЬр, закрывает раздел сценария, есЬо

глава

1

'

I

Не ,3dJ!.?L€ctU"Yr\e, ЧYr\о M.bL Сo.3Эd.е,,>,\

?t1P -I{О'<1 с Э"У!)ОZО моМе.н."Yr\d мbt. gО.3~РdЩdе.мся 1{ оdЬ!.чн.ому НТМL.

HTML-С1Т\Рdн.u.u,у: н.еоdхоэu.мо .3dK pbL"Yr\b рctн.ее O"Yr\Kpbt."YI)bt.e HTML-"Yr\e.zt.t.


вдохните жизнь в ваши статичные страницы

сvщеСТВО8Jf

Несколько РНР-правил KeAllpe8i Сценарий Оуэна

демонстрирует несколько

report . php

фундаментальных правил языка РНР, которые относятся ко всем

РНР-сценариям. Давайте рассмотрим их подробнее.

[j( fНP"'KO() &иr()a ~КАючен мtж()у ma8MU <~php U~).

есЬо

'Спасибо

за

заполнение формы.<Ьr

/>';

ТоЧкct с ,3cti1 Я:Vf\ОU

э ctе)'\'\ i1oК5l)'\'\b ?Нf, ЧYr\о :)'\'\0

KorLeu,

?Н? -i1ре.э ложе к.uЯ.

[j( ~U на &J"'''''paнuut UМШn(.Я АЮ&Оt КОАUЧtan&о fНP"'Ko()a, лучaut

U(.nOAb,o&amb & UMeнu файла на &J"'иp&tpt pac:.auupeнut fНP, а Ht Н'1Мk Xopowct5l мbtслЬ - Эd.€ct)'\'\Ь

?tI'? -С\.А,еWАРu.я.м ~"'eн.a

с r(кwu.Fе~ш.ем ?т1? И .7)'\'\0 Н.е \ipoc)'\'\o долее ~ ~ !(орo)'\'\кое pd.Cwu.peHu.e,

[j( Имена ntptмeнHbI)( fНf()олжны начuнаmь(,я (.о }Нака ()омара <". ~

$emai1

3н.Ф{ ЭОЛЛ4р4 оэк.О3rL4Ч~lО

l.щек."Ir\u.Фtщuр\~е"lr\

pfj Р -t)еремен..ч.Уro,

= $_.POST [ , emai1 ' ] ; Рассматривая переменные, использованные в сценарии

report.php,

обнаружили ли вы еще какие-нибудь правила

РНР, имеющие отношение к переменным? Запишите их!

I(ОIr\ОРФ{ соэее:>IGtJ."Ir\

uн.cpopМctu,u.ro 'gftJ«! ри. СIJ,еН4Рu.я. РНР.

8Ьlздесь ~

61


nровunовы60роuмендляnеременных

Поиск допустимых имен AIIЯ переменных

Пере.мeннas

-

В дополнение к тому, что имя переменной РНР должно начинаться

это К,oнmettнep.

с символа

5 к'omорый 5ы1

$, оно зависит от регистра клавиатуры (строчная и прописная

буквы рассматриваются как разные) . Но и это не все. Имеются другие важные правила, регламентирующие выбор имени переменной. Некоторые из этих

.можете за.нOCUtnb

правил относятся к синтаксическим: интерпретация кода будет прервана в случае

gaHHMe. u

их иrnорирования. Другие относятся к хорошему стилю программирования,

nepeмeннas gолжна

полученному нами в наследство от добрых РНР-программистов.

uмetnb YНU.КaAb~

Давайте начнем с официальных правил, которые, безусловно, приведут

UМ9.

кажgas

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

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

d

l.):J..l1Ч'.",О c.uM.OA ё}оАЖем

Не суцYf\~я. CЦМ€OM

"Вo'tТ\ ок.! $, I{OYf\opbt.u эолжен.

I"''''b ,наком ё}ОМ8l'а <;). ~___. . . :дbt. . . :Yf\;.:.:;Ь € цмен.ц 1(~Ж:90Й ~ Имя nЧ'емемttоQ ё}ОАЖttо С.Ос....Оя...Ь "Оlllяl", u~ оё}ttOf\) c.uM.OAa. t)ере.мен.н.оЙ.

(t( CuM.OA, СА~ЮШUО ttalOc.I'eё}c.....eмtto ~ c.uM.OAOM ё}ОМ8l'а,

ё}оАЖем I"''''b Aulo ~.oO aн~uOc.кotu ~a.u ...a, Aulo c.uM.OAOM n<ЮчЧ'кu.анuя (_', nl'u , ...ом .и nОСАеё}уtoШU~ C.UM.OA'" Mcny... I"''''b Iyк.aмu, uutl'aмu UAU C.UM.OAaмU nоё}ЧЧ'кu.анuя.

(t(111'0leA'" u с.nШUаАbtI"'~ c.uM.OA"', KI'OM~ _ Ut, ~ Доt'\~с'tТ\v..МО.

ДОI1УСYf\ЦМО.

)

-.?

НеЭОI1УСYf\ЦМО! Тцре

€ ц.мен.ах

~

I$fang-spotted I ').

н.е РdJреШdе'УТ\Ся. ,

ЦСt)олЬ.30g~'tТ\Ь

liepeMeн.н.btx РНР.

H~ ё}onyс.кato ...с.я • АюlоQ час.... u UMeмU nЧ'емемttоО.

~

н еЭОt)~С'УТ\v..МО! тцре ц liрОдел

~

' .'

when-it happened $what they_did

I$how_long I ЦСt)ОЛЬ30€~Yf\Ь н.е РdJреш~еYf\Ся. цмен.ц €

t'\ере.мен.н.оЙ РНР.

~

.J

ДОI1УС'УТ\ЦМО.

г.-I ia;l;-:L::·е;n;~d~е~s~с=r=i=р=t=i=о~n~J-:-,: ~

' - НеЭОt)УСYf\ЦМО!

имя. t)ере.мен.н.оЙ РНР

Несоблюдение этих правил приведет к тому, что ваш код

эолжн.о ~Чцн.а.'tТ\ЬС'я.

станет невыполнимым . Но кроме них есть еще правила,

со 3~I{~ ЭОЛlk:l.р~ '( $).

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

(jf Ис.nОАь~уQ...~ с....l'очtt"'~ Iyк.", ё}АЯ UMeм nЧ'емемtt"'''. (t( О...ё}еАяQ...~ САо.а C.UM.OAOM n<ЮчЧ'кu.анUЯ • MttOtuCAO.tt"'X UMeмaX nЧ'емемtt"'Х. Несоблюдение двух последних правил не прервет процесс выполнения кода. В своей практике вы наверняка столкнетесь с примерами

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

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

62

глава

1

Имена РНР-nеременных' gоАЖ.НЫ

. 1

,

н.ачuн.аtnbC9 со знака goмapa:

u не мorym 5КАЮчаmь

nposeл06.

.

I:!' t:l


вдохните жизнь в ваши статичные страницы

tfG БЫ~itG1h.

'9: Имеет ли значение, ввожу я команды

РНР прописными или строчными буквами?

О: И да и нет. В большей своей части РНР не зависит от регистра клавиатуры, поэтому вы можете смешивать регистры

при вводе большинства команд. Например, вы можете использовать

echo,

ЕСНО или

EchO, когда вы хотите вывести какие-либо данные. Тем не менее учитывая вопросы совместимости, считается хорошим стилем придерживаться сложивwихся

в программистском сообществе соглашений. Большинство программистов РНР предпочитают использовать строчные символы при написании команд. поэтому

вы увидите

echo

во всех примерах кода

этой книги.

возложенная на ве6-сервер,

пporраммироваНИЯ,я могу смеwивать

и совмещать РНР-код, написанный

в разных регистрах?

О: Нет, не во всех случаях. Исключением из этого правила является использование регистров клавиатуры при определении имен переменных, которые вы создаете

ДЛЯ сохранения данных. Возьмем, например, переменную

браузеру чистый НТМL-код, почему URL ссыпается на имя РНР-сценария, скажем,

предоставлять браузеру НТМL-страницы.

webpage.php?

РНР не меняет этого принципа.

О: Не забывайте, что каждая

Что РНР позволяет вам делать, так это менять НТМL-контент на лету,

ве6-страница

используя, например, сегодняшнюю

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

стоимость всех товаров в ваwей покуnaтельской корзине. Таким образом, РНР позволяет вам манипулировать

be6-страНИЦУ, чего невозможно добиться при использовании статического кода,

то еСТЬ разработанного во время создания

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

поэтому вы не можете обращаться к ней

$eMai 1. Все имена

переменных в РНР зависимы от регистра клавиатуры, поэтому необходимо быть очень внимательным при их выборе и ссылках на них в своем коде. Дополнительно об именах переменных чуть позднее.

'9: Это действительно допустимо

-

использовать и РНР-, и НТМL-код в одном

и TO~ же файле?

О: Абсолютно. Во многих случаях это

это результат

включающего запрос от браузера и ответ от веб-сервера.

URL -

это основа запроса,

в то время как контент, полученный от сервера,

-

это ответ. РНР-сценарии

запрашиваются как обычные НТМL-страницы

URL, введенный

в адресную строку

браузера, или гиперссылку с другой страницы, или как результат передачи

формы на обработку. Это объясняет, почему

URL для РНР-страницы ссылается на имя РНР-сценария.

'9: Должен ли РНР-код, вставnяемый

Вторая часть этого диалога

-

это ответ

В НТМL-файn, нахOДlПbCllВ своей

сервера, который генерируется в результате

собственной строке или я могу вcтaВnIlТЬ

интерпретации РНР-сценария. Большинство

HTML-KOA,

ero в НТМL-строки, например, как часть

РНР-сценариев генерируют

cnpм6yтa НТМL-тега?

но только этот код и имеет смысл для

О: Кроме требования размещения РНР-кода между тегами

< ?php и ? > не существует

никаких ограничений на встраивание необходимо «вклинить» фрагмент РНР-кода в случаях, когда вы устанавливаете

значение атрибута

Это является coвepweHHO допустимым

использованием РНР.

'9: я видел РНР-код, ограниченный

< ? php.

О: Не совсем. Говоря технически, это допустимо, но не рекомендуется. В принципе,

сервер можно сконфигурировать на допустимость короткого стартового тега

« ?), в ТО время как обычный стартовый ?php) работает всегда, поэтому

'9: Почему у меня может возникнуть

что он будет работать при любых

лучше ИСПОЛЬ30вать его и быть уверенным, обстоятельствах.

URL,

браузеру содержащийся в этом файле РНР-код вместо HTML-коАа, полученного в результате его интерпретации .

О; Да. Вы можете использовать

переменные, содержащие булевы

<?

это правильно?

тег «

при котором сервер, получив запрос с

ссылающимся на .PHP-фаЙл, отправил бы

другие типы данных?

HTML-Tera.

В качестве cтapтoвoro тera вместо

браузера. Поэтому невозможен случай,

'9: Могут ли переменные РНР содержать

в середину HTML-коАа, как, например,

пРосто необходимо.

в этом необходимость?

-

двухстороннего обмена информацией,

через

НТМL-кодом, который формирует

его в НТМL-код. Фактически очень часто

$ernai 1,

'9: Если ве6-сервер вcerдa оmравnяет

заключается в том, ЧТО он должен

такой страницы.

'9: 3начит, хоть это и мохоМ CТМnb

как к $EМAIL или

Z'if1tbJ-Х ~01tfOCO~ О: Потому что основная задача,

(true/ false) данные. А числовые данные могут

быть как целыми числами, так и числами с плавающей запятой (десятичные дроби). Существуют таКже массивы, содержащие множество данных с кодом, позволяющим

манипулировать ими. Массивы

рассматриваются немного дальше. этой

главе, а объекты -

в главе

12. Имеекя

также специальный тип данных NULL,

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

переменная со значением

NULL.

вь, здесь ~

63


добавьте потерянные данные Оуэна

о

liIcмI'leCDe врПlLlloЦW 1IIIIIIЩIJI8

..... - _ _ о 1IOI1IQeII11

Рacaraиte IIIIDY lICt'OPIUO IIOXIIIЦCIIIllIOC:IOf'ICCJaOO 1IJIIIDICIILuaыи: Яма:

[~

Фuotaп:

:~ · .НМP~ .. .::::.. "" ....."", . -::"",,=... ""

ваш адрес эncпpotUIOЙ ПO'JТЫ:

КDr.u mJ DpOКIOIПJI01

: 1,nOjl~_pM;o1m.!

1. нoяI!pef1llOOUlOfO ~ )

КвДQJПO ... ~

1~--'' -'--'-'

С_ их бblJlO?

! ~ ....

Omamm:их: Что oюr JICIIЗдJI с

,

Ясн.о €Ц.9н.o, '-I'Yr)о оtщссжu.е

_1

1{0СМu.Ческщ

ВидeJIJI JIIf 8IiI КОЮ coбuy Фэвra'/

t) [>u.weJJbu,e€

€вe.g e н.o € форму, •. ... н.0

Э'У!)о

Ot)U.CQH.u.e

O'Y!)CY"'Ic'Y!)€ye'Y!) f-t.Q C11}p<tKu.u,e

110.9'У!)~еРЖ:9ен.u.я..

ВIIбши nохищо.., iю8бpe l!J"'IJ!!"'ГО IЩa .~.-'II....,..

Опнuпrre",,:

8 _ J1JIВЫ I<0IO c:oбaJcy Ф:>нra? Нет ваш 'IЩ>eC ЭЛCl:lpOЮloii lIO'I1J,I: alfil(4!IbeyreaUygroca.com

64

глава 1


вдокнuше жизнь в ваши статичные страницы

~МЯ nopa6omamb в сценарии Оуэна

report. php

имеется проблема с данными

формы «Описание космических пришельцев». Просмотрите все строки кода, которые, на ваш взгляд, имеют отношение к этой

проблеме, и напишите, что они делают. Как вы думаете, в чем проблема?

<htrnl> <head> <titlе>Космические пришельцы похишали меня - сообщение о

похищении</titlе>

</head> <body> <h2>Космические пришельцы похишали меня - сообщение о

похищении</h2>

<?php $when_ it_ happened

= $ _ РОSТ[ ' whепithаррепеd'];

$alien_ description $fang_spotted

=

=

$_POST[ ' description ' ] ;

$_ POST[ ' fangspotted ' ] ;

$ernail = $_POST[ ' ernail ' ]; echo ' Спасибо за заполнение фОРмы . <Ьr /> '; echo

' Вы были похищены

echo ' и отсутствовали в течение ' . $how_long echo ' Опишите ИХ:

'

.

$alien_description .

' <br /> ' ;

' <br /> ';

ефо ' ВИдели ли вы МОЮ собаку Фэнга? ' . $fang_spotted . ' <br /> ' ;

echo ' Ваш адрес электронной почты :

' . $ernail ;

?>

</body> </htrnl>

report~

выздесь ~

65


заточите карандаш решение

хшенuе зааачu в сценарии Оуэна

report ,php имеется

проблема с данными формы

«Описание космических пришельцев», Просмотрите все строки кода, которые, на ваш взгляд, имеют отношение к этой проблеме, и напишите, что они делают, Как вы думаете, в чем проблема?

<html> <head> <titlе>Космические пришел ьцы похищали меня о

сообщение

похищении</titlе>

</head>

Ко.9 Э1f\Оо. C1f\POKU.

<body>

I')оля. «ОI')u.Сd.rше

о

сЧu.'Yt\tя.€d.е'Yt\ 3НдЧеrше кос,МuЧескu.x

I'\рu.шелЬu,е€» cpop.мbL u. I1pU.C€d.U.€d.e'Yt\ ег.о

<h2>Космические пришельцы похищали меня -

сообщение

похищении</h2>

<?php $when_ it_ happened

= $_ POST['whenithappened ' ] ;

l')epeMeкн.oo. $d.~iel'\_ de.scriptiol'),

$alien_ description = $_ POST['description ' ]; $fang_ spotted = $_ POST[' f angspotted']; $email = $_ POST['ema il'];

Ко.9, одЪе.9u.н.stroщu.u. ot)u.cd.н.ue кос,МuЧе.скu.x

I)рu.шелЬu,е€ С .9pyг.uм 1f\ekc-що,М u. HTfIIL-к°.9°М u. t)ере.9d.)ОЩu.u. реЗУЛЬ-Щd.1f\

дРd.уз е ру.

echo 'Спасибо за заполнение формы,<Ьr /> ' ; echo ' Вы были похищены ' , $when_ it_happened; echo ' и отсутствовали в течение '

. $how_ long .

'<br />';

' Опишите их:

echo

. '<br />' ;

echo ' Ваш адрес электронной почты;

, .

?>

</body> </html>

110 Kd.KUM-1f\О I"IРu.Чu.НдМ

. .

мре,Мен.ная. $d.~i:-ll_dеsсr\рtlOl"I

OKd.3d.J1d.cb Эmо IlЛОХО.

66

глава 1

I'),'jC-ЩОU,


вдохнumе жизнь в ваши сmаmичныесmроницы

aaHHble содержатся 8 перемеННЫI сценария РНР-переменные

-

это контейнеры, в которых содержатся данные, так же

QК напиток содержится в чашке. Так как переменная

$alien_description

3е содержит данных, мы знаем , что данные формы никогда туда не поступали.

Таким образом, переменная

$alien_description не содержит данных,

~~ютря на наши попытки присвоить ей значение. ~

МЬ!. UЩем Чd.UЩУ, н.ctt] олн.ен.н.))О

к сож4J1е.к.u:)О,

ot]U.Cd.к.u.eM

€ I-W.С"VI\оя.щее €ремя I-W.Шd ЧdWКd. t1yc"VI\d..

I1рu.шелЬu,е€.

К ОСМиЧескux

$allen_descrlptlon

Е!инственный способ исправить сценарий

$allen_descrlptlon это присвоить

-

};онкретное, ожидаемое значение переменной ~

5.::" ien_descr ipt ion,

вот так:

$аliеn_dеsсriРtiоn~маленькие

зеленые

человечки';

~ ФРd.zмен.lI\bL "VI\eKC"II\d. € рнр, "II\d.кже 3мк pd.€eНoC"VI\€d. ~o€OPU"VI\ ?Н? :'jClI\d.Нoo€U"VI\b jl-W.Че.к.u.е 1IJd.€Ou. Чd.С"VI\U эля ", е ремен.н.оа. € ле€оu ЧctСll\U-

Н4jbL€aeМbLe C"VI\POKa..мu.•.9 0Л.ж.н.Ь!.

дbL"II\Ь €cez.9d. ог.ра.к.u.Ченbt Кd.€bLЧКd.МU. - 0.9 UН4 pнbt.Мu.

UJ1U. .9€oЙнbt.Мu..

Этот код работает, так как он действительно присваивает текст маленькие зеленые человечки' перемеННОЙ$аliеn_dеsсriрtiоn.

Но решив одну проблему, мы создали другую: использование такого кода

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

Как-то получилось, что попытка присвоения переменной

$alien_description значения описания

космических

пришельцев, взятого из данных формы, не удалась.

$alien_description

=

$_POST['description'];

Как вы думаете, что в этом коде неправильно?

выздесь ~

67


Bceo$. POST

Пробllема действитеllЬНО св_зана с $_'05Т, представn_ющим собой механизм, ИСПОllыуемый дn_ передачи данных формы сценарию. Символ доллара в начале $_POST дает ключ ... $_POST - это контейнер! Точнее, $_POST - это набор контейнеров, используемых для сбора

данных из веб-формы. В случае с Оуэном эта переменная содержит все данные, которые были посланы нашему сценарию report . php, когда кто-то заполнил все поля и нажал кнопку «Сообщения о похищении!>. Поэтому, для того чтобы получить доступ ко всем данным формы и производить над ними какие-либо действия, мы должны пройти через

$_POST. Помните этот код?

$when_it_happened

=

$_POST['whenithappened'];

$alien_description $fang_spotted

=

=

$_POST[ ' description'];

$_POST['fangspotted'];

ЧctС"У!1Ь Э<:Iкн.Ь!.х cpop~, соэеР~~<:IЯ ЭЛLA"У!1ельн.ос"У!1Ь

~ОХLA~енuя,~рu.с€оенд t)ере.менн.оЙ

$hOV,,-~Оt)Э·

Таким образом, данные каждого поля формы «Сообщение

о похищении!> доступны благодаря $_POST. А что такое $_POST в действительности ... переменная?

68

глава 1


вдохните жизнь в ваши статичные страницы

$_POST - специальная переменная, содержащая данные формы $_POST -

это специальная переменная, известная как суперглобальная, потому

что она встроена в РНР и доступна из любого места сценария. Переменная

$_POST

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

<html> <head>

1fМ.I: Фаыиnи.:

< titlе>Космические

Ваш адрес ЭJlсlПjXJR1tOiI пO'ltЫ: о

Кorna :по npoIOOIWIо?

похищении</titlе>

льцы похищали меня

-

сообщение

</head> <bOdy>

Как дoпro вы arcya:noвали? COCO)lbl(l) их БЫiЮ'!

<h2>Космические ПР]~Ш'Jль,uы похищали меня - сообщение

OmOD_НХ:

о

. Чro они ДCJI8JIII с вами?

8иде;'" JIlI ВЫ мою собаl<Y Фэнra'!

ДаО Hc:r@

похищении

< /h2>

<?php $when_i c~1a;~~~~~~~~~n $how_long

$alien_des ~~~~~~;;'~~ $ fang_spotted = $_POST[ $email = $_POST['email'],

echo echo echo echo echo echo ?>

'Спасибо за заполнение 'Вы были похищены ' . ' и отсутствовали в течение 'О пишите их: ' . $alien des

'Видели ли вы мою собаку Фэ~га? 'Ваш адрес электронной почты'

. '<br />'; '<br />'; "'.ОЦ ''' __'''J..'JLted . '<br />'; .

</ body> </html>

Суперглобальнаяпеременная$_РОSТ непосредственно связана с методом

submi t

~~~~~~~~~~~~~1I1I1I1I1I.\111111

(передача на

вызывается, когда форма заполнена и посетитель сайта передает ее серверу

на обработку, нажав соответствующую кнопку. Если атрибуту method тега <form> установлено значение post, то все данные формы «упаковываются!> В суперглобальную переменную $_POST, из которой они при необходимости могут быть извлечены для использования.

· ~iorm~od="p?action="report .PhP" > Что вы думаете по поводу того, как

(!iерезС\.чС\.

работает суперглобальная переменная

sSiot)

$_POST? Каким образом она содержит

OdpC\.dO"Yr1KY)

Оllрезеляе"Yr1, КаК Эdн.ч.Ь!.е

форМЬ1. aY3Yrll l'1ереэС\.кbL РНР-сu,екдрu}() ЭЛЯ odpctdO"Yr1KU.

reporthlml

множество значений, взятых из всех

этих текстовых полей в форме Оуэна?

выздесь ~

69


$ POST -

это массив

$_POST

передает данные формы

BaweMY

$_POST - это специальный вид РНР-контейнера, известный как массив, который содержит множество переменных под одним именем.

Когда кто-нибудь передает форму Оуэна на обработку, все данные,

сценарию r...-.--.. ___ .......... _

-:

ha:a:D~8IW)'fICq:IIUODOI _ _ ~~

которые он ввел накануне в поля формы, сохраняются в массиве

им.:

$_POST, задача которого заключается в их передаче РНР-сценарию.

в...

_ _ ."",,,

КIII»""_1

Каждый элемент массива $_POST соответствует значению,

КaкACIIIUe"~? <&1". .. 6м:to1

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

0.-...."

использовать имя поля как указатель в массиве $_POST. Так, продолжительность похищения содержится в

$_POST [ 'howlong' ] .

НТМL-код формы Оуэна показывает, как имена полей связаны с данными, содержащимися в массиве <р>Расскажите

вашу

историю похищения

$_POST.

космическими приmепьцами:</р>

<form method="post" action="report.php"> <label fог=nfiгstпате">Имя:</lаЬеl> <input type;Ntext" id="firstname" name=nfirstname" /><br <label fог="lаstпатеn>Фамилия:</lаЬеl> <input type=ntext" id=" lastname" пате=" lastname" <label fог="етаil">Ваш адрес электронной почты:</ <input type=ntext" id=" email" пате=" email" / r /> <label fог="whепithаррепd">Когда это произо ?</label> <input type="text" id=n whenithappend n па =" whenithappend" /><br />

IT••fjjiil~,~jIJ.lt'iltlll"II••ifrl.1 <label

fог="hоwmапу">Сколько

их

было?

заполнен

gaHHMMu

/ label>

~o~ ~eн:~ <input type="text n id="whattheydid n пате= ha ttheydid" si, ='32" /><br /> <label fог="fапgsроttеdn>Видели ли вы мою баку Фэнга?</lа.~l> Да <input id=" fangspotted" пате=" fangspott n type="radio" ·'J.lue=nyes"/> Нет <input id=" fangspotted n пате=" fangspott e type=nradio" v, 1.ие="по" /><br /> <img src="fang.jpg" width="lOO" height="175 n аlt="Моя похищенная собака

тита 5 nо.лsl фОрМЬL

ФЭНГ.">

<label for="other"> Дополнительная информация:</ lаЬ <textarea id=" other" лате=" other" /></textarea><br <input type="sabmit" vаluе="Сообщение о похищении" </form>

имя \')оЛЯ форМbt о'"'реэеляе.-m, каК мо.ж.н.о l')оЛ~Чu.-mЬ9.0С"Yf\~\')

К эаКJ-tbtМ ~ Мd.сщ€е

'Iastname'

'whenlthappened'

eaIIOn':?

'hawmany'

д ОС'Yl1УI1 1(0 €ceM .9.a l-tН.b!.М $_POST ~cpop.мbt ОСУЩес)Тi~ЛЯе'Yl1СЯ чере..з .мo.ccu.(? $_. РО 51.

70

глава 1


вдохните жизнь в ваши статичные страницы

Просмотрите внимательно сценарий Оуэна

report . php

и найдите

код, который приводит К тому, что описание космических пришельцев отображается в виде пустой строки. Напишите, как исправить это. Совет: используйте НТМL-код с предыдущей страницы.

<html> <head>

<titlе>Космические пришельцы похищали меня - сообщение о похищении</titlе>

</head> <bOdy> <h2>Космические пришельцы похищали меня о

сообщение

похищении</h2>

<?php $when_it_happened = $_ POST[ ' whenithappened']; $how_ long = $_POST['howlong ' ]; $alien_ description = $_POST[ ' description ' ] ;

~I"\ОМl-tu:VI\е:

$fang_spotted

paк.ee~

$email

реwu..лu.

=

= $_ POST['fangspotted ' ];

$_ POST['email ' ];

t1ро~лему

эля- Э'У!\ux э€ух С"",РОК КОЭ Q ·

echo 'Спасибо за заполнение ФоРмы.<Ьr /> ' ; echo 'Вы были похищены ' . $when_it_happened ; echo ' и отсутствовали в течение '

-----~C;;:o 'Опишите ИХ:

'

. $how_ long .

$alien_description .

' <br /> ';

' <br />';

::)

echo 'Видели ли вы мою собаку Фэнга? ' . $fan(Lspotted . ' <br /> '; echo 'Ваш адрес электронной Почты ' . $email ; ?>

</body> </html>

выздесь.

71


заточите карандаш решение

~шеное задачu Просмотрите внимательно сценарий Оуэна

report . php

и найдите

код, который при водит к тому, что описание космических пришельцев

отображается в виде пустой строки. Напишите, как исправить это. Совет: используйте НТМL-код с предыдущей страницы.

size= "32 " /> <input type= ·' text "

id= "aliendescription"

reporthlml пришепьцы

похищали меня

-

сообщение

имя t)оля. cpop"'bL

g report.ht"'lТ\~

_.-

«d~iet)de$Crif~t.\or(»,

<?php

ЧI1iо н.е coo"'lТ\~e"'lТ\C"'lТ\gye"'lТ\

['whenithappened') ;

uмеtl~, ~Сt)олЬзуе"'о"'у

g $_.POSТ.

'aliendescription'

$alien_description =

ut:::bl.....L...L1J L ..l.. V11 ' ) ;

$fang_spotted = $_POST['fangspotted');

HdM н.еоdхo.эuмо

$email = $_POST['email');

~.3Me~"yy\b ~_POST

"уу\сЩ ЧI1iОdbL ~

~"УУ\dЛО t)PdgtV1b~:

echo 'Спасибо за заполнение формы . < Ьr />';

d.Riet)descripi:iot) .

echo 'Вы были похищены ' echo

I

. $when_it_happened;

И отсутствовали в течение

echo 'Опишите их:

'

I

$how_long .

. $alien_description .

' <br / >';

'<br / > ';

echo 'Видели ли вы МОЮ собаку Фэнга? ' . $fan(Lspotted . '<br />'; echo 'Ваш адрес электронной почты : ?>

</body> < / html >

72

глава 1

'

. $email;


вдохните жизнь в ваши статичные страницы

ecT-драйВ----Исправьте сценарий и проверые, как он работает. Измените ошибочную строку кода в файле

report . php и загрузите report. html

его на ваш веб-сервер. Откройте веб-страницу

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

<1Сообщения о похищении~, чтобы отправить форму на обработку.

Iocoчеекве op8IIIf.IIWIW JЮUЩlJlJllleu - соо6щепе о попщевп ~ вашу ж:ropиlO п\1XИlЦCllllJl КOCМ!l'leClOOlВ пpишem.цами:

Ibo: Ф."II)l1I1I:

Ваш адрес эneпpoииoii пoчrы:

КOIДa это проИЗOlWЮ7

каждoпro1lы1и77 CJDJJ>IO IIX было" ()mпDJm: их;

ЧтоOllll~lИс"""'l В~1И JIII ВЫ МОЮ c()/juy ФэllГа?

C-тр4rtUUP

t)оэ-тее ржэ ен.u.5t

-mel"1epb коррек-т н.о o-тодР4жде-т Э 4НН'ьLе форМbt 1"10 01lU.C4rtU-;О

G о

косМu.ЧескW<

t) рu.шельu,е@.

вы здесь ~

73


исправьте РНР-сценариu Оуэна

~МЯ

no,a6omamb

в форме Оуэна «Сообщение о похищении» имеются некоторые данные, которые мы пока не использовали.

Не забывайте, что они содержат жизненно важную информацию о похищении космическими пришельцами,

Ireeuчееае ЩlIDJUЬЦЫ II8UIIQ.U мен - ем6щeue о о....еп.

которая может привести Оуэна к его потерянной

собаке Фэнгу. Поэтому мы должны получить все данные о похищении и сохранить их в переменной

P~вamy lIt1OpИJO lЮIUIIQeвиI ~ 1IJ'IIIDtJIЬцaaaг.

$_POST.

ИVII:

~ н.аС'У\!оящu.il

момек.'У\! cu,eн.apu.il

rерогt.r:р ц;;.к.орцруе'У\! "Я'У\!Ь ?dJЛu.Чkbtx Эd.н.Н.bix cpopМbL. :%)0 к.u.КУЭG\ к.е г.ОЭU:VI\с$t! <form rnethod="post" action="'r·eport.php"> <label for=" firstпаmе">Имя: </label> <input type="text" id="firstname" name="firstname" /><br /> <label for="lastname'" >Фамилия: </ label> <input type="text" id=" !astnarne" пате=" lastname" /><br /> <label for= " email">Bam адрес электронной почты:</lаЬеl> <input type="text" id=" email пате=" email" /><br /> <label fоr="whепithаррепd" >Ко rда это произошло? </ lаЬеl> <input type="text" id=" whenithappend" пате=" whenithappend" <label for="how!ong">KaK долго вы отсутствовали?</lаЬеl> <input type='"text н id='" howlong'" пате='" howlong'" /><br /> <label fоr="hоwmапу">Скольк о их было?</lаЬеl> <input type='"text'" id=" howmany" пате=" howmany" /><br /> <label for=" аliепdеsсriрtiоп">Опишите их: </ label> <input type="text'" id='" aliendescription'" пате=" aliendescription" sizе="'З2" <label fоr="whаtthеуdid'">Что они делали с вам:и? </ lаЬеl> /> <input type=Htext" id="whattheydid" narne="'whattheydid" <label fоr=·fапgsроttеd"'>видели ли вы мою собаку ФЭНГ" ?'(~.аt,е l> H "/> да <input id=" fangspotted" name=" fangspotted type=H Нет <input id=" fangspotted" п ате=" fangspotted" type='"r""ir' "~~" '''F'= <img src="fang. jpg" width="lOO" height=H17S" lf

аlt='"Моя похищенная

собака

т е.г. (iI')PU1 > эЛЯ />

1(d..:>I<:90;;'0 1')0лЯ

Э4 нн.btx форМbt

Фэнг. Н>

соэер)IШ.'У\! КЛ)ОЧ

<label for=" other'" > Допо лните льная информация: < / labe 1 > <textarea id='" other'" пате=" other /></t extarea ><br /> <input type="sabmit'" vаluе="'сообщение о похищении" narne=Hsubmit" /> </forrn> </ body> </ html> H

эля. ЭОС'У\!jt)d. 1{

Э'I'r,\.Л.М ЭG\н.н.bt.М

u.з РНР.

Н апишите Р НР - код, создающий четыре новые переменные, которые

будут содержать недостающие данные формы:

reporthlml

$what_they_did

и

Совет: создайте переменную посетителя саЙта.

74

глава

1

$narne, $how_rnany,

$other. $name так,

чтобы она содержала имя и фамилию


вдохните жизнь в ваши статичные страницы

iiIUa

работа еще не закончена. Веб-странице

~ения, генерируемой РНР-сценарием, ...жхОДММЫ эти новые переменные, чтобы воспроизвести

- -.-·.........'ел ьную ~....;ен,ьц,ам и.

информацию о похищении космическими

-.,..w.ЦWНIIIII\IJI.меD-~,о,,п,,,,,

-

.1IOOбpe upownoro roдa и OI'C)'rotWOIIaIa ТC'ICИМ. 11 'I8C08.

а:: l8.К:fII&ИC ЗC.ICRЫC 1fC.iЮВCЧIИ

ICocмll'letПе opllJlleJl1oЦW OOllrцau IIfll - сое6щfllf О 101Iщевll

·""" с:обоуФэнra?Нer .1~Jlygrten.COПl

...... 3IISI'JIOfIВOII UO'I1'Ы:

спас:вбо за _еиие фopoiы.

вы быDи _ . ооабре прошлoro roдa. orcytC1.1I088ШIа teЧatllO 11 ......

Кoпнчecrao -1lpIIШCIIWIO:

"""*""""

0m0шrreJIX:--­ Ч1Ооив_:~.,g.:ro-""""

~ t}олЬ.3 0 €d"Yf\еля. I-lе цМе.е"Yf\

l!ид6aи ли ... ...., ooбu:y Фэвга? Нет

~иифopw!.u: iJoDJlyiicrl, roяocyйreза ...... ваш адрес эпепронвoi пom.r. alfD@lheyIeallygROII.com

&>JbШоzо 3М Че.I-lLt5l эля.

~I.фt t} ОЭ"Yf\€ерж.э е t-lLt5l, хolr\Я он.о t}омэодu."Yf\Ся. мм 3.91-lее, КОZЭd МЬ!. д:i9 ем qocblJa"Yf\b О~ЭI-l~ соо~щеl-lUе !",О элеl\tl\РОI-lНDU t}оЧ"Yf\е.

Используя все переменные, которые мы только что создали, за исключением $пarnе, допишите ниже пропущенный код, который

генерирует более информативную веб-страницу подтверждения.

echo

'Спасибо

ech o

'Вы были похищены

echo '

за

заполнение

формы. < Ьr

1> ';

' . $when_it_happened;

и отсутствовали в течение'

echo

'Опишите их:

echo

'Видели ли вы мою собаку Фэнга?

echo

'Ваш адрес

. $how_long .

'<br 1> ';

' . $alien_description . ' <br 1> ';

электронной почты:

' . $fang_spotted . ' <br 1>';

'

. $emai l;

вЬlздесь

75


исправленный РНР-сценарuu Оуэна

~шенuе задачu в форме Оуэна «Сообщение о похищении» имеются некоторые данные, которые мы пока не использовали .

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

собаке Фэнгу. Поэтому мы должны получить все данные о похищении и сохранить их в переменной $_РОЗТ.

Кotu'leeQeIlp......... 1IOUIЦU IIWI-C8O&Q_.~ Расасаанте вашу иcnJpию lICIJUUцeaиo 1COC-"1I\МIIDe.OЪ1WOИ: И-.

ФамвJlllJ':

\

<form method="post" act i on="report.php"> <label for='" firstname '" >имя : </ label> <inpu t type= "tex t" id= . . firs tname" name= "firstname '" /><br /> <label for::'"lastname" >Фамилия: </ label> < iпрut type="text" i d=" lastname'" пате=" lastname'" /><br /> <label fоr="еmаil">ваш а дрес электронной почты:</lаЬеl> <i nput type="text" i d=" email пате=" email" I><br 1> <label fоr="whепithаррепd">Коrда это произошло ?</ lаЬеl> <input type= " text" id= * whenittlappend" пате=" whenithappend" < label fOI'="howlong ">KaK долго вы отсутст в ова ли ?</ l аЬеl> <i nput type="text" id= " howlong пате='" howlong" /><br 1> <label fоr="hоwmапу">Сколько их быпо?</lаЬеl> N

N

<input type="text" id="' iрtiОП">Опишите hОt>lПlапу" пате=" их:</ howmany" I><br /> "1~~~~~~!,'1!1~1!1!1!1!1!1!1!1!1!!!I1!. <label for=" аl iеп dеSСI l аЬеl > <input type="text'" id=" aliendescription" пате=" al i endescription'" s i zе="З2" / ><br <labe l fоr="whаtthеуdid" > Что они дела ли с вами?</lаЬеl> тег. эля. <input type="text" id="'whattheydid" name =" whattheydid" /><br /> <label fоr ="fапgs роttеd">Видели л и вы мою собаку ФЭнгя С'''""JЯ'''' l }(о.жэог.о t)ОЛя. Да <i nput id=" fan gspo tted " пате=" fапgsроttеd" type=" /> Нет <input id=" fangspotted" пате = " fangspot ted'" type=" 'V;'l ",~="n,o"/><br /> эо. ккbtx <img s r c =' fang .jpg' width='lOO' height='175'

(illput >

cpOpMbt.

аlt="Моя n охищен.ная

собака ФЭНГ.">

<l abel f or =N ot her" > Дополнительная информация :</ l аЬеl> <texta r ea id=" other " пате=" other " I></textarea><br /> <input type =" sabmit" vаluе='"Сообщение о nохишении" name='"submi t" /> </ form > </body> </ html >

соэер.ж.u."YI\ КЛ)ОЧ

эля. ЭОС"YI\Уllо.

К Э"У!)Uft\ эо.н.нbtМ

uз РtlР.

Напишите РНР-код, создающий четыре новые переменные, которые будут содержать недостающие данные формы: $name, $how_many,

report.hlml

76

глава 1

~OlТ) liроае.л

$what_they_did и $other.

О"Yr1З ел я.е:m,

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

ЦМ5(

и фамилию посетителя саЙта.

о",

cfX\MWJu.u.


вдохните жизнь в ваши статичные страницы

Ваша работа еще не закончена. Веб-странице подтверждения, генерируемой РНР-сценарием,

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

((ecмnetne .,._аы IOПIIIJ\Iмeu - cteбщaoIe о 88llщевп

-

:

I

C

R~ • teЧ<IIIIe 11 """"". I

Ы

I

D

I

8

I

J

1

1

и

п

о

К

____

I

__

Omnmпeвх:

C

CIIacибoЗl_фopwы· Вы бышI_ 811О11бре t1pOlDJIOtO _

8

Вы БWJIII_ 81t011C1pe IIPOIIIJIOI'O I'OJII R arcyIt't8OIUH 8 _ . 11 _08. OtIВW"'" их: -зeaat,,,,чеооIlC'4ОСВ Видели ли ... ""'" ooбuy Фэtmt? Нor Вош ..., ЭIIC8:IpOtDIOI """"': alfu@thcytallygrocJLCOIII

ЧтоORВ_: =::-.t:"~­

Имя t)ОЛЬjо€ct'Yf\еля I-le u.мee'Yf\

Вн.целв ли вы NOIO coбu:y Фoнra? Н... ДonOJ1ll)ПeJl>llU и:aфopмauIII: Пo>caпyiicnt, rIIJIOOYihe ЗI ......

доЛЬшог.о jн.d Чеl-ШЯ ЭЛЯ

ВamI/фCC.-rpoнкой- ~.""",

C'Yf\pctl-Шupt "ОЭ'Yf\€ерж:эеI-ШЯ,

ХО'Yf\Я он.о t)Он.dэодu'Yf\С.я. мм

\1o.3Эl-lее., ког.Эct .мbt. d'jgeM

"ocbVJct'Yf\b ОуЭI-lУ соо1ш,еl-Ше. \10 элек'Yf\РОк.н.о u. \10Ч'Ут\е.. Используя все переменные, которые мы только что создали, тег.

< br 1> t)OMozcte.

за исключением $пarnе, допишите ниже пропущенный код, € rhОРМ<:\...... который генерирует более информативную веб-страницу

g,

'yf\

подтверждения.

"IUPO ctк.u.U uГ\.,/орМ<:\u,u.U I-le. jctdbt.€ctu'Yf\e, Чmо

.lGIlОЛЬjуеYl1СЯ ЭЛЯ

echo 'Спасибо за заполнение формы. <br 1> ' ;

/IIbt

~еfеэС\уu дра.удеуу

echo . Вы

КОJol4н..ЭCI e.cho

30 t)ОЛI-Ш'Yf\елЬн..оu ~орМ<:\u,u.U

'11

KctK~ echo •

L-l<оКYI1екYI1ct.

:.-J:>€CI ollepctYl\Op ::""-, оЧкct»

.. :!")ользуе'Yf\С.я. ЭЛЯ : аеэu.н.еl-lUSl €Mec'Yf\e :1r,POK Yl\eKc'Yf\d. .. ~еремек.н.bt.x.

.

и~ I

UСIlОЛЬjУе.м РНР

были похищены • . $when_it_happened; ЭЛЯ СОjЭФШЯ

и отсутствовали в течение

• . $how_long .

'<

HTML.

1> ' ;

~~~ .~~.~~~.~~ .~..~~~?'.:. ~h?~-:7'!!\.<:'!1~:..' .~ .~~ .....;.. ............ ........... ................ echo

'Опишите их :

'

. $alien_description . ' <br 1> ';

..~~~.'~.<?~~..9~~. ~ в~Т.:.~~~.7.~.~~-:7Ф~. :.'.~.~~/?.'.;........................... echo

'Видели ли

мою с обаку Фэнга ?

..~...~ .... ~I)~~~"!')~~~~. ~~?p~~:: echo

'Ваш

адрес

' . $fang_spotted . ' <br 1> ';

.'..?~#)~~.: . ~~. ~.~. {~:: .............. ......... ... .

электронн ой почты :

' . $email;

вЬlздесь ~

77


проведите тест-драйв РНР-сценарuя Оуэна

v

ест-драив Исправьте сценарий Оузна и проверьте, как он работает. Добавьте код для новых переменных в файл report . php, а также код, который передает значения этих переменных в виде отформатированного

HTML.

Затем загрузите сценарий на свой веб-сервер, откройте страницу report. html в браузере и занесите в форму информацию о похищении космическими пришельцами . Теперь нажмите кнопку «Сообщения о похищении~ для

передачи формы на обработку и наблюдайте результат.

Не 5bj~a.e't1t.

gVl1bJX ffi Ol1focoffi

'Р: Что фактически происходит, когда я объединяю вместе 'Р: Хорошо, но как сервер преобраэует РНР-код в HTML несколько строк текста, испольэуя точки?

и

О: Результатом объединения нескольких строк с помощью

О: Bo-пеРВblХ, не забblвайте, что по умолчанию

оператора <<точка»

( . ) является одна совершенно новая

(SS?

действует принцип, согласно которому код РНР-сценария

строка. При этом не имеет значения, сколько отдеЛЬНblХ строк

должен в конечном счете стать

первоначально принимали участия в такой операции . Поэтому,

РНР- код от остального текста в сценарии, размещая

когда объединяете несколько строк как часть

его между тегами

KOMaHAbl echo,

HTML-KOAOM. BbI отделяете

< ? php и ? > . Сервер видит

РНР вначале соединяет все строки в одну, а затем передает

эти теги и интерпретирует код внутри них как РНр,

ее браузеру.

а весь код за пределами этих тегов передает браузеру

'Р: Когда я объединяю с помощью оператора «точка»

как

(конкатенирую) переменную со строкой текста, должна

ли переменная содержать текст?

HTML, без изменения .

'Р: Хорошо, но это все еще не объясняет, как именно

РНР-код преобраэуется в НТМL/(SS-код. Что происходит?

О: Нет. Хотя результатом конкатенации всегда является

строка текста, перемеННblе не обязательно ДОЛЖНbI

содержать текст для Вblполнения этой операции. Если, скажем, переменная содержит число, РНР сначала конвертирует это число в строку, а затем произведет саму конкатенацию.

'Р: Что происходит с PHP-коДом В брауэере?

О: ВОТ здесь как раз и вступает в игру команда e c ho.

Вы можете рассматривать ее как средство вывода информации

за предеЛbl границ, определеННblХ тегами

Поэтому команда

e c ho

< ?php и ? >.

играет ключевую роль

в возможности РНР динамически генерировать НТМUС55-код. Объединяя строки текста с перемеННblМИ РНр, вы можете конструировать

HTML-KOA на лету, echo, чтобbl передавать

О: Ничего, потому что браузер не понимает РНР-кода.

его браузеру как часть результирующей веб-страНИЦbl.

РНР-код интерпретируется на сервере и преобразуется

Хорошим примером этого является сценарий

в

Оуэна

HTML-KOA, который

И передается браузеру. Поэтому браузер

а затем использовать команду

report . php, где тег <br / >

совершенно не знает о существовании РНР. Веб-страницы

добавлен к концу текста, чтобbl генерировать

поступают на него в виде чистого

перевод строки в

78

глава 1

HTML- и С55-кода.

HTML.


вдохните жизнь в ваши статичные страницы

~~-сmrЗ+1Цца flОиm&er>киwця полeJНЭ иля посemцmеля с.аUmэ, 1'10 иля

мwя ОИЭ t1е пrwсmэ&ляem t1Цкакой

цetitlостц. Я хочу, чmоОы иЗ+1t1ые оылц оmпrэ&лwы Мtlе по ~лекmrоtltlоu ПОЧmе.

Сценарий РНР доткен еще пepecnать Оуэну данные формы по :мeкrpoннoii почте.

Как уже было замечено, сценарий РНР считывает данные из формы «Сообщение о похищении~ и генерирует страницу подтверждения для посетителя саЙта. Но все еще остается нерешенной первоначальная

проблема отправки Оуэну электронного письма, после того как форма будет обработана.

Альф Нэйдер был похищен в ноябре прошлого года и отсутствовал в течение

ЛН4ЛО2UЧКО

€ed- c 'fl1pd.н.u.u,e 110Э)Тt€ер~ен.u.я..

~

Э'fl10 элеl('fI1рокн.ое

t)UCbMO соэерJК.u.)Тt

11 часов.

Количество космических пришельцев: множество. Описание космических пришельцев: маленькие зеленые человечки.

Что они делали? Допрашивали меня о правительственных

постановлениях в области нло.

с)Тtd.)ТtuЧнbt.й )ТteI(C)Тt

Фэнг замечен? Нет.

u Эd.кн.bte фор.м.bt.

Дополнительная информация: Пожалуйста, голосуйте за меня. Это электронное письмо может быть сгенерировано РНР-кодом путем

объединения строк статического текста, таких как «Дополнительная информация: », С данными формы, содержащимися в переменных.

Напишите, как бы вы объединили строки статического текста с РНР-переменными для составлення электронного письма.

выздесь ~

79


построение содержания сообщения в РНР

Вы уже видели, как оператор ~точка>,) может быть использован для конкатенации (объединения) нескольких строк текста в одну. Сейчас нам

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

' Количество космических приmельцев:

' .

1.1.1.~~II'I;tllj . 'Что они делали?'

tlllt.[~r

'Фэнг замечен? ' . li~,~llllill.j~I! .

'Описание

к осмических

'Дополнител

приmельцев :

'

ая информация: ' .

._

- Не .3d.dbtЙd.UlТJе:

...........

Одна из проблем заключается в том, что требуется составить длинную строку

Кd. ЖЭd.51 Г\еремеННd.51

Gоэер.ж.u.lТJ ClТJ РOJ<)'

РНР-кода, который трудно читать и понимать. Вы можете распределить

lТJeKClТJd., u.зелечен.к.ог,о

РНР-код между несколькими строками, чтобы сделать его более легким для прочтения и понимания. Только следите за тем, чтобы разбивать строку на фрагменты в тех местах, где ввод дополнительных разделителей (в данном

из СРорМь!.. « Сооdщен.u.е 11 охu.ще н.u.и » ,

о

случае перевод строки) не имеет значения (игнорируется РНР), например

между двумя соединяемыми строками текста, а не в середине строки. Поставьте

точку с запятой в конце последней строки, чтобы завершить РНР-предложение.

••~1

'Количество космических приmельцев: ' . il~~~I

разgелена межgy несколькuмu БОлее KopomкUMu. но

HeosXoguMO

соsлюgать ocmорожнocmь

оnpegелeнuu .мест.

Kyga

нужно ycтaHOBUffib

gоnолнumельные разgелumелu

80

глава 1

npu


вдохните жизнь в ваши статичные страницы

Этот РНР-ко() ()ейст17uтелЫi() очень

хорошо Бы i()uт •. 110 Ье"? наVлежаiJ.\еrо форматuро17анuя не оуuет ЛU злектrюнное nUCbMO е,ыrляuеть оесnоряuочным нату.IОМОЖUенuем текста? о

Да. Но то, что PHP-КОд хорошо упорядочен, совершенно

не значит, что результат

ero

интерпретации будет так же

хорошо упорядочен автоматически.

Организация РНР-кода с целью сделать его более легким для прочтения и пони мания ДЛЯ вас

-

совершенно не то же самое, что форматирование

результата его интерпретации, который будут наблюдать посетители вашего

саЙта. Обычно для такого форматирования вы при меняете теги

HTML,

так как в большинстве случаев РНР используется для динамического

генерирования веб-страниц. Но это другой случай. Здесь мы генерируем электронное письмо, которое является простым текстом, а не

HTML.

Мы должны принять во внимание тот факт, что пока

это письмо будет выглядеть так:

Альф Иэйдер был похищен в ноябре прошлого года и отсутствовал в течение

11 часов. Количество космических

пришельцев: множество Описание космических пришельцев:

маленькие зеленые человечкиЧто они делали? допрашивали

меня о правительственных постановлениях в области ИЛО Фэнг замечен? нетДополнительная информация: Пожалуйста, голосуйте за м~ня.

- - Oйf Но Э"У1'\о соесе.м. НЕ ТО, Y"rrjo

ОуЭн. tlpe9.lloM2dJ1 liОЛУЧU:)'f)Ь

f1 I{d,ЧеС"У1'\1s'е элеl("У1'\Р О I-ll-lО20

Не БЫ.&!Ol.G11t,

ZVl1blX ffi ol1focoffi

~: Существует ли способ ИСПОЛЬЗ0вать форматирование -ПМL в :lЛектронных письмах, которые вы посылаете

113 РНР-сценария?

О: Существует. Но этот метод требует следующего шага, который '.асается установки поля content type (ТИП контента) ;; заголовке электронного письма. Вы узнаете больше об этих

заголовках в главе б и тогда сможете вернуться к вопросам,

Ilu.cbfi\d, о t)охu.щен.u.u.

l{ос.м.u.Ческu..м.u. lifu.шельU,d.Мu.!

~~~ЛД

1Х1Мь,~л~ Как бы вы переделали электронное письмо

в формате простого текста, чтобы оно выглядело удобнее для прочтения?

:вязанным с электронной почтой в НТМL-формате.

выздесь ~

81


форматирование текста в РНР

Даже простой текст может Оыть ОТформатирован ... немного Раз Оуэн отправляет электронное письмо в виде простого текста

для перевода строки в местах, где возникает необходимость разбить

~ре-nослegО5аП\е.льнocmu в РНР начuН8Юt1\C9

длинную строку на несколько коротких . Но он может использовать

с cu.мвoм. <cжpamнag

без НТМL-форматирования, он не может использовать тег

<br / >

символ новой строки в форме Еsсаре-последовательности (экранированной последовательности)

'\n'.

Н8КЛoннas чepma»

Если в электронном

(\).

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

символами новой строки:

$msg =

$пате

. '

'\r,' u.СI10лЬ.зуе'll)СЯ эля 1I1o~o, ЧYrIодЬ!. €C'll)d.€u.'II)b СtJ.ft\€оЛ к.o€oй C'II)POKU. € 'll)e/{c'll) ~лек'II)РОн.н.о~о r,U.CbМd..

был похищен

$when_it_happened . ' и отсутствовал в течение ' . $how_long . '.

' Количество космических npишель ев: 'Описание

космических

приmельцев:

'Что они делали?' . $what_they_did 'фЭНГ замечен?

' . $how_many .

'\п'

$alien_description

,§I}

' . $fang_spotted . '

'Дополнительная информация:

~. ~

'.

' . $other;

о о

Альф Иэйдер был ~щен в ноябре прошлого года и отсутствовал в течение 11 часов~оличество космических пришельцев:

множеств~писание космических пришельцсв: маленькие

зеленые человечк@то они делали? допрашивали ме я о правитель~нных постановлениях в области ИЛ \п

энг

~Mec'tТ\o 'tТ\o~o Ч"Yr\Одbt t)ер,е€оэu.'tТ\Ь C'tТ\POK~,

замечен?не~ополнительная информация: Пожалу та, Голосуйте за меня.

Ife

Бы.GJ.е1h.

'\11' t)оя€ляе'tТ\с$t € 'tТ\e/{c'tТ\e - - - - - Kd.K оdbt.ЧМя.

ZV11blX ffi 011focoffi

'F: Что в действительности представляет собой Еsсаре-последовательность?

llослеЭО€":'lТ'tелЬк.ос'tТ\Ь Сu.М€оло€.

О: Еsсаре-последовательность (экранированная последовательность) позволяет добавить символ, который трудно ввести (клавиша с таким символом отсутствует

на клавиатуре) или интерпретация которого может вызвать конфликт с другим кодом РНР. Вы, возможно, уже знакомы с Еsсаре-последовательностями в

HTML, где они

кодируются

несколько иначе, например: © или &сору; для символа копирайта. В РНР набор Еsсаре-последовательностей невелик: например, символ одинарной кавычки двойной кавычки

82

(\ ") и,

глава 1

конечно, новой строки (\п).

(\ '),

ill


вдохните жизнь в ваши статичные страницы

Символы НОВОЙ строки неО6ХОДИМО помещать В строкн, ограниченные ДВОЙНЫМИ кавычками Проблема с кодом Оуэна заключается в том, что РНР обрабатывает строки по-разному, в зависимости от того, заключены они в одинарные или двойные кавычки. Символ новой строки (\п) будет рассматриваться как экранированная последовательность, если он помещен в строку, ограниченную

.1ВОЙНЫМИ кавычками. Поэтому, для того чтобы символ новой строки интерпретировался именно как символ новой строки, а не как последовательность символов обратной наклонной черты

(\ )

и английской буквы п,

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

Но это еще не вся разница между одинарными и двойными кавычками. Строка, ограниченная одинарными кавычками, рассматривается РНР как «сырой!> текст, в то время как в строках, ограниченных двойными

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

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

Smsg

=

И$пamе

"Ко личество

"Опи са ние

был похищен

космических

$when_it_happened

$hоw_mапу\п И

пришельцев:

космических пришельцев:

и отсутствовал

в

к о НJ( 0.1Т\ e!-i4u,u.u' 01Т\ l"\d..9d е1Т\, 1Т\аК каК t)epemeHJ-lbt.е мог.'j«I дbt.1Т\Ь рcI.JМе щен.Ь1. ГLеt)осре.ЭС'IТ\€ен.н.о € 1Т\e.KC'IТ\e,

"Что они делали? $whаt_thеУ_did\ПИ~ Сu.м€ол ГLO€oй

C'IТ\POKu' "yy\el"'lepb

oг.p..aГlUЧен.н.оМ Э€ОCiн.Ь1.Мu'

U,ГL1Т\ерtJре"УУ\U,руе1Т\С5{ "Допо лнительная

информация:

$оthеr

И

~

~ cdJ/IoM, KOГLu,e ГLe'lТ\ ГLеоdхоэu.мос'IТ\u' cmct€u''IТ\b сLtМ€ол ГLo€Oй С1Т\РОIЩ "IТ\a~< Kcl.K о71Т\О i\ослеЭГL5{5{ С1Т\РОКcI.

о7лек'IТ\РОкн.ог.о I')u,cbмo.,

l\еd€u.лЬГLоdло.г. ОЭdР5{

;

и

\п . .

НеОdХОЭLtМос1Т\Ь € ot)epo.u,u.u,

.

$аliеп_dеsсriрtiоп\п И

" Фэнг замечен? $fапg_sроttеd\п И .

течение $how long ~

Кd~bt.ЧКcl.Мu'.

Но !-i4М €ce. pa€ГLO

э€оЙн.bl..М Кd€bt.ЧКdм.

ГLе.одхоэLtМо РdСl"'lреэе.лu''IТ\Ь сооdще.ГLU,е !-i4 ГLескоЛЬко

1fG БЫ~OlG1h.

CO~u'ГLe.н.н.bt.x Me.~y

ZЛv11ЫХ fl. 011P OCOfl. V jcJ 1 '1С)

содоц C'IТ\f>OI<' Ч'lТ\оdbt. КОЭ dbt.Ло УЭО~ГLе.е Чu''IТ\d1Т\Ь.

~: Если двойные кавычки такие удобные, почему мы до сих ~: Итак, одинарные кавычки поддерживают \ ' , пор использовали в основном одинарные?

но не поддерживают \ п. Как мне определить, какую

О: Примите во внимание тот факт, что строки, заключенные

экранирующую последовательность я могу использовать

в одинарные кавычки , никак не обрабатываются РНр, что

делает их идеальными для использования с простым текстом,

в строке текста, оrраниченноrо одинарными кавычками?

О: Одинарные кавычки разрешают только экранирующие

то есть не содержащим переменных, Поэтому мы продолжим

последовательности

использовать одинарные кавычки на протяжении всей книги,

использованы лишь в строках текста, ограниченных двойными

если только не возникнет серьезных причин использовать

кавычками,

\'

и

\ \. Все остальные могут быть

двойные, Наиболее важным соображением относительно использования одинарных или двойных кавычек является

стремление быть настолько последовательным, насколько это возможно .

выздесь ~

83


компоновка электронного письма для Оуэна

Скомпонуйте электронное письмо ДЛЯ Оуэна С содержанием письма, сгенерированным в виде строки текста, вы можете

двигаться дальше в компоновке остальных частей электронного письма для Оуэна.

Сообщение электронной почты больше, чем просто содержание: имеется еще

несколько его составляющих. Хотя некоторые из них не являются обязательными, следующая информация используется практически во всех электронных письмах.

о Адрес электронной почты получателя (КОМУ).

~A-:9pec эле к 1'I\Р О кн.ой

t)o'hr,bi ОУЭН4. Электронное письмо примерно такого вида Оуэн надеется получить, после того как кто-нибудь отправит форму на сервер.

,Э-m,о .МОЖе)!) dbt"rY}b

,Э-m,о ct.эрес

с)!)роко r,РОСlY)ог.о

эле.к"rY}РОкк.ой

"rY}€.KClY)d..

7Ino dЭр'е.с эле.КlY)рон.к.~й t10ЧlY)i.1t Оуэна, KO'i'l\0pbLu. lY)d.кже може.lY) dbLlY)b ClY)FOKOCi t1РОСlY)ог-о lY)e.KClY)d..

t)o'hr,bi 11 0С €.lY)U"rY}е.ля.

Cd.U)!)d., KO)!)opbLu сохрС\н.ен.

g t)e.peMeMoU $€."rY}d.i).

От: alfn@theyreallygreen.com и меня т космические приwельцы похищал

.

ема,

_

со()БIllLe".~~~iiИllЦеt'ИИ

б

2009 r 11 '54'00 GMH2:00 МИНСК Дата: 5 сентя ря . , ' о Кому: owen@aliensabductedme.com . .. .... .......................... .. "........ " и oтcyтcтвoвan в течение 11 часов. Anьф Нэйдер был ПОXl1щен в ноябре прошлого года ких пnuweльцев' множество

Кonичество космичес

F"

.'

Описание космических приweльцев. мап

енькие зenеные человечки

Что они делали? допрашивanи меня о прав

Фэнг замечен? нет

ительственных постановлениях в области НЛО

О

' Пожалуйста ronосуйте за меня. ,

дополнительная информация .

МI:я уже соззd.Ли. C"rY}pOKY с соэерЖ4Н.u.е.м элек)!)рокн.ог.о I1цcbМd., КО)!)Орd.я' t)plA.Ceoe.КL1. t)€.ре.ме.н.к.оЙ $)!)sэ.

Этот пример электронного письма показывает, что большая часть контента находится в его содержании, которое мы уже закончили.

Все, что осталось,

-

это добавить тему, адреса электронной почты

<\кому» И «от кого!> ... и, конечно, как-то отправить его, используя РНР!

84

zлава 1


вдохните жизнь в ваши статичные страницы

Разделы электронного письма содержатся в переменных у нас уже есть содержание электронного письма в пере мен ной $msg, но все еще нет темы

сообщения и адресов электронной почты «KOMY~ и <ют KOГO~. Тема сообщения и адрес

э.lектронноЙ почты «кому» могут быть присвоены новым переменным как строки простого текста,

в то время как адрес электронной IЮЧТЫ посетителя сайта «от KOГO~ уже сохранен в переменной 3email благодаря коду обработки формы, который мы написали ранее, читая эту главу.

$етаi1

, От: alfn@theyreallygreen.com

,

,

I

чecltllе прмшen"ЦЫ мelUl Тема, ОС"" 11'54'00 GMT+2:00 МинСК Дата: 5 сентября 2009 г, . ' о

кому: owen@8Iiensabductedme .com

'

дnЬф Нэйдер был похИщен в ноябре пpowлoro

_

сообщен- о ПОХII":-

-.. .. ..

,

,

,

.. roдa и 0ТC'fТC'I1'088" в '!eЧ8tI1I8 11 часов·

Количet'fВО KOC~ пришепь~: M~зеленые чenoвeчкм О описание космических пришепbЦ8ll· мane вителbCТВllН НЫХ постановленияХ В oбnac1М НПО ЧlO они Аелали? АOIIр8WИвали меня о пра 1у фэнr замечен? нer

. пожалuUмй roлосуКте за меня. , •••. -.

дополнитenьная информация.

I I

I

, I

"Количество космических пришельцев: $how_many\n"

"Описание космическиХ пришельцев:

$alien_description\n"

"Что они делали? $what_they_did\n" " Фэнг замечен? $fang_spotted\n" .

"дополнительная информация: $other";

ВСЯ u.н.срОрМcii.J,l.tЯ.

(01'8')1(8111'8 Эll8ктронноrо "исьма.

эля ЭлеК'l!jрон..>1..0~О

. . T8111t& all8anpoHHoro "иеЬМ8. I")t.A.CbМci. сод'рd.Н4 u. ZO'l!jO€{d. ------~.A. К O'l!jt"\pd.gKe'

-v АдреС электронной ПОЧ'l'Ы 0'l'П'8ВИ'МII. (ОТ KOfO). е АдР8е Эll81t'1'РОНIIОЙ "014"'" "ОIl"ча1'еll. {КОму). вь, здесь ~

85


отправка электронного письма с помощью РНР

Отправка электронного письма с помощью РНР Итак, вы готовы написать РНР-код, который отправит электронное

письмо Оуэну. Для этого необходима встроенная РНР-функция

mail ( ),

отправляющая электронное письмо, основываясь на информации, которую вы ей предоставляете.

Аэре.с _ элек~ОО~ОU ,J« M\I "~ \iОЧ"'lY\о;;" ко J '. 'f

.

mai1( )

omnpaвAget1l

теМС\ элекmоок.н..оz. о

V~ r'jlJ.cbm. mail($to, $subject, $msg);

PHP-q>yНКlJU9

I

электронное nUCbМO

из cueнapU9.

~ Со.эеРЖ4н.u.е ЭлекI'I)РОкн.ог.о lliJ.cbMd.

Эти три фрагмента информации являются обязательными при вызове функции та i 1 ( ) , поэтому вы всегда должны их

Аэресу элек~ро~оCi t)otrтbt о-т1tdgu.-теля.,

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

dРг.умеГl-т d cpyt-U<u,u.u. -n\di~(), ОдЯJd~елЬГlO

mai 1 ( ) , обязательно должен иметь в своем начале

э олжГlO t"\реэшес-теО€d-тЬ слоео 'frо-т: '.

предоставлять. Адрес электронной почты «от KOГO~ не является

слово <iFrom : ~.

llереЭdgdе ому g КdЧес~gе

~ ~

mail($to, $subject, $msg, 'From:'

. $email);

~ 1-

Ot)ePdl'l)0P <СI'I)ОЧКd» ' - - - оt)ЯI'I)Ь u.Сt)ОЛЬJуе)1'jСЯ ЭЛ5/.. КОНj(dl'l)екдщ;,u

$t

слоgd Тrощ' ц ~pecd

;:::, .' wen@q-.!iensabductedme . com ';

$aubject =

' Космические npишеnьцы ПОхищапи меня - СООбщение о по:щении' ;

. Оnисание космических пришельцев ; ·Что ОНИ делали?

О:уэкд.

..

$msg '" • $ пате был ПQхищен $when_i t_happene -Количество космических приwельцев ;

"Фэнг замече н ?

эле к)1'jРОкн.оЙ t)оЧYi)bL

8bl~OlG'fh,

'9: Имеется ли еще какая-нибудь

$aliefLdescription \ n" .

$what_they_did\ n" .

$fang_spotted\n· .

. Дополнительная информация ;

JfG

Z4fl1blX /c>Ol1fOCO/c>

$howJ1\any\n· .

информация, которая может быть

$other" ;

определена как часть электронного письма,

кроме адреса электронной почты «от кого»?

О: Да. Вы можете определить поля «копия» И «слепая копия» таким же способом, как и в случае с адресом электронной почты «от кого». Используйте просто

о

Э l<Pdн.u.pO~dl'l)b сu.мgолbt I

ооцн.. J

Jct ~P\lZu.м J 31'1)0 tlpd u.лЬнbt.й ct)OCod. "

МЬ!. IJ.С\lолЬ.3уем эgоLiн.btе. Кd€btЧКI..t,

86

глава

1

.

' Вес:

'вместо'

'Се:

' или

From: '. Если вы хотите

определить как поле «от кого», так и поле «копия», вы должны отделить их друг от друга

комбинацией символов «возврат каретки» и «новая строка», как показано ниже:

~uFrom :

n

$from

U\ r\nCe

'I!1dK KdK tlРiJ.JI.\ек.я.ем ЭКРdн.u.РО€dкнbtе \Jосле.эО€d-телЬГlос-тu. \r u. \~ . _ _ _ _ _ _- - - - '

n

$ее


вдохните жизнь в ваши статичные страницы

lак как же мы оуuем

uсnоль;р&аmь СРУИКЦUIO mailO иа nraKmUKe~

() о

Просто доба.ьте • с.ой сценарий КОд, котор",й ....э....ает mailO.

Строка кода, который вызывает функцию mai 1 ( ) , - вот все, что вам нужно, чтобы отправить электронное письмо. Убедитесь в том, что этот код появляется в сценарии после кода, который создает все переменные,

связанные с электронной почтой, и все будет в порядке. Ниже приведен полный код сценария Оуэна report . php, включающий вызов функции mail ().

<html> <head> <titlе>космические </head>

<bod~~ <

пр иmельцы

похищали меня -

сообщение о похищении</tit lе >

V\звлекае"i!\ все

>Космические пришельцы похищали меня - сообщение

о похищении</h2>

э

. . ·" .I-e mopI ~~ .. 1-

цмruJv

1:

~ u..3 )oIДCCu.~a $_?О$Т

<?php

$name = $_POST [ , firstname ' ) " $ POST [ '1 $when "t h ". astname'); _~ _ appened = $_POST [ 'wheni thappened' ) ; $how_long = $_ POST['howl ong ' ); $howJlany = $_POST [ 'howmany' ) ; $al~en_description = $_POST[ 'ali end escription')')/d $whacthey_ d id = $_ POST( ' whattheydid ' ) ; $fang_ spotted = $_ POST [ 'fangspotted' ) ; $ema~l = $_POST[ ' email ' ); $whaCthey_ did = $_POST[ ' WhattheYdiY'); $other = $_ POST( 'other');

I\Pu.ceau.€ae"i!\ ux 10 .,1- .. u.1-«}u.~u.:9\1аль~'\

U.

!)epeMeн.нbLМ. ":J

J

о

,еэu:mесЬ ~ "Yr\oJA, Ч'mо €b!. 3ctМен.илu. aa~c

элеl<"Yr\РО..u-wu- t")O~

$to

~

'owen@aliensabductedme. сот' ;

$SUbJ:C:

$msg _

=

'Космические приmельцы ПQхищапи меня

$name

был похищен

$when it ha

~Количество космических пр ' иmел~це-Б p$hPene

O"i!\!)pa€Ka

~

d

bt. н.а. C€Ou., t")ереэ "Yr\eM l<al<_"Yr\ec"Yr\u.poea"Yr\b Э"Yr\О"Yr\ cu,eн.a.pu.u. - сообщение о похищении ';

и отсутствовал в течение $how_l ong.\n·

: ow many\n • Описание космических пришельцев: $alien=description \n' Что они делали? $what_ they_ did\n' " " $fang_ spotted\n' .

Элек"i!\РОI-U'tОz. о

:ФЭНГ замечен?

l\u.cb.МC..

~~.";;:'''QП' ная "нфОРМalШЯ ' ~Qtbf>r""

~~$t~:

'Спасибо за заполнение формы. $subJect, $msg , 'From:

' .

W

Оl\реэеля.е"i!\

~О"i!\.9еЛЬкbt.е час"Yr\u.

$emaйj)

I

Элеl<"i!\РО..u-wz. о t")u.cbмh. t")e еэ "Yr\eM ez.o

каК O"i!\IiPa~u."i!\b I

echo <br 1>'; echo :вы были похищены ' . $when_ it_ happenedi echo , . $how_ long " '<br 1> " echo Количество космических npиmельцев" $Ь ' есЬо 'Опишите их: • . $alien_descriptio~ . : <brO~;~~nY . ' <hr /> ' ;

и отсутствовали в течение '

: что они делали?

$what_ they_ did . ' <br /> '; ' . $fang_ spotted echo ,дополнительная информация: ' . $other . ' <hr /> ' ; есЬо Ваш адрес электронной ПОЧТЫ: ' • $email," echo echo

I

ОуЭн.у.

, видели ли вы мою собаку Фэнга?

'<br 1> ';

?> </body>

</html>

выздесь.

87


финальный тест-драйв

ест-драйв Заверwите сценарий Оуэна и испытайте

ero.

Добавьте три новые переменные, связанные с электронной почтой

($to, $subject и $msg), в сценарий report . php, а также вызов функции mai 1 ( ) . Убедитесь в том, что переменная $to содержит ваш адрес электронной почты, а не адрес Оуэна. Загрузите сценарий на ваш веб-сервер, откройте его в своем браузере и введите в форму информацию о похищении космическими

пришельцами. Нажмите кнопку «Сообщение о похищении!>, чтобы отправить форму на сервер. Подождите несколько секунд и проверые ваш электронный почтовый ящик на наличие письма.

До.нн.bt.e форМbt ,УСllещк.о

-

оУ()формо.1Т\u.r. О €ClНЪt {А О'Yl1tlра€лен.bt € €u.э е

J

Ibtr: в

... _~п""",,:

ЭлекУ() ро н.н.о г.о

Кorna..,...,....,.....,7

rlu. cbмo..

~.цОШ'О'" O'1'tyttDO.aтt1 С8lD:lWt01D.6ы,,1О? ОfUU,lUlТCЮС:

что оки д,emL1M С ).$1.8'~

8J111C11M !I'М ... МОJO собаку Фэвra7

Вам, возможно, понадобится настроить РНР на

BaweM

веб-сервере, чтобы он знал, как отправлять электронную почту.

Если функция таil

()

неработаеm,

проблема может заключаться в том, что в вашем РНР поддержка электронной почты настроена неnравильно. Обратитесь на WWIN. php.

net Imai 1 для получения

более подробной информации об этом.

88

глава 1


вдохните жизнь в ваши статичные страницы

Оуэн начинает получать электронные письма Оуэн волновался, сможет ли он гарантированно получать из Сети

CcJ.ллu. дbtЛс!,

к.еЭdек.о

информацию о похищении космическими пришельцами напрямую

на свой почтовый адрес . Теперь ему не нужно волноваться, узнает

ли он о том , что кто-то видел его собаку, потому что у него будут

~ lIохu.щек.ct.

электронные адреса всех, кто вступит с ним в контакт. Более того,

он сможет просматривать их ответы в любое свободное время.

AiТ)pu.dyYr1 d,ctiot) iТ)eг,c!, <foriТ) > Jd,t)~ci(d,eiТ)

- ............iiiIiiiit,CcJ.ллu. .3dIlОЛ fW..}1d,

~~~:"'_-:::"_.-.d:)Оk~С~f€~;~dеu.Лd.

\

l

~~.~ ~?~~: ~ ::::=~'::._, ~-=--.z,..

~..,..."..--- ...

..

r<-f-o-rm-a-ct-i-o-n-

=

"report.php"

;~;=::':~;~~~KЦ ~P'

\t .

"""""--

....

~=::: ~~.----.--I­

=:.-==~..,...c

=:-,..::--..:::;....-.. ..... ~--.-'

=::-:.:.~':

Эmо ззмечаmелы·ю!

С СОООl!\енuямu о nОХUI!\е!1UЯХ, nruсланнымu мне

по элекmrонноu nочmе, я знаю,

чmо наб()у Ф,mrа.

РНР -сц,еl{d,рu.Й

iТ)d,j(Же

cOJ.9d,eiТ)

ЭлекiТ) рон.н.ое t)U.CbMo

u. ОiТ)t)рr~gЛ5(еiТ) его Оуэну.

вы здесь

89


nерегРУЭКQ электронной nочты

Оуэн начинает терять электронны e письма То, что Оуэн получает электронные письма, хорошо. Но плохо то, что он получает

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

----~

----

и.

........ -.-..--"': "._o _~

( _ .. w.!

-~

.,...----.~

\

..

_..,~

' -.......1

:

\

I

\

~

,--

~~:;;;::]

:,;;;;,,;,:..

.-,:: ::~

-~ 9Jo_"IOIC_'

\

. 0......:.: _ _ c-'

_

....... ....

f...- "'''····--..:;

.I

• Эmо n"O)(o."f7;,rflfll-iUmе на Ike 3mu з"екmrонные nисьма!

Мне неоо)(ооим kakou-mо СnОСОО

,

оОrаu.lamься к 3mUM оанным morva, Korva я )3)(очу. Мне mакже неоо)(ооимо )(raнUmb и)( &оезоnасном Mecme, чmоОы они не mеря"UСЬ.

. I

\

111

.. ...I

~

90

глава 1

,

,,

.. t


вдохните жизнь в ваши статичные страницы

Космические пришельцы в голове? Вытряхните их оттуда, соотнеся

tHML

HTML-

и РНР-компоненты с тем, что каждый из них делает.

Программное приложение для просмотра веб-страниц и диалога с веб-сервером, которое выступает в качестве клиентской стороны в процессе веб-коммуникациЙ.

Plfr

Команда РНР, предназначенная для вывода контента, например простого текста или НТМL-кода.

Эти теги используются, чтобы ограничить РНР-код и таким образом дать

возможность веб-серверу определять и интерпретировать его. Встроенный РНР-массив, в котором содержатся данные, передающиеся

на сервер при использовании метода

«POSTi>.

Программный язык, используемый для написания сценариев, исполняемых на сервере.

То, что ограничивает строки текста.

Программное приложение для создания и передачи веб-страниц, которое выступает в качестве сервер ной стороны в процесс е веб-коммуникациЙ.

uho

Язык разметки, используемый для структурного описания контента

веб-страницы, которая просматривается на браузере. Имя, используемое для описания встроенной РНР-переменной, которая доступна для всех сценариев.

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

информации от посетителя саЙта.

/

Встроенная РНР-функция, которая отправляет электронную почту.

c:r-Cf И\обаЛЫfa,jf ~1tfCMGlflfa,jf)

Ячейка памяти, для которой РНР-сценарий назначает уникальное имя и тип хранимых данных.

Тип хранилища данных в РНР, позволяющий сохранять множество разных данных в одном месте.

8Ьlздесь ~

91


кто что делает решение

Космические пришельцы в голове? Вытряхните их оттуда, соотнеся каждый

HTML-

и РНР-компонент

с тем, что каждый из них делает.

Программное приложение для про смотра веб-страниц и диалога

с веб-сервером, которое выступает в качестве клиентской стороны в процессе веб-коммуникациЙ. Команда РНР, предназначенная для вывода контента, например простого текста или НТМL-кода.

Эти теги используются, чтобы ограничить РНР-код и таким образом дать возможность веб-серверу определять и интерпретировать его. Встроенный РНР-массив, в котором содержатся данные, передающиеся на сервер при использовании метода ~POST». Программный язык, используемый для написания сценариев, исполняемых на сервере.

То, что ограничивает строки текста.

Программное приложение для создания и передачи веб-страниц, которое

выступает в качестве серверной стороны в процессе веб-коммуникациЙ.

ссЬо

Язык разметки, используемый для структурного описания контента

веб-страницы, которая просматривается на браузере. Имя, используемое для описания встроенной РНР-перемснной, которая доступна для всех сценариев.

Некоторое количество полей ввода данных, используемых для получения информации от посетителя саЙта. Встроенная РНР-функция, которая отправляет электронную почту. Ячейка памяти, для которой РНР-сценарий назначает уникальное имя и тип хранимых данных.

Тип хранилища данных в РНР, позволяющий сохранять множество разных данных в одном месте.

92

глава 1


вдохншnе жизнь 6 ваши статичные страницы

Ваш инструментарий РНР и 8

rлаве

1

MySQL

вы узнали, как

использовать РНР, чтобы ВДОХНУТЬ . жизнь в веб-форму Оузна. 8зrляните на все, что вы уже изучили

...

вы здесь ~

93


-+

2 сое8ц,lftlfц,t с лtr4Jt1L

КtlК 8te э,о torntltye'tll -.междуt060Й мы uоЛ>кны Т10UКЛlOчumьсЯ

к UHmf.j?lIJwyuo то[о, как сможем соwuнumься

с сайтом КОНфuryраmора.

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

как это вам необходимо. С другой стороны, этот способ должен позволять вам обращаться к данным по мере необходимости. Хорошо известная система управления базами данных

MySQL может надежно хранить ваши данные.

Но вам необходимо как-то подключить ваш сценарий к этой системе, чтобы

-------

воспользоваться теми возможностями, которые она предоставляет.

ЭТО новая глава

95


ловушки на пути данных формы, nересылаемых по электронной lючmе

xopowo.

РНР-форма Оуэна ра60тает

'~

xopowo ... ·

~

HO&bIU cцwarUU t'aOomaem

.,

• I

[лиwком

I ,

.....

xoroulO, но я сmал nолучаmь (ЛUU!КОМ много

~' ,I

злекmrонных nUCeм. Я не cмory nt'uняmь сmолько KotpWHa, ЧmОды rа3Одt'аmься аОсолtomно со &сем.

1,

..

f

~

I

I

l' I

.\

I

" ~ О

v

Сценарий Оуэна с поддержкой эnектронной почть. работаn успешно, пока приходиnо HeMHoro сообщений, но сейчас он стаn поnучать эnектронные письма в боnьwом коnичестве - значитеnьно боnьwе Toro, которое он в состоянии обработать. Он случайно удалил несколько электронных писем не читая. Другая

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

писем была скрыта от него в тот самый момент, когда ему крайне необходимо было их прочитать ... Оуэну необходим Сllособ сохранять

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

отношение к Фэнгу.

в Э"'/l10М t']О!'l')еРЯf-(f-(ОМ

llоээер.жctнu.е

€ I')оряэке €cex сооdщенu.U о !lох u.щекuяx,

1') РU.дЬtЙct)OUJ,UX

н4 !lОЧ'У!\о€btй Ящu.к Оуэ-но., € 1( он.u,е КОн.U,О€ t)рu.€еэе1У\ ezo € СОС1У\оЯнu.е

011110

-I'st "е! ",оКЯ - сооБЩ От' sa\\y@9regs ~ . \IIenьцы nОJ(IIщaJ111 •

че«:КIIО "р"

... .

о t)ОХlJ.Ll.1,ен.u.u.

•• СОТ

т010\2.: кос"',, 2008 r. 12:11:29 р ". Aata: 1 ОКТllБРII. abductedme.c:om Kolo\Y: owen@a\lenS ... .

IIщена 3 АН!\ наз

.)111 омu.но.лосЬ .

Konl\'l"'" \j6CКIIX ПРllшenьцев. О nIIсзl\llе KOCMII? Мы просто оаз~ова~МВЗI'~~::"::_фэнr замецен? Аа

АОnOПl\llТenьнз!\ инфОpIoI

о "'/110М, Ч-'t'Yj0

.. з е течеНllе 1 АНЯ.

ад IIl)!CyтCl1!OeaJ1

сanлll........an Д1\ФIIСKOCМI\'l8C 6blпа похKII)( ПРllшenьцее~:. зе: ',,:eтbI::ре~wes:~~~lа~-:Ч10 01111 АenЗnIl .

соодщенu.u.

О nОJ(lIщеll llll

~.

.._------\1

а

СОО<:l.l<.у ~u.эелu..

)то КС\Х Fd.j )Тj<:I u.н.формаu,u.я.,

й

)l(l!Т8Cb СО МНО .

ena взШ)' cr!JaVl/, свя

КО!'!')ОРС\Я кра.йн.е

aЦll!l: В03мOЖIIО, !\ ВИА

одхоэtA.l>"\d. Оуэн.у.

Kpa.Йн.e~o

l1 е ре€Оjdуж.э е нu.я

Это как раз тот случай,

0"'/11 €bu)u."'/I10г.о кофе.

Оуэн.у н.еодхоэtA.МО, Ч'У!\ОдbL

где база данных

!lО.9 0д н.bt.е

Э"'/l10.му, СОХРd.н.я.лu.сЬ € 0.9н.ОМ \-ldэеж.rwм .меС1У\е,

г.э е дЬ!. он. MO~ €!-UJ.}Ad1У\елЬн.о IlpocМct"'/l1pu.€d."'/I1b \АХ, О"'/l1дu.р ct я. "'/I1e, g K0"'/l10Pbt.x: Уllо.мu.но.е"'/l1Ся. , Ч'II\О Фэ-к.г. дbtЛ jd.Мe Чен..

96

глава 2

MySQL может помочь ...

На ,"о," СЛУ'ай, есл" !h ',"о?-о J

н.е. jн.ф~)Т!е ; jv\i·ШZu.е. лroэи.

t)роu.,3НDСЯ"'/I1 сло€о

M\/SQ.L

ка.к «МQЙ-ЭС-I{Ь)О-Э~Ь».


соединение с MySQL

Jамечательное средство ДЛЯ хранения данных

MySQL -

Оуэну действительно необходимо хранить сообщения о похищении космическими

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

систематизированном виде. При этом вы можете извлекать из нее именно те данные,

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

баз данных на языке, который он понимает; в нашем случае это структурированный язык запросов

SQL.

Mv::;(}L хранит

Обычно сервер баз данных работает на том же компьютере,J

.

что и веб-сервер, образуя вместе с ним ансамбль, читающий и записывающий

gaННbte

информацию и предоставляющий ее посетителям саЙта.

В maв

Beд-cep€ep OdPC\d~i'f\b!gC\e)\') 3C\tlpoc

дрС\у.3 е рС\ ка !)ОЛУ-iен.t..lе €еd-С"УУ\fClн.t..ltJ,bt.,

L,Ki'f\eptlF,ei'f\u.pye)\') РНР -cu,eк.a.pu.u u,

~сер.ерный компьютер ·

дC\к.н.L4.e

Л

&азо данных MySQL

О)\')t)рС\€ля.е)\') HTML-кок"уу\ек"YI'\. ...

БаЗЫ

U1,JaX

\

узер

~ф~S:;:€ctч:~:::rt':е.~ ~~ Эd: !.х )

В структуре базы данных MySQL существуют таблицы, в колонках

и рядах (строках) которых хранятся данные, которые могут быть связаны

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

Cep€ep дС\.} .9С\ННЬ!.х

/JI.\\iSQL Може)\')

ЧС\С"УУ\О

()-to

н.е €сег.эd.)

IIреЭGI'!\d.еля.еl'!\ U.3 седя. г.РIjI\~

фd.u.лое kd ж.есI'!\КОМ эu.ске.

~ дС\з е Эd.ННbtx мож.еl'!\ dbt.l'!\b м.~ожеСYriео д Рd.,3Лu'Чк.btx )\')С\ лu.u,.

J

соэерЖd.i'f\Ь мн.ожес)\,)€о

РС\,3Лu''-Jн.btx дС\.} 9С\н.н.btx.

. ......

~

::;(}L -это S13Ь1К запросов.

uCnOAb3yeМbtU

gASl Используя данные о похищении космическими пришельцами, сохраненные

в базе данных

MySQL,

Оуэн в любое удобное для него время может

анализировать сообщения, полученные от тех посетителей его сайта, кто ответил «Да!> на вопрос о Фэнге. Все, что ему необходимо для этого,

-

это написать

небольшой SQL-код для обмена информацией с сервером баз JЩнных.

ОБмена

uнqюpмаuuеu с БаЗОU уаннь1Х.

My::;(}L. ebl здесь >

97


MySQL может помочь Оуэну

Оуэну неО6ходима 6аза данных

MySQL

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

report . php изменения,

которые позволят сохранять данные

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

в которых могут содержаться сведения о Фэнге. Но вначале о главном

-

базе данных!

Создание базы данных MySQL требует наличия сервера баз данных MySQL и специального инструментального программного обеспечения. Причина этого в том, что в отличие от веб-сервера обмен информацией с сервером баз данных

Coзgанue БаЗЫ ga.нньV\ My~

mpesyem osмeнa uнqюpмачueU

СМУ~Л\ БаЗ

gaHHblx.

должен осуществляться с использованием запросов, составленных на специальном структурированном языке

запросов

SQL.

о

Оуэн.::; к.еоdхоэu.м.о Ltк.с~румек.~QЛЬк.ое

I1POzp4MMi-loе

оdеСl1еЧен.u.е.. ~oдb!. СО3Эd.Yl1Ь д43У :ld.1-t.I-t.btx /m4dЛLtu,у, ~ "f5 КО1У\орой он. дуэе"l!'\

Xpaн.u.~b соодщен.u5t

о !')охLtЩе.н.u.яx КОСМLtЧескu.м.Lt

11 РLtшелЬu,o.мu.,

е ~1~~L~~льн.ос'lY\u.. phpMyAdmin - графическая "тилита f~tju..Cd.rt Kd. ?НР,

,.

~

~pMyAd1Y\ill )1У\О г.fd.фLtчеСК45t yvnUЛLt1У\4,

1l 0з€ол5trolJJ,45t \10Л Ь 3 0 €41У\е-лro

СО3Э4€41У\Ь д43Y94~

Lt 1У\4длu..$ чере,3 €еd-Ш-l1У\ е fфеu..с,

Две популярные утилиты

MySQL -

это

и

phpMyAdmin.

Обе позволяют выполнять запросы SQL дЛЯ создания баз данных и таблиц, добавлять данные, просматривать их и т. Д., но phpMyAdmin продвинулся на шаг вперед, реализуя веб-интерфейс с поддержкой принципа <1УКазал и щелкнул». Некоторые хостинговые компании включают phpMyAdmin в стандартный MySQL-сервис, в то время как MySQL-терминал может быть использован для получения доступа к большинству MySQL-инсталляциЙ.

98

гла8а2


соединение с MySQL

у вас ДОllжен быть ycтaHoвneH сервер баз данных

MySQL,

прежде чем вы приступите к чтениlO этой страницы. Без такого сервера невозможно помочь Оуэну! Если сервер баз данных

MySQL у вас уже -

установлен и находится в рабочем состоянии, продолжайте чтение дальше. Если нет обратитесь к приложению

11 и установите сервер согласно инструкциям, изложенным в нем. MySQL, попросите вам доступ к серверу баз данных MySQL. Для получения такого доступа вам

Если вы пользуетесь услугами хостинговой компании, предлагающей

их предоставить

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

D Размещение моего MySQL-сервера (IP-aдpec ИJDf домениое имя): .................................... . D Мое имя пользователя базы даlПlЫX: ....... .. .............. .... ... ... ......... ... D Мой пароль: ........ ............................... .. .... Еслu е/:я доиrп,есЬ, Чfr}о 0<=

ЙС\НJ-tQ5I. Kн.u.zC\ t)ot)~eYf\

)3d.м н.eoдx0.9UМo еее

t)Лоxuе руки, н.е

JС\1l 0Лн.5l.UYf\е .7Yf\Y Crп,POKY.

.7Yf\O IIpOeepUYf\b, После получения этой информации о сервере баз данных

MySQL все, что

вам остается,

-

это удостовериться, что сервер находится в рабочем состоянии. Отметьте одну из позиций

внизу, для того чтобы убедиться, что вы можете успешно получить доступ к MySQL-серверу.

~ l3CIМ эоС'tТ\С\'tТ\очн.о

oYf\MeYf\u.Yf\b Yf\оЛЬко О.9н.у

t)o..,u.u,u.)O.

D я могу успешно получить доступ к MySQL-серверу, используя MySQL-термниал. D Я могу успешно получить доступ к MySQL-серверу, используя phpMyAdmin. D я могу успешно получить доступ к MySQL-серверу, используя ... ................. ...... ... ~

Еслu. gbt Кдw.лu. K6.ky)'O-t-W.дуэЬ эруz.У)О ymu.лu.'tТ\у MySQ.L. €btllоЛн51.)OI..U\j)О .7Yf\u. 3а.96.Чu., .36.I'\u.Ulu.Yf\e ее С)О.96..

8ызiJесь ~

99


создание баз oam"blX u таблиц в

MySQL

Создание 6азы данных и та6лицы в

MySQL

в некоторых инсталляциях

Если в вашей инсталляции нет

MySQL база данных уже создана.

базы, необходимо ее создать, используя SQL-запрос CREATE DATABASE в MySQL-терминале. Но сначала вам необходимо открыть MySQL-терминал . Для этого введите команду mysql в окне

операционной системы (в

Windows это

«Командная строка!». В случае успешного выполнения

этой команды вы увидите приглашение терминала

MySQL: mysql>.

Для создания новой базы данных о похищениях космическими пришельцами введите:

CREATE DATABASE aliendatabase; как показано на рисунке:

Ког.эct еЬ1. \jолЬзуе:'1Т\есЬ ""!у\ермш"'длоМ, €kег.Эd Перед тем как создавать таблицу в базе данных, вы должны выбрать ее, то есть сделать ее активной. Введите запрос:

C""!Y\d(Sb""!y\e ""!у\ОЧКj

с jdlIЯ""!У\ОU

USE aliendatabase;

mysql> USE aliendatabase; База

дaHHЬ~

изменена

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

%Wш',.m!,W.II~ ~~

:7У1\О SQL-3dI"\РОС _ \-ld СО3ЭdГUJ.е Koeou

'aliens_abduction' -Vn4длv.l.фt, 'first_name' VARCHAR(30) , 'last_name' VARCHAR(30) , Все oCYl1cV1brloe ""'whеп_it_hаррепеd' varchar(30) , 'hоw_lопg' VARCHAR(30) , ЭYrjо v.н.срОРJA.d.iJ,u.я 'how_many' VARCHAR(30) , О "rY!ом, эctкк.bLе 'alien_description' VARCHAR(lOO) , К4КЩ 'lY\щ)о€ д::l3J«1 'what_they_did' VARCHAR(lOO) , СОХР<.lН5{'YrjЬС5{ ~ Э'YrjОЙ 'fang_spotted' VARCHAR(lO) , YrjG\длv.v1е. 'other' VARCHAR(lOO) ,

.email .VАRСНАR(50)~сеС.lndНЭ.~Р.lY\i-tbLе J4llfocbt,

); ~ ggоэu.Мbtе €;' fJ'\ySQL.-'IY\ермv.!{dле~ ~ эолЖкL"'L 34К4 к.Ч\J.еd'lY\ЬСЯ 'lY\O'4KOU G

100

глава 2

3dttЯ""!У\ой..

(S

ко\-ш1е

КctЖ:90г.о JdllfoCd.


соединение с MySQL для того чтобы создать новую таблицу, введите большой запрос CREATE TABLE в MySQL-терминале (вы можете найти код этого запроса на веб-странице по адресу

www.headfirstlab.com/books /hfphp). После успешного выполнения этого запроса у вас будет сияющая новизной таблица aliens_abduction.

Ch!)€e"Yl\ cep€epa

MySQL «Q.uery ОК» (3aI"1POC €Ьщолн.ен.

jСl"\ешк.о)

~o€oPu."YI\ €aм о "YI\ оМ Ч'vr\ о

"YI\аdлu.u,a dbl.лa

COjqdкct де"

11 рОдлем. -----:ь

в вашей инсталляции утилита

MySQL вам может быть предложена основанная на веб-технологии phpMyAdmin, которая позволяет получить доступ к вашей базе данных и таблицам

через графический интерфейс. Пользовательский интерфейс рhрМуАdmiп-утилиты

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

phpMyAdmin,

которая работает так же, как MySQL-терминал.

S-r: gjJ IOcaIItost ~ DatabaSe:

i!P "lIendatab••e

~~1 ~ i ~~ Г]iSe.tI:!I Iг~QtнliVll ~O}iёiatI-l CREATE TJI..ВLE 'aliens_abduction'

firstJ1ame'

(

VARCНAR(30).

'last name' VЛRСНАR(ЗО),

'when=it_happened' vаrсhаr(ЗО).

IslJendatabase Н

.::J

'how_long' VARСНАRtЗО} . 'howJf\any' VдRCНAR(30) . 'alien_description' VARCНAR{lOO).

'what=-they_did' VARCHAR(lOi» ,

l3bt МоЖе1Т}е €€ес1Т}u. ~dКОU Же "ctIlPOC,

цй,К

€b!. €€о,Эuлu.

€ MySQ.L-1Т}ермu.н.але.

ПРОС1Т}О н.аЖМU1Т}е Kн.ol"1KY «бо»

(На Чй,1Т}Ь), Ч'vr\оdbt. "Qt) рос dbtJi €btt)олн.ен..

@! Show II\~ qUe!Y here lij)aJII

or ~ of .tom_1Itr. .,,_.----=>... . , с 8rowse ... ) (Мвк: 8,19Zl(8)

SQ. L-.3al) POCd

COmPreSSIOO:

@)AutocIe\ecI С Non8 O ~

CIIarac:!et $8tof It\e те:! ut18

После €€о,Эй,

.::J

н.аЖМu.-те Э'rrtу

цн.Оt)КУ- Ч"rr\Оdbt

€btIlОЛI'tU-тЬ e~o. Таким образом, вкладка с ярлыком SQL-утилиты рЬрМу Аdшiп предоставляет возможность вводить SQL-запросы непосредственно, как будто вы используете MySQL-терминал.

вы здесь ~

101


знакомство с запросом

INSERT

1'"enерь, KOf"Qa у меня есть оаза "Qэнных UmаОлuца, как мне ~~ecmu ~ HUX C~OU "QaHHbIe:?

Дn.

TOrO чтобы ввести данные в табllИЦУ,

ИСПОllьзуйте запрос Язык

INSERT.

SQL предоставляет множество продвинутых

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

просто шаблон, используемый для того, чтобы показать вам общий формат запроса INSERT.

дd.Лее сле.эу)(YV!J u.мe~

ОС"УТ)d.ЛЬн.bt.x

3dt1?OC W.!. Чu.ме1У\Ся.

с кЛ)О'-Iе€btx сло€ I~SIКT I~TO.

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

102

глава 2


соединение с MySQL

3апрос

INSERT

в действии ПОР_ДОК имеет

Далее опишем, как запрос INSERT может быть использован

значениеl

для того, чтобы добавить данные о похищениях космическими

Значения данных,

пришельцами в новую таблицу Оуэна aliens_abduction.

nодлежащиедо6авлению,

7n,o u.мst 'VI'}аdЛUu,bt, V\мeM €аШUX КОЛОl-lOк . должны6ыmь € KO'Vl'}0pJ)O dJЭJffl ~ € CljucKe, закл)ОЧе.н.н.оМ ~; nеречисленыmочновmакомжеnорRдке, эоdа€ле.н.bt. эакн.btе. 7n,o € скодки.. Orw. О'У!\.9еле.кbt ~ чmоuuменаколонокma6лuцы . 'НЕ u.мst dCIJbt. эан.н.Ь!.х. эруг. O"iТ\ эруг.а заl"l51"iТ\IJtМU.· О :·· ······· ·····0··· ················ ······ ·· ············ ·

aliens_abduction (first_name, last_name,

о.

О

when_it_happened, how_long, how_many, alien_description,

О

О

О

Ф

what_the_di~ fang_Sp~ted, othei» email) ('Салли',

О

'Джонс',

'зеленые с шестью щупальцами',

О

'3

дня назад',

'1

о

день' i

О

'четыре',

'мы просто разговаривали и играли с со6ахай'

е

' да', ' ВОЗМОiО, я видела вашу собаку, свяжитесь со /tМИОЙ' ( 'llу@ ва

IhnoP<?u

_ _

gregs-

1.

~st

CIlUCOK

дН4~н.u.й эclн.н.bt.x ЭЛЯ

€cex КоЛон.оц з l(Л)ОЧе.к € СI(Оdцu. Oн.u. "II'IaJ(Же

а

О"I!'IЭелен.bt. ЭРJг.

0'Yl1 9p:-Jг.а .3аIlЯ'Yl1bt.мu..

.net

,)

!

()

'в KOI-ill,e. So.\..-JQI"lРОСО~.

€C"iТ\poe~ ~ Р~f-КОМdНЭУ·

"iТ\очка С заl"l51'Vl'}ОU. € \-Le

c"iТ\a€u"iТ\c51. Ом сег.эа

C"iТ\a€u"iТ\c51 "iТ\олЬко € KOl-ill,е c """",o u.

~M"

~

VH\'-\(оМdl-Щbt.

3Qe':1O ё)e(iсrn&urnелЬНQ Heo~ чнQ

~ce Э'Vl'}U 3Н4Чек.u.я.

()

O'Vl'}I-lOСЯ"ll'lСЯ К "II'IeKC"II'Io€oMJ

&ыrлs:l~~u.lUU

I1I?UlJJелец~ 1-

"II'IUIlJ.IlOЭ"ll'lО.му

Oн.u. Jd.КЛ)ОЧен.bt. € ОЭ UН4 рн.bt.е

Кclgbt.ч~{u..

IOta6omllllb Таблица аl iens_abduction, показанная ниже, пока не содержит

данных. Запишите в нее данные о похищении Салли космическими пришельцами. Если вам не хватит места в ячейке для добавления

~o \J.МeM коЛО\-LОЦ .

,

какого-либо значения, напишите его над таблицей и укажите стрелкой , в какой из ячеек оно должно находиться .

8ы здесь ~

103


решение nроблем

u не Бы аеmm глупых вопросов

~шеное задачu Таблица

aliens_abduction,

показанная ниже, пока не содержит

данных. Запишите в нее данные о похищении Салли космическими

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

3елен.btе с wecl'r)b)()

МЬ.. \lPOCI'r)O рС\3Z0еctрu.€олu. u. IЦР~ЛU С содQI(ОU. "/

~\')<.V1bU,QMU..

aliens_ bduction Cctмu

Джон.С

3 ЭНЯ Н.Q,3~ 1 эен.Ь

~

Scl))у@з rе Э S -)isl.t)е ~о.3.мо.ж.к.о, я. €u.эем

гощ <о&1.у. ~

че"УУ\bt.ре

ЭQ

IfG 8ЪJ~rlG11t,

ZV11bJX ~011rOCO~

~: я не уверен, что до конца понял разницу между базой ~: А что по поводу phpMyAdmin? Где я могу найти это данных и таблицей. Разве данные хранятся не в них обеих?

приложение?

О: ЭТО так, но необходимо некоторое уточнение. Таблицы

О: в отличие от Му5QL-терминала phpMyAdmin -

служат для разделения данных на связанные между собой

это веб-приложение, предоставляющее доступ к базе данных

группы, в результате чего вы имеете дело не просто с одним

My5QL. По сути, оно является РНР-приложением, и это

огромным массивом данных. Это примерно как разница между

объясняет тот факт, что вы всегда получаете к нему доступ из

тем, чтобы свалить множество пар обуви в одну большую

веб-сервера, вместо того чтобы устанавливать как локальную

коробку, и тем, чтобы вначапе разложить каждую пару

клиентскую программу. Множество веб-хостинговых компаний

в отдельную, небольшую. Большая коробка маленькие коробки

-

это база данных,

таблицы. Таким образом, данные

хранятся в таблицах, а таблицы

t1)

-

-

в базе данных.

предоставляют

что оно для вас уже установлено. Если же нет, вы можете загрузить

:

-р Что в действительности является MySQL-терминалом? Как мне найти его на моем компьютере?

О •. MySQL-терминал -

phpMyAdmin как составную часть своих

стандартных хостинговых планов, поэтому вполне возможно,

phpMyAdmin и установить его самостоятельно.

Оно доступно для загрузки с сайта www.phpmyadrnin . net.

Но не забывайте, что это приложение должно быть установлено

на веб-сервер и настроено так, чтобы обеспечить доступ

это техническое средство,

к вашей базе данных MySQL, так же как любое другое РНР- и MySQL-веб-приложение.

позволяющее получить доступ к базе данных MySQL через интерфейс командной строки. MySQL-терминал не является

~

Это, скорее, соединение, которое вы устанавливаете

Что из них я должен использовать для получения доступа

• • Мне доступен и MySQL-терминал, и phpMyAdmin.

единственной программой, обеспечивающей этот доступ.

из «стандартного» терминала, используя интерфейс командной

к моей базе данных?

строки. В роли такого «стандартного» терминала может выступать, например, терминальное приложение в Мас 05 Х.

О

Способ, с помощью которого вы достигаете соединения

Преимущество

: Это вопрос исключительно личных предпочтений. phpMyAdmin заключается в том, что вы можете

с My5QL-терминалом, в значительной степени зависит

работать с вашей базой данных и таблицами визуально, без

от используемой вами операционной системы, а также от того,

необходимости вводить SQL-запросы. Это может оказаться

является ли ваш MySQL-сервер локальным или удаленным

очень удобным, если вы чувствуете себя достаточно уверенно

(то есть размещенным на вашем компьютере или где-то

в

в другом месте). В приложении

каждой мелкой операции. Тем не менее на этом этапе, чтобы

11 изложено более подробно,

5QL и не хотите вручную вводить запросы для выполнения

какие шаги необходимо предпринять, чтобы получить доступ

более полно понять, как происходит ваше взаимодействие

к MySQL-терминалу.

с данными в базе, лучше использовать SQL-запросы. А в этом смысле оба приложения работают достаточно хорошо.

104

глава 2


соединение с MySQL

-Тест-драйв Сохраните набяюдеНИR о похищеНИRХ космическими приwеяьцами в ваwей баэе данных с помощью SQL-эапроса INSERT. Используя инструментальное MySQL-приложение, такое как MySQL-терминал ,

или вкладку с ярлыком

SQL в phpMyAdmin,

введите запрос INSERT для сообщений

о похищениях космическими пришельцами. В качестве примера ниже приведен запрос

INSERT о

похищении Салли Джонс.

INSERT INTO aliens_abduction (first_name, last_name,

VALUES

('Салли',

'зеленые 'да',

с

'Джонс',

'3

дня назад',

шестью щупальцами',

'ВОЗМОЖНО,

я

видела

вашу

'1

день',

'четыре',

'мы просто разговаривали и играли собаку,

свяжитесь

со

с

собакой',

мной',

'sal1y@gregs-1ist.net')

~ ре.Jу.лЬ1Т\G\i1!е u.Сt"]олн.ен.LI.5!.

Запрос

JG\l1pocG\

Запишите внизу, как мы можем убедиться в том,

INSERT

€ MySQL-1Т\еr,мu.кдле К 1Т\С\алu.~е d.~iet"]s_C\bduct\otl

INSERT был выполнен успешно.

что данные были добавлены.

dbt.лd. .90dd.gлена О.9Н4 C"tl1fOKd..

вь, здеСh ~

105


знакомство с запросом

ИСПОЛЬJуйте

SELECT

SELECT,

Добавление данных в таблицу

-

чтобы ИJвлечь данные ИJ таблицы

это очень удобная вещь, но трудно избавиться от чувства беспокойства

по поводу того , что вы не получили подтверждения, что данные действительно прошли весь путь

до таблицы. Это примерно как если бы вы вносили деньги на свой счет в банке, но никогда не имели возможности проверить баланс. Запрос SELECT - это именно то, что позволит вам контролировать <;баланс~ своей таблицы в базе данных. Вернее, SELECT позволяет вам запросить отдельные колонки данных вашей таблицы.

3d кл}Оче€bt.М сло€ом

SELECT слеэуе'll\

SELECТ €cel.9ct 01Т}н.осu:~ся. к кок.кре'll\н.оU 'll\ct~лuu,е, ct н.е КО €ceй ~clJe .9 ct н.н.btx.

t)еречен.Ь

колок.о!(, .9ctн.н.bt.e !(O'll\0pbtx

€ctc перечень_колонок

имя_таблицы

t ЧdС1Т}Ь 3

liосле

SELECT I<л}ОчееО2-0 сло€ct fR.OM ctli POCd

Оliреэеляе'll\, Ц3 I(r.\.!(ой 'll\ctdлuu,bI. 3У.9У'111 €bl.дuрct'll\ЬСЯ эctн.н.bt.е . Имена колонок, перечисляемых в запросе, должны отделяться друг

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

Этот запрос

SELECT извлекает только имя и фамилию похищенных

космическими пришельцами из таблицы а 1 i ens_abduc t i оп:

3С\\1РОС

Запрос

SOL SELECT

uзвлекaem

gaHHble колонок

u3

rnasЛU1.jbL

SELECT

u.3€леК<::Iе1Т) .9d.ННbte 1Т}олЬко Ц.3 1Т}d.длuu,bt

<::I.Riel1s_d.bducfiOI1.

FROM aliens_abduction Для проверки выполнения запроса INSERT вам необходим быстрый способ, позволяющий просмотреть все данные, а не только данные для отдельных

колонок, имеющиеся в таблице. В запросе SELECT для подобных случаев предусмотрено сокращенное указание перечня всех колонок:

Сuм€ол «.3€е.3зоЧкct» гoo€oPU'll\

SELECI, Ч1Т}о к.еоdхоэuмо u,3€леl<<::I'II\Ь зctн.н.bl.е ЭЛЯ €cex

3<::1lipocy

!(олон.D!( 'II\<::I~ЛUu,bt. ~

SELECT * FROM aliens_abduction

106

lлава2


соединение с MySQL

-Тест-драйв Убедитесь в том, что запрос

IN5ERT на добавление данных

по похищениям космическими приwельцами выполнился, путем

извлечения данных с помощью запроса 5ELECТ. Выполните запрос INSERT, используя MySQL-терминал, чтобы просмотреть все содержимое таблицы aliens_abduction. Убедитесь, что в результате выполнения запроса появилась новая строка с данными, которые вы только что добавили.

SELECT * FROM aliens_abduction

~o I(ОЛОНJ{lJ..

3cthpoc SILICТ gЬfЙОЭlJ."'!Т)

110э к~жэоli КОЛОI-lXОu. Р~С\jолож.ен.bt Эd.н.н.btе. эля. i"lee.

еэu.н.с"'!Т)gенку}О С"'!Т)РОКУ

~~~, СОХРQн.е~ .f5 "'!Т)Qdлu.u,е.

Сколько строк данных в вашей таблице?

вы здесь ~

107


автоматизация составления запросов в РНР

Это так, каждое добавnение информации в базу MySQL требует запроса INSERT.

AaHHblX

и это именно тот случай, когда обмен данными с базой данных

MySQL с использованием запросов SQL в их чистом

виде

становится довольно утомительным занятием . Безусловно,

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

SQL-запросов в

MySQL не выглядит удачным решением .

Как вы думаете, проблема добавления

информации в базу данных может быть решена?

108

глава 2

MySQL Оуэна


соединение с MySQL

Пусть РНР 06ра6атывает эти утомительные эапросы Решение проблемы Оуэна заключается не в том, чтобы избежать

SQL

SQL, а в том, чтоБЬJ автоматизировать его

с помощью РНР. В РНР можно задать такой код, в результате интерпретапии которого на сервере будет составлен и передан на исполнение SQL-запрос и у вас не возникнет

Оуэн. c039ctel'lj SQl-,3ctt)рос

необходимости в использовании какого-либо инструментального программного обеспечения

INSIRT KOI'Ij0Pbt.u. 90дС1.6'ля.еl'lj

Это означает, что НТМL-форма Оуэна

MySQL.

эctН.Н.btе.

может вызвать РНР-сценарий для добавления информации в базу данных

t)lAcbМd.

после того, как эта форма передана на сервер для обработки . Никаких

11.3 элеюу\рон.н.оzо

g dd3Y 3C\;-(нЬ1.х.

электронных писем, никаких SQL-утилит, никаких проблем!

IOML-срорМd. г-ен.ерцре.t'r\ ~

элекYr\РОк.к.ое. liu.ebMO. KOYfjOP0e. l\ocYfjyMeYfj

К Оуэн.у, 110 еле Чег.о он.90л.жен. еручн.'j)О эодctеu.YfjЬ

.

..

::::=-=--___ _

.

::';~,:='-

110луче.!-\.!-\.btе

Э(l!-\.!-\.btе е dcIJJ &ез помощи РНР: требуется вручную

добавлять в базу данных каждое сообщение о похищении космическими приwельцами

с помощью SQL-запроса

INSERT.

с помощью РНР: РНР-сценарий, используя SQL-запрос

INSERT,

автоматически дополнит

базу данных, после

Toro как форма будет

передана на сервер для обработки. <?php

Sdbc = mysqll_Connect ('data allens J:x1 'allensdatabase') u uctedme сот', $

'owen'.

'allens r ool '

~r d~e .. ('ОШИбка соединения с MySQL-сервером ' );

INSERT INТQ aliens abducti Е' ·wheILit_ happend, how 10П - how оп ( lr~tJlame. lаst_пarnе . " . :what_ the_ did . fang_s;ott~d, ot~~Y ~~~~П:-dеsсriРtiоп , " . VALUES ('Салли ' , 'ДжОНС '. '3 ДНЯ Н ,, ' " ' зеленые С шеСТЬD щупальцами' , азад , 1 день' , 'четыре ', " . .. 'да', 'ВОЗМОЖНО. я видела Ba~ с:а:~с:~я~:;:~:а~:вали ~ и~рали

qu ry -

$res u lt. = mysql.l_query ( аЬс, $query) or dle

НТМ l-cpop.мo, 6'bt.3bt6'C1.eYfj РНР -cu,e.н.a.pu.u, KOI'IjOpbtu эоdС1.6'ля.еl'lj 9C1.KH.bt.e cpOfMbt 6' dct3J'

('Ощибка при ВЫПОлнении запроса к базе

МНой .

с СОбакой ' ,

.. .

sal1y@greg s -list . net')" ;

' ) ,

mysqli_close ($dЬc) ?>

PHP- сu,ен..-:lршJ созэ(~ еw, 3dl1POC

ЩSIRт. /{01\lOpbtCt ~одd,€ля.е'YIl 9ctHнboe форМbt g- Oc.IJ} .. l)J~н.

rte t)рJ.н.u.Jлctеw,

reportphp

§:. ~Yr\О/Л

к.еI10ср.еЭСYfj€е,...J{,Ог.о .~ЧctСYf\u.я.1

вы здесь.

109


как nриложение Оуэна может иСnОЛЬЗ0вать РНР и MYSQL

РНР управляет движением данных формы РНР расширяет возможности веб-формы Оуэна о похищениях космическими пришельцами, позволяя сценарию отправлять данные

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

Салли заполняет форму о похищении космическими пришельцами и нажимает

кнопку «Сообщение о похищении». Информация передается сценарию

report . php

на сервере.

о О

Gtnлu.

co€ceM н.еЗQ€н.о

дbtлo. t)оxu.щем 1( ОСМи. Че с 1( UМи.

reporthtml

t) рu.ше.льu,ctМu..

• 110

глава 2

Все больше и больше людей продолжают заполнять и передавать формы на обработку.

\.


соединение с MySQL

Сценарий Оуэна report . рЬр соединяется с базой данных MySQL и добавляет информацию из формы после каждой обработки, используя SQL-запрос INSERT.

Соодщен.usl о 1l0хu.щек.u.Я.x

СОХРd.КЯ)QYl\Сst € "VI\d.6лцu,е d.~ieIlS_d.bdlActiOI"\ € €цэ е C"VI\POK

_,.б..../ Эd.н..н.bt.x (Jd.lilAceOJ.

Оуэну необходим не только сценарий, который добавляет данные в базу, но и еще один, который просматривает ее и ищет нужные данные. Фактически этот сценарий должен играть роль главной страницы его саЙта. Сценарий index . рЬр соединяется с базой данных, извлекает данные о похищении космическими пришельцами и показывает их Оуэну.

Cep€ep да.з Эdн..н.bt.x .7"V1\0 IlPOC"Vl\O IlP°lpaм.м.a, Jd.Il~vJ,еКJ-(Qst

~ cep€epttoM

I(OMIi!;;)QYI\epe, ОдbtЧrw

Cu,eк.o.plAu. illdex.f*'p цз€леКd.е"Vl\

~"VI\омже, чу!\О

Эd.кнJ:iе LJ.J "VI\d.длLJ.(фt. d~ieliS_d.bdu.ctiOI) dd.Jbt "VI\dK, чу!\Одbt

ц €eд-cep€ep.

oн..u. Мог.лu. dbt"Vl\b О"Vl\фОР.м4"V1\LJ.РО€d.н.bt LJ. t'\OKd.Jdttbt 0y.7tty.

Оуэн может получать доступ к данным с помощью множества

новых способов, что позволяет ему

действительно сосредоточиться

на поиске своей

потерявшейся собаки

111 -.

Фэнга.

8ыздесь ~

111


создание соединения с MY5QL

Соединение с ваwей 6азой данных из РНР О'У!\.9ел "'I1'\ехк.u.ЧеСI(О~О Прежде чем РНР-сценарий сможет добавлять или извлекать данные из базы MySQL, он должен подключиться к ней. Подключение к базе данных MySQL из РНР во многом подобно тому, как это происходит при доступе к базе данных из MySQL-утилит. Этот процесс требует

одслуж.u€d.н.и.я. €d.шеЙ ХОС"'l1'\и.н.~о€оЙ I(ОМIld.Н.u.и. u.ли. €d.ш

€ed-.мa.c"'l1'\ep мог'jYYI9d."'I1'\Ь €C\М

!..AJIi\5l .7"'11'\ого xoc"'l1'\d.. VГли., если. €d.LU

ввода такой же информации. Помните три пара метра, которые вы

€ed-cer,€ep и. M:ySQ.L-сер€ер J'С"'l1'\d.н.о€лен.bL н.ct ~.9н.OM и. "'11'\0/1',

записали немного ранее при чтении этой главы? Вот они, вместе с еще

.же I<OM"b/O"'lТ\er,e, fГb!. мо.же"'l1'\е

одним, новым - именем базы данных. Давайте запишем их еще раз .

и.СГIОЛЬЗО€ct"'l1'\Ь € I(d.ЧеС"'I1'\€е .7"'11'\ого

и.Меf-UJ. сло€о ~ocd.~hosi:.

Размещение моего MySQL-сервера (IР-адрес или доменное имя)... .. .... .... ....... .. ..... ...... ,!

о Мое имя ПОЛЬЗ0вателя базы данных: •

')

........ ...... .......... ......... ........... .

Мой пароль: ........ .... ............ ..... ... .. ... .. .. ....

И/.-\5!. dG\,3bt. .9d.н.н.bt.x. I(O"Yr10pyro

€b!.. СО~d.Ли. рd.н.ее. d.1:d.bd.se. Е~лu "" .. t)o I(d.KlJ.M-1У\О СОООРd..жен.u.7VУ \ €b!.. .9d.Л\.I. c€oeй dd.з е .9d.I-tr\.bt.x .9ругое и.i.-\5!. u.лu

О Имя моей базы данных: .. ......... .. .... ..... ... ... .......... ....~ G\~\et) Размещение MySQL-сервера, имя пользователя базы данных, его пароль и имя самой базы данных

- все это необходимо для установки MySQL из РНР-сценария . После того

как соединение будет установлено, сценарий получит возможность

решu.ли. и.Сt)ОJъ,3оеd.1I\Ь сущеС1l\gУ~)Q dd.JY.9d.н.нb..x,

делать SQL-запросы, точно так же как вы делали это вручную,

t)Рu.Ме.к.Я.U"'l1'\е .7'1'f)O 1.JJv'5{..

соединения с базой данных

используя MySQL-утилиты.

nd.pd.Мe"'fY1,pbt, l(01l\opbte

uс\')О лЬзуе'l'f)е €bt. JIt.oc,'jYYI 01l\Ли. Чd.1I\ЬСя.

011\ 1I\e.x, 1(0'lТ\0pbte tioKC\3d.н.bt н.u..же.

Имя dd.Jbt .9d Mbt.x -.d.)ie"q'G\1d.bd.se: он.О н.е.оdхo.9UJЛ.О сц,ен.ctрщо

\

эля. oдMeн.Q (Aн.<:po~.мa. ц,и.е u С Э'l'f)оu dd.JОЙ эС\н.н.bt.x

<

Это dd.3d. Зd.Н.н.bt.x

И. 'IY1С\dли.up., /{01l\Opy)O

vt'v\Я. 'l'f)d.дли.ц,bt·­ d.~ie.rls_C\6ductiOI") .

СО3Зd..ли..

.90 'lТ\ex t]op. t)OKd. €b!.. н.е н.c.IЧн.е'lТ\е и.сtiОЛЬ30~С\-I1'\Ь 50..\..- 3C\t)pocbL

€b!. "(f\ОЛЬКо '-I"'fТ\o 112

lлава2

Он.о н.е одн.c.lру.жu.€d.е'lТ\ седя.


соединение с MySQL

Добавление данных с помощью РНР-сценария Осуществление MySQL-запроса с помощью РНР-сценария требует от вас вначале установки соединения с базой данных. Затем вы должны создать запрос в виде РНР-строки. Он не будет выполнен до тех пор, пока вы не отправите его на сервер баз данных. И, наконец, после того как вы завершите выполнение всех запросов к базе данных, необходимо закрыть соединение. Все эти задачи кодируются в РНР-сценарии. Вот пример, в котором показано, что происходит при добавлении новой строки данных о похищении космическими пришельцами:

3э есЬ Э ОЛЖнbt dbL'tr\b че'tr\bLре Ilctр~е)Т}рd.; MUМ, ct н.е О:уэн.о...

<?php $дЬс

mysqli_connect .'

or die

('Ошибка соединения с MySQL-сервером'); ~оJМО.жк.о, €b!. d:igeW\e uсt) ОЛЬ 3 0€d.'tr\Ь

~occt~host ~MecW\o эомен.к.ог.о () Кctчес""€е MeclТ\ct $query = "INSERT INTO aliens abduction (first пате last пате ". uмeн.u х ос""'''' "1 ~'" , , ctJМеще.н.u.я. €ctWeU dctJbt эctК!-l.btx. "when_it_happend, how_long, how_many, alien_description, " "what_they_did, fang_spotted, other, email) • . "VALUES (' Салли', "'зеленые "'да',

$result =

с

'Д.жонс',

'3

дня назад',

шестью щупальцами',

'возможно,

я

видела

вашу

'1

день',

'четыре',

" .

'мы просто разговаривали и играли с собаку,

свяжитесь

со мной.',

собакой',

" .

" . 'sally@gregs-list.net')";

F-----------~ СОдэctU'tr\е 3d.I1POC INSERT mysqli_query($dbc, $query) €ffu.э е c'tr\P0I{U PHP-КОЭct. 3эесЬ 3~эыт\e

or die

L----_

('Ошибка при выполнении

запроса к базе данных.

');

осоден.н.о

ен.uМctlТ\еЛЬн.bL

с UС\Jоль з оеctн.uем

mysqli_close($dbc) ; ?>

oЭUНдУк.btX U эеоuк.btX кctеbtчек. 1Т\ctК ж,е KctK U с \)rоdе.ло.мu I \)еrеэ U \)осле н.шс

Как вы думаете, что делает каждая из этих РНР-функций В сценарии?

mysqli_connect() mysqli_query ( ) .mysqli_close ()

вы здесь ~

113


три РНР-функции для МУSQL-соединенuя

Испоnьзуйте PHP-фУНКЦИИ ДnЯ соединения с lii30Й AiHHblX Существуют три основные РНР-функции, используемые ~

для обмена информацией с базой данных

mysqli_connect () ,mysqli_query ()

MySQL:

у,

иmуsqli_сlоsе

Если вы заметили повторяющийся префикс

-

().

это не совпадение.

Все современные РНР-функции, которые осуществляют / взаимодействие с MySQL, начинаются с mysql i_. ~

щуsqli_соnnесt() Открывает соединение с базой данных

MySQL,

используя

информацию, содержащуюся в четырех параметрах, о которых

mysqli_query() Осуществляет запрос к базе данных

MySQL, который

часто

Закрывает соединение

связан с добавлением или

с базой данных

извлечением данных из нее.

MySQL.

вы уже знаете.

Использование этих трех функций обычно происходит по вполне предсказуемым этапам.

Откройте соединение с 6азой AaHHbIX, испоnьзуя функцию

mysqli_connect() •

Передайте функции в качестве аргументов адрес размещения сервера, имя пользователя и его пароль,

чтобы получить разрешение на обмен информацией с сервером баз данных

MySQL.

У кажите также имя

базы данных, так как соединение осуществляется с конкретной базой.

о Создание переменной и присвоение ей значения строки SQL-запроса. Для обмена информацией с сервером баз данных вы должны использовать SQL-запросы . Например, запрос INSERT необходим для того, чтобы добавить данные в таблицу

aliens_abduction. Не существует специальных требований

к выбору имени этой пере мен ной

(кроме общих требований к РНР-переменным), но непосредственное имя

$query

(переводится с английского как «запрос») можно считать удачным .

.3qt)poc СОJ.9Q н.

е еи.9е c~pOl(oeoй l1 е ремекн.ой $9 uery.

'-------=----~~ 114

глава 2


соединение с MySQL

Передача запроса на сервер дnя выпоnнения с испоnltЗ0ванием функции

mysqlCqueryQ. Используйте переменную

на сервер баз данных

$query в качестве аргумента функции mysql i_query ()

al iens_abduct ion. С функцией mysql i_query () которое вы создали на этапе

на этапе

для передачи

MySQL информации, необходимой для добавления данных в таблицу вы должны передать серверу ссылку на соединение,

(1), и имя переменной, содержащей строку вашего запроса, созданную

(2).

ЭmQ ф,'jl-U<u,u.я €btt)олн.lХУ!'\ €QШ 3Qf1 POC INSERT ~ н4 .90~€лен.u.е .9ФtНbtx € "YI'\Qдлu.u,у.

э";ю.5ае...е",,,

mysqli_query ( )

()О

&mа6лuцу, коmоrзя

~

у&асесть!

о

Операция ВЫпоnнена ycneWHO!

Эакpьnиe соединения с 6а3ой данных с иa'IOIIlt3OIICIнием функции И, наконец, функция

mysqll_closeO.

mysql i_close ( ) сообщает серверу баз данных MySQL о том,

что вы прекращаете обмен информацией с ним.

о

00

Соединение закрыто. ~o u.МЯ. ccbtJ1KU. н4 coe.9ик.eн.u.e с daJou .9aн.нbtx MySo..\...

$dbc = ilit~likJiiJI'_~ifil1i,,( 'data. aliensubductedrne. сот',

'owen' , '

INSERr,

€ реJУЛЬ"Yl'\Q"YI'\е €btt)олк.ен.u..я I<O"ll)opozo .9 а н.нЬ!.е

"~л;,~:t~~~~~нш.

<?PhP;J_ .2__ ,.. •

Эmо SQ.L-3QI1POC

Еслu. ЧYr}о-н.u.dу.9Ь f1ou.ge"ll) к.е "II)aK,

~dJlbк.еuшu.u ХО.9 "p0г.paммbt

.90даgля.}О)Т}ся. € €QШУ dc1J} iensrool',

'aliensdatabase')

.: : die ('Ошибка соединения с MySQL-сервером ' );

Вt~~1 = "INSERT INTO aliens_abduction ( first_narne, last_name, " . "when_it_happened, how_long, how_many, alien_description, " . "what_the_did, fang_spotted, other, email) " . "VALUES (' Салли', " ' зеленые

с

'Джонс',

'3

дня назад',

шестью щупальцами',

'1

день ',

' четыре' ,

'мы просто разговаривали и

"

играли с

собакой',

" .

"' Д~':;j'.~:i:::':{' ~a вашу собаку, свяжитесь с::нсй~~м~~~~;;~~~s~у~qj~~9u.~rу()

$r,,:~, d;е~:::~п~~':'У:аnpoса к ба" дa~ ." !~:~:r":м'~1:::r~~~к~э.

Зае Ь JIIbt О ~i<k;!i".nr&tdl%~ _,д!:m::.\О!:·=т"",}!! С J

JQl<fbt.€'aeM

?>

сое.9tлн.ен.u.е.

СО.9 е р:ж.а.щ. 5 u.u.fСЯ !,\;рремек.к.оlЛ ~lЛеуу, Э"II)о 1<0.9

50.1.-, Q к.е 1ft .

Давайте взглянем поближе на каждую из этих РНР-функций по работе с базами данных, начиная с

mysqli_connect ( ) ... вы здесь ~

115

_


UСnОЛЬ308Qнuе MySQL

~ CoUllllallIH nOМOUlIllO тysqICconncd(). ~

Чтобы ваш РНР-сценарий смог создать соединение с базой данных с помощью функции

mysql i_connect ( ) , вам

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

Со""а&ШlIIС ""POI(II }anpoc&

О

f ..nOAtlalllc }anpoc.a , IIMIi_1UuyO.

О

пкр".к сШlIНalUII , noМO\lllltO 117S11i_ cI.osc().

noмoUllllO

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

Кто?

размещена ваша база. Эти данные вы либо устанавливаете сами, либо получаете от хостинговой компании, когда

MySQL устанавливается

впервые. Если вы

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

Имя вашей 6аэы данных. В нашем примере мы назвали базу данных aliendatabase. Ваша база данных может иметь любое другое имя, которое вы решили ей дать, когда создавали ее. Если базу данных для вас создавала ваша хостинговая компания, используйте то имя, которое вам

сообщат в ее отделе технической поддержки.

Расположение вашей 6аэы данных (доменное имя, .Р-адрес или

localhost). В нашем примере мы использовали несуществующее имя для места расположения базы данных Оуэна. Вы должны использовать реальное место расположения вашего MySQL-сервера. Часто это

localhost, если сервер баз данных расположен на том же компьютере, что

и веб-сервер. Ваша хостинговая компания сообщит вам эту информацию. Это может быть также IР-адрес или доменное имя, как у Оуэна; например, вашсевер . вашпроваЙдер. сот.

CJ>yнкuU9

Имя пользователя и его пароль для сервера баз данных, а также расположение MySQL-сервера и его имя в функции

mysqli_connect ()

/ ~

mysqlcconnect< )

должны заключаться в кавычки.

ИСt)ОЛЬJУU'fl)€ ЭYr1У

t1eyeMeMYK> ЭЛЯ tlроееэек.uя рd,JЛLA чн.bt.x Ot]ePdu,LAU с ddjОЙ .9 a н.нbt.X.

$dbc = mysqli_connect('data. aliensubductedme.com' , ИМ51 ~ 'owen' А Г\ оль зо (5d'V!\е.Л51. 1. ' 1 ' - - РdJft\€щеi-llAе. ~ , а lensroo ' дQ,3bt ClMbt.x

('aliendat~base'); Т/С\рол.ь. '''----- И,>ЛSt дС\3Ь'-

Э·

.9 C1 нrt.bLx .

В результате вызова функции создается РНР-переменная

со значением ссылки на соединение с базой данных. Используя эту

переменную, вы можете обмениваться информацией с базой данных. В нашем при мере эта переменная имеет имя

ей любое другое понравившееся вам имя.

116

глава 2

$dbc,

но вы можете дать

paccмaтpuвaem С50и

аргументы (uмз n0Ab30вameA9

nароль ваз

gA9

gaHHblX.

u

его

сервера а также

расположение

MySOL-cepвepa u его uмsv как строки.

noomOMY

вы gолжны

заключать

в кавычuu

ux


соединение с MySQL

~ремя nорабоmаmь Ниже следует несколько примеров РНР-кода, обеспечивающего соединение

"

-

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

$dbc = mysqli_connect('data.aliensubductedme.com', 'aliensdatabase') ;

'owen',

'aliensrool',

$dbc = mysqli_connect('data.aliensubductedme.com', -aliensdatabase-)

'owen',

'aliensrool',

$fangisgone = mysqli_connect('data . aliensabductedme.com', 'aliendatabase');

'owen',

'aliensrool',

'owen',

$dbc

mysqli_connect('localhost',

$dbc

mysqli_connect( ' data . aliensabductedme . com',

'owen',

$dbc = mysqli_connect('data.aliensabductedme.com', mysqli_select_db($dbc, 'aliendatabase');

'owen',

'aliensrool',

'aliendatabase');

'aliendatabase');

'aliensrool');

вы здесь •

117


решение

~ешеное задачu Ниже следует несколько примеров РНР-кода, обеспечивающего соединение

"

с ба зой да н ных . Посмотрите на каждый и з ни х и запишите, будет ли он работать,

и если не будет, то как можно исправить это положен и е. Также обведите карандашом каждый проблемный, по вашему мнению, фрагмент кода.

$dbc = mysqli_ connect( ' data . aliensabductedme.com', 'aliendatabase ' ) ;

'owen',

' al i ensrool',

... ...... . ?:tnc;J...<im.p.~~c;J...~уэ~m. f.~?C?m.c;J.!!\~:......... .. ...... .... ... ......... ... ................. ................... ..:.... ....... .

. . ········~~~t~:~:~~:~~:~:·i~?-~~·~(1л:я~'ffIог;6:····~~~~:~;:3~~~;;~~~r~~::l~: Л5l р:э Ж Н.uЯ.

Э

(t('data ; . aliensabductedme . com',

$dbc = mysqli_con "aliendatabase "

J

u.СIjОЛЬjО~dkuЯ. u.x ~S(),L-jdt)rОСdX.

' owen' ,

' aliensrool ' ,

.~~: ~.1YJr9.~~. ~~ .~~.9.~m .р~~?:-rnt;.\'(I)?',..t)~!1\~~~ .~9..~. ~~. ~.9t!-~~. ~!1\~Y!!\~!:,)~)'~!1\. !!\?~~~ .~. 'з~I).~~?~:.... . .oд~9.i;i.~~ .1:<~~i:'.t.~~~.э~t))'9~~~~~,. ~~~..~.~. ~~~..l!-..<?.9\!-.~p.~~: ... ........ .. ..... ........ ....... ........... ..... .. Не слu.u..u<оМ u.кфОРМd'lf\u.€н.ое ш::я. эЛ5l одОjн.ctЧеt-lU.5l

_--._~=--- t)ер еме н.н.оi1 сое.эu.н.еt-lU.5l с ddjou. ЭdКJ-tbtx. ~ngiSgO~= mysql i_connect('data . aliensabductedme . com',

'owen ' ,

' aliensrool',

' aliendatabase ' ) ;

............ ЭrtJQ.~У.9е.'Щ. p,<l.dQ"tI:\d.mb, Ййm .'ЩМЬКQ .u.ЩМЬJQ€ан.Q. -,:\.е. ~Л!,.l,WКQ.м.. .... .. .. ....... ........ ............. . ............ \J:t1:фRр.~i\Н~€t1:9~. ~.Э,[]-?\.I.1.~f.~~~~!1. ~9·Е?Э\J:~Е?·~· ~. 9~9.~. э~~·........................... . .с-- llpu. услоgu.u., 'hт\o се.реер ddj .9aн.н.bt.x УС'У!1dн.оgлен.. r--~-

t\.d

'У!10М Же KOMllb)O't\jepe., 'hт\o u. ee.д-ce.p€e.p.

$dbc = mysqli_connect~calh~ 'owen ' ,

' al l ensrool' ,

' a l lendatabas~ ' ) ;

.....щ'Q. ctуэе.1ТI· f<l.дQi1\ аmЬ. !1 р!,.l, ·Y~11Q€!,.I,v..· ~Q . C.~f€~·P· ~.;!J. ЭQ.~ .:У~1r.\!1.н.9.в!1~t1: ....... .... .. ...... ......... . ..... М .!1\.<?~..~.~.К?~lJ.ч~~р.~/.~~.\J:.~~~-:-.<;-~f.~~р............ ............. ...... ......... .. ......... ...... ........ ..... ... llУС'У!10о. t'\dРОЛЬ -

______ •

н..е слu.u..u<оМ :JЭdЧн.ct5l u.э е5l . ~ $dbc = mysqli_ connect( ' data.aliensabductedme . com ' ,

' owen"~

'a l iendatabase ' );

..

......Еслu. .€bt. .у.с1f\.dНдgu.:Yr\е. .\':);;IС:ЩО,й.. ~ctРQJ.lЬ.,9Мt .€ctш.е.il. dQJb1. эакн.t-м э.-щQ .~~.9-e.m .pt.\dQ:YJ19.mp., ..... .. . ..... .~т!\. :m~.[]9H~ .-7."!\\R ЗWJ~К<? .~.I? ~~~ "у3<;\':/М-?\ . ~э.~?!-! . ~ ·У!l~Ю~!1\· .~~~.~Э~ )'~!1\~~~!I~~c;J.~~..... . I1dРОЛЬ э л5l Кd>К:ЭОu. д<:\3Ь!. Эdн.н.bt.x. ~ СЛУЧdе, еслu. че'У!1gеРi11Ьtд aP~Me.н.'Y!1 н.е. указа н.

зэе.сЬ, ео.м н.еоdхo.эu.мо dуэеi11 fs'bLdPC\i11b ddjY Эdн.н.btx €bt.JO€OM фун.кu,u.u. i11ys9~\_se)eci __db().

$dbc = mysqli_ connect('data . aliensabductedme.com ' , mysqli _ se l ect_ db($dbc, ' aliendatabase') ;

118

глава 2

' owen ' ,

' a li e n sroo l ') ;

}

~


соединение с MySQL

110ХОЖе, nоmerяmь какuе-лu8'о ()анные, Heo8'xoQUMbIe ()ля соwuненuя с 8'а30(I, 8'ОЛЫ!lОГО mrY()a не сосmа"ляem. I<aK мне у8'wumься, чmо соеОинение ra8'omaem:?

Это тот CIIучай,

РНР-функция РНР-функция

KOrAa свои возможности демонстрирует

dle().

die ()

прерывает ход выполнения сценария и выводит

сообщение о коде, который выполнить не удалось. Хотя это и не раскрывает всех причин неудачи в подробностях, функция

die () все же сообщает нам:

что-то случилось и необходимо принимать меры по решению проблемы.

Если что-то не так с одним из четырех аргументов, необходимых для соединения функции mysql i_connect ( ) , или сервер баз данных не может быть найден, функция die () останавливает ход выполнения сценария и выводит сообщение об ошибке, которое передается ей в качестве аргумента в скобках.

вы эдесь •

119


построение заnросов в РНР

Отлuчно. Итак,

Mbl устаное,uлu

PHP-соwuненuе с оазоu ()анных.

о

Что menerb~ Можем nrocmo начать nerwae,amb cere,erY ~пrощ как мы ()елалu Jmo из Му5Qvтеrмuнала~

Да! Коль скоро вы установили соединение с базой данных, используя функцию mysqli_connect(), можете передавать серверу на выполнение

SQL-запросы непосредственно из РНР. Практически все, что вы можете делать в MySQL-терминале, вы можете делать и з РНР-сценария при наличии соединения, которое вы только

что создали. Это соединение, которое устанавливает канал обмена информацией между РНР-сценарием и базой данных

MySQL.

Например,

сейчас, раз у Оуэна имеется соединение с базой данных, он может начать

добавлять данные в таблицу al iens_abduct ion, используя для этой цели

mysql i_query ()

и соответствующий SQL-код.

Не 3Qd(;nJ{QuYrje, rw.w'o. u,елЬ 3Q1{ЛlО Чd,еiТjС5{ g YrjO/\>\ Ч't!)одbL

d,gYrjOJV\d,'Yr~u.~U.pogd,Yrjb созэС\К,u.е 3d,\ipocc\ j,NSF.RT с t)омош,ыо РНР.

mysqli_querY($dbc,

So.L-"а"рос \iе~еэС\еYrjс5t

cpyГU<u,u.u. YrjYS9~i_9uery() КаК ?H?-С1Т\рока.

Функции mysqli_query () необходимо передать в качестве аргумента SQL-запрос в виде РНР-строки (значения переменной

$query), для того чтобы произвести добавление данных о похищении космическими пришельцами.

120

глава 2


соединение с MySQL

INSERT

Построение запроса

в РНР

SQL-запросы в РНР представлены как текстовые строки

и обычно передаются функции mysql i_query ( ) в виде строчных переменных. Так как текстовые строки,

содержащие SQL-запросы, могут иметь достаточно большую длину, часто возникает необходимость составить строку запроса из нескольких строк меньшего размера. Запрос Оуэна

INSERT

Ol')epct'lТ\op '<'YI'\оЧкct:» zogopu.'YI'\

наглядно это демонстрирует.

РНР сое.эu.к.u.'YI'\Ь Э'lТ\У C'YI'\POK'y

Эmо С'lТ\рочн.ая \iере.меКJolctЯ РН?, KO'lТ\opct5l СО.9ер.:>fШ.'IТ\ .3ct\iPOC I~SIRT.

со сле.эУ)ОЩеЙ C'YI'\POKOU.

"

j

"what_the_did, fang_spotted, other, email) "

"VALUES (' Салли', "'зеленые

с

шестью

'ВОЗМОЖНО,

я

видела

~YММctpк.o gecb

;/'

~o.9 Эр'Yl'\н~U C'YI'\P~KU. _._~

"''IТ\o f -ко.э, ~ ezo 1< ок.це ..90ЛЖн.а

.С'Yl'\ОЯ'YI'\Ь 'YI'\ОЧ/(ct с j<Щ Я'Yl'\ ой.

1): Почему

вашу

назад',

'1

день',

'четыре',

с

собакой',

собаку,

" .

свяжитесь

со

мной',

" .

С'IТ\РОКб. jctt1pocct рctСllре.9 еле н.а .ме.Ж:9:i к.есколЬкu.мu. C'YI'\poKctMU. KOQct Ч'lТ\Оdbt сэеЛct'lТ\Ь ezo долее уэоdкbt.М .9 я. IlРОЧYr\еrU:; u. 1l0к.u..мcttшЯ.. ТоЧкu. ~О€ОРЯ'YI'\ РНР соеаu.к.u.'YI'\Ь gce KOPo'Yl'\Ku.e c'Yl'\POKU. g оэк.у элu.к.н.У)О· J I I

л

После составления SQL-запроса можете передавать его функции

INSERT в виде строки текста вы mysqli_query () для выполнения .

IfG 5bJffi01G't1b

ZVl1blX ~011ГOCO~

называется 1): Почему строка запроса INSERT

SQL-KOA INSERT (query)

запросом? Разве «запрос»

" .

"

и играли

"'sally@gregs-list.net')

TctK I<ctl<

дня

щупальцами',

и,мы просто разговаривали "'да',

'3

'Джоне',

не означает, что мы просим что-нибудь

не создается как одна большая строка?

1):Обязательно ли перечислять имена колонок в запросе

INSERr?

О: Не забывайте, что строка запроса

О: Нет. Вы можете не перечислять имена

одна большая строка, хотя и создается

случае вы должны перечислить значения

означает, что вы просите что-нибудь ...

из нескольких строк меньшего размера.

для всех колонок таблицы строго в том

вы просите базу данных сделать что-нибудь.

В идеале строка запроса

порядке, в котором они перечислены

В MySQL-приложениях баз данных

бы кодироваться в виде 0ДНОЙ большой

в структуре таблицы. Принимая это

слово «запрос» употребляется в общем

строки, но, как многие другие строки

во внимание, более удобно и безопасно

смысле, который имеет отношение

SQL-запросов, строка INSERT обычно

перечислять имена колонок в запросе.

к любому действию над данными, включая

имеет большую длину и не помещается

у базы данных?

О: Да, «запрос» (query) действительно

как их добавление, так и извлечение.

INSERT сохраняется в переменной как

INSERT могла

колонок в запросе

INSERT.

НО в этом

в строку кода, имеющую «нормальную»

длину. Поэтому удобнее рас~атривать такую длинную строку запроса составленной из нескольких коротких строк, «склеенных»

между собой оператором РНР «точка».

8ыздесь ~

121


функция mysq/Cquery()

Выполнение Jапросаи баJе данных ИJ РНР

MySQL

Функции mysql i_query () необходимы два аргумента

для выполнения запроса: ссылка на соединение с базой данных и строка SQL-запроса.

ссыnка_иа_сое~ние_с_базой~аниых,

~ ~ ..trI\O ccbvll(C\ М соеэu.к.ек.u.е с дС\.3оо. эфtНbt.x, I(О"уу\ОРОе. уже dbvlo ус"УУ\С\но€лен.о рС\нее. €bt.jO€OM функu,uu. "VY\YS9~i_c.ot)l)ect().

запрос);

Уто So..\"-.3C\l1p0c., KO"VY\0pbLu.

~ d e"vy\ €Ьt.\")Олк.ен.. •• "vy\O"vy\, KO"VY\0Pbt.U.

y~

""

сохр

С\кuлu. € C"VY\DOKO€OU. _

I

1) е ремек.к.о u..

Ссылка на соединение с базой данных была возвращена вам ранее

Не jC\db!.€C\u"yy\e: Э"уу\u.

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

о"vy\лu.ЧС\"уу\ЬсЯ ЭЛЯ €С\шеu.

соединение.

1( oн.cpu.г ypC\u,u.u.

функцией mysqli_connect ( ). Если вам не совсем понятно, о чем идет! ll e peMeнн.bt.e могJ!!l

&t.3bt. ЭС\н.н.btx.

~IIIII = mysqli_connect('data.aliensubductedme.com', 'owen', 'aliensrool', 'aliensdatabase'); or die ('Ошибка соединения с MySQL-сервером');

l

СсbtЛl(С\ М соеэu.к.ек.v.е С dcIJou. ЭС\~ дbt.М сохрС\к.ем € Э"vy\Оu. l"\epe.Meк.к.ou. рС\к.ее.

Итак, у вас есть соединение с базой данных (переменная Все, что осталось,

$result

-

это только передать их функции

= • •r~( $~

l'or die ( 'Error querying

L ~_

..1 "\0

$dbc) и SQL-запрос (переменная $query). mysql i_query () в качестве аргументов.

реjУЛЬ"уу\С\"vy\

3С\1l РОСС\.

Этот код показывает, что вызов

$~ э-mо SQL-Jc(llpoc. database. ' ) ~o ссbtЛКС\ мl-U-I.bt.X соеэu.к.е..ш.е С dcIJ°U. эd.

mysqli_query ()

не является

SOL-зanрос это mpesoвaнue. наnUсанное

на 93Ь1Ке

SOL

U otnnраменное

односторонним процессом. Функция возвращает вам информацию,

на сервер saз

содержание которой присваивает переменной

gaHHblK

$resul t.

реальных данных в результате выполнения запроса

Но никаких

INSERT

не возвращается . Эта переменная только информирует вас о том, удачно или неудачно завершился вызов функции

Ч'унк\JUU

mysqlj,_query () .

gлs

вьтолнeншt

mysqlCquery( ) нeosкoguмы1 ссылка

на ~Heнue ~ saзoй gaHHbIK.. у 9!:~Ka SOL-зa1!JJ9'!l. gлs того чтОБЫ выполнить этom запрос.

122

zлава2


соединение с MySQL

3акры иеe соединения с помощью

фvнкции

mysqli _close()

Так как мы заинтересованы в исполнении только запроса

INSERT, обмен информацией на этом заканчивается, по крайней мере, для сценария. А раз вы завершили работу с базой данных, соединение с ней необходимо закрыть. Соединение с базой данных будет закрыто автоматически, как только посетитель сайта перейдет с текущей страницы на новую, но, как привычка

закрывать за собой дверь, закрытие соединения после окончания работы с ним считается хорошим стилем программирования. Функция mysqli_close () закрывает соединение с базой данных.

XopoUJa9 nРU5b1Чка зaкpb1Вatnb coeguнeнue

~

7tnO

ссbt.ЛКd. н.а Gоеэu.к.еrш.е

с дd.JОu. Эd.к.н.btx,

KO"Yf\0pOe

€bt u.сt\ОЛЬЗ0€о.лu. эля. о6мен.а u.K<f)O p.мct u,u.eu. с к.е u..

mysqli_close ()

~ $dbc) ;

MySOL сразу же после

раБОты с нei1.

в качестве

аргумента ссылку на соединение с базой данных, которая сохранена в переменной

gaHHblK

оконча1-l'Ш:1

В случае со сценарием Оуэна нам необходимо передать функции

с saзоi1

$dbc.

Зн.аЧек.u.е.м Э"Yf\ой I1ере.мен.н.ой я.€Л5!.е"Yf\Ся. ссbtлкd. н.а соеэu.к.ек.u.е с dd.JОЙ .9C1.н.нbt.x,

GOJ.9d.Ko

1(0"'11)0

ое dbtло

€bLJО€О-;:оФУк.кu,u.u. "'II)'yS9~i_cfl1l1ect() ран.ее

I(ог.9а Ок.о О"'ll)КРC1tt>d.ЛосЬ

€l1 epgbLe.

l'

Но шu COWUHe.tiUe

с оазоu ()анных ~кrы&aemся а&mомаmuческu, ~чем

оесf10коumься~

Сервер баз данных выдеll.ет оrраниченное КОllичество соединений, доступнь.х одновременно, поэтому чем

раньше они будут освоБО1КДатьс., тем lIучwе. Как только вы закрываете соединение, выделенные для него ресурсы

освобождаются и могут быть использованы для создания нового соединения. Если вы работаете с разделяемой базой данных, вам будет выделено, например, пять соединений. И если вы создадите в таком

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

вы здесь ~

123


никаких глупь,х вопросов и ключевые моменты

'Р: Разве мы не можем просто записать весь SQL-KOA

'Р: Должен ли КОд, в котором используется запрос INSERT,

переменной

mysqli_query()?

непосредственно в функцию

mysqli_query() вместо

$query?

О: Можете, но это затрудняет чтение и понимание кода. Представление SQL-коАа в виде строчной переменной

с последующей передачей этой переменной функции

mysqli_query ()

в качестве аргумента делает ваш код

делать что-либо с результатом, возвращаемым функцией

О: Скорее всего, да. Пока что мы использовали die ( ) для того, чтобы прервать ход выполнения сценария

и передать браузеру сообщение об ошибке, в случае если что-то идет не так. Со временем вы, возможно, захотите

немного легче для прочтения и понимания, что упрощает его

передать пользователю более подробную информацию, если

СОПРQвождение.

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

КЛЮЧЕВЫЕ МОМЕНТЫ •

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

Функция mysql i_c onnect ( ) создаетсоединение между вашим РНР-сценарием и сервером баз данных MySQL.

Функция

di е ( ) прерывает ход выполнения сценария

и передает браузеру сообщение об ошибке, если создать соединение не удалось.

Выполнение SQL-запроса из сценария РНР включает представление запроса в виде текстовой строки с последующей передачей его в качестве аргумента функции

mys ql i _qu ery ( ) . •

Вызывайтефункцию mуsqli_сlоsе

() длятого,

чтобы закрыть РНР-соединение с базой данных MySQL сразу же после окончания работы с ней .

124

zлава2


соединение с MySQL

-lест-црайв Замените код с эnектронной почтой в сценарии Оуэна report.php так, чтобы он добаВnRn данные в базу данных и проверьте ero работу. Удалите код в сценарии Оуэна

report . php,

MySQL,

который отправляет данные формы

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

MySQL, создает

SQL-запрос в виде РНР-строки, передает запрос серверу баз

данных на выполнение и, наконец, з акрывает соединение .

Загрузите новый файл

report . php на ваш веб-сервер и откройте страницу report . html

в браузере, чтобы получить доступ к форме <iСообщения о похищениях космическими

пришельцами!>. Заполните поля формы и нажмите кнопку «Сообщение о похищениИ», чтобы сохранить данные в базе. Затем запустите свою инструментальную программу

MySQL

и выполните запрос SELECT, чтобы увидеть изменения, произошедшие в базе данных.

Это правильно? Напишите, как вы думаете: то ли это,

что сценарий должен был сделать, и почему.

вы здесь ~

125


использование $_POST в INSЕRТ-заnросе

110()ож()umе секун()у, f'азl'е rлаl'ная зэ()ача не заКЛКJчaemся l' mом, чmоаы l':Jяmь ()энные

l' cf0rMe Uсохrэнumь ux l' аазе ()энных?-110ХОЖе, 110 зэпrосу ~l'о()яmся O()HU Ume же ()энные незаl'uсuмо om moro, чmо аыло l'~e()eнo ~ cfOrMY. Я не ~uжу, как зmоm f1-If'-cцeнaruu аl'mомаmUЗUrYem nroцecc..

Это боnьwая пробnема. Запрос INSERT доnжен быть cocтaвneH так, чтобы добавnять данные формы, а не статичные строки.

В запрос, который мы составили, включены жестко запрограммированные строки вместо текстовых данных, введенных

в форму о похищении космическими пришельцами. Для того чтобы

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

mуsqli_чuеry (

)

\....""----.,.. ~ Эmu.М 34t-U-lbtМ н.е06хозu.МО

ФорМq о t)охu.щен.u.u.

l\ol\4cYf\b g CYf\POK~ j41"\pOCa $C\uer~.

)(Ос.мu.Уескцмu.

t'lfu.щельUf:tМu. Э'll1о Mec"'tYjo,

0'111 КУ.94 t)ОС"'tYjУt)С\Ю'I!1

.9 4 н.нbt.e t)осе."'tYju."'tYjелеU

C4U"'tYj4.

126

zлово2

Какой РНР-код может помочь нам передать

значения полей формы в INSERt-запрос?


соединение с MySQL

$_Р051

передает данные формы

Хорошая новость заключается в том, что сценарий

report . php

содержит данные формы, сохраненные в суперглобальной переменной

$name

СУIlе.рг.лодdЛЬк.У}Q ll е реме.к.к.уlO $_POSТ мbt.

$_POST. Помните этот код?

=

$_POST [ , firstname']

.

'

, . $_POST [ , lastname' ]; уже u.Сllользоg~Jlu., Ч1т10дbt

$when_it_happened = $_POST['whenithappened'];

~ u. I1pU.C€OU.l11b ЭI11u. 3Н4ЧеfШ5t

$_POST [ 'howlong' ] ;

cool11 gе.1У\ C1Y\gУ}QШ,u'м

$_POST [ 'howmany' ] ;

=

$fang_spotted

t)ОJlУЧu.I11 Ь JН4Че.fШ5t КФК:90г.о t)ол5t сЕОРМЬ!. з~к.к.btx ОуэН4

t)epeMe.н.н.bI.м.

$_POST['fangspotted'];

$еrnаН

$_POST [

$other

$_POST [ , other ' ] ;

'еrnаН

'];

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

INSERT о

похищении космическими пришельцами.

Только вначале вам нужно будет сделать небольшое изменение. Раз вы теперь не будете отправлять данные формы по электронной почте, вам больше не нужна переменная $ernail. Вам все еще необходимы имя и фамилия посетителя сайта, чтобы добавить эти данные в базу, но в отдельных переменных.

$first_name $last_name

= =

$_POST [ , firstname' ] ;

$_POST [ 'lastname' ];

~ 3~чек.u.я U,МеfШ u. фdмu.лu.u. 1l0се1У\u.1У\ел5t

<:

"'

c~и1Y\~ 1Y\ellepb I1ru.cgoeк.bt. u.к.зuЙu.зJ'cUlbк.bt.М ll e peMeн.н.btМ, t)ОЭ1У\ОМУ ок.и. Mol'jY'f\ dbt1Y\b

coxp~к.eк.bt. К~Ж:90е.

g cgoeu

l11~длu.u,bt. Q.fiet)s_~bductiOt).

КОJlоЮ(е

Напишите РНР-код для создания строки запроса INSERT Оуэна и присвойте

ее значение переменной $query. в результате выполнения этого запроса в таблицу

aliens_abduction должны быть добавлены действительные данные формы.

вы здесь

127


одинарные и двойные кавычки в РНР

Напишите РНР-КОД для создания строки запроса

ее значение переменной

$query. в

aliens_abduction должны

INSERT Оуэна

и присвойте

результате выполнения этого запроса в таблицу

быть добавлены действительные данные формы.

Имена. коЛО\-LОI{ \"\оя.€uлu.сЬ € SQ.L-,}<:щросе. У1\ОЧ\-LО У1\о.к ж,е., ко.к u. t\реЖэ е .

\ }

$<1~~r.J .=:. ]N..$f.RT .lN.J9. .t;lJi~n-?_~.Ь~ЦУ~i.сm . \.fjr.~t_nфn~,}~~t_Лr.1.m~, .wb.~\I_!t_b~p.p~!1~.g, .h(м_~Щ).~,.· . ~hqW_"m~nу,.9.!i.~!)_q~.;;~Г.ift.Фn,. YYhcAt_i~~~_sl.i{ .f~!1э-~р.qtt~~,. Rth~.c .~:m. (.~~. ~ . : ... ..... .. .. ..... ... .. ....

~У!1hЩ$.,( $.f.i.r:~.t~n~"!1)~:,..'.$J~~~~,I).Фn~'.,. : $~<?!)~~t.~h~f.p.~.I') ~~'I' : $hf:>!:'~f~I).~.' ,.: $.b.~w~~~I)i, .~ .'.......

~'.$,~.~!~I)~4.~~~X!p.t\9n: •.'.$~~t~tb.~;;L~Ф{ <.'.$.f~!)з~?,р,~tt~{, :~9.tb.~r:' tе~Ф JX:.. ....... ........

J

BMe. c"lТ1o С"lТ1о."IТ1u.Чн1:rlX .эо.нrtbIx О t(охu.щен.u.u. СС\ЛЛu. джон.с "IТ1eMpb .мbt. €СУ1\о.€ля.ем "IТ1e

........ .

Тlo я. ок сле.Qо€о.tW.5ll!еремеНJ-tbu< _90лжен. CY1\po~o coXY1\~eY1\cY1\(o€o.Y1\b t)оря.<lКУ слеэо€"о.к.и.я. \J.Мeн.

jo.ннbt.e., K01Y\opbte t(осе'YrIи,"IТ1е.лЬ Co.й"lТ1o. €€ел ~фо му.

колон.ок € У1\о.дли,u,е. <..fmOдbt ко..жэое JмЧеl-Lu.е dbtЛо

сохDб.I-Lе.1-LO € c€oe.й колон.ке. I

IfG 8w~a.G'}h,

Z1f1tblX ffi o1tfocoffi

~: Должен ли я создавать все эти переменные, предназначенные О: Да, это имеет значение. И вы не можете ограничивать ДЛЯ сохранения данных, содержащихся в

одинарными кавычками весь запрос целиком, а двойными

просто сослаться на

переменные. Причина в том, что РНР обрабатывает строки по-разному

О: на

$_POST? Разве нельзя $_POST непосредственно в строке $query?

Вы можете. Нет ничего такого, что бы препятствовало ссылаться

$_POST в запросе непосредственно. Тем не менее считается

-

в зависимости от того, ограничены они одинарными кавычками или

двойными , Разница между этими двумя подходами заключается в том, что одинарные кавычки представляют текст, заключенный между

хорошим стилем программирования изолировать данные формы,

ними, буквально, как есть, в то время как над текстом, заключенным

прежде чем манипулировать ими. Это важно потому, что достаточно

в двойные кавычки, производятся дополнительные действия.

распространенной практикой является обработка данных формы

В результате этих действий имена переменных, н аходящи хся между

перед сохранением их в базе данных. Например, существуют

двойными кавычками, заменяются на их значения, что достаточно

изощренные хакерские методы, предназначенные для того, чтобы

удобно и объясняет тот факт, что двойные кавыч к и обычно более

перехватить ваши запросы путем ввода в форму потенциально

предпочтительны при построении строк SQL-запросов .

опасных данных. Вы узнаете, как предотвращать такие попытки,

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

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

~: Хорошо. Имеет ли значение, в каких случаях используются одинарные кавычки, а в каких

конкатенацией переменных и SQL-кода?

О: Можно, и если бы вы последовали этой схеме, то могли использовать одинарные кавычки вместо двойных. Но строки

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

Mory ли я оrраничивать одинарными кавычками весь запрос целиком, а двойными -

ограниченные двойными кавычками, с непосредственно встроенными

переменные?

в них переменными, удобнее для понимания, чем конкатенации

-

двойные?

~: Разве нельзя создавать строку запроса простой

прочтения и понимания,

-

это хорошая практика. Строки запросов,

переменных и SQL-кода, ограниченного одинарными кавычками.

128

глава 2


соединение с MySQL

Давайте, используя все, что мы узнали, закончим сценарий Оуэна по обработке данных формы, чтобы он мог успешно сохранять в базе данных информацию о похищениях космическими пришельцами . Закончите РНР-код, чтобы завершить сценарий

report . php.

<?php

$when_it_ happened = $_ POST['whenithappened']; $how_long = $_POST[ ' howlong']; $how_many = $_ POST['howmany']; $alien_ description = $_POST[ ' aliendescription']; $what_they_did = $_POST['whattheydid ' ]; $fang_ spotted = $_ POST['fangspotted'] ; $email $_POST['email ' ]; $other = $_ POST['other ' ]; $dbc =

$query = " INSERT INTO aliens_ abduction (first_name, last_name, when_ it_ happened, how_long, "how_many, alien_ description, what_ they_ did, fang_ spotted , other, email) " . "VALUES (' $first_ name ' , ' $last_ name ' , '$when_ it_ happened' , . $how_long ' , '$how_many' , " '$alien_description', '$what_they_did', ' $fang_ spotted ', '$other', '$email')"; $result

=

echo 'Спасибо за заполнение формы . <Ьr 1>'; echo 'Вы были похищены ' . $when_ it_happened; echo , и отсутствовали в течение ' . $how_long . '<br /> '; echo 'Количество космических пришельцев : ' . $how_ many . '<br />'; echo 'Опишите их : ' . $alien_description . '<br />' ; echo 'Что они делали с вами? ' . $what_they_ did . '<br 1> ' ; '<br /> ' ; echo 'Видели ли вы мою собаку Фэнга? ' . $fang_spotted echo 'Дополнительная информация: ' . $other . '<br /> ' ; echo 'Ваш адрес электронной почты ' . $email ; ?>

6ыздесь ~

129


nражненuе решение

Давайте, используя все, что мы узнали, закончим сценарий Оуэна по обработке данных

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

report . php.

Д€e f-lO€btе l1 е ре.мек..ч.bt.е соэерЖd.'Yr\ U..М5I.

Г €€еэек.о

u. ~цлщо t)осе'VТ\u.'VТ\елЯ cc.Hl'Yr\Q, KQJ{ dbv!o € срорме .

(?php

.$.f.i.r:~.t_I)~"'ffi.~.:=:. $._~9$Тf.'.f.i.r:~Ф1g,"t)'\~'J ........... . .$~~~.'t_I)~"'ffi~.:=:.$.J.Q.$JU9.~~M~~'J;...............

~b!. эолжк.bt СО3ЭQ1Т\Ь соеэu.к.ек.u.е

$when_i t_happened = $_POST [ 'wheni thappened ' ] ; с dQJOu. ЭQк.н.bt.x, t)ереЭQ€ u.к.срор.мо.u,що, $how_long = $_POST [ 'howlong' ] ; к.еоdхоэu..му)О эЛЯ к.егд, I1ре:ж.эе Чем $how_many = $_POST [ 'howmany' ] ; 01Т\t)РQ€"ЛЯ1Т\Ь на €btt)олк.ек.u.е л)Одоu. $alien_description = $_POST[ ,aliendescriPtiOl']; JQt)poc. $what_they_did = $_POST[ 'whattheydid']; I 3Q $ fang_spot ted = $_POST [ , fangspot ted ' ] ; I'1pOC СО3ЭQк. u.э е $еmаН = $_POST [ .еmаН .];PtJP-С1Т\рокu.сu.С I1 ОЛЬ.30€Qк.u.ем

€€

$other

=

Э ФtКbtx . €€еэек.кbtx € срорму.

$_POST [ 'other ' ] ;

$мс = ~J$9~!_~9.l)h?,у~Сф:ф~,g,J.i~\\$~.~~цу~~.q~~..~9:(1}:,..\~W~h·J.:~gi.~!JНR9.J: •.'.~.~~~\\<;!~tg,~й?~.')') 5?Г, .Ф~. с Qщ~~кg..q9·~9~t\~·J:W:5!.··Ci. ~~~Q..~:-:~.~f€~.р.~м:)! ............................... ...................... .. .../ $query = "INSER'l' INTO aliens_abduction (first_name, last_name, when_it_happened, how_long, " "how_many, alien_description, what_they_did, fang_spotted, other, email) " . "VALUES (' $first_name', '$last...:.name', ' $when_it_happened', '$how_long', '$how_many', " . "'$alien_description', '$what_they_did', '$fang_spotted', '$other', '$еmаН')"; $result

. $ ~ _ = '{I)~$.q~.\-<1IJ..~.r:~с.~Ь.у, .$.~tA~.. ~!...........

~ ре.3улЬ1Т\Q1Т\е €btt)олк.ек.u.я. .3QI1POCd

на cep€epe эфt.кbtе СОХРQк.5t/ОУ1\Ся. € dQJe.

оу: .<;tj~. (Q\JA~~K<:\. np.tA .€!:1t:t)p!Jt\~Jw~ ..з~1)р.9.У!1.к .~QJe Эdк.кbtx:);

."'ffi~?<1J.i_Y~9.:?~($.clkY.~:~ ~J{pbt?"u.e соеэu.к.ек.u.я. С

oQJOU ЭQк.кbtx.

echo 'Спасибо за заполнение формы.<Ьr />'; echo 'Вы были похищены ' . $when_it_happened; echo , и отсутствовали в течение ' . $how_long . '<br />'; echo 'Количество космических пришельцев: ' . $how_many . '<br />'; echo 'Опишите их: ' . $alien_description . '<br />'; echo 'Что они делали? ' . $what_they_did . '<br />'; echo 'Видели ли вы мою собаку Фэнга? ' . $fang_spotted . '<br />'; echo 'Дополнительная информация: ' . $other . '<br />'; echo 'Ваш адрес электронной почты ' . $еmаН; у\ llОЭ"lТ\€ерэu."IТ\е УСl1ешн.ое COXPQн.eк.u.e

. ~ ЭQк.н.bt.x форМbt € дQзе эф\.н.&t.x, "IТ\оЧн.о 1Т\QК же KQK €b!. эелс:\Лu. Э"УТ\О € C'Yr\QPOM

?>

cu,eнapu.u..

l ЗО

глава 2


соединение с MySQL

-Тест-драйв Измените сценарий Оуэна report .php так, чтобы он ИСПОllьзоваll действитеllьны e данные формы при ВЫПОllнении запроса INSERT. Удалите переменную и

$name в сценарии report . php, добавьте переменные $ f irs t_name $last_name, а также значение переменной $query так, чтобы вместо статичного текста

в строке запроса

INSERT использовались данные формы . Загрузите новую версию сценария

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

для. А теперь в MySQL-терминале введите запрос

содержимое таблицы

aliens_abduction.

SELECT и проверьте

ccwlu. Д.:ж.ок.с

е'УТ\dдлu.U;е Ll.Ме.е'УТ\Ся. 0.9Нd. .J1ULUI{5lЯ. С'УТ\ рокd

UOI"'1'L'IЛ. КO'YТIоpctя.

.·· 1I0я.€цJldСЬ

: .90 'VТ\О,Щ KdK

еь!. : O'YТIкоррекYf'\u..ро€ctлu. о t'jохu..щеrw.u..

К ocMu..ЧескLl.Мu..

r,рu..w.ельupмu..

IlОя.€u..лu..сЬ € 'УТ\dдлu..u,е.

.• jdllPOC INSIRT .•.• Не gолк.уu.'УТ\есЬ,

е слеэytOЩеu. <;Лd€е €b!. y3Нd.e'YТ\e, KdKy~'YТ\b к.ек.ужкbte

8ыздесь

,3dt'\u..cv..

131


до6Qвленuе

WHERE в ваш SELECT

Оуэну неО6ходнма помощь в «про,енваннн») его данных Новый и улучшенный сценарий report . php делает свое дело и автоматизирует процесс добавления в баау данных сообщений о похищении космическими пришельцами. Оуэн может просто сидеть, откинувшись на спинку стула, давая возможность сообщениям собираться в ... но вот опять проблема! ПОСТУllление большего количества информации вовсе не нриводит автоматически к увеличению шансов найти среди всего этого множества сообщения о ПОХИll\ении космическими пришельцами, имеющие отношение к потенциальному обнаружению Фэнга.

я Ueiiстl'uтелы·1О 1'0 I'сeuРУЖULI, так как моя оаза uaHHblX аl'n1Оматuческu наnОflняетсЯ сооОUJ,енuямu о noxuUJ,eHuu космuческими nРUUJельцамu, cocmal'fleHHbIMU nосетuтелями Moero cauma. Но Это не nOMoraem мне I'ыuелuть те из них, которые MorflU ~_-""oы помочь мне Haumu сРэнrа. Оуэну необходим способ поиска опредеnенных данных, таких как сообщения, авторы KOTOPItIX видеnи Фэнrа. Вы знаете, в какой из колонок таблицы имеется интересующая нас информация:

fang_spotted.

Эта колонка содержит ~Дa»

или ~HeT» в зависимости от того, сообщали ли похищенные, что они видели Фэнга. Поэтому все, что вам необходимо,

-

это способ выбрать

только те сообщения из таблицы al iens_abduct ion, у которых колонки с именем

fang_spotted

имеют значение «Да».

Вы знаете, что в результате выполнения следующего заllроса выводятся

все данные, содержащиеся в таблице:

SELECT

* FROM aliens_abduction

SQL-запрос SELECT позволяет вам добавить условие, Уllравляющее выводом данных при выполнении запроса . Добавляя ключевое слово WHERE (англ. ~гдe») с аргументами, вы точно определяете, по какому критерию

вы хотите отфильтровать вывод запроса. В случае с Оуэном это оаначает,

что необходимо вывести только те сообщения о похищениях космическими пришельцами, 11 которых колонка

fang_spot ted

имеет ::НIачение «Да».

~(:\ ЧdС)ТIЬ J<::\IlPOCd SELECТ ос"уу\<::\еi'Т\СЯ де.3 i.LJмен.ен.uЯ - усло€u.е WHIRf о)Т\€еЧ(~еl1') 3<::\ фUЛЬ"уу\Р<::\u,u.ro р е3jЛЬ"УУ\d"УУ\d.

132

глава 2


соединение с MySQL

· -ТеСТ-JJ.раЙв - - - - - Проверьте выполнение запроса SELECТ с условием

WHERE,

устанавливающим критерии поиска.

Используйте в своем MySQL-терминале запрос SELECT с условием WHERE для поиска только тех сообщений о похищениях космическими пришельцами, в которых

говорится о том , что Фэнг был замечен.

~o есех J'Yf\UX 3d.!')lJ.cS\.x КОЛОrtl{lJ. fd.l'1э __s роtt.еd v.мe)O"/Т\ 3 Н4Че н.uе «Дц».

вы здесь ~

133


МУSQL-6аэа оанных Оуэна работает исправно

Оуэн на пути 06наружения Фэнга Благодаря РНР и его функциям по обмену информацией с

MySQL сервер баз

данных Оуэна получает данные НТМL-формы и сохраняет их в таблице базы данных. Эти данные терпеливо и в безопасности ожидают момента, пока у Оуэна не появится необходимость перебрать их. И как только он будет к этому готов, все, что ему

понадобится для того, чтобы выбрать только те сообщения о похищениях космическими пр~шельцами, которые, возможно, имеют отношение

к Фэнгу,

-

это простой запрос SELECT.

Оуэн.. НЛО -~на'1l\u.к

u. 1l0КЛОww.к ~CIJ

эан.к.bu<.

\

134

глава 2

!<rymo. Исnоль;,оl?анuе оа;,ы оанНы)( намно[о уооонее ~лекmrонноu nочmы. Я MOry menerb сосrwоmочumьсSI на тех COOOlJ..lel-\USI)( о no)(ulJ..IeI-\uSI)( космuческuмu nrUUJельцамu, 1? KOmOrbI)( сооОlJ..lаemщ чmо cP~H[ Оыл ;,змеЧel-\.


соединение с MySQL

Попробуйте определить, что делают эти

HTML-,

РНР- и MySQL-компоненты.

Это SQL-коД, который РНР-сценарий отправляет на MySQL-сервер.

Программа, которая интерпретирует РНР-сценарий и отправляет

НТМL-страницу браузеру, при этом часто обмениваясь информацией с сервером баз данных. Имя базы данных, которая содержит таблицу aliens_abduction.

fCfort·fhf

НТМL-форма использует этот метод для передачи данных формы

P041I

Это место, куда в конечном счете поступают и где хранятся данные

РНР-сценарию.

из формы, опубликованной на странице report. html. Здесь Оуэн получает информацию от посетителей своего саЙта.

Эта РНР-функция закрывает соединение с MySQL-сервером баз данных.

Это имя РНР-сценария Оуэна, который обрабатывает данные, внесенные посетителями сайта в его форму, опубликованную на странице

report . html.

Эта РНР-функция отправляет на выполнение запрос

3ii1!foc

MySQL-серверу баз данных. Этот элемент управления

HTML используется посетителями сайта

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

с

MySQL и всеми базами данных, а также содержащимися в них

таблицами.

Эта РНР-функция (необязательная) сообщает серверу баз данных, какую из имеющихся в его распоряжении баз он должен использовать. Эта РНР-функция открывает соединение между РНР-сценарием

и MySQL-сервером баз данных, таким образом обеспечивая им возможность обмениваться информацией.

вы здесь ~

135


кто что делает решение

Попробуйте определить, что делают эти

HTML-,

РНР- и MySQL-компоненты.

Это SQL-коД, который РНР-сценарий отравляет на MySQL-сервер.

Программа, которая интерпретирует РНР-сценарий и отправляет

НТМL-страницу браузеру, при этом часто обмениваясь информацией с сервером баз данных. Имя базы данных, которая содержит таблицу al iens_abduct ion.

НТМL - форма использует этот метод для передачи данных формы РНР-сценарию.

Это место, куда в конечном счете поступают и где хранятся данные

PO&jI

из формы, опубликованной на странице report. html. Здесь Оуэн получает информацию от посетителей своего саЙта.

Эта РНР-функция закрывает соединение с MySQL-сервером баз данных.

Это имя РНР-сценария Оуэна, который обрабатывает данные, внесенные посетителями сайта в его форму, опубликованную на странице

report . html.

Эта РНР-функция отправляет на выполнение запрос

MySQL-серnеру баз данных. Этот элемент управления

HTML используется посетителями

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

с MySQL и всеми базами данных, а также содержащимися в них таблицами. Эта РНР-функция (необязательная) сообщает серверу баз данных, какую из имеющихся в его распоряжении баз он должен использовать.

Эта РНР-функция открывает соединение между РНР - сценарием

и MySQL-сервером баз данных, таким образом обеспечивая им возможность обмеииваться информацией.

136

глава 2



3

СО~rlJ-{ц,G Ц, 3rl1)oJ\J-{GJ-{ц,G Orlзbl grlJ-{J-{Ь~

'*

*'

Создан"е ваш"х

ео6nвенных данных f

у вас не всегда будут необходимые вам данные. Иногда вам придется создавать данные, прежде чем вы сможете их использовать.

А иногда вам придется создавать таблицы, чтобы хранить эти данные . А иногда вам придется создавать базу данных, чтобы хранить данные, которые вам нужно

создавать, прежде чем вы сможете их использовать. 3а путались? Разберетесь! Приготовьтесь узнать, как создавать свои собственные базы данных и таблицы. И после всего этого вы создадите свое первое РНР- и MySQL-приложение.

ЭТО новая rnава

139


необходима программа -

лист рассылки!

у Элмер<1. eC"'tТ\b 328 а.эр,е.со€

элеюnрm.t..:ой I!O'fvY)bt, с-одр<1.!-{Н14,Х

Магазин «3ЛВИС» открыт

p4c-lТ\elТ\ с К4Ж3bLМ эк.ем.

Элмер Пристли открыл свой магазин «Элвис!>:

СnllСОН аДресов Эl1е

MakeMeEl vis . сот. Спрос огромен. Он продал множество полиэстеровых комбинезонов в обтяжку с заклепками, уйму

nОНvnателен 311

искусственных баков и сотни солнцезащитных очков.

АНдеРсон дж

д>кОф

Каждый раз, когда кто-нибудь покупал у Элмера что-либо,

харт ТОТ

Пока что ему приходится вручную находить каждый

Райан

в адресную строку электронного письма при отправлении

n Икер ' аузрс

ЭН

andreWWiI/

Р n/lrпos,corп

angryPirate@b;h~gumbol/.net

c'aY@starbuzzce~ neckpizza,corп

БРа ~

Д

Тедеско Д ебра

о ее. СОт

annmeeker

ЬР@hоnеу:~i~СОhоf;с-iпс.соrп

ат86@0.

debm

.сот

bJectviI1e.net

В >кенис ' . onster@breakneckp' дИ КРд М v tarbuzz.COffi,zz.a.com ш >ко ffi ee.Com еРИдан да SZVedjoe@ob' ее'Сот

Эдsа"1а на

сноу

ОТТО

e.peмs:l на flОvра>канuе эле.uсу, а не на

Глен Рд

~ар,qи

ручную от11рае.ку элекmронных l1uceм!

\Jf ОЭ<1.ЖU

Рд/Оfrпiпе@е:,;ОЬjесtvЩе.nеt

Талвар 3вед

эmо занuмаem СЛU\.l.lком MHofo e.peмeHu. /\УЧ\.l.lе ды S:I mраmuл се.ое

ок.л4Uк.оеоu.

US.Com

Апама

ММЭ Нсон Анн:ан ен,qель

@breakneck . g9S@boards_ r _ P1zz.a.corп

overcraft@b

AnneToth@fear~akneckPizza.com

~аккинли клэй

объявлений о распродажах. Это работает, но требует

сЬг;

h

Эн,qрlO

ПаЛУМ60 Том

адрес электронной почты в своем списке и копировать его

король

РИс

Ллойд АНна

УИЛЛИ

------

)Offe@sirпUd @breakneckpiZZa

ГаРСИR Эд аНда arпan2IuV@bUCk.com .Сот РаУн,qrри дж ed99@bOno reakneckPizza с Бриггс К O~AH jOjoround rnsup,com . От

использовал эти адреса, для того чтобы рассылать информационные бюллетени о распродажах в своем магазине.

Элмер, деСС\lОРrti:Я-u

НТРОl1110Н ПОЧТЫ

"'ера:

Кев;:иан. jifl_anderson

ныоомM Ам

он оставлял новый адрес электронной почты. Элмер

слишком много времени и усилий.

.

н.ct Э<1.ru-tbш MoMeKYf\, к.о ux колцЧес!Т\I'.

АНна

ил

Мэри

джагел

еещеu Эл€ЦС4.

о

~еСtvШе.пеt

sheridi@mi

'nowman@t;htY9umbol/.net

g/enn0098@0~;~ean/ounge.com anneh@bOttO

Эн

nobigdea/@

ctvll/e.net

т'иР.сот

:;"::Фи джеймс

ddreamgir/@b'r~;~~:Zkcoffee.com

ПаРl{ер

feeo1iyp~...~ Оmsuр.соф

еР

Р'ИЧчи

Ре

ЛИ

Aн+v nИтер

М но

rmem @bOtt

ап

с PIZZa.COm

<:C"'"~aeneгoг

. nep@starbuzz ama,com ncc;man@tikib COffee.com

грейс

3еnЬда grace23@object:~,7founge.com Д3~CC и Кnи zefda@we e.net Болгер дж Ф~ор,q clifnight @~herorama.com 6nант Анн~ИС joYCe@choc~eak~e~kPizza.com 6~1nИНГ ЛИН annebJant@b hOflc~lnc.com

гэирс

дж

'Iи

Фред

31{Обс АНна

Iind reakneck . Y@tikibean/ P1ZZa.com gareS@Objectv."ounge.com аПпе99@ Ь. I e.net

~

О ~ectvme.net

J1"toЭu.

е КJ1"toЧеrtbt. е ct)IJ.COK 4Эресо~ Дорогой друг Элвисониан!

На этой неделе в MakeMeElvis.com будет большая распродажа!

u.

Баки из натурального конского волоса со скидкой и не

20 %!

забывай:

покупаешь один

злекmроi-'J-Юй nоЧ"mЬ>. Эл.мера

~

полиэстеровый костюм - берешь втор~и бесплатно! Осталось только три дня.

J

С ~,-е"1Т\еFt)еfi.l..tе~

ОЖ1..i..94)О1У1, КО2-Э С

CMOZ,\[Yf\ С е?,о "

t)oJv\oW,b]<) ew,e долЬше !j ОХО3 Ц'!"":

К4 ЭЛ;u.С4. Элмер тратит слишком много времени на то, чтобы вручную находить каждый адрес электронной почты в списке и копировать его в адресную

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

140

гnовоЗ


создание и заполнение базы даннь,х

злмеру неоОходимо п~иложение

-

Приложение - это программа, разработанная для выполнения

Вев-nрuложeнuе

-

это guнамuческ.uи

определенной пользовательской задачи. Элмеру необходимо пр~ложение, саит к: торыи

которое бы содержало в порядке его СIШСОК адресов электроннои почты и позволяло ему простым нажатием кнопки, размещенной на форме,

О

разpasotnaН .

отправлять электронные письма людям, включенным в этот список.

Он хотел бы, чтобы это выглядело примерно так:

чтОБЫ peuш111Ь

~ O~!<l'ытb &ti... anl'анuцу u &&шnu &t0I'MY с.о()Ч'жанu~ зл~ml'онноrо

nUCbMa.

~ Нажаmь !<HOnКY omnl'a&!<u t0I'MbI на Uf'&Ч' ()ЛЯ

ODI'J"om!<u, & l't.3ульmаm~ чtrо ЗmО зл~mI'ОННО~ nUCbMO 6'у()'!" оmПl'а&лtНо &им поиmumtЛЯМ с.аЙта MaktМ~ls.com, чьu а()l'tCЗ зл~mI'ОННОЙ почmы

d

UМtЮmс.я

&c.nu(.I<(.

~

оnpegеленные заgачu gлs

nocemuтелеи этого

caUtna.

Э1nо tJРuJ10.же н.u.е э Л51 fd.ССbLлКU,

элекmрон.н.оu. 110ЧYr1 bt н.d.ljoMu.H.deW, \lDWlоЖен.u.е ОуЭн.d. о I'""jохu.щен.u.5lX

~ А&mомаmuч~u ооно&ляmь c.nuc.o!< a()l'tc.o& ~ кЬсмu.чеСКU)I>,U,l1рU,w.еЛЬ\Jf.i,f;\U" зл~mI'ОННОЙ почmы, nl'woana&u& &озможноanь н.о оmЛU,'-fd.еl'!\с51l'!\ем, Ч"tТ\о е н.еМ покynаmtЛЯМ I'tfUanI'Ul'о&аmьс.я ЧЧ't.3 &ti...t0I'MY· CljU,CO'K ~pecog элеКI'!\РО1-,Н.оu. t10Ч"tТ\bt 3лмерd. д~эеl'!\

одн.оеЛ51I'!\ЬСя. ctеI'!\ОМd.I'!\u.ческU, u. аО элеКI'!\р-оннL-<tе \iu,cbМd.

БУЭym ОI'!\\iРd.f5Л51I'!\ЬС51 есем,

с перечнем задач, которые должно решать это приложение, у Элмера

появляется возможность показать его во всем блеске ...

KI'!\0 \iеречu.слен. g Эl'!\оМ c\iu.CKe. l1РuJ10.же н.u.е Элмерct t1еd.КI'!\u.Ческu. ,\олн.ОGI'!\Ьro

ctf5'I'!\ОМd.I'!\u.зu,rо€d.н.н.о!

-

Приложение

MakeMeEl vis . cam со сто и т

и з двух основных компонентов : веб-формы для

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

почты Элмера, и веб-формы, п озволяющей новым поку пателям присоединиться к этому списку. И мея в в иду две эт и фор мы, разработа й те схему п р иложения Элмера .

выздесь ~

141


структура нашего листа рассылии

Визуализированная структура приложения 3лмера ~U Л~U €кл}ОЧе~

€ cl')UCOK оэресо€

Всегда полезно визуализировать структуру приложения, перед тем как

элеК"IY\рон.н.оQ I!ОЧ'lТ\bt.

погружаться в его детальную разработку. Это означает, что необходимо определить, Элмера U l!оЛ)Ча}O"fY\ в решение каких задач будут вовлечены веб-страницы и сценарии, как они должны элеК"IY\рон.rtbt.е взаимодействовать друг с другом и, что, возможно, наиболее важно, как будут I!UСЬ.м4, KO"lY\0pbte

ок. О"lY\l!ра€ля.еm

сохраняться данные в базе MySQL.

~a KOMduНt.".\u,u5l

~o.", РНР-сu,еrщрuй

«rhО~М41 cu,eНt.".\puu.»

--...==::-=.;..~=..".................................... ...._.. ..... ,

~_ :

.;

:

:

.

(~

't'

\103

оля.е"lY\

\lосеYl\UYl\ел

_ я.м aLi"Yt'\a

с

к' CI')UCKY ОЭDеСО15 I-

u-bt.

~леК"IY\оон.н.О\..lI!О'"1 I

'=~~===-~_-. ~.~~ _

........ -: ....... _..

. ~~~

~г · ···· · ··········· · · · ········~

Эл.м.ер jc\11 0Лt-L5l.е1Т) . Э'Yr\у форму, sendemc:il.hfml

эля. "II10го

Ч'vr\о~bt СОJЭ d;У\1Ь U

0'tY)t) pct€U'tY)b

~леl{"II1рокн.ое

I)ucbм.o €ceM Л~ям.

€I{Л}ОУен.нbtм € его

cl1ucoj( ~pecoe элеК"lY\РОкн.ой 110Ч'vr\bt.

142

глава)

~леК'tY)РОКНbLе

I

1') Duсоеэuк.uYl\Ься.

addemc:il.hfml

О'tY)t)РdЙЛя.€'tY) Ь

"

о

t"]uc м.ct f.)CeM Л)ОQQ АА

~

€КЛ)ОЧеКНbLм

J~V'\

ct)UCOl( ctэресо€ Элек'tY) ()он.н.ой 1-

t"]ОЧ'n1Ы Элмера.

)


создание и заполнение 6азы данных

Иmак, с чего мы начнем

rазrаСоmку жр- UMySQl--пruложенuя~ .D.oIIжны luu мы lI!начале Hanucamb f}tf'-cцeнaruu, а ззmем со)<>ать mаСlIUЦУ VIIЯ со)(rаненuя VaнHbI)(~ ИIIU нам Cl\Wyem сначала созvаmь mаСIIUЦУ, а ПотОМ

-- cцeнaruu~

ДжО: Я не понимаю, какое это имеет значение. Нам будут необходимы и таблица, и сценарий, прежде чем приложение сможет работать. Фрэнк: Это так, но мне кажется, нам следует вначале написать сценарий,

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

Фрэнк: А разве мы не можем создать сценарий пока без кода, обеспечивающего соединение с базой данных? Тогда мы могли бы делать все, кроме фактического обмена информацией с базой данных. Это могло бы быть вполне полезным, так ведь?

Джо: Необязательно. Не забывай: единственной задачей сценария является чтение данных, введенных в НТМL-форму, и запись их в базу. Или, если речь идет о сценарии, отправляющем электронные письма людям, включенным в список адресов электронной

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

Джип: Это так, но мы еще даже и не думали об НТМL-форме. Как эта форма будет согласовываться со всеми остальными компонентами? Мне кажется, мы должны создать базу данных, прежде чем сможем даже подумать о написании сценариев.

Фрэнк: Вот именно! Сначала мы создадим НТМL-форму, затем определим, какие данные пойдут в базу, и когда все будет готово, мы свяжем все вместе с помощью сценария. Джо: Я не уверен, что действительно стоит так делать. Как мы можем создавать НТМL-форму, если мы не уверены на 100 %, какие именно данные хотим получить от посетителя сайта?

Джип: Джо прав. НТМL-форма опять возвращает нас к тому, что вначале необходимо определить, какие именно данные нужны нашему приложению. Все зависит от данных, поэтому нам, видимо, следует вначале создать базу данных и таблицы, затем НТМL-форму и потом сценарий, который обрабатывает данные, введенные в форму. Фрэнк: Вы меня уговорили . давайте делать так!

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

Перечислите отдельные этапы, которые, на ваш взгляд, перейдут

из схемы в окончательный вариант сайта

MakeMeElvis.com.

вызде,ь ~

143


nланuрованuеnрuложенuя

-nРЕ''Е Нам действительно необходим план действий по согласованию отдельных частей приложения. Разбивая приложение на отдельные этапы, мы сможем сосредоточиться на решении одной задачи и не запутаться в деталях.

Создание 6аЗ18. данных и та6nицы дnя nиста рассыпки.

В этой таблице будут храниться имя, фамилия и адрес электронной почты каждого, кто включен в лист рассылки Элмера .

Создание ве6-формы «До6авnение адреса эnектронной почты)) и РНР-сценария

дnя до6авnения

HOBoro

покупатеnя

в nист рассыпки.

Здесь мы создаем форму и сценарий, которые дадут покупателю возможность легко ввести свое имя.

фамилию и адрес электронной почты и затем добавят эти данные в лист рассылки.

е Создание ве6-формы «Отправка эnектронной почты)) и РНР-сценария дnя отправки почты

cornacHo

nисту рассыпки.

И наконец, мы создаем веб-форму, которая позволит Элмеру составить текст электронного

письма, и что более важно, сценарий, который, используя текст, написанный Элмером, отправит электронное письмо всем покупателям согласно

списку, сохраненному в таблице листа рассылки .

144

глава

3

.

addeffi<il.php

oddennl.html


создание и заполнение базы данных

Все начинается с таблицы

база gaHHblx. KoнmetlHep

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

говорил ось о том, что база данных внутренне разделена на другие

XpaHeнt19

контейнеры, называемые таблицами?

5

Каждая строка таблицы содерж ит информацию об одном конкретном

5Uge.

объекте, а каждый столбец - конкретную характеристику этого объекта (имя, фамилия, адрес электронной почты ...). Строки такой таблицы называются записями, столбцы

-

это

gA9

gaHHblx.

структурuрованном

колонками .

Пример записи: « Венди, Верл иц , wwег@stагЬuzzсоffее.сош!>.

(

календарь

:1mO колон.Кd. лист рассылки

~ .---"> Оде Э'tТ\u. С1Т\ РУК1У\урЬ!. Эdf.u.tbtx

яЙля./O"IТ\c5( 1Т\С\dлu.u.pмu..

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

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

Но сами таблицы все равно состоят из колонок и записей.

,А.анные

~ эаttн.btX, ~\eW,еw-\.dЯ

5 maвлuче 5 колонках

&\3 ~.

u заnucsx.

кд M~so.\..-cefeefe

-t f

Тdдлuu,ct.

j

-t

Дof

~o КОЛоНJщ.

;:?~&a5\.

d Л\J.u.p.·

...-

..-

-

...-

....

~o

J C\ t')LAcu.

..-

..-

...- ... ........- ...-

......-

До-

"~

....

"""-

IfG 5bl~01G11t,

РС\СС Мcl1Т\рtл-

ZV11bJX ~011fOCO~

еай1Т\е дС\3у d) :.9 a к.н.btx КаК -р; Где фактически сохраняются данные

---- --- ----- -- ---....

xpammcs

....

До-

"-

д-

кон.1Т\еан. е р

базы? Mory я увидеть файл?

эля.

О

u.н.ФОРМclu,u.u.. I

; ?бычно данные базы сохраняются

в фа иле на жестком диске. И хотя

вы действительно можете посмотреть

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

Вот почему необходим

SQL -

чтобы дать

нам возможность просматривать базу и взаимодействовать с находящимися

в ней данными .

8ыздесь ~

145


создайте

(CREATE)

свою базу данных

Еще ОДИН контакт с MySQL-сервером 6аз данных Структура приложения Эл мера требует создания базы данных и таблицы. Большая часть ежедневной работы , связанной с базой данных, включает обмен информацией с таблицами. Но вы не можете просто перепрыгнуть через одну ступеньку и начать

создавать таблицы, не создав предварительно базу данных, которой они должны принадлежать.

SQL-запрос CREATE DATABASE используется для того, чтобы создать базу данных.

После того как это сделано, вы можете идти дальше, создавая таблицы с помощью SQL-запроса CREATE TABLE. Но прежде чем вы сможете ИСПОЛЬЗ0ватьлюбой из перечисленных запросов, вы должны соединиться с вашим MySQL-сервером

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

Ин.СYriрумен.-тd,ЛЬн.ое t)po~pctМ.М.Н.oe ri 'е. еЧен.u.е M\lSQ.L

M'J 'Q.L О ( ) . ) ' 'rТI<1.l(oe, J'"' d -'rТIермu.Кс\Л, t)ОJ~оля.е'rТI М.м coe..9u.h.u.-тЬся. J -сер е.ро..м <!J ..9<1.НJ-IЬt.x t)pu. усло€u.u., 'hт!o €b!. YriоЧН,Q оЗн.С\е'rТIе, z..g e € ..9 е u. С'rТI€u.'rТI ельн.ос"У!1u. Рd,Сt)ОЛожен. cep€e.p д~ Кc\IlPUJ.....ep !{<1.К

с

M,ISQ.L 1'

..9d.н.нbtx, u.мя. t")ОЛЬJО€<1."У!1еля. u. ezo t")d.РОлЬ.

I

I

Точно так же, как в случае открытия соединения с базой данных

из РНР-сценария и обмена информацией с ней, данные о месте расположения сервера баз данных, имени пользователя и его пароле являются ключевыми при использовании MySQL-терминала

или веб-приложения

phpMyAdmin.

И использование этого

инструментального программного обеспечения очень полезно для создания базы данных и ее таблиц на первоначальных этапах

разработки приложения, которое использует базу данных. Так как создавать базу данных и таблицу для приложения Элмера нужно только один раз, есть смысл сделать это с помощью

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

MySQL и приготовьтесь выполнить приложения - сформировать базу данных

первый этап создания и таблицу для листа рассылки .

146

zлава)

~i"'~мlcll ."ai~~.· .· AК8Iaf8ЩWIlL . .... .. · .· · d ~lJ..фоl*"'~ii&

~;=:,t:::=м:J."~ пoкynhfAII. AUQ8 .~~•.••

о ~1II1ic tci-+оl'МIII«Оlllllpaha

-poжt04 цочм",,,u fНf~QЩlapu.

)~. 01IIII1'*11 noчlo COfМCIIp ~"""7 I'acQIAК"


создание и заполнение базы даннь,х

Создайте 6азу данных ДЛЯ электронных писем 3лмера

Cf\EAТE DATAВASE

Для создания новой таблицы для листа рассылки Элмера первое, что нам понадобится,

-

это создать базу данных

содержать эту таблицу с именем

el vis_store, которая и будет email_list. Мы будем использовать

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

-

это CREATE DATABASE (~создать базу данных»).

Вы уже кратко рассматривали его использование в предыдущей главе. Давайте

рассмотрим подробнее, как он действует.

~ имя к.о€оu. dd.3bt.

имя_базы--цаиных Эd.н.к.btx, KO"Yf\°P~)O

к.еоdхоэL!..МО СО3Эd."Yf\Ь.

данных Эл мера:

CREATE DATAВASE elvis_store

После того как вы передадите этот запрос серверу баз данных

это

~npoc. ucnользуемьro

gASl

Вам необходимо указать имя новой базы данных после ключевых слов

CREATE DATABASE. Вот так выглядит SQL-запрос на создание базы

(<<созgаmь вазу gаннь1К») -

созgаНU9

H050ti вазы qaHHblK Koz.9d. €b!. €€o.9и"IТ1e SQ.L-Jd.ll pocbt € окк.е "IТ1 е РМLAк.ctЛd., €b!. €сегэd. ~О&'€ля.е"lТ1е "IТ10ЧКУ с Jd.t) Я"lТ10U KoKu,e 3d.llpOCd. ... Но к.LAI<О~.9а

на выполнение, будет создана база данных.

к.е эеЛd.е"lТ1е Э"lТ10~О. KO~.9a 3d.t1poc осущ еС"lТ1€ля. е"lТ1Ся. mysql> CREATE DATABASE elvis store;

Запрос выполнен успешно,

В результате создания базы данных

'!ере.) руккu,що РНР

~~

1 ряд задействован (0.01 сек)

el vis_store с

"IТ1YS9~i_9uery().

'-----~.

помощью запроса CREATE

DATABASE вы становитесь обладателем сияющей новизной базы данных, но без единой таблицы, в которой вы могли бы сохранять ваши данные ...

tю..3d Эd.н.к.btx СО.3Эd.К4, н.о оК4 н.е смо.ж.е"lТ1

соэе р.ж.ct"lТ1 Ь Эd.н.к.btx Точка с запятой ставится в конце SQL-запроса только

TorAa, KorAa

де;, "Yf\d.dлu.u,.

вы вводите запрос в окне терминала.

В вашем РНР-коде в конце SQL-запросов точка с запятой

не ставится.

MySQL -терминал интерпретирует код

иначе, поэтому он требует точки с запятой в конце каждого SQL-запроса. Это потому, что терминал может обрабатывать несколько запросов одновременно, в то время как в РНР вы должны передавать на выполнение по одному запросу за один раз.

6ызоесь ~

147


теперь создайте

(CREATE)

свою таблицу

Создайте та6лицу в 6азе данных Вы должны знать, какие данные вы собираетесь сохранять в таблице, перед тем как ее создавать. Элмер хочет использовать имя и фамилию

.

покупателя в своем листе рассылки, чтобы электронные письма, которые Тd.Ьлuup. e.!'Y\d.\~_;\st-е

он отправляет, имели больший персональный оттенок. Добавьте сюда адреса электронной почты, и тогда станет ясно, что таблица Эл мера

.э-!'У\О 0.91-14 U'з мк.о.жес!'У\ d. !'У\d.длuu,. KO!'Y\0pbLe мог.jiY\

еmаi1_1istдолжнасодержатьтривидаданныхнакаждуюзапись.едd.Jе .9aКJ-\bU< Каждый вид данных в таблице помещается в отдельную колонку,

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

1ast_name и emai1.

first_name,

Каждая запись в таблице содержит по одному

экземпляру данных из всех трех колонок и определяет одну позицию

в листе рассылки Элмера.

r

12 0JMo ",,-,ос"Vn о 11 o/fVr<. ",и. С1Т\Clрог.о 1Т\е.кс""!у)о\')ог,о фd.Йлct

Эл.мерct, е КО!'У\oрo.м OJ-( 3ctrtlAСb!.€С\Л аэресС\

-"'с.... ___--..-л........-...--.../"---w, эле~~ ронн.ой t)o'hт\bt., к.е UЭyrt1 к.u е Какое

~ С pcte,teк.u е со C!'Y\F.Yk""!Y).Ypupof5'd.K1-ШС1Т\ЬЮ

]~~~i~1i~~~i§~~ ~~I:;~~~:~~:Ь;=~Р'уЮ одеСt)ечu€d.Ю1Т\ .... _ _ . ,' ,

_~~~{~1~~o.!§·_:~~~~~~ __ ..•....

......

..... .

ДЖОБО~~~~~.~ __.-

email_list

,,,

,

___ ....- .

-ik~g@g~~::Ils~,~t . ~ ......_.... -. .... ....... ...... _-_. ------_.-.-

_

_

Эmо колок.кu..

13 1-14шеu "'II\С\6лuu,е

mcilinglisttxt

Ш<

!'Y\fU'

Итак, вы знаете, что имя, фамилия и адрес электронной почты

покупателей должны быть созданы как колонки таблицы

Заnuси в maвлu\,le pacnолагаюmсэ горизонтально. а к'олонкu­

вертикально.

148

глава

3

email_list.

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

Вы должны сообщить базе данных немного больше о том, какие данные вы собираетесь хранить в данной колонке.


создание и заполнение базы aaHHblX

Нам неО6ходимо указать типы наwих данных Когда вы создаете таблицу, вы должны сообщить серверу

MySQL, данные

какого типа будут

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

какие-то

-

числа, какие-то

-

даты или время и т. д. В

MySQL определено

множество типов

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

у Эл мера есть таблица с именем

products,

которая отслеживает движение товаров

в его магазине.

Jw,Q l(олон.кQ соэержи."!Т1 "!Т1eKC"!Т10€oe Ot"ju.Cd.Нl..Le Кd.жэоzо "!Т1 0 €<:Iрd.

€ ,.Лd,г.ctJu.к.е Элмерd.. ;

Голубые замшевые туфли

2

16

Накладные баки

93

1.99

7

48.00

Парик Элвиса

К~ОЛОК<.I

23.50

Полиэcrеровые брюки с блеcn<ами

i~ соэержu:Yf\ ук.ЩdлЬк.ое

\\

а

orice

оЛОt-U< I

(<<u,eГ\d»)

a!-tН.bte g gu.э е

ji-ld.Чеl-lJ.Ае u...9ек."!Т1и.РЩ{d."!Т10Рd. (ТО) ЗЛЯ СОЭ~~~ Чu.сеЛ.

цеJlое ЧИCJlО

i<d.ЖЭОг,о -!Т\О€d.fd. € Мd.zctJLlrle ЭЛN\ер<.l. эес:vnu. Обратите внимание на то, что

p roduct - единственная колонка с текстовым типом product s. Имеются также следующие типы: десятичное число price и целое число для колонок id и inventory. В MySQL для

(lnteger Number)

данных в таблице для колонки

всех этих типов данных установлены свои наименования, так же как и для некоторых других типов.

Очень важно при создании колонок таблицы использовать оптимальный тип данных, чтобы добиваться наибольшей точности и эффективности. Например,

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

после того как вы определили конкретный тип данных для какой-либо колонки, сервер баз данных

MySQL

не позволит вам ввести в нее данные

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

Созgaвast masЛUЧУ, вы gолжны знаmь. KaкUe

munbl

уанных ВУgytп

cogержаtnЬC9 в кажgоu u3 ее колонок.

Как вы думаете, использование разных типов данных лучше, чем использование просто текста

для сохранения всех данных?

выздесь ~

149


часто используемые типы данных MYSQL

Познакомьтесь с некоторыми типами данных

MySQL

Имеется несколько наиболее полезных типов данных

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

\

в 3ct€Ltcu.мocl'l1 lA. 01'11 €epcцц €ctщег.о cep€epct дctJ эctн.н.bi.x MySQ.L элцно, мож.еYr\ СОС"У!'1ct€ля.Yr\Ь 255 сu.м€оло€ эля.

€epcцo. Кli.Же. 5.03 ц 65 535 сu.м€оло€

эля €epcцo. 5.0.3 ц €bLше..


создание и заnолнение 6азы данных

IfG 8ЪJ~itGTh,

gV11blX ~011roco~

"Р; Зачем мне вообще испольэовать тип CHAR, если

в случаях, когда вы знаете, что данные, помещаемые

VARCHAR делает то же самое, но со эначительно большей

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

гибкостью?

"Р; Зачем мне нужны числовые типы данных INT и DEC?

О; Ответ заключается в точности и эффективности. С позиции

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

содержащей краткое наименование штата (в США), будет всегда помещаться его двухбуквенная аббревиатура, имеет смысл

предусмотреть в этой колонке только два символа, выбрав тип данных CНAR (2) . Тем не менее, если колонка для сохранения пароля может содержать любое количество символов,

но не более 1О, тогда выбор VARCНAR (1 О) более оправдан. Это объясняется особенностями исполнения

MySQL. Тип данных

CНAR более эффективен, чем VARCНAR, так как он не должен свою

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

О; Все объясняется способом сохранения данных

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

таблицы и увеличиваете скорость обработки данных. Сохранение числа в виде численного типа данных

(lNl; ОЕС), вместо

сохранения его в виде текста, обычно значительно эффективнее.

"Р; Это все? Других типов данных больше нет? О; Есть, но это наиболее часто применяемые типы. Лучше мы

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

Приведите каждый тип данных

MySQL в

соответствие

с описанием данных, которые вы могли бы сохранить в таблице.

Ваши имя и фамилия CНAR(l)

Наименование штата США в виде двухбуквенной аббревиатуры

DАТЕ

Стоимость пари ка Элвиса:

TIME

Сколько денег было выручено за альбом-бестселлер Эл виса

VARCHAR(2)

дата похищения космическими пришельцами:

DЕС(4,2)

Количество баков Элвиса на складе

VARCНAR

Вы видели собаку Оуэна? У или

(6О )

48.99

19.02.2004

N

CНAR(2)

Ваш адрес электронной почты

DATETIME

Когда вы обедаете

DЕС

Сколько космических пришельцев вы видели во время похищения

(10,2)

Когда родился Элвис

8ыздесь ~

151


в чем заключается моя цель? решение

*

....--------+

Мf~,.

Приведите каждый тип данных

MySQL в

соответствие

с описанием данных, которые вы могли бы сохранить в таблице.

Стоимость пари ка Эл виса:

48.99

Сколько денег было выручено за альбом-бестселлер Эл виса Дата похищения космическими пришельцами:

19.02.2004

Количество баков Эл виса на складе

DEC(4,2) Вы видели собаку Оуэна? У или

N

Ваш адрес электронной почты CНAR(2)

Когда вы обедаете Сколько космических пришельцев вы видели во время похищения

DEC(10,2)

1 \

Когда родился Элвис

DIC OdbtЧн.о

~u эвd ЧuсМ

UСl)олЬзуе-mся.

110 Kct;3bt€d)O'tТ\. сКоЛЬКО

u,u.cpp

эля. СОХРdкен..u.я колон.кd. u,eK Ш1u эру2.ll..Х lIее.Эl\оМZd.еУ1\

э ес я.-m uчН1iк Чuсел.

~~uэе-mЬ t)еfеэ

эес~-muЧн.оu 3dl"'t5(.Y1\Ou. U сколЬко t)осле н.е.е .

152

zлаваЗ

\

~bt. gо.)Можн.о.

gырdЛU зэесЬ DЛТЕ ко КdС1У\оя.щuе

Э..тiuсон.u.a.н.е ,3Кd}O)Yj 1У\оЧн.у}О Эd1У\У..!~.Jремя..

в MySo.L сущеС1У\gуе1У\

эру 2.0 U. (1I01У\ ен.u,u.a.ль н.о ЛУЧlU.uй) ме1У\ОЭ t)р еЭ С1У\dgлен..u.я Эdн.н.btx

«Дd»/«Не1У\». Чем

UСllользоgакuе СНАRСЛ, н.о u Э1У\ОiТj ме1У\ОЭ IlpOC1Y\ u ЭОС1У\d1У\ОЧн.о ЭсрфеК1У\ugен..


соэдание и заполнение баэы даннь,х

Создайте вашу та6лицу с помощью запроса у нас есть все, что необходимо для создания нашей таблицы, даже хорошее имя

( еmа i 1_1 i s t). Есть у нас и имена для колонок: emai1. Чего у нас нет, так это типов

first_паmе, 1аst_паmе и

данных для каждой колонки и SQL-запроса, который собрал бы все это

8

~ЗIIU~ &и-.рoрмы «Ao5a&Aettu~ аО"«8 :t.w<mrOIlIlOIi nочmы» Uf'Hf'-с;цettаruя i)АЯ i)о5а&Аettuя IIO&Oro nокynаm~я & AUan r~bIAKU.

е

~ЗIIU~ &и-.рoрмы «Omnra&Ka

вместе и создал таблицу. SQL-запрос для создания таблицы начинается с ключевых слов CREATE TABLE (<<создать таблицу~). После ключевых слов CREATE TABLE следует имя таблицы.

Две круглые скобки ограничивают разделенный запятыми список имен всех колонок. За каждым именем колонки следует тип данных, кот орые

она будет содержать . Вот так выглядит этот запрос:

имя_колонки2 тшz-.данных2,

~

\

Еще ~<олон.кu.. есЛu. н-еодхоэu.мо.

~МЯ

omnra&KU nочmы G011\aGIIO AUGmy

r~bIAKU.

И"'-5t К олотuщ.

(

:tA~mrOllIlOIi nочmы» Uf'Hf'-Guettаruя i)АЯ

тu.t) зФ·ж.bl.x

к.,_рлоНJ(U

snL-зanрос CI\EA1f. ТАВШ uCnOAb3yemcg gю созgаНU9

НО5О11 truШлuчы ~b!. н-е одЯJс:1.нbt еклк>чс:1."УТ\Ь е u.мeн.ct КОЛОК.ОК сu.меол 1I0эчеркu.ес:1.к.u.я. эля. РdJQеле н..u5i. слое, н-о хорошu.u. С'l'l\u.ЛЬ

5

вазе

gaHHblx.

Ilpo~pc:1..ММu.pOec:1.н..u5i. tlреЭIlОЛс:1.с,с:1.е"УТ\ .:7'1'1\0.

no,a6omllllb Напишите SQL-запрос, позволяющий создать таблицу Элмера

emai1_1ist

стремя колонками данных: first_паmе,

1аst_паmе и

emai1.

6ыздесь ~

153


nроведuте тест-драйв своего запроса СЯЕАТЕ

хшеное задачu Напишите SQL-запрос, позволяющий создать таблицу Эл мера

email_list с тремя колонками данных: first_name, last_name и email.

'_.Тест-драйв - - - - Создайте базу данных и табnицу ДnЯ Эnмера. Выполните запросы CREATE DATABASE и CREATE TABLE, чтобы создать базу

данных

el vis_store

и в ней таблицу

email_list, используя какое-нибудь

из инструментальных MySQL-приложениЙ.

CREATE DATAВASE elvis_store CREATE

TAВLE

email_list (first_name

VARCНAR(20)

, last_name

VARCНAR(20)

,

еmаН VARCНAR(60))

Оба запроса будут вьmолнены без проблем? Если нет, напишите, что, по вашему мнению, может пойти не так.

154

глава 3


соэдание u зоnолнение 6аэы данных

110uожuuте, что-то зuесь не лаUuтС51.

Я ""ел ко(}, чтоСы созuать таО'лuцу, точНО такой

С CdМLI.М Jd,t')pOCOJvl, CRIATE TA~LE €ce € t')°f~Ke. н.о MySQ,L-)'У)ермu.ндл н.е JrtdeYr\, € I{ClI{Ou. 6С\3е н.уж.н.о созgct€d,Yr\Ь Yr\Cl6лu.u,у.., ~o h-u'I{У.9ct н.е ~О.9u.iТ\сяТ

же, как тот, что мы тоЛЬКО что соста"uлu ... И "от

Я получаю какое-то странное coocl.1\eliue оС ошиСке..

с ()

По KctKl.L/'A-iТ\О I!pu.Yu.MM Jd,t')poc CREATI TABLE н.е срctдОYr\dЛ I1pU. t)o\lbLYr\Ke g'bLt)Oлн.ен.u.я. его u.J MySQ.L-Yr\ермu.Н4Лct.

Тао.nица

т_д_га

базы данных

впереди ДIJlМiАИ

Элмер столкнулся с серьезной проблемоЙ,. связанноЙ с тем, что

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

что создали базу данных

el v is_store,

но на этом сервере может быть

множество других. Он не может предполагать, что вы хотите иметь дело

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

\

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

...

Элмер fС\3.9fdжеrt,

IfС 8ЪJ~a.G')h,

t')OYr\0МY Ч"Iт}о e~o

Jdl1pOC CRIATE TABLE деJУt1речен., d MySQ.L, Yr\eM н.е Мен.ее COOdtll,de)'Y) о 1(~I<ОЙ-Yr\О

ошu.дJ<е.

ZV11blX ~011YOCO~

~; Что это за странное приглаwение о>, которое я иногда вижу в моем МуSQL-терминале?

О; Приглашение -> показывает вам, что вы вводите один большой запрос, разбивая его на несколько строк.

MySQL таким образом

говорит вам, что он знает, что вы все

еще продолжаете вводить запрос, даже если вы нажали клавишу «Ввод» (<<Перевод строки»), чтобы разбить длинную строку запроса на несколько коротких. После того как вы поставите точку с запятой в конце запроса (неважно, сколько строк он занимает в окне терминала),

MySQL выполнит его. выздесь ~

155


не за6ывайте про ключевое (лово

Выполните запрос

USE

USE

перед ИСПОЛЬЗ0ванием 6азы

Для того чтобы запрос CREATE TABLE работал , Элмеру необходимо выбрать базу данных в MySQL-терминале, и он будет знать, какой базе данных принадлежит новая таблица. Запрос USE ( «использовать. )

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

Запрос

onpegeAget11 вазу

. ~ 3cs.l1poc USE lO€OPU)!} MySQL, 1<0.1<:/,1O dct,3y J!:эо.н.Н.bu< €bt н.o.мepeн.br. (АСt1O!lbдово.1Т\Ь. ИИJI_базы~аиных

USE

gaHHblK

ПО умолчанию

gA9

всех

nослegyющux

~p0c06. Эл меру необходимо указать имя своей базы данных в запросе USE, чтобы получить доступ к таблице именно в этой базе данных.

еlVi.Бlуriсs

156

глава 3


соэдание и заполнение баэы данных

=~-TeCT-драйв 8начаnе выберите базу данных Эnмера с помощыо запроса

USE,

а затем создайте табnицу.

Выполните запрос

USE, чтобы выбрать базу данных е1 vi s_s tore

в каком-нибудь из инструментальных MySQL-приложений, а затем выполните

запрос CREATE TABLE, чтобы создать таблицу USE

emai 1_1 ist

в этой базе данных.

еl vis_store

CREATE TABLE email_list (first_name VARCHAR(20) , last_name VARCHAR(20) ,

еmаН VARCНAR(60) )

(' Ko~ СО3ЭQн.u..SI.

'YI\QdЛЦu,bL

'YI\QI(ОЙ Же,

I(QI( u. I1ре.жэе. н.о 'yI\олы<o

'YI\ре~уе'Yl\СЯ

€I:МPQ'YI\b ~y

ЭФi.НЬt,х,l1р е .жэ е ЧеМ Он. СМОЖе'Yl\

PQdO'Yl\Q'VТ\b.

выздесь

157


ЭQnРОС DESCRIBE

Ой! ~ моем ~11poce CfJ?A11~1~~ 0l1ечаmка, но он ~ce pa~HO ~ЫI10"Heн. ~тb ~ SQl--коМatt()а о

в

SQL

отсутствует команда «Отменит.. ввод))

..

В чистом виде, но возможност

исправnеНИR

оwибок все-таки существует. Тем не менее, вы должны определить, что за ошибка была сделана, прежде чем при ступать к ее исправлению. Предположим, таблица ета i

1_1 i s t Bblrлядит так

lаП-"аmе

I

emoil

Проверьте, что не так в этой таблице.

Есть какие-нибудь идеи, как можно исправить ошибку?

158

главаЗ


создание и заполнение 6азы данных

3апрос для

DESCRIBE

покаэывает структуру таблицы

Toro чтобы исправить ошибку в таблице, ее нужно прежде найти. Даже если

вы

не предполагаете наличие ошибки, никогда не вредно лишний раз проверить свою работу. Запрос

SQL DESCRIBE (.составить описание~) анализирует структуру таблицы и

выводит

список имен колонок, типов данных и другую информацию.

Замена шаблона имя_таблицы на действительное имя таблицы дает нам следующий SQL-запрос:

~ Имя Yf\cJ.dлuu,b!., ot)UCcJ.НlA.e DESCRIBE email_list

.м.bt ХОYf\елu дЬ!. €~geYf\b.

KOYf\ODOU I

~ колон.ке fieJd €b!. нctu.эе"Yl\е u.м5l KcJ.)!(.QOu. колон.к u

€cJ.UJ.~U "YI\cJ.длuupt.

MySo..L

н.е Чy€СYf\€UYf\елен. к

peZUcYf\py

КЛcJ.€UcJ.Yf\урbL,

коzэcJ. речЬ uэеYf\ о КЛ/ОЧе€bix СЛО€cJ.Х, Yf\QI{UX I{dK 'Yt)ut)bL Эdкн.btX, t)оэ'Yt)о.му uн.ог.Эd €b!. дуэеYf\е €uэеYf\Ь ЭYf\U СЛО€Q, rtdt)Ucdннbte СYf\роч~ дYK€d.Ми.

IfG БЫ.ffitiG'Jh,

f: Что)то за колонки:

Null

(<<нonь»,

gVl1 blX ffi Ol1focoffi использование станет критичным для

«отсутствие данных»), Кеу (<<кnюч»),

приложения.

Default (<<значение по умолчанию») и Extra (<<дополнение»)?

~; Если в моей таблице имеются

О: MySQL позволяет вам установить различные опции

SQL -

ограничивающие условия)

данные, можно ли с помощью этого

запроса увидеть их?

О; Нет. DESCRIBE показывает вам

f; Могу ли я точно так же увидеть структуру таблицы, используя

phpMyAdmin?

О; Да. Графические инструментальные программы, такие как рhрМуАdmiп ,

позволяют видеть структуру таблиц с помощью запроса

DESCRIBE

только структуру таблицы, а не имеющиеся

или щелкнув на вкладке визуального

Эти опции контролируют такие условия,

в ней данные. Не волнуйтесь, очень

просмотра таблицы. Какой конкретно

как допускается ли отсутствие данных

скоро вы увидите данные вашей

инструментарий использовать

в колонке или установлено ли для нее

таблицы ... но сначала мы должны узнать,

Адя анализа ваших таблиц -

значение по умолчанию. Мы рассмотрим

как поместить данные в таблицу.

зависит исключительно от вас.

АдЯ каждой колонки вашей таблицы.

эти опции немного позднее, когда их

8Ъ1здесь

159


удалите вашу таблицу

(DROP)

я uспrа~uла опечатку UПОПыталась

~ыполнuть J3nroc C~I? -rюu:; ,aHO~O Это не uало HUKaKoro rезультата. я что, uолжна ~начале уuалuть тадлuцу с опечаткой;'!

'р и.мен.u. I\epgou. коЛоtu<и. дbLЛ~ сЛ~Чd.u.н.о .9ol\yw,eк.ct Оl\еЧd.'Ir\Кd.· first_f)d.e'lr\ ...

ой'

Фактически это вам и необходимо сдеllать. Вы не можете пересоздать табllИЦУ с помощью запроса

CREATE TABLE,

еcnи така. табllица уже БЫllа создана. После того как вы создали таблицу, она IIродолжает существовать 11 не может быть пересоздана с помощью нового запроса

CREATE TABLE. Если

вы хотите переСО:I)!ать

таблицу с нуля, то должны сначала удалить существующую и зате:\1 начать все СII<lча..'Ja .

В

SQL дЛЯ удаления

таблицы из базы данных используется :ШlрОС

DROP TABLE

«<удалить таблицу!». В результате выполнения этого запроса таб.'lица удаляется вместе со всеми хранящимися в ней данными . Так как в новои таблице пока никаких данных нет, мы ничего не теряем в результате операции по удалению старой таблицы и созданию новой с откорректированным именем

f i rs t_паmе . V\/~\Я. ·fТ\6,дЛ\)',J..~;)L KOW,O?y)<) мЬ1. хоw,ели. Оl:,tу.9d.Ли.w,р 'j"< \·р,(я 9с,ннЬ...х. "v 0_".

160

главаЗ


соэдание и заполнение баэы данных

3лмер готов Jаносить данные

ОmЛUЧНо.l1осле moro как оазз иэнны)( u mаелuца созиэны,

SQL-запросы CREATE DATABASE, USE и CREATE TABLE

('Ы.1И успешно использованы для создания базы данных листа рассылки и таблицы. Элмер мог бы быть более довольным только 3 том случае, если бы таблица была уже заполнена жаждущими

я romo& к тому, чmоеы !lt'ucmynumb к СО)(t'эненuю &ажны)( иэнны)( иля лuсmа t'эссылкu.

:юкупателями. Это работа для РНР ...

Бd.3d. .9d.н.нh!.x e.Rvis_slore соэ.ер.жu."YI\ еЭUНД·f\gенн.у)О "YI\Ф~ЛUu,у e"Yl\d.i.C)ist.

email list lascname

emoiI

)' тd.длu.u,ct elY\d.i~._~ist COC"Yl\ou."YI\ UJ "YI\pex колон.ок. UС1\ользуемbtx эля. xpd.rleкu.51 d.~ лu.СlY\Q Pd.ccbtJ1кu. Элмерd.. Э I tfG БЫ~itG't1I,

ZV11bJX ~011ГOCO~

~.

~.

9 НеМ каждый раз, когда вы показываете код SQL, вы ставите

все мои данные будут потеряны?

"ОЧКУ с запятой в конце всех SQL-запросов. Почему здесь их нет?

О: это так. Поэтому будьте внимательны, когда удаляете таблицы.

·Р. Эй, у меня есть книга Head First SQL (отличная, книга, кстати). -.р. 3начит, еcnи в моей таблице есть данные и я удanю ее,

О: Мы рады, что вам понравилась книга «Очертя голову ; 5Ql". Разница заключается в том, что, когда вы имеете дело ~.o<;peДCТBeHHO с

SQL, вы обязательно должны использовать -:>-;1()' с запятой, чтобы SQL мог понять, где заканчивается ;artpoe, потому что MySQL может обрабатывать несколько ;.anpoeOB одновременно. В РНР при использовании функции -с · ::

::; 1i_query ( ) вы можете передавать на выполнение

-о одному SQL-запросу за один раз, поэтому точки с запятой

~ требуются. Но не забывайте, что вы обязательно должны ставить

'9: 3начит, ecnи мне необходимо удалить таблицу с данными, мне крупно не повезло?

О: Эй, совершенных людей не существует. Все совершают ошибки, и

SQL предлагает запрос ALTER (<<изменить»),

с помощью которого мы можем изменить существующую таблицу. Мы поговорим об этом запросе немного позднее.

-;-..rt;y с запятой в конце каждого РНР-выражения.

выздесь ~

161


сцеНQРUЙ QddemQi/.php

Создайте сценарий

addemall.php

Эл меру необходима НТМL-форма, которая могла бы принимать от покупателей их имена и адреса электронной почты. Получив такие данные, он мог бы передать их РНР-сценарию и сохранить в таблице

email_list.

В веб-форме

(addemail. html)

необходимо иметь три поля ввода данных и кнопку. Атрибут формы

action является наиболее важной частью кода, так как - передать данные формы сценарию addemail . php,

его задача

к созданию которого мы приступаем.

~aIIU~ &U--ФОI'_« "Пl'а&ка 'АО<"I'OIIIIOII nOЧ .....1'> u f'Hf-CIШIaI'UII

A-mрU.dyn1 actiot) -

'аАII o"nl'a&Ku noч ..... ~O "U""1 1'aca.t"Ku'

..7Yf\O Yf\O, Чmо сое.9tA.Н.Я.еYf\ НТМ L-€еd-срорм,У

с PHP-сu,ек.арu.ем (ac{cleYf\ai~'f*1P ),

'

KOYf\Opbtu u. IlP0U.,3€0.9u.Yf\ к.eoдx0.9u.мbte ollepau,u.u. с .9aн.нbt.Мu..

__-

~~ELV;~.COМ ..... ..... ................. и.:

~

_~::.....

Г---.,

tIIIIIIIt Г-"-·

,

~-~=~

'-.--'\:------<form те

th d=-post- action= - addemail . php-> о • o</label> for=·firstn~e :~. • narne=-firstnarne - I><br /> --text- ld= flrstname type• ЛИЯ' </label> for=-lastname >фами ' . e=-lastname- I><br /> _. • id=-lastname пат type- te~t. электронноЙ лочты:</lаЬеl> for=·~mall.>~~~mail. name=-email- I><br /> . type= text. ~d =.Submit- vаluе=-Отлравить /> type=-submlt пате

<label <input <label <input <label <input <input </ form> </body> </html>

/ 162

глава

3

"


соэдоние и эоnолненuе 60Э'" донн",х

Сценарий

addemai 1. php обрабатывает данные формы «Добавление адреса электронной

почты». Этот сценарий должен получить данные от формы, соединиться с базой данных е1 vis_store и добавить эти данные в таблицу

email_list

с помощью запроса INSERT.

Помогите Элмеру. Напишите сначала пример SQL-запроса для добавления нового пользователя, а затем используйте этот запрос для окончания кода сценария.

,.,---:>

НQt'luшu"W\е 'з.9 есЬ t'lpuмep .3Qt'lPOCQ,

€ ре'зУЛ:>"W\Q"W\е

€I::iи)олн.ен.uя.

l<o"W\0p0Zoo ~

~.9,YY!) .90~€ленbt

€"=rnQдЛUu,y Элмеpct.

<?php

$dbc = ... .. . . . . . ... . . . .. .. . . ... . .. .. ... . ... . .. . ..... . . . . . ..... .. .. . ... . •. . ..... . .• .. ................ . .......... . .. . . . ........

... ....... ... ... ... .. .. ............ ....... .............. ...... .... ................................................. ............ $first_ name = $_ POST[ ' firstname'];

........ ...... ....... .. ...... ... ... .............. ...... .... ... ......................... ............ .............................. .... .... .................. ...... .. ........... ..... ............ .... ...... ....... .. ..... ...... ......... ..... ....... .............. .. $query = . ... .... . . .... . ..... . ........ . ................... . .... . ............ . ... .. . . .... . ....... . ...... . . .. ..... . .......... .

......... ... ....... ..... ............. ......... ... .... .... .... ..... ........... ............................... .... .............. mysqli_query (... .. .. . ... . ..... .. .. . .

....... .......... ... ......... ...... .... ......... ...... ........ ..... .. .. .......... ... ........... ... ................ ....... ..... echo ' Покупатель добавлен.';

.. ....... ....... ............. ................. .... ............. ........... .......... ...... .......... ........................... ?>

addem<iI.pl1)

8ыздесь ~

163


уnрожненuерешенuе

Сценарий

addemai 1. php обрабатывает данные формы «Добавление адреса электронной

почты». Этот сценарий должен получить данные от формы, соединиться с базой данных

e1vis_store

и добавить эти данные в таблицу

email_list

с помощью запроса

INSERT. Помогите Элмеру. Напишите сначала пример SQl-запроса для добавления нового пользователя, а затем используйте этот запрос для окончания кода сценария .

.т~~т. т:щ .~:m~~!~~~~t..(f~r~t~IJ~)!\~"!4~t~IJ~)!\~,. ~-m~i~)

...~~~~~ .~:~~~.~:: . '.~:f.!'<,. )':':~.i~~~~~~~.~~~~r.~~~~:COlY\') ) 11 Ptuмer. заt\роса INSER.T Mpet\ucatt € €u-эе PHP-С"YI\р,0КU, КО"Yl\ОРdЯ. €КлtoЧctе"Yl\ € седя. э.анн.btе фОР Мbt• t)оэлеЖА.(,lI,uе эода~леtШ)О.

~o 3Нd.Ченuя. Элемек."YI\О€ #4ccu.€a $_POSТ. € KO"Yl\0P btx 3 ct1(Л)ОЧеНd. мреэакндя.

u.Нф О р#4u,ust.. , '_ й

<?php

$dbc

k'

,,~ .

$:tore')

= .m~~.~gi_у.q!"lм~t.сd.~-t~.:Vn~~~"Yr.I~~:-{i~...с;~-ro .•..~~~c .. !-fI;...\I1~., .... ':-1:\$-

·

('О

.Qr..d,е. .

"J.l

. ....... .... ..

~ u" .... a r М\JSQ..\..-сеj)веj)ам.)l . s.е.r~е.r..), ........... .......... .. ······ .... . ШUаl(d. co.e.9"""'~' ''' .L'.':J •. . I I

..

$first_name = $_ POST[ ' firstname'] ;

.$.g4~i:_Mmf:...7 ..$_Р'QSТГ)~$:tt\ФJ\~'J ...... ···· ··· ··········· ······· ······· ····· ······ ······· ······· ····· ···· ' . Й'1' ....... ........................ ...... . ... . .$.~:m~\~й..7. .$_t1>0.. ~С'Тl " .~:m~\~. '........ ..... ....... ...... ..... ...... ....... . $query -_

·It.lS-сР'Т It.lTO e"WI О Dist (first !1Ф'I1~,~~~:t;_t)~"'!'I)~ •.~mФЛ .~ . : .................. ..··· · \~ h'~ '~ 1т'" :1~~ ... .......... .. . . A ,'

.~VА.ku~.·(:. $.f.;.~;.~~~·~~~:~·.:.$g~$t_\l~-m~'J' : $.~"Yr.Iфgт ~ .................................. ................. ( .$~.~~,..$.~y..~r.~...) , ..9.( . d.i.Е}СQЩ\Аqк9. .в~q/J~~.I:Щ,5!.. .3~t:1.p.RY~. х . 9.Q3~ :9-4~ •.)!............ ......................... ..... .

mysqli_ query

echo ' Customer added.';

........ ....... ............ .... ......... ................. ...... .... .... ?>

Еслu. €b!. xO"Yl\u."YI\e сэем"YI\Ь c"Yl\paнuu,y

u.н."YI\ереск.ее, мо.ж.е"Yl\е эода€u."YI\Ь сtoЭа

zu.ll ерссbtлI(У. Уl(ctJbtЙа~)О нd. €dШУ форм} с 1l0МОЩЬ)О HTML-"YI\еzа <а>. 164

главо3

addemail.php


создание и заnолнение базы данных

-Тест-драйв Проверьте форму <сДо6ав.nение адреса эnектронной почты». Загру:ште код для веб-страницы «добавление адреса электронной почты~ с сайта

Не

С\д

«Лаборатория " Очертя голову"~ по адресу www.headfirst1abs.com / books / hfphp. .3 У.9 Ь У11е Этот код находится в каталоге chapter03 и включает веб-форму Эл мера UJMeн.u.Y11b a ddemai1.htm1 . каскадные таблицы стилей (style. css) и два файла изображений t)еремекн.уJO. (e1 v is1ogo .g if и blankface. jpg).

А теперь создайте новый текстовый файл

со~еfЖС\~

~ CCvl.,III(Y н4

addemai1 . php

и введите весь код

coe.9 ц Н,eн.u.e

IIрелыдущей страницы . Это сценарий. который будет обрабатывать данные веб-формы 11 добавлять новых покупателей в таблицу

Загрузите все файлы на ваш веб-сервер и откройте страницу

с Y-lеУ11ом

addemai1 . htm1

€С\шеzо

н веб-браузере. Введите данные нового покупателя в форму и нажмите кнопку

1( он.к.реУ11Н,Ог.о

« Отправить~ .

Ш~~ #~ - ~~~""""~­ Ma~M~EI.."'$.COМ

s-te--. ~._""""""""" ДntII ...... мет '*""*.Catмi'rt а.-о.) ИIIIo : ~ .... _ - _ ......,

80'

_:

.....

~o;;.--"' '''' --'

~"*"",,",,," ........ -" "''''''~ '

с cep€epOM

dCIJ .9а.ННЬ!.х,

emai 1_1 i s t.

01( рУЖен.u.я..

~ ДОdd€лен'це н.o€oг.o

JC

~~~===~Ba_=&._ 11 0 КУI16.У11еля. € лцсУ11 ?dССbt.ЛКц

~

I1ОЭ1Т\€ерЖ:9еН,о cu,eн.d.pueM

6.ddе1Т\diЯ.~р.

Проверьте. что покупатель был добавлен в базу данных запросом SELECT и з ИJlструмеllТальной программы

MySQL .

8ы здесь ~

165


nроверьте свое знание запроса SELECT

tlG 8Ы~OlG'}h,

Z4t1tblX ffi o1tfocoffi

~; Есть ли в SQL другие символы, имеющие специальное значение, как «звездочка»?

О; ХОТЯ в SQL есть и другие символы, имеющие специальное значение, «звездочка»

-

единственный, о котором вам необходимо пока знать. Более важным ДЛЯ наших текущих целей является то, что это единственный из специальных

символов, используемый в 3апросах

SELECT.

Так как в лист рассылки Элмера стали поступать данные, помогите ему написать несколько SQL-запросов, которые он мог бы использовать для поиска определенных данных покупателеЙ .

Вblберите все данные для покупателей с именем Мартин:

Вblберите только фамилии для покупателей с ' именем Буба:

Вblберите имена и фамилии покупателей, чей адрес злектронной ПОЧТbI Is@оЬjесtvillе.пеt:

Вblберите все колонки для покупателей с именем Амбер и фамилией Маккарти:

166

глава

3


создание и заПолнение базы данных

Оmлично.leперь ~ти покynаmели мотут по()писыВаmься на мои лиСm рассылки чере,

Вед-страницу. Эmоm лиСm очень Хорошо СОсmаВляemся сам.

о

~ ~o н.е I< он.еи, "lТ!С1JлщJ,bt. ЛЦ"IТ! Рd.ССЬtЛКu. Эл..мерd.

pctc"IТ!e)y) )Y)_et)epb с о;;ро.мн.ои. c KOPOCYf1b}O.

Но эnектронное ПИСьмо не будет cocтaВnATЬCA

саМОСТОАтеnьно.

Эл меру все еще не хватает другой части веб-ПРИЛОЖСIIИЯ _ той, которая предоставит ему ВОЗМОЖность Составить содержание

электронного Письма и затем Отправит его всем rrокупателям. перечисленным в его листе рассылки. Чтобы решип, зту эадачу, ему необходима новая НТМL-форма и РНР-с/{енарий

для обработки се данных.

.. -нм '~"I". &а., ... •• """'_14" Cq"aaнUf "'(";0o".",

iatlllb81C •

(

~Yf1opou. }Yf1d.1i gbtIiОЛн.е.н1

.A

"М,..... gq t"IIUI

=::.-:t::::;.1fOtorb "81.,... • • • AUCIIi " . е а",,, ....

~aнK W-top.", «Olllnpalкa !МaClllpoнн04 nОЧIllIll7) U fH"-щенарtlfl

а"lI OIII11pa&кU ПОЧIIIIII ~O "1К8Iy

Pac.c.w"KU.

выздесь

167


эаmо.,umе карандаш решение

Так как в лист рассылки Элмера стали поступа т ь данные , помогите ему написать несколько SQL-запросов, которые он мог бы использовать для поиска определенных данных покупателеЙ .

Выберите все данные для покупателей с именем Мартин:

.~Р.-:ДJ. .~..~..~m~.i .~~~\~i . W.HtRf; .f\l:"~t~lJ~m~..7..'~.~rmщ·( ... ... ..............................

:~:~o::>,,;=Xв~p"". ~ :J.сло€u.е, ~~€;..'C; ;;Н;l~щее .3f{dчен.u..Я. !(олок.о!( i'!\ddлu.lфt.

u..3 gcex

COZJId.CI-tO KO"Yr}0p0My

ft!:я.€оэяi'!\СЯ i'!\OllbKo i'!\e Jdt)U.CU., ЭЛЯ

!(Oi'!\0p btx u..мя. t)ОКуt)di'!\еля. -

Мdрi'!\u.к..

Выберите только фамилии для покупателей с именем Буба:

Выберите имена и фамилии покупателей, чей адрес электронной почты Is@оЬjееtvillе.пеt:

.~ЦJq .f.i.r:~.-t~t)~ro~..~~~.-t~t)~ro.~ . FR9.~ . ~roф~~.fi.~~ )mF.~ .~m<;\i.~..7..·g~.~9.Q~~~t.Y.i .~~~. !1et' \.. lIb<

о"р еэeJ!W1\< ы"Э JНdченuu:]61"

колон.ОI(,

t)pu.

Лf\о,М l.J.Мef{d !(олок.ок ~ .3d t)poce

РdJэелен.bL Jdt)Яi'!\bt.Мu.. Выберите все колонки для покупателей с именем Амбер и фамилией Маккарти:

168

глава 3


соэдание и заполнение баэы данных

Другая сторона ПРИJlОlКения 3J1мера

ФорJlo4 «(}тl')r-€КQ

Задача отправки электронных писем людям, перечисленным в листе

€оз,мФI<'н.ос."YI\Ь Элмеру

рассылки Элмера, напоминает в каком-то смысле задачу добавления сведений об этих людях в лист рассылки, потому что обе они решаются с использованием НТМL-форм и РНР-сценариев. Главное отличие

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

ernail_list,

в то время как сценарий

addernail. php имеет дело

с данными только одной ее записи.

элек"YI\РОнн.оu "O'ftr\b!.» .9Qe"Yl\

€€ec"Yl\U "YI\eMY U СО.9 е р,ЖДкu.е элеК"Yl\РОнн.о~о l')ucbJlo4 U 3Q"YI\eM O"Yl\t)PQ€U"YI\b e~o всем t)окуМ"YI\еля..м..

Чuс.лен.н.bt.М € лuс."YI\е

'OJ?=MM 68) ......."•• ...... '~ -.

,.,ре

1'8".'."

е '"."м' hf= 4-'''''' ·А..... ,.."

:=:=;:::1:1;.. М

.....,.•••••

~O"YI\ 'lТ\QK. мbt уж.е м

.....

t)ослеэк.ем

са "1 111 ~. .

Э'lТ\Qf'l е

.

~ method;'post'

'sendemail . php'>

for=*subject*>TeMa злектронноrо nисьма:</lаЬеl> . put type=*text* id=·subject- name=·subject* /><br 1>

<~n

о nисьма"</lаЬеl>

<label fоr=·еlvis~аil~>содеРЖ~:Иlе ~леК~~~~:s=.8. соiS=*БО* ></textarea><br /> <textarea id=·elv~sma11· пате- е У1эта1 <input type=*submit* name=*Submit· vаluе=·Отnpавить· />

</form> </body> </html>

8ыэдесь ~

169


сценарий sendemai/.php

Колесики и винтики сценария «Отправка электронной nOIlTI»I»)

(sendemail.php) Сценарий

sendemai1 . php должен объединить данные из двух разных источников информации для

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

emai 1_1 i s t

базы данных е1 v i

s_s tore.

С другой

стороны, он также должен прочитать тему и содержание электронного письма, введенные Элмером

в форму «Отправка электронной почты»

(sendemai1 . htm1). давайте разобьем все это на этапы.

Счumы&attUt темы Uс.<ЮtpжattUЯ ,AeК~OftHOfb nUGbQ &форм

о

с. uc.nОЛЬ,О&attUем ntpeмtНHOO , _ f051:"

Ничего нового здесь нет. После нажатия кнопки «Отправитм В форме «Отправка электронной

почты»

( sendemai1 .htm1) все данные передаются сценарию sendemai1 . php, в котором $_POST.

мы присваиваем их значения переменным с небольшой помощью массива

о

'ыnoAНtНut ,аnросз 5~к mа5лuUt tmаiL_Lбt. PHP-фУIIКЦИЯ

mysq1i_query ()

выполняет запрос

SELECT,

в результате чего получает

данные из листа рассылки . Так как нам необходимы все данные, имеющиеся в таблице, мы используем запрос вида

о

SELECT *.

'ы60РI<a ~амны)С о nокynаmелях '" р~ульmаmа ,anp0C8.

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

о

,~& Ф1НКUUU таiLO -аля omnpa&KU ,ла<mрOftнbIX nUctМ каж-аому nокynаmелto. Отправка электронных писем возможна в результате обращения к строкам листа рассылки, каждая из которых соответствует строке

=--==--=~ .~~

......... .

(~': " "" "

..

данных в результате запроса. Цикл, который мы здесь создаем, начинается с первой строки данных, затем переходит на вторую и повторяет такой переход для всех оставшихся строк результата ,

полученного после выполнения занроса

SELECT.

ЦИКЛ

прекращается после обработки последней строки данных .

email - list Iast

, {;rst;:.narne

juliал@Ьrеаеkпееkрizzа .еаm

Оуте

Джулиан Кевин

Джоне

Аманда

Санчес

Тема элек"'rоt-U-W~О

еФа"

J\QI11e

t)u,cb.мd

е г,о

соэеrЖАt-UJ.е

sunshine@breakneekpizza.eom

t) е. rе.эС\)O"IТ\ ся. cu,eн.aru,)O че.rе.з

...

суt)еr~лоМлЬн.~)О

1

l"\е~е..мен.н.у)О

Сu,еКс\fЩQ

h.eodxo-эlAМbt

4

LАманда I \

---""

el'T1C\i,C-Рist.

3

Санчес

Ажулиu.

..-

(А,3 l'Т1С\длuu,bt глава

$_РОSт.

....

~С\КГt.btе.

170

u,

jones@simuduek.eom

."

I

SUn


создонuе и заполнение 603." донн."х

в первую очереАЬ

-

ИJвлечение Аанных

у вас уже богатый опыт по извлечению данных из форм в РНР, поэтому для вас нет ничего нового в выполнении первого этапа. Просто используйте суперглобальную переменную $_POST для того, чтобы сохранить значения темы электронного письма и его содержания в переменных РНР. Пока вы здесь, давайте будем двигаться дальше и присвоим эти значения переменным, которые

понадобятся нам позднее для отправки электронных писем.

,

$from = elmer@makemeelv~s. сот $subject = $_POST [ 'subject' ] i $text

=

Аэрес элек"'IТ\РОкн.ой 1l 0Y'tr\bt Элме ct

~ coxpctНoeНo € llepeMeкн.ou, Y'tr\odbt. k "'IТ\очн.О.3н.ctлu., г. е он. н.ctxоэu."'IТ\СЯ,

i

~

$_POST [ 'elvismail' ]

_

i

Остальные данные, необходимые сценарию sendemail . php,

будут получены из базы данных MySQL Эл мера. для извлечения

данных покупателей из таблицы

email_list

еслu. КО2Эd.-н.u.~эь e0.3н.u.Kк.e"'lТ\

н.еоdхоэLA..МОС"'lТ\Ь ег.о tJ.jМeн.u."'IТ\b.

дctННhr.е фоо.мь!. «О

Эле/(Yrlрон.н. I ~

D

Yrlt)pct~/(ct

coxpctKelibt еи Il D ЧYr)Ь!.» Yrld.I(.Же t)epeMeн.н.btx.

сценарию необходимо сделать запрос

SELECT. В отличие от того, как мы делали это прежде, когда передавали запрос SELECT из MySQL-терминала и просто смотрели данные таблицы, на этот раз мы сделаем это из сценария

sendemail . php вызовом функции mysql i_query ( ) .

llеремеКНдЯ $C\uer~

r

t

соэерJIШ."IТ\ SQ.\"-.3с:\I1РОС

g f:uэе C"IТ\POKU "IТ\eKc"IТ\a.

Э"'IТ}о НQШ jctl1poc, € ре'зУЛЬ"'lТ\d."'IТ\е

~ €bu)олн.ен.u.я. I(O"'lТ\0P020 дУЭY"IТI

u.3€лечен.bt .3н.ctЧен.u.я. €cex l(олон.ОI(

"IТ\d.длuu,bt. e"lТ\d.i~_~ist.

= "SELECT * FROM email_list"i $result = mysqli_query($dbc, $query)i $query

/

ФУНJ<Щ-tЯ "'IТ\YS9~i_9u.ery() UС I1 0ЛЬ.3уе"lТ\

11 ер е.менн.у)О, СОЭ~Жd.~)О ccbuJк.y НQ соеэu.н.ен.u.е с д<:'JОu. ЭctннbIx (~cl!'c) u. С1Т\РОI(У .3d.IlPOCd. ($9u.ery).

~ ССЬ\.ЛКd. к.d. соеэuк.ен.uе с dct,30U. эctк.н.bt.x н.еоdхоэu.Мd. ЭЛЯ "ереэd.ЧU .3d.I"\POCd.

НQ €btllолн.ен.uе . Де"lТ\d.ЛU, КctСd.)OUJ,u.есЯ

Э"lТ\Ог.о соеэuн.ен.uЯ, соэерЖд"lТ\Ся. € l1 e pemet-U{.Оu. $dbc,

Нет. в действитenьности ?начum, Ike, чm() мы U()ЛЖНЫ сuелаmь, -

переменна. $result непосредственно не содержит

никаких данн",х та6nиц.... Если вы попытаетесь вывести значение переменной

3!n() nу.юumu no сmу.юкам ft3ульmаmа

зэnроса, зн<зчetiuе к()m()у.юr() nruce,()eti()

~__n .....~eмetiH()U tresult, maK~

$result непосредственно echo, вы увидите что-нибудь подобное:

с помощью команды

Resource id #3 Переменная

$ resul t

содержит номер идентификатора ресурса

MySQL,

а не непосредетвенные данные, полученные в результате выполнения запроса.

Происходит это следующим образом: MySQL-сервер временно сохраняет результат выполнения вашего запроса и присваивает ему номер ресурса, по которому его

можно идентифицировать . Затем вы передаете этот идентификатор функции РНР

mysqli_fetch_array ( ),

которая извлекает данные по одной записи за раз.

8ызоесь

171


uсnольэуйmе mysq/Cfetch_array() для получения результатов запроса

ФУНКЦИЯ

mysqli _fetch _array()

ИJВJlекает реJуJlьтаты

Janpoca

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

$result . Функция mysqli_fetch_array ()

использует эту переменнуюдля того, чтобы получить

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

• ..,--

$row . -

~C!. фУНJ<u,цst ИJ€'леКcJ.е1Т\ JС\rщ.сЬ 3C!.ннbt.x

Цд реJУЛЬ1Т\С\1Т\О€ Jdt)POCd ц СОХDС\НЯе1Т\ ..71Т\ц Эdн.нbt.е €' €'цoe .мctccц€ I $r~w mysqli_fetch_array ( $resul t); к So.L J cJ.. 0 '-~ C\:*:9btu -JС\t}рос u..мee1Т\ CMU Т1еременндя. $row - ..7"n\O .мctccu€', КО1Т\о ~~ COдC1Т\€e~й u.э е н.1Т\u.СРu.l(du,u.он.н.btЙ н.омер, t)e-р€'оК4Чd.Jlbн.о соэерЖu.1Т\ t)ep€y}O JdllU.bb I(О1Т\Орbtu Ц С IlОЛЬJуе1Т\Ся. ЭЛя. Э ОС1Т\УIJd IL

_

=

ЭdНн.bLx К4шег.о реJуJJb1Т\d1Т\Q.

1(

Эdн:н.bt.м, dCCOu,u.U.PO€dн.нbt.М с ре.JУЛЬ1Т\d1Т\ОМ

..71Т\ог.о

Каждый раз, когда этот код выполняется на веб-сервере, запись

данных из результатов запроса сохраняется в массиве $row.

Вы многократно вызываете функцию mysql i_fetch_array

()

JdIJpoca.

<J>yнкЧus1 mysq1i..fetch_81Тay<) COX~ зanucъ

gaHHbIx

для доступа к данным каждой записи результатов вашего

запроса. Таким образом, первые три вызова функции u3 резуAbtnatn06 зanроса mysqli_fetch_array () извлекут первые три записи таблицы, 1\ мaccu& сохраняя з начения колонок в виде элементов массива $row.

= mysqli_fetch_array{$result); = mysqli_fetch_arraY{$result); . f;rЯ_l\Qnte Джулиан

Ке8ИН АмаНАа

= mysqli_fetch_array{$result);

Io,,-,,оте

ЗК4че.н.u.е I(dжgой I(ОЛОНJ<u.

Оутс Ажанс

СохрС\няе1Т\Ся. € €u.эе ..7лемен.1Т\d .мctccц€'a $row.

Санчес

$row

172

глава 3

$row

$row


создание и заполнение базы донных

Для того чтобы убедиться, что вы действительно можете извлечь данные по одной записи за раз, закончите код РНР так, чтобы , используя команду

echo, вывести

имя ,

фамилию и адрес электронной почты каждого покупателя,

содержащегося в таблице

$query

=

"SELECT * FROM

еrnаН_Н s

email_list.

t ";

$result = rnysqli_query($dbc, $query) ; $row

= rnysqli_ fetch_ array($result);

выздесь ~

173


не

CQMOe лучшее petUeHue

~шенuе задачu Для того чтобы убедиться, что вы действительно можете извлечь данные по одной записи за раз, закончите код РНР так, чтобы, испольэуя команду

echo,

вывести имя, фамилию и адрес электронной

почты каждого покупателя, содержащегося в таблице

$query $result

=

email_list.

"SELECT * FROM email_list";

= mysqli_query($dbc,

$query);

$row = my sqli_fet c h_array($result );

·~m9. .$J9.w[f.ir$~_t)~1Т1~:1. ,.:.:.'..$.r:-9.wU<,\$Lt\<'\-wn~:J .•.'..:..'.:. $.Г9wГ~:m~\.r.l ... .'.~ .~y: j? :" ·..$r.Q~.. ~..1Т1~ $.Q/i_f.~:t.clL~п:<\~.< $. r~$.v.i.·t).;... ..... ......... ............ ..... .. ......................... ·~m9. .$J9.w[f.ir.$~_t)~1Т1~1:.:.: .'..$.r:-9.wU<,\$Lt\<,\-Wn~] .• .'..:..'. '. $.Г9wГ~:m~\.r.l ... .'.~ .~y: j?:" ·$.rQw..7. :m~$~.~j_f~t.9.L<'\rr~~.< $.r~$.v.~~)i .... .... ....... ......... .................. ..... .. ............ . ·~m9. .$J9.w[fjr.$~_n~1Т1~1 ,.:.:....$.r:-9.wU<,\$Lt\<,\-Wn~] .•.'..:..'.'. $.Г9wГ~:m~\.r.l . . .'.~ .~y: j? :;. ·$.rQw..7. :m~$~~j_f~t.9.L<'\rr~~{ $.r~$.v..~~)i .............. ........ ....... ................................ . ..~m9..$J9.w[f.ir.$~--I1~1Т1~1t.:.: ....$.r '. ' t.$.r.QwГ~:m~\.r.l.. .'.~.~r.j?:" ·$.r.Qw..7. :m~$~.~j-f~t. . -Вы Meн~ ra)bIrt'bIe,aeme. f!oe,morel-iue ul?yx cmrOK коиа сное,а u сное,а -- самое глупое ;,aн~mue, ·~m9. .$J9.w[fjr$~... .'.~ .~r.l?:" которое ~ когuа-ЛUдО е,uuелд. я ye,epel-ia, Чmо есть ·$.r.Qw..7. :m~$~.~j-f~ .. долее уиОдНЫО сnосоо. .~m9..$.

~~f!IIII!1~!!!!l'!!!t"~"..<.~.'1~i ..1 ....'.~ .~r.l?:" ($.r~$.v..~~)i ............................................................. . :1. ,.:.: ....$.r.9.wU<,\$Lt\4.-wn~'J.,.'..:..'. '. $.rQwГ~:m~\f.l ., .'.~ .~r.l?:" .< $. r~$.v..f:t )i ... ..... ... ....... .... ........... ...... ... ..... ... ......... .. . :1. ,.:.:....$.r.9.w[.'i4.$Ln4.-Wn~]., .'..:..'.'.$.Г9wГ~:m~\.t'l ....'.~ .~r.l?:"

Существует боnее приемnемый метод: нам необходим цикn. Цикл

-

это механизм в языке РНР, который повторяет

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

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

любые необходимые нам действия в процессе этих переходов.

174


создание и заполнение 6аз", данн",х

Повторение операции в цикле Цикл

whi 1 е ( «пока~ ) -

while

это ЦИКЛ, в котором код повторяется снова и

lJuкл

снова в течение всего времени, пока соблюдается какое-либо условие. Например, в вашем приложении по техническому обслуживанию может быть переменная с именем

$got_custorners, значение которой зависит

от того, нуждается ли кто-нибудь из покупателей в обслуживании или нет. Если

$got_custorners

имеет значение

true

(<<дa~, «истина~), это говорит

о том, что у вас есть покупатели, нуждающиеся в обслуживании, и поэтому

вам необходимо вызвать функцию

whi1e nosmopgem Kog. пока (whi1e) ca.wogaemC9

next_custorner (), чтобы принять

следующего покупателя и обслужить его. Вот так этот сценарий может быть запрограммирован с использованием цикла

kakoe-лUБO условuе.

while:

rUu.кл t)o€lТ\op51elТ\C51 crw€a. u. crw€a., t)OKa.

.,f,

eClТ\b ХОlТ\51 ~~ озu.н. 11 0 КУt)а.lТ\елЬ.

while ($got_customers) { next_customer();

)

~OlТ} КОЗ dуэе"'tl) t)o€lТ\OP51lТ}bC51 t)pu. Ka.~OM

l1o€lТ}opeнuu. Up.KJk1.. }

~ 3а.кл)Очен.u.е коза. u,uKM в ~г.ypкbt.e СКОдки .эо.еlТ\ €озмо.ж,н.оСlТ\Ь вЬщолt-lЯ.lТ\Ь СlТ\олЬКО ClТ\POK кО.эо., СКОЛЬко €aм н.еодхоэUМо'

)

Когда мы пытаемся определить, имеются ли еще покупатели, нуждающиеся

в обслуживании, мы проверяем условие. Условие за ключевым словом

while,

и его значение или результат его интерпретации всегда

должен выглядеть как ответ «Дa./«HeT~ на поставленный вопрос. Если ответ «Да.,

или

true ( .истина. ), то код выполняется,

Ко.9 € Up.кле whi~e t)оts'"'tI)ОР51еlТ}СЯ

это код в скобках, следующий

-

если же «Нет., или

false ( .ложь. ),

эля Ka.~oг.o 11 0 l<УI1<:1lТ}еля З О lТ}ex

цикл прекращается и управление передается коду, следующему за ним.

t)op. 1101<0.

н.е ос"'tl)<:Iн.еlТ}СЯ

Когда мы вызываем функцию

next_custorner ()

для обслуживания покупателей,

мы выполияем операцию. В данном случае операция

-

это код, заключенный

внутри фигурных скобок, который выполняется снова и снова, пока условие сохраняет значение

false,

t rue.

Как только условие примет значение

цикл прекращается, что приводит также и к прекращению

выполнения операции.

?езулыт\.lт\ t)po€epKu.~сло€u.5l

? while

€сег..эо. лu.до true, лu.30 fa.Rse I1р оз ол.ж.е.н..u.е u,uKM (-t.ru.e) u.лu.

t)rекра.щен..u.е u,uKM (fa.Rse).

(test_cond~tion)

action }

н.u. ~н.oг.o

н.ео3слу.жен.н.ого.

{

Как вы думаете, цикл

whi le

может быть ИСПОЛЬЗ0ван для рассылки электронных писем покупателям

изтаблицыЭлмера

email list?

8ыздесь ~

175


как работает цикл

while()

06ра60тка данных в цикле Применяя цикл

whi le

while

к данным электронной почты, давайте будем обрабатывать

данные запись за записью без дублирования кода. Мы знаем, что функция

mysqli_fetch_array () может извлекать одну запись таблицы и сохранять значения $row, но функция сама не будет перемещаться по записям таблицы - она просто сохранит первую запись Усло€tAе'м ЩАКЛd ~i~e я.€ля.е'Yf\Ся. _ и на этом закончит обработку. Цикл while может вызывать Jмчен.u.е, еОJ€рdЩdе/Ме. СРУНJ(ЩАеu. функцию mysqli_fetch_array ( ) , перемещаясь по 'Yf\~s<1~i_fe1~_drrd~(): tru.e колонок в виде элементов массива

каждой записи данных за раз, пока не достигнет последней.

("tAC'Yf\tAM») eC'Yf\b tA есЛu.

u.x

есЛu. .9aк.н.bte

fd~se ("лоЖЬ»)

-

н.е'!!\.

} , Оt)еРdu,uя'

gbu')олняе-тся I1Ри. ка)/(,.90,М

t)pox 0.9 е u,u,KJJct.

цикла email Оутс

Джул иан

Джонс

Ке в ин

I I I

Санчес

ДМанда

,,

iuliа л@Ьrеасkпесkрizzа .соm iones@simuduck.com sunshine@breakneckpizza.com

2-.. ПРОХод

\ \

Цltknа

\ \ \ \ \

176

главаЗ

,

,

ClJe,q" "

'~

"р rlOЩlfе O~OAЬ,

qltl{JJa

•••


создание и запоnнение базы данных

, ,

+

+

,

6

,

+

:

И9е~~ugoUКQYГtор, UС~ОЛЬJУ~~Й

ЭЛя. ЭОС~У~Q

1(

jле.ме~~у

.fv'I.QCCU€.::t

эол.ж.е~ coo~€e)ТJc~€o€Q~b u.мe~'

Джулиан Оутс

: julian@breakneckpizza.com : jones@simuduck . com P~aHдa Санчес : sunshine@breakneckpizza . com Бо Вэлэйс : bo@bOttOmsup.com Амбер Маккарти : amber@breakneckpizza.com Кормак Hep~c : churst@boards-r-us . com Джоис У.арпер : joyceharper@breakneckpizza.com Стивен Мэйер : meyers@leapenlimos . com Нартин Уилсон : martybaby@objectville.net 'iо л т Перала : walt@mightygW11ball.net Шэнон Муньон : craftsman@breakneckpizza.com Джо Милано : joe_m@starbuzzcoffee.com Кевин Джон е

I(ОЛОНJ(tJ..

IJUКA while

npoxogum через

gaHHMe

tnaБAU\,Jbl

заnuСЬ за зanuсыо.

Кorgа заnuceil БОАЬUJe нет \}UКA

nрек.ращaetnС9.

I

'-О

()

+

$row [ . f 1rst_name' ]

' ,+

!

+

1 Q \

$row [ . last_name' ]

~ эе.йс~вu~ель~с~u JЛbt UСt\ оЛЬзуем ЭЛя. СОе.эu~е.~ ~ескоЛЬкu.x C~POI( ~e .3 Кдк <l:t)Л)ОС», Q o~epQ~Op «~ОЧКd».


не бывает глупых вопросов по поводу while()

tfG БЫ~iiG't1I,

ZV11bJ-Х ~011ГOCO~

'9:КаКИМ образом цикл

while

КЛЮЧЕВЫЕ МОМЕНТЫ

определяет, что проход необходимо

повторип.? Я имею в виду тот факт, что цикл проверяет, какое из значений,

true или false, принимает условие перед каждым проходом. в то время как функция mysqIUetch_array() воэвращает что-то вроде идентификатора ресурса, в котором содержится массив $row•.• не похоже, чтобы это выгnядепо как проверка условия true/false.

О: Хорошее наблюдение. Дело в том, что РНР достаточно либерален в вопросах, касающихся интерпретации условия

true. Если опустить

подробности, при проверке условия любое значение, которое не является

false, считается равным true. Поэтому, когда функция mysqli_fetch_array () возвращает массив данных, переменная $row (в контексте проверки условия) интерпретируется как t rue, так как она не является ни нулем (О), ни false.

while

Данные сохраняются в таблице в виде колонок и записей.

SQL-запрос CREATE DATAВASE используется для создания новой базы данных.

SQL-запрос CREATE TABLE используется для создания таблицы

данные

любого типа, а не топько те, которые имеют непосредственное значение

это контейнер

структурированной форме.

нулем (О) или

'9: Значит, я могу использовать для управпения циклом

Ба3ёl данных -

для сохранения данных в высоко

внутри базы данных.

Вы можете удалить таблицу из базы

true или false?

данных с помощью SQL-запроса DROP

О: ЭТО так. Но имейте в виду, что в конечном итоге цикл whi le

TABLE.

интерпретирует эти данные как

true или false. Поэтому

что именно определяет значение проверяемого условия как

true

false. И простой ответ заключается в том, что любое значение, которое не является нулем (О) или false, всегда считается равным true.

Функция mysql i_fetch_array ( ) извлекает строку данных из результатов

при интерпретации данных других типов очень важно понимать,

запроса к базе данных.

или

'9:Что произойдет с циклом

while,

возвратит пустой массив данных?

если функция

mysqIUetch_array()

О: Если в результатах запроса нет данных, это будет интерпретироваться как то, что функция В результате цикл

mysql i_fetch_array () возвратила значение false. while не совершит ни одного прохода, что означает,

что код внутри фигурных скобок не будет выполнен ни одного раза.

'9:Значит, возможен цикл, который не совеpwит ни ОДНОГО прохода? О: ЭТО действительно так. Возможен также цикл, который будет

повторять и повторять проходы, никогда не остановившись. Посмотрите на этот цикл

whi le:

while (true ) { Такой цикл известен под именем бесконечный цикл, потому что проверка условия никогда не позволит ему прекратить проходы и продолжить ход

выполнения программы. Бесконечный цикл

-

очень неприятная вещь.

Цикл whi 1 е повторяет фрагмент кода РНР до тех пор, пока соблюдается определенное условие.

• • ~:;':::=:.~ 1Cacuoe. ~a, .,мко.

C~.IIUI • • .. ',,_

«Ae681:*I .. "01010

1111.,....."'11 • ~ac:"' f8ееЫl\'ИI>

о

Co,'aatlU~ IU--cf'ОрМ'" «О-пр.''''' :JAСК_РОИИОО поч"",» UfНf~QЩlаРUII ё)i\Я o"np.'KU поч ..", COfJI8GIIO i\Ucmy P8CQIi\К1I.

l н• .J<1~""''' ~ НdC

€ce е.ще н.е €bt!')олн.ен.

Э'lт\0"IТ\ !')ослеэн.uU Эll'\dl') эля. t\Oлн.оz.о

,3ct€ерw.ен.uя. Pddoll'\bt.

178

глава

3


создание и заполнение базы данных

Магниты РНР и

MySQL

Используйте магниты, изображенные ниже, чтобы закончить код для сценария «Отправка электронной почты», что позволит Эл меру начать отправку электронных писем покупателям,

включенным в его лист рассылки. Ниже

mail(Koмy,

Тема,

-

напоминание, как работает функция

Содержание,

, From:

rnai 1 ( ) :

,

<?php $from = 'e1mer@makemee1vis.com'; $subject = ............................................................. . $text = ................................................................. · connect('data makemee1vis.com', 'e1mer', $dbc mysq1 ~_ . ,). or diе('ошибка соединения с MySQL-сервером. , $query = "SELECT * FROM emai1_1ist"; $resu1t = mysq1i_query($dbC, $query) or diе('Оmибка при выполнении запроса к

'theking', 'e1vis_store')

базе данных.');

whi1e($row = mysq1i_fetch_array($resu1t» $first_name = $row['first_name']; $last_name = $row['last_name']; n •

$msg = 'Уважаемый $fist_name $last_name, \п ............ .. ..... . ....... '

.

$to = .... ... ......... ....................................... , таН(

echo

..................

.........................

'Электронное письмо отправлено:

...................

'From:'

.

) ;

...... .... ..........

..................................

'<br

mysq1i_c1ose($dbc); ?>

sendem<il.php

8ыздесь

179


законченный сценарий sendeтai/.php

Магниты РНР и MySQL Используйте магниты, изображенные ниже, чтобы закончить код для сценария «Отправка

электронной почты», что позволит Элмеру начать отправку электронных писем покупателям, включенным в его лист рассылки. Ниже - напоминание, как работает функция та i 1 ( ) : mail(Koмy, Тема, Содержание, Не з<:\3уэЬ-mе LtJMehu-mЬ flr\o?" <:\9рес ~

, From:

,

элек-mрон.н.оu. t)ОЧ'Ут\bt нд c€Oц содс-m€еннbtu.. <?ph p $from =

$ text =

, $dbc -- mysq l'~_connect( ' data . makemee1vis . com' , , )' e1mer' . or diе( ' Ошибка соединения с MySQL сервером. , $query = . SELECT * FROM emai1_list .. ; $resu1t = mysq1i_query($dbc , $query) or diе( ' Ошибка при выполнении запроса

$to =

Поле €€ОЭ<:\ соэерЖ<:\1-W.Я. u.мee-m u..мя. e.l'V i S"tТ\<:\ i ~.

к

$first_ name = $row [ , firscname ' ] ; "аа '_n~a " $row [ , laa '_n~a' [ ;

·УважаеМЫЙ

' e1vis_ store ' )

элеК"tТ\рон.н.о г о t)u.cbМc\ нд форме

whi 1e($row = mysq1i_ fetch_ array($result))

$msg =

' theking ',

$fist_name $last_ name ,

базе данных .' ) ;

n

{

/

ОЛНDе со.эеРЖd.н.u.е Элек-mрон.н.ого UJ LlМeн.u.

"Цcb~ coc'tТ!Oц'tТ!

r: _ 'т; ~$ J tex:.t; a?~eннoGO COO'Yr1~C'tТJ€\J)()'jfee '"

Г]ОКУt)<:\-mеля. u. со.эерЖd.н.u.я. Э;"""'I""-о t]щb"",

1

1

t)O]Je CPOpNbt.

mail(

' From :'

echo

' <br / > ';

J'--"

.

mysq1 i_c1ose($dbc) ; ?> .~_

...

Колон.кс:\ 'tТ!<:\dлuLфt. с LlМeн.eM e-m<:\i..f

со.эеРЖu-m <:\.9рес элек'tТ! рон.н.ой t)ОЧYr)Ы t)ОI(Уt)<:\'tТ!еля., l(o'tТ!0poмy эол.жн.о

dbl.'tТ!b О'tТ!t)р<:\€лен.о

ЭлеК'tТ!рон.н.ое "исЬмо.

180

глава 3

Одbtчн.о СЧU"tТ\<:\е'tТ!Ся. .эОС'Vl\<:\)\'\оЧн.о

Ot)<:\cн.oU t)f<:\K'tТ!UI(<:\ t1ере.э<:\€<:\'tТ!Ь ~ННbte,

€€е.эеКJ-ibtе t1 0 се'tТ!u)\'\елем cc:\й'tТ!c:\,

Фун.кщш 'VI\<:\i..fO J-tet)осреэс)\'\€ен.н.о,

дез ш< l1р'еэ€<:\рu-mел,н.ой t1po€epl<l)..

~ гЛc:t€е б u.,yicIг.с:\JC'II1СЯ н.екo-mорbl.e

~ехн.uЧескuе I1pue/Y\bl. ре.ще.н.uя flr\ой t1роdле/Y\bt.


создание и заполнение 6аз", данн",х

)_. TeCT-JJ.раЙв Отправка эnектроннlIIX писем покynaтen.м, перечиcnенным

в nиcrе раccwnки, с испоnьзованием формы «Отправка

эnектронной почты».

ИмеU:YI\е

Загрузите код ве6-страницы .Отправка электронной почты. с сайта .Лаборатория

Ч'У!\О €о.ш. ОЭР: С

"Очертя голову". по aдpecywww.headfirstlab.com/books/hfphp.

€ €u.э~,

элеКYl\РОкн.оu.

Он в каталоге chapter03. Так же как и код ве6-страницы .Д06авление адреса электронной почты., этот код включает ве6-форму Элмера

t'\оЧ'У!\bt.зол.жеtt ~1:я.'YI\Ь лu.С'Yl\е

sendemail. html, каскадные таблицы стилей (style. css) и два файла изображений (el vislogo. gif и blankface. jpg).

pacCbU1KU.,

g-

JЧ'YI\О~1:я. €I:я.

Создайте новый текстовый файл с именем sendemail . php и введите весь ~ I"\Oл~чu.J1u. код, приведеШlЫЙ на предыдущей странице книги. Загрузите все файлы на ваш

элеКYl\роtt!'tое

веб-сервер н откройте страницу

l'1u.cbMo.

sendemail . h tml

в браузере.

Вы получили письмо... от Элмераl Наконец ЭЛ~lер может отправлять свои электронные письма, содержащие

_

объявления о распродажах в магазине MakeMeEl vis. сот любому покупателю, PHP-сu,;ttd.Рu.u включепному в его диет рассылки, используя свою новую ве6-форму

«O'Yl\l'1po.{)Kd.

того, ИСПО.lьзуется Д.;IЯ вывода подтверждения о том, что каждое письмо было успешно отправ.lено. Каждый~ раз. когда выполняется код в цикле while,

эеu.С'Yl\~u.'YI\еЛЬttO

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

t'\u.cbJМ. ttd. ~pe.ca

.Отправка электронной почты. и PHP-сценариЙ. Этот же сценарий, кроме

элеК'YI\еокн.оu. \')оЧ'Yl\bt»

О'Yl\t)ро.€ля.е.'YI\

элеК'Yl\роttttbtе

он видит сообщенне: .Электронное письмо отправлено кому-то@куда-то.соm. информация о его товарах распространяется лучше и

в стиле Элвиса!

-

хорошо ли, плохо ли

-

i

1')0К~d.'YI\елеu.

u.ме)OUJ,UXСя.

€ dct,3e

ga~, 1'10Э'Yl\ОМ~

дУ~'YI\е ОС'Yl\';fО.жн.bt, Мdttl.ЩУЛu.ру

uм.

~~1~::a~....~.If.~==дroo~11OI'I"I'"" Электронное ПИСЬМО отправлено: julian@breakneckpizza.com т_

Электронное письмо отправлено: jопes@simuduсk.соm Электронное ПНСьмо отправлено: suпshiП<Cl>Ьreakпесkрizza.соm

"*"""""" -

• _......... . ~,!!............ ~. _ _ _ _ гн. .~ : ,........ _ _ _ - 1co~ XIIl ~____

.... __

... ---

:::~_-=:.=_ ~........

Электронное письмо отправлено: bo@bOttOmsup.com Электронное письмо отправлено: amber@breakneckpizza.com Элеnpoиное письмо отправлено: churstOboards.r.us.com Э.,ектронное Письмо отправлено: joyceharper@breakneckpizza.com Электронное письмо omравлено: meyersCleapenlimos.com Электронное Письмо отправлено: martybabY@Objectville.net

Э.1ектронное ПИсьмо ОТllравлено: waltOmightygumball.net

:

~ _ .... _... ,. .. __,... _... ~ ......... " ......_ ........- .. -..... _........._..._... - Э.'1ектронное ПИсьмо OТl'paв.r8eHO: craftsmanObreakneckpizza.com

(o~,; \

Э.,ек-rРОIIН()(' ПИсьмо отправлено:jое_mCstaгЬuzzсоffее.с:оm

ЭлеК1рОННое письмо О111равлено: bruceCchocoholic.inc.com Электронное письмо отправлено: prOhoney.doit.com Электронное письмо отправлено: bertieh@objectvi!le.net Электроиное письмо отправлено: bettieh@breakneckpizza.com

_._.,./

••••••••••••

lJ

Э..,еIcrp<ШНое ПИсьмо отправлено: wiliamwuOstarbuzzcoffee.com

. Электронное письмо отправлено: samjffe@starbuzzcoffeecom ?леКТРОНllое ПИсьмо отправлено: Is@oЬjесtvШе. пеt . . ЭлеJ<rРОННое п ьмо отпраалено: bshakes@mi htygumball.net

выздесь ~

181


нашему nриложению необходима функция удаления

Иногда люди хотят удалиться На дороге любого процветающего бизнеса могут встречаться ухабы. Похоже, некоторые фанаты Элвиса дезертировали с корабля и хотят, чтобы их исключили из листа рассылки Элмера. Эл мер хочет удовлетворить их желание, но это означает,

что ему необходима возможность удалять записи о покупателях из базы данных.

Уважаемыи ДРуг БеДРо_в Хот", '" все е Ращатель!

Уважаемый элмер! Я tie хочу больше получать

неnовтор

электроtitiые письма

о распродажах в магазиtiе элвиса. Я остаюсь покnоtitiИКОМ элвиса, tiO tie могу больше приtiимать участи

е в вашем

предприятии. удалите меtiЯ, пожалуйста, из вашего

листа рассыЛКИ. МОЙ адрес

Ще Обожаю

но так Си имые двИжени", Э

вnечатл",::НсО ~H мен", УЖе :виса, неnовто· еИчас", n е ЛИбеn.a _римые СnОСОбнРеДnОЧитаю ,,""ис в Ор

и ее Маете

я nолаrаю, не кажUЫU

., OCoдetl uмumuro&amb коrоля. Мне неодхоиимо уuалumь зmuх ЛЮUW из сnиска rассылкu Uсосrwоmочumься на НЭСmоЯtJ.\UХ сранах.

ОСти

гани3ации к

:i адрес электРство nианисткиО;цеРтов . Оll(,алуйста РоННой почты (~ то мой .• ссылки): ' мен", И3 списка ;QaпИте,

электроtitiО Й почты:

cbriggs@boards-r-us.co Благо

m

г------------

' dY@tikibean/ .• OUnge.col7I

______-JI(:р:е:нн~е~8~а~щ~а~,

.

Уважаемый сэр!

экс-и

после ~ескольких аллергических

реакции на ваши ПОДЛИННЫе баки

И3 КОнского ВОлоса я решил

Видимо • что, Э ' подражание внешнему виду Лвиса - это не мой СТИЛЬ. Мне нравится наряжаться, но баки _

это, Пожалуй, слишком. УдаЛите

пожаЛУЙста, меня из Списка рассылки.

Искренне Ващ

Брайан Пауэрс

bP@honet-dоit.сОI7l

'

Эме.р к.е слuшко,м

.90€олек. 1У\е..м. 'flI'\o он. )1U.1J.!Qе.'У!\ся. к.ек 01Y\Opbu< 110Кl'~1У\еле.u., к.о он. .9 0 лж.ен.

У.9 0€ле.1У\€ор5l1У\Ь u.x I1pocbдbt. ка уэ~еtше. u.x u3 лuс1У\~ РdссbtЛl<U.

Это факт MySQL-жизни : иногда вам приходится удалять

данные из своей базы. Элмер должен усовершенствовать свое приложение и найти возможность удалять покупателей

из таблицы

email_list.

Запишите новые компоненты приложения, которые,

как вы думаете, будут необходимы Элмеру для обеспечения функции .Удаление адреса электрониой почты •.

182

zлава3


создание и заполнение 6азы данных

Удаление данных с помощью запроса

DELETE

для того чтобы удалить данные из таблицы, нам необходимо выполнить запрос DELETE (<<удалить»). Мы будем использовать запрос DELETE в новом сценарии

«Удаление адреса электронной

почты», который

удаляет данные покупателя из листа рассылки Эл мера. Фактически нам

необходимы новый сценарий и новая веб-форма, чтобы приводить этот сценарий в действие ... но сначала мы должны удалить

(DELETE) данные .

SQL-запрос DELETE удаляет запись из таблицы. Вы должны соблюдать осторожность при использовании этого запроса, так как в результате

• • :tr=:;::~=:UR • мt

... a paccH,Мtt;

'~&lIIIe.ei

'1' '1'.... (C.A06at~Ulue 1108010

A8t'1"aJRCЫ.". "асм f8eebIAI'''"

WlCIC"f'8111180 "8~ln"''' 11 А4Р 611111af'1III

~.'>A 8""l'alмll "1I~ln'" COI'II8CIIO ка,"?

его выполнения в мгновение ока таблица может оказаться совершенно

пустой. С учетом этого ниже приведена наиболее опасная форма запроса

DELETE,

в результате выполнения которого удаляются все записи

из таблицы .

(

Похоже, I-I.CI.М

DELETE пои

н.e.oдxo.9~ н.о€ctя. ClТ\Yf1e.к.b ... Ин.огэct

Бе.,3 Кctкоz.о-лu.dо

)

I1Mкbt .мен.Я-)ОУ!\Ся.!

оz.pctнцчu.€ct~е.z.ОjСЛО€u.Я

€ ре.,3jлыт\tlт\е. €I:я.I)ОЛн.е.нця. 3ctf1 poca DfLETE lТ\ctдлu.up dj.9e.lТ\ оЧu.LЦе.ка OlТ\ €ce.x СО.9е.РЖc:lщu.xся. € н.еи. .9a н.нbl.x.

Нет, совершенно не так. Запрос

DELnE

можно использовать

с точным указанием тoro, кака. конкретно запись должна

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

удалить с помощью запроса DELETE, необходимо добавить ограничивающее условие WНERE

( «где» ). Помните, как использование этого выражения в запросе SELECT позволяло нам выделить определенные записи в запросе?

Предположим, у Элмера есть

11

23

покупателя с именем Анна,

покупателей с фамилией Паркер и один покупатель с именем

и фамилией Анна Паркер. Напишите, сколько записей будет удалено при выполнении каждого из этих запросов:

DELETE FROM ernail_list

WНERE

first_narne

DELETE FROM ernail list

WНERE

first_narne

DELETE FROM ernail_list

WНERE

last_narne

=

'Анна';

'Анна'

OR last_narne

'Паркер'

;

Паркер;

выздесь ~

183


запрос DELETE с условием

WHERE

~weHue зад8ll:редпопож.м, у Эп"ер. опь по.уп,,"". ."енем Анн., ,

23

11

покупателей с фамилией Паркер и один покупатель с именем

и фамилией Анна Паркер. Напишите, сколько записей будет удалено при выполнении каждого из этих запросов:

DELETE FROM email list WНERE first_name DELETE FROM email list

WНERE

first_name

DELETE FROM email_list

WНERE

last_name

.23 ...

'Анна' i

=

'Анна'

IfСПОЛЬЗ0вание ограничивающего У для удаления определенных дан Используя ограничивающее условие WНERE в запрос

OR last_name

овия

'Паркер'

;

.3.3...

WHERE

IX

DELETE, мы определяем конкретный перечень

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

В данном случае из листа рассылки .

на данных одного из покупателей Элмера, который пожелал быть удаленным

~

DELETE FROM email_list WНERE

ИМЯ I(ОЛОJ-Uщ

"lТ\С\длu.u,bt..

email

J

ЗКQЧек.Lte, I<0l"ll0poмy .эОЛЖек. coo"lТ\€e"lТ\c"IТ\€ot{<I.'YI\b <l.qpec Элеi<"lТ\рок.нnй t)ОЧ"lТ\bt, Ч"lТ\Одbt J<l.t)u.ct, дЬ!.м Y..9<1"eКQ,

-·рr@hоnеу-dоit.СQm·

~ ~o. Ч<l.С"tТ\Ь €btР<l.жен.u.Я W'HERE n J € -

t)роu.J~ОЭu.'YI\ t'\po ерку Кd.ж.gоu .3d.t)u.cu. YI\<l.dлu.u,bt на cOOYl\ge'Yl\cYI\€u.e .3.:s.эФ~.}tОМУ jнa Чен.u.)О.

Фактически проверка на соответствие условию WHERE

производится путем сравнения значения колонки с заданным

значением для каждой записи в таблице. В этом примере знак равенства (=) говорит о том, что будут удалены только те записи , для которых значение колонки

email

равно

pr@honey-doit.com. Напишите, как вы думаете, почему в ограничивающем

условии запроса использовалась колонка етаН, а не first пате или last пате:

-

-

.вь

11=:ние vv 1 u:.1'1:..

осранuчuвaem запрос.

pacnpocmpa1-m его только на onpegеленные заnucu

184

zлаваЗ


создание и заполнение базы данных

Минимизация риска случайного удаления Важно пони мать, что, хотя для проверки соответствия записи

Выражение WНE1\E

ограничивающему условию в выражении WНERE может быть использовано имя любой колонки, существует очень веское

orранuчuвaem

основание для выбора колонки email в запросе DELETE Элмера.

запрос.

Совершенно понятно, что если более одной записи отвечают

требованиям ограничивающего условия WНERE, то все они будут

pacnpoclnpaнgg

удалены. Поэтому очень важно, чтобы ограничивающее условие

ero

WНERE точно соответствовало записи, которую вы хотите удалить.

только

на onpegеленные заnuCtL

DELETE FROM email_list WНERE

email =.pr@honey-doit.com.

/

И С IlОЛЬ.3 0 €d.кuе колон.кu.

eYl\d.\~ в ог.еd.кuчu.€d.)QЩе.м.

усло€u.u. Wf\IRI 1l0мог.аеYl\

email li st

YCYI\d.Нoo€u.YI\b ~н.u.кd.Лbн.ОСYl\Ь u. cКW\(,d,eYl\ pU.CK слуЧd.u.н.ог.о JЭr.Vlек.u.Я 3d.IlU.CU..

fInt~\ ~~ 4' Джо

" щ..

..,

-""'1.

I~

wilmawu@starbuzzcoffee.com Ву

Бу6а

~

--

Is@objectville.net

Шеффер

bshakes@mightygumball. net

Шекспир

johndoe@tikibeanlounge.com До

Джон

(Пэт

samiaffe@starbuzzcoffee.com

ДжеффИ

Сэм

I(ОЛОНоКУ firs·CIld.YI\e €MeCYl\o I(ОЛОНоКu. е1Т1d.i~, ,71Т101Т1 11 О КУt)d.1Т1 еЛЬ дbt.л

gregeck@breakneckpizza. com

эскштеин

Вильма

ЛУИ

,j

,nА"_

bertieh@obiectville.net Хендерсон

Грег

JСЛО€u.u. '-'НЕП

I

n. -

Берти

«.r:

bruce@chocoholic-inc.com

Спенс

М.

dbt. 1Т1акЖе ,19r.Vlен..

mъыФ""'· ·~

ioe_m@storbuzzcoffee.com Милькно

Брюс

Iслu. дь!. мbt. U.C t) олЬзо€о..лu. € oг.p'aНlJ. Чu.€d. )ОШ,е.м.

/\k

grommetp@simuduck.com

')

громмет

..

'

выздесь •

185


проведите тест-драйв своего заnроса

DELETE

ест-драйв Попробуйте применить запрос DЕLПЕ к базе данных ЭlIмера. Загрузите инструментальную программу

несколько записей из таблицы ета i

MySQL и попробуйте удалить 1_1 i s t с помощью запроса

DELETE. Идентифицируйте удаляемые записи, основываясь на адресах электронной почты покупателеЙ . Не забывайте включать ограничивающее условие WНERE в каждый запрос DELETE, чтобы случайно не очистить всю

таблицу.

Это верно. Удanение покупатеllей вручную,. с помощыо индивидуаllЬНЫХ запросов

-

никуда

не rодный способ обработки lIиста раССЫIIКИ. Так как Элмер рано или поздно непременно столкнется с ситуацией, когда покупатель пожелает, чтобы его удалили

из листа рассылки, имеет смысл разработать пользовательский

веб-интерфейс для удаления покупателеЙ. НТМL-форма и РНР-сценарий должны решить эту задачу, используя запрос

DELETE . FROM с небольшой помощью ограничивающего условия WНERE.

186

глава

3


соэдание и заполнение нэы данных

Элмер создал веб-форму

(removeemai1.htm1) для удаления покупателя из своего - это ввести

листа рассылки. Все, что необходимо при работе с этой формой,

в поле с именем email адрес электронной почты. Закончите код сценария Элмера removeemai1 . php, который вызывается формой для удаления покупателя из листа рассылки.

~~8iiiliiiil!ft~~I

НctЖ4'"1У\v.е KКDI1KV. «Уэ<tJ1V.'"IY\Ь»

О'"lY\I1~€ля.е'"lY\ ~ctнН.bt.e ф<>рМbt ~ €v.эе Jctl1pocct POSТ

сu,енарщо 'РНР.

<?php

$dbc = mysqli_connect('data.makemeelvis . com ', or

diе('Ошибка

соединения

mysqli_close($dbc) ;

'elmer',

'theking',

' elvis_store')

с MySQL-сервером.');

removeemcil~

?>

8ыздесь ~

187


закон.,енныU сценарии removeemail.php

Элмер создал веб-форму

(removeemai1.htm1) для удаления покупателя из своего листа - это ввести в поле с именем emai1 адрес электронной почты. Закончите код сценария Элмера removeemai 1. php, рассылки . Все, что необходимо при работе с этой формой,

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

имя Э"lТ\О20

мavsM~EL.V;~.COМ

I)оля pop.мbt. _ в..neадресэne«JPOllНOli nOЧТWдlUlyдвлeItIIЯ e"lТ\cti~ . ~ ~3ПIIКIjIOННOIinOЧТW: .., (у_)

~

Нd.Ж.ct1Т\U,е KtW\1KU, «У.э ctЛ U,1Т\Ь»

01Т\\1рct€ля.е1Т\ .эctкн.bt.е форМbt € €u,эе .3ctt)pocct POSТ сu,екарщо PТlP. А.эрес эле.К"'II\роt1Н.OCi t)o'-h'!\bt.,

со.эерЖ4ЩU,u.ся. € с~еР2лодctЛЬн.ом МClсщ€е $_POSI СОХРd.н.я.е"'ll\Ся. € l'\еремен.н.оCi u, U,Сt"\оль.3уе1Т\Ся. .3а1Т\ем € .3d.l'\poce DILITE.

removeemciI.html

$dbc = mysqli_connect('data . makemeelvis.com·,

188

zлава3

'elmer',

'theking',

'elvis_store')


соэдание и заnолнение 6аэы данных

'оУэн,,' к')ы oa""1II1( 11 IIIailllllo.,4}MI .....w6.1

pycWМttt.

.. ~:::=:a_"O&OIO ~II!, '".{''''О,,''III «Aoia&AQlu~ "8ItJ'М"'MII

!X>"IТI u.

€ce, ~

t-\4кок.еu,-1У\О

.3с1.I(Ок.ЧuЛu.!

~

& Aachl1'81Ce1i1i\1t1lo

• • :-A=:~:;== iЩ~III1'81i1iеll "8""'''~

4}МI 8"'''1'1.1111

11 f!Wf

l1li'111"1111

118""'' eolМCllO АIIСМ,

,.а&Е IhМtt

'~81ll1e 8eS

'1'0"11" 1~"lfiIllle

"OК)"lllllu,1I ~ fll_l'а"ШIIIL

-[ест-драйв Удаnите noкynaтen. из nиста рассыпки, испоnltЗУ. форму «Удаnение адреса зnектронной ПОЧТЫ». Возникает чувство, что это вам уже немного знакомо, а? Загрузите код для

веб-страницы

«Удаление адреса электронной почты~ с сайта «Лаборатория www.headfirstlabs.com/books /hfphp. Этот код находится в каталоге chapter03 и включает веб-форму Эл мера removeemail. html, каскадные таблицы стилей (style. css) и два файла изображений (el vislogo. gif и blankface. jpg).

"Очертя голову"~ по адресу

А теперь создайте новый текстовый файл

removeemail . php и введите

весь код предыдущей страницы.

Загрузите все файлы на ваш веб-сервер и откройте страницу

removeemail. html в веб-браузере. Введите в форму адрес электронной почты пользователя и нажмите кнопку «Удалить~ для того, чтобы удалить пользователя из базы данных.

~~EI..V;~.COМ

'*""'"-~ ...... ~­

~~IIO'fIW;

! ~:u;;m---_.~

~')

выздесь

189


nриложение для ведения листа рассылки закончено!

MakeMeElvis.com -

это be6-ПРИЛОJКение

Это официально. Благодаря РНР и

MySQL сайт

Эл мера

MakeMeEl vice. сот заслуживает того, чтобbl наЗblваться приложением. Элмер теперь может как угодно долго хранить данные

в базе данных

MySQL и

обмениваться с ней даННblМИ через веб-форму .

Совокупность НТМL-страниц, РНР-сценариев и встроенных

SQL-запросов предоставляет Элмеру возможность добавлять покупателей в лист раССblЛКИ и удалять их из него (они также

могут добавлять себя в лист раССblЛКИ самостоятельно). Кроме того, Элмер может отправлять элеКТРОННblе письма всем покупателям, перечислеННblМ в листе раССblЛКИ.

/).;а ;;()rае>CtТl~Юtт1 11-tf UMySQt..J 1enerb Эtт10 (?W'-nrUЛОЖe!-iUе. Я MOry

Страница «добаВllение адреса эnектронной

СОСtт1а(?ляtт1Ь С(?Ой ЛUсtт1 rассылкu, Оtт1nrа(?ляtт1Ь nUCbMa

почты» дo6aВIIAeT

(?сем MOUM покупаtт1елям U()аже COKrau.\3tт1b ЛUСtт1 ...

HOBoro

покупатеnА в nиа

U(?се Эtт10 U) MoerO (?W'-oraj3era!

рассыпки Эnмера. odderткil.php

о

о

~V;S.CQМ

=ra=--=.....-.. ~~~_

.... .. ..

~~.~

_

....... .. ..

Страница «ОтпраВllение эnектронной почты» отпраВIIАет эnектранные письма каждому покупатеnlO из перечиcnенных

sendeIOOl.php

в nисте рассыпки простым

нажатием ОДНОЙ кнопки.

-----..~~.~~. _ ....

[:;;;;;.)

Otт1(?eт Оtт1nrа(?utт1елю!

)'VалUtт1f. Me!-iЯ, nожалУЙСtт1а, U~ ЛUСtт1а rассылкu Элмerа.

Страница «Удапение адреса эnектронной почты)) удаn.ет покупатеn. из nиаа рассыпки.

190

глава

3


создание и заполнение 6азы данных

KpOCC50pg

РНР

u MySQL

Как только вы закончите совершенствовать танцевальные движения

Эл мера, попробуйте решить этот кроссворд.

По rОРИЗ0нтали

1. Продолжает выполнять

По вертикали

какие-либо

операции, пока определенное условие остается истинным.

з. Используйте этот SQL-запрос для просмотра структуры таблицы.

4. Тип

данных

MySQL для

сохранения целых чисел.

б. После создания новой базы данных в МуSQL-терминале вы

2. Используйте этот SQL-запрос

должны выполнить этот запрос, прежде чем сможете делать

для извлечения записей данных из таблицы.

какие-либо манипуляции с базой данных.

з. Этот SQL-запрос удаляет всю таблицу

7. Используйте этот SQL-запрос для удаления записей из таблицы.

~з базы данных.

5. Иcnользуйте

этот тип данных

8. MySQL

Ограничивающее условие; может быть добавлено

к SQL-запросу для указания записей, на которые

для сохранения текста переменной длины .

распространяется данный запрос.

9. Здесь в таблице содержатся данные

11. Из

определенного типа.

10.

Постоянная, высоко

систематизированная и структурированная

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

них состоит база данных

12. Полный

MySQL.

набор данных в таблице, содержащий по одному

значению для каждой колонки.

1з . После добавления к веб-странице динамической _ _ _ _ _ __

функциональности она становится

8ыздесь

191


кроссворд решение

KPOCC50pg

192

глава

3

РНР и

MySQL.

Решение


создание u заполнение баз", данных

Ваш инструментарий РНР и

MySQL .--~~~~~~~~~

DЕSСRrВЕ имя~ таблИЦN

Если. ~ н.еодхоэu.мo У3нд"Yl'\Ь

C"Yl'\pYК'trl,Ypy "rI}ddJJU.u,bt, Э"rl}О"Yl'\ 3dl1poc- .;mo,.Ч"mо I{'yJ!6Н.o. ~ pe3J'lbll1ct11'\e gI:iU,ОЛJ-le1-ШЯ. !m0~o SQ.L-3Ql1pocct gbt. J-le fiи.ЭЦ1У\е Н4J(ф<Щ эctкнbt,x

соэерЖctШ;ЙХСЯ .~ 1У\ctdЛUu;е, ' н.о YJНQe"rl}e \А.Менд €cex ОЛокок u. 1Т1и.t). bt.ЭQННblx, jflОг,.YlIl dbr.lI1b g кш< DELETE FROM

*

FROM

имя~ табдtJЦЫ

~OI)ОЛЬ3'уu.1У\е .7lI'j01Y\ SQL3dt'\poc ЭЛЯ 'y~1{LI.5f. 3dt'\и.сеi1 1,;\.31У\ctдлцLфl.. ~ ~и.С\А.МОС1У\и. 011'\ "al0~0, KctK ,gbt. и.Сt'\QJJbз,Уе1У\е Эlf\О1У\ 3dl1poc, gbt. МоJl<,e1У\е У.9ctЛЦ1У\Ь ОЭI{У u.лu. НоескоЛЬко 3dt'\и.сеu..

6blздесь ~

193


.IlIше .еб-nр"ложен"е -.-

4 fСrlJ\ЫfЫС u, 11f~11t,U,qcc1;u,c 11fU,J\oJJcr(Utjf

.-

-*

~u Я ззсуну 0311311 ~ ~ы)Слопную труоу мaUJUHbI MOeU ~umельнuцы, ее мaUJuHa не )а~Wemся. И HUкaKoro ЭК)амена.

Но morCJa mощ кто оуё)ет ее )аменяmь,

ycmroumb тест, поэmому он mоже ё)олжен пол~umь ~Oй 0311311. orCJa mощ KomOrbIU оуё)ет )аМеняmь moro, KomOrbIU оуuет )аменяmь... можem

-r

Инorда надо реалыю смотреть на вещи и менять свои планы. Или планировать более внимательно с самого начала. После загрузки приложения на ве6-сервер вы, возможно, обнаружите, что спланировали его недостаточно хорошо. Некоторые решения, которые, как вы предполагали, будут работать, в реальной жизни оказались не слишком удачными. В этой главе мы рассмотрим некоторые проблемы реальной жuзнu, которые могут возникнуть, после того как ваше приnожен .. е выйдет

..3 peJlOllMa тестироваН"Я .. переместится в Интернет. По с примерами более важного кода РНР и

пути мы познакомим вас

SQL. это новая глава

195


3лмеру нужно более качественное nриложение для ведения листа рассылки

у Элмера появились раJдраJlеииые покvпатели Лист рассылки Эл мера стремительно разросся, 110 его электронные письма в ряде

случаев повлекли за собой некоторые жалобы. Они носили различный характер , но, похоже, все сводились к тому, что покупатели I10ЛУЧaJlИ пустые электронные письма или сразу

110

нескольку писем, ни одно из которых не содержало ничего

полезного. Элмеру необходимо выяснить причину этого явления и исправить положение. От этого зависит его бизнес.

От: Дени" Бaбmoн <dennyOmightygUmbaI!·net> Т....: c&n- с тonкy

I I

дата: 24 Q1CТЯбp112008 r. 12:20:29 РМ СОТ Кому: ЭnмeP ПрмстЛМ elmerOmakemeeМl.com ЭnIIeP.~

i !

1

Деннм.

I !

От: Апмсон с..........

.

Т....: WWEO

- - <aJ,sons@SlarbиZZCOffee.co

Кому: Эnмep

r: 12:18:50 РМ СОТ

nr.:::

д.тa: 24~

~~,

I,

~kemeeмa.com J

~IЫ

~ l1OC7OJIННO

i

!!!I---t{ _,.1

... - - _ . - lIIICIOМe БI8 "" ... ' ! "." я n ...._ ТIIIЫ" БI81IIIIeIe ~~~ "V_, НI1'. Yд8l1lne . . " : " ' , - ~ lIOCТ)nan /)Ieмнoro , ~ 11311W8ro lIIItra ~ точно

AiJМCOН -~. p.s. от беков lII7rOPЫe ,

Эmо плохо. Интересно, не cl?~o ",и это со страницей

.

1Ы1IIte~,y..,,~ CIoIJь.

Элме? 3н.cte'YТ\. Ч'УТ\о С'УТ\олкк.улся. с t\роdле.МО U u ему

дJ9 е'УТ\ к.уЖНct l')омоЩЬ

€" 'УТ\ом. Ч'УТ\Одbt l')ок.Я'УТ\Ь.

Ч'УТ\о .же t\?ОUСХОЭU'УТ\

€эеUС'УТ\€U'УТ\еЛЬк.ос'УГ\U' 196

глава 4

4.

«OmnpaI?Ka эr.ектронноU почты» :? _ • •


реальные и nракти.,еские nрuложеНUR

с11t,~Jib11ъt rJgMU,Hu,c11t,irJ..11t,0iOM

J\u,c11t,rJ.. irJ..ccblJ\tu, ЭJ\МGirJ.. Ваша заgача

U Sb19CHUmь.

-

сыграть роль Злмера

как отnраSЛ9ютcs

nycmы1e электронные

nUCbMa.

Он nogозpesaеm что sсе это СS9зано с qюр.моtt sendemail. htm1.

Нd.I'1U,ШU,1Т\е,

€ ЧеМ

jQl(л)ОЧd.е1Т\Ся.

I'1РОдлеМQ

1')0

mh..eJ-Ш.)О

Элм<:J

~lIIIIIOpOНIQuп.~ _ _ ... _ _

i

(~ )

ser ldemciI.hlml

8ыздесь ~

197


6удьте 3nмером решение

с1Ыilfb11bG rJgMU,lf U,C111>frl111>O уом

J\u,c111>rl frlccbJJ\l;U, ЭJ\МGfrl Ваша заgача

u

-

сыграть ро,Ль ЭМ\ера

6Ы9CНUmь. как отnpat\А9Ютcs

пустые э,Лектронные nUCЬMa.

Ha\)UUlU'YI'\e. € ЧeJw\ .}аI(}1)OЧо,е'Yl'\Сst

Он nogозреsaеm что 6се это С69Зано с qюрмой sendemai1.htm1. Ест и.Q.Ж.d'Yl'\Ь Kнorll<Y «Oml1pa€u'YI'\b» де.} JdI10лн.еfШЯ. \)олst «СО.9еРЖ4н.uе элеl<'Yl'\РОкн.ог.о

~M~EL.v;s.coм 1I8POOНW,НO: только Д/1II ПOIyII8Т8II8Ii Эnмepe

=:~~I*CЫ/JIIII~ ПIICЫIOД/1II /IOIyII8Т8neй,

Теме 3I1e«ТpOttюro 1IICЫI8:

~~

• • • •• • • • •. ... +

• • • • • • • •••••

:

..• • •

!

_._._-----,

.г--~~·

sendemc:iI.hlml

tслu КdЖ41r\Ь Kнor)l(Y «O'Yl'\\)pa€u'YI'\b» € МOMeНo'YI'\. ког..9а € \)оле €€0.9a «СО.9 е РЖ4н.uе элеК1r\РОн.н.ог.о

\)ucb.мa» н.uЧег.о Нoe'Yl'\. дУ.9 е1Т\

01Т\t)ра€лено IlУС1Т\ое элеК'YI'\рон.н.ое \)ucbMo. То ж.е самое 01Т\НОСU1Т\Сst к 1I0Л)О вв0.9а «Т е.ма элек1Т\РОн.н.ог.о lIucb.мa» .

198

глава

4

l1ucbJ.'d». dY.ge1r\ О'Yl'\l1ра€лено \)yc1r\oe элеl<'Yl'\рокн.ое l1ucbMo.

1)0 мн.енщо


реальные

u nракmuческuе nрuложеНUR

3ащита Элмера ОТ ••• Элмера Итак, основная проблема здесь заключается в .человеческом факторе •. Элмер по оплошности нажал кнопку .Отправитм до того, как ввел содержание электронного письма, и пустое письмо отправилось всем покупателям, включенным в лист рассылки.

Достаточно не6езопасно считать, что веб-форма всегда будет использоваться строго так, как это предусмотрено ее создателем.

Вот почему это исключительно ваша, бдительный создатель

РНР-сценария, задача

-

toдIIlJ1IIIII118'...~ ПIICWI8:

протестировать и устранить проблемы

'-'--'1,

г--_·-·_-_··-

подобного рода, пытаясь предугадать все неправильные действия любого пользователя, имеющего дело с вашей формой.

.

\

\

Давайте взглянем на код текущей версии нашего сценария

. _. . _. _ . _. ._. . .J

sendemail. php, чтобы понять, как у Элмера получается пустое электронное письмо.

НС\Ш cu,e~Euu. set1c:le1l\C\i.f.p,p t1Ь1.1I\С\е1l\СЯ uсt10лЬJО€С\1I\Ь 'YI\el{c1l\,

u.мещuuся в СРОр,м,е, эля 1I\o~o, ЧYrIодbl. cOJ,9C\1I\b Элеl{1I\DОКJ-Юе t)UСЬ.м.о,,9dЖe еслu t10лЬJО~'YI\елЬ н.u.Чего к.е в€ел в KeJ.

.

тel<c"lТ\ I"\олеu. ф<>Dмbt ~влеl<dе"lТ\СЯ UJ ll,efeMeкк.btx

'e lmer@mak;;:~~~~;: com'/ $_POSТ['subjec{] u $_POSТ['e.f$isb~i~t] [smш' 3; ~ $~~~~:в:~c~$:=o~ su з ес $dbc or

= mysqli_connect('data.makemeelvis.com', diе('Ошибка

соединения

с

MySQL-сервером.

$query = 'SELECT * FROM email_list"; $result = mysqli_query($dbc, $query) or diе('ошибка при выполнении запроса

к

'elmer', ');

базе

'theking',

'elvis_store')

данных.');

~dлеМQ JC\I<ЛЮЧС\е1l\СЯ 'YI\о.м., ЧYrIо

while ($row = mysqli fetch array ($result) ) { € $ to = $row [ , email ' '] ; . UJt'10ЛЬJуе,м, t'1 е ре,м,енн.ую $text $first_name = $row [ , first_name' ] ; / fteJC\~ u.cu.мo 01l1111 0 го, СО.9еРЖu.1I\ он-с\ $last_name = $row[' last_name'] ; ~ 1(С\l(оu-лu.до 1I1 e l{C1l1 UЛu fte 1l1 ... $msg = · УважаеМЫЙ $fist_name $last_name, \ n~~E;pgf,," ; таН ($to, [~JШ'~Ф, $msg, 'From:' . $from); echo

' Электронное пис~_л_е_Н_О_:__' __, __--$_t_о_--_,--,<_ь_r--/_>--,;

mysqli_close($dbc); ?>

Напишите, какие, по вашему мнению, нужно внести

изменения в код сценария sendemail.php, чтобы решить проблему пустых электронных писем:

выэдесь ~

199


sendemail.php требует контроля вводим ых oaHH tJ1 X

Тре6уйте достоверных данных, ВВОДИМЫХ в фОРМУ Форме Эл мера <iОтправка электронной почты» необходим коитроль достовериости вводимых в форму данных. В результате такого контроля должно быть установлсно , что данныс в форме отвечают требованиям, предъявляемым к ним, и могут быть использованы для дальн е йших операций . Элмер уже использует контроль достоверности , хотя прямо так его и не называет.

KoнmpoAb gocmсжернocmu

npcжogutnC9. чтОБЫ

yвegtltnbC9

Каждый раз, когда он получает заказ на отправку товаров, связанных с жизнью Элвиса,

в том. что

он не выполняет закаэ немедленно ... Сначала он проверяет достоверность каждого заказа!

gaHHbJ.e.

в каждом случае вначале он проверяет, действительна ли банковская карточка lIокупателя ,

кomорые вы

оформившего заказ. Если с карточкой все в порядке , он оформляет заказ и готовит его

nолучaerne.

-

к отправке. После этого он должен обязательно про верить, все ли в порядке с почтовым адресом это те gaHHbIe. покупателя. При отсутствии каких-либо проблем с адресом Элмер отправляет заказ. УСllешное кomорые вы выполнение заказа для магазина Элмера тесно связано с контролем достоверности всех данных, ожugaeme. приведенных в этом заказе . ПОЧ'Ут\о€btй ~pe c

l1режэе ЧеМ

оc'j:>ор.мля.1Т\Ь ~ аОКI\j, Эл.мер

t')ОКУt')d.1Т\ел51.

эолжен. dbt1Т\Ь t'10Лн.bt.м,

эолжек.

lIeO€epu:YI\b эля. кажэог-о

~

3ctKdJ дjэеYr\

ОYr\l\ра.€лек. Yr\олЬко е 'YI\oM

.

-

+

110К~IId.'YI\еля.,

случа.е,еслu

Мк.коеска.я. ка.РYr\оЧКd.

1') OKYIj<1.'YI\еЛя. U ег.о 1')0'f'lТ\o€btu.

эейС'Yl\€UYr\ельн.ct ЛU ег.о

да.к.коеска.я.

а..9еес эеUСYr\€U'YI\ельнЬ-

ка.РYr\очка., Для того чтобы решить проблему Элмера с электронными письмами, нам необходимо проводить контроль достоверности данных , передаваемых сценарию

sendemai 1. php.

Это означает, что все данные, отправленные с веб-формой на сервер СI\енарию

sendemai1 . php, должны быть проверены в нем на достоверность и IIОЛНОТУ, IIрежде чем будут использованы. Мы можем добавить в сненарий sendemai1 . php код, который проведет такую проверку. И только в том случае, если результаты проверки окажутся положительными, сценарий отправит электронные письма.

Эnмер запоnн.ет

Данные формы отправnены

и отправn.ет на сервер форму «Отправка

сценариlO «Отправка эnектронной почты»

эnектронной почты».

на сервер.

РНР-сценарий производит праверку достоверности

данных. Еcnи

< form a c tion "s e ndemai1.php"

все в пор.дке, он oтnpaвn.eT эnектронные

письма. Еcnи нет - сообщение

____

~ V

~

~---

ОБОWИБке в кnиентской

... проrрамме.

Сервер отправn.ет браузеру ответное сообщение в виде НТМL-страницы: иnи о том, что эnектронные письма быnи

отправnены, иnи о том, что введенные данные не проwnи проверки на достоверность.

200

глйва4


реальные

u nракmuческuе nрuложеНUR

Логика в проверке на достоверность AaHHblX формы «Отправка электронной почты») Эл меру необходимо проконтролнровать достоверность данных, полученных от формы

sendemail . h tml,

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

sendemail . php.

Нам необходим код с таким алгоритмом: «Еслн данные достоверны, отправляйте электронные письма~ .

4mOdbt ~н.rtbte. сЧu.'VI)dЛu.сЬ ЭОС'Vl)о€е&к.bLМu., н.еоdхоэu.МО, Ч"tI'\Одbt содЛ'r0,9алu.сЬ .9 а 'VI)aKtAX

усло€u.я..• .с

~

ЕСЛИ в поле формы «Тема» содержится текст

И в поле формы «Содержание» содержится текст,

/

V

~

TorдA отправить электронное письмо

\

fслu. содЛ~Q)O'II')Ся. Ода Э'Vl)u.

усло€uя.. €ce О'УТ}Лu.Чн.о u. мbt МОЖеМ О'УТ}t)ра€ля..'УТ}Ь элеК'УТ}рон.н.btе t)u.cbМc!..

МЬ!. t)осbtм.лu. ЭлеlОl1рон.н.btе t)u.cbМc!.

н.u.сколЬКО н.е dесt)окоя..сь о 'УТ}0м, '-I'YI1~ tAМeн.н.o ~

ggеэен.о g Э'УТ}u. t)ОЛЯ, ЭQ U. gООдще ggеэен.о Лu.

'YТ}Y.9 Q ХО'УТ}Ь '-I'YI10-н.u.dуэь.

пМCЫIII:

~

С I\ОМОЩЬ)О t)po€epKu. н.а Э ОС1f\о€ерн.оС'у!)Ь

мbt можеМ dbt'Vl)b у€ерен.нЬU,\u.. Ч"tI'\о н.u. Оэн.о t)u.cbMO н.е дуэе1f\ 01f\t)РQ€л е н.о, еслu. эля. н.ег.о н.e1f\ эан.нbtx ХО1f\я. дЬ!. € оэн.оJv\ U.J Э1f\tAX

t)олеu. ввоэа .

IfG БЫ~iiG't1I,

ZV11bJX ~011ГOCO~

sendem<il.html

~; я слышал также о том, что существуют способы проверки О; При проверке данных на достоверность на кnиентской данных на достоверность на кnиенте, а не на сервере. Как зто

стороне мы решаем только часть проблемы. В принципе,

происходит?

Элмер может открыть

О; Клиентской программой в данном случае является браузер.

в браузере и отправить пустые электронные письма. Но когда

Поэтому проверкой данных на достоверность на кnиентской

стороне будет любая проверка, осуществляемая до оmравки данных на сервер РНР·сценарию. Такой язык, как JavaScript, может проводить проверку данных на достоверность на кnиентской

стороне. Если вы заинтересованы в более глубоком изучении этого вопроса, обратитесь к книге

Head First JavaScript.

~; 3ачем вообще осуществлять проверку данных

на достоверность на сервере вместо того, чтобы делать все на кnиенте?

sendma i 1 . php непосредственно

вы осуществляете проверку данных на достоверность на сервере,

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

проверку данных на достоверность на кnиентской стороне неправильно. Фактически это очень хорошая практика . Но нужно всегда помнить, что сервер -

это последняя линия

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

выздесь ~

201


ynptl8llRIOЩQR KOHCтpYKqUR if (если)

Ваш КОА может принимать решения, ИСПОJlЫУЯ упраВJlЯЮЩУЮ конструкцию Управляющая конструкция РНР

i f

1I

(если) позволяет вашему коду принимать решение на основании

проверкн истинности иекarорого выражеИИJI. Рассмотрим опять заказы Элмера. Прежде чем оформить заказ, Эл мер планирует получить деньги в размере стоимости этого заказа, что означает,

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

Если ОПJIата по банковской карточке покупатeJUI пронсходит без npoблем, он офорМJUlет заказ. Мы можем перевести этот сценарий в РНР-код, используя управляющую конструкцию

для принятия решений подобного типа.

Основа ynра....lOщeiii конструкции

If

COCI'OИТ И3 трех 'ICIcтei:

Ключевое слово if

Начало управляющей конструкции.

Условное выражение

Условное выражение располагается в круглых скобках сразу за ключевым словом

i f . Здесь находится утверждение, истинность

которого нам предстоит проверить.

Блок кода

Блок кода следует непосредственно за условным выражением

и заключается в фиrypные скобки. Он выполняется только в том случае, если условное выражение имеет значение

I'} ~C\ ФC!ZУРКd.Я СI<061<С\ JC\l<pbt€cte"WI

dЛОI( I(~,

€Х<>.9S1.Щu.й € COC"WIC\~ J1j>C\€ЛЯ )O(.IJ,eU l(oKC"WIpYI<u,uu

202

if·

ZЛQва4

true

(истина) .

i f , которая служит


реальные и nракmuческuе nрuложеНUR

Проверна на Аостоверность Центральной частью управляющей конструкции

которое всегда интерпретируется только как

i f

true

является ее условное выражение,

или

false. Условное выражение

может быть переменной, вызовом функции или результатом сравнения какого-либо объекта с другим объектом. Элмер использует вызов функции, которая производит проверку достоверности номера банковской карточки и возвращает либо true, либо

false в зависимости от результатов этой проверки.

r

условн.ое. ~н.u.e. t'\

~e"yт\ 3Кt:\чe.н.u.е. лv.~о

-tfue..

лv.~о fd~se.

омер банковской

~

if(

----------------~~-- ~ TorДA оформить заказ

)

{

fillOrder ( ) ;

L

Еслu 'jсло€н.ое €~н.ue I'1pu.l-I.J..(,МQе'll'l

JКdчен.uе {гие, 'II'Iог.эd €btI'10лн.я.е'll'lСя. ~ЛОI( 1<0.9", огран.uЧекнbtй cpu.Z\lPн.bt.мu~

CI(O~I(dJ.\u..

JI

Достаточно распространенной практикой является использование

в качестве условного выражения сравнения. Обычно оно сводится к сравнению значения переменной с какой-либо величиной. Например,

Элмер хочет предоставить скидку тем своим покупателям, которые живут

~O'll'l 0l'1ePd'll'l0P €О'з€РdЩdе'll'l

в Неваде. Он может создать управляющую конструкцию, которая будет

{Гие, ес.лu ,3КdЧен.uе

проверять часть почтового адреса покупателя таким образом:

t)epeMeн.н.oU $~iPPit)9_stdte

.

Еспи покупатель живет в Неваде if

.---

TorДA предоставить скидку

~ "УТ\О.>К:9 еС'll'l€ен.н.о 'YI'\еI(С"ут\o€ОЙ

~

c'll'lp0l(e 'Не€аэа'. ($shipping_state == 'Невада') { $tota1 = $tota1

Еслu. jслo€н.о е в~н.u.e

* 0.9;

~ I'1p~e"YТ\ зК!:\чен.u.е {гие.

"ут\ог.эа €buiолн.я.е"УТ\ся. dЛО!(

!(~ 1)0 I'1р е.эОС"УТ\d€лен.u.'IO

10%-й CI(u..9KIJ.. Это условное выражение осуществляет проверку на тождество, которое производится оператором ==

(два знака равенства, следующие друг за другом без пробела). Оператор тождества можно использовать не только для сравнения переменных с текстовыми значениями. Вы можете сравнивать переменные

с числами, переменные с переменными и даже с результатами вычислений.

,с-- Не ,3Ф(}I)ОЧа Й'll'lе Чu.сЛd

l!bt .мо.же'Yl'\е I'1po€epu.'II'Ib• 'II'I ОЖ:9 еС'll'l€ен.н.о JJU ,3КdЧен.uе о.эн.оЙ l'1 е ре.мен.кой

,3КdЧен.u)О .эр:уг.оЙ.

($nwn_items == 10)

~

($shipping_address

I<d€btЧI<IJ..

$bi11ing_address)

(2 + 2 == 4)

~ ~ мо.ж.е"ут\е u.ct)oJb,3o€a"YТ\b dрl.l.фме"УТ\u.ческu.е Ot'lepa"YТ\opbt в jСЛo€н.ом ~.ж.ен.u.u..

выздесь ~

2ОЗ


сравнение значении 8 РНР

В управляющей конструкции

ir

может осуществляться

проверка не только на тождественность AaHHblX &10~ ЭO'l~~~и;~~~~

в управляющей конструкции i f может осуществляться проверка данных более, чем просто на их КОКС E::!KU,lJ.K_ тождественность. Условное выражение в вашей управляющей конструкции i f может также проверить, t1 ЛgОСyr_ не превышает ли заданное вами значение какой-либо величины. Если превышает, то результат про верки

будет

true,

оэ

что приведет к выполнению блока кода, заключенного в фигурные скобки. Ниже приведено еще

С1!1 р<?

H"KM';;;;::~H;==:PHM'H:::~=:X;:~H;;;';;:;;:;;:"/ Имеется два оператора для проверки нетождествеlПlОСТИ двух всличин: <>

и

if ($smаll_пшnbег <> $Ьig_пшnbег) { echo 'True';

!=.

Результат такой проверки будет противоположным результату проверки на тождсственность (==).

Символ ~больmе, чем. (> ) используется в качестве оператора, выполняющего проверку, больше ли значсние величины объекта, расположенного слева от него, значения величины объекта, расположенного

if

($smаll_пшnbег

if

($smаll_пшnbег

1=

echo 'True' ;

$Ьig_пшnbег)

~ Ре,з'УЛЬ"\Т1Q"\Т1 Э)'yJОЙ >

$Ьig_пшnbег)

лоЖЬ.

I1po€epl<u. -

{ echo 'True'; }

справа.

Символ .меньше, чем.

u.c:YI\u.rtd.

«) используется в качестве

Оllсратора, выполняющего проверку, меньше .1И

значение величины объекта, расположенного слева от него, значения величины объекта. расположенного

if

($smаll_пшnbег

<

$Ьig_пшnbег)

{ echo 'True'; }

справа.

Следующие друг за другом без пробела символы «больше, чем!> и .равно. (>=) используются

(

в качестве оператора, выполняющего проверку, аналогичную проверке, которую проводит

Ре,зУЛЬ)'yJQ)'yJ Э)ТJой I1po€epl<u.

-

лоЖЬ.

if

($smаll_пшnbег

>=

$Ьig_пшnbег)

{ echo 'True'; }

if

($smаll_пшnbег

<=

$Ьig_пшnbег)

{ echo 'True'; }

А как

Oiuem оОсm<.JЯmь ()ело

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

Следующие друг за другом без пробела символы «меньше, чем. и ~paBHO.

«=) используются

в качестве оператора, выполняющего проверку,

аналогичную проверке, которую проводит оператор,

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

с nеременными, со()ерЖЭu.luмu meкcm?­

Можем лu мы сосmз~umь ~om mзкое

усло~ное ~ыrзженuе: ("d0,9" ) "сз()?Да, вы можете сравнивать строки в УCIIовном

выражении упраВnlllOщей конструкции

if.

Такое сравнение основывается на интерпретации алфавитных символов, при которой символ а считается меньше, чем символ

Использование операторов ",больше, чем!> и «меньше, чем!> может помочь вам, например, если возникнет необходимость расположить информацию в алфавитном порядке.

204

lлава4

z.


реальные и nракmuческuе nрuложенuя

С't1l,~JfЬ1М cfCi\O~lfblM ~bjfr1~GlfU,GM ~ cf11f~i\.fflO~Gii, l;Olfc't1l,k1Jj~U,U, jf Ваша заgача - Uгpaffib РОЛЬ условного выражеНU9 в ynраВА9ющеt1 KOHcmpyкuuu if U решать. ucmUHa вы uлu ЛОЖЬ. В кажgом UЗ случаев. когуа 68.л\ Бууут

npegлагатьС9 УА9

$mу_паmе

=

$a_decimal

npo6epKU

'Бастер'

=

$another_number

==

;

4.6; 'Беспокойство';

$favorite_song =

($a_number

слegyющuе nеременные:

=

О;

з)

($another_number ($favorite_song

($favorite_song

== "") == "Беспокойство")

==

($favorite_food =

'Беспокойство')

'hamЬurger')

true

иnи

fa.se

true

иnи

fa.5e

true

иnи

fa.5e

true

иnи

fa.5e

true

иnи

fa.5e

true

иnи

fa.5e

true

иnи

fa.5e

true

иnи

fa.5e

true

иnи

fa.5e

8ыздесь ~

205


6удьте условным выражением решение

C11\,rllfb1h,G j'C1\O~lfblM ~blfrl~~lfU,~M ~ j'11f~J\jПО\ц'~ii,

~Olfc11\,IJ'~~U,U,

jf

Ваша заgача - uгpatnb роль условного выражеНU9 в ynраВЛ9юще'Q KOHCmpYK:UUU tf U решаmь. ucmUHa вы uлu ложь. в к.ажgом uз случаев.

ttorga

58.А\ 6Уgytп

npegлагатьС9 gЛ9 npoвepKu слegyющuе nеременные:

$my_name

=

'Бастер'

;

-- '$your_name')

==

($favorite_song ($a_numЬer

'Веспокойство')

> 9)

($favorite_food

Q, hamburger' )

ЕсЛI.L €b!. ХО1Т\lЛ1Т\е ОI\~еэелlJ.1Т\Ь, 1Т\ о ж.э ес"V!\€ен.н.bt ЛlJ. Э1I'\lJ. э€а.

"_,,)

odoeK"V!\d. эр~г. эр~г.J зэ есЬ ..90л~еrt дbt1Т\Ь оl\ееа.1Т\Ор 1Т\о~ес"V!\gа. (--) ,

а. ке !"IPlJ.G~dlJ.€a.rtu.5l (=),

IfG

БЫ~iG't1I,

ь1!11ЫХ ~011YOCO~

'9: Явnяется ли уcnовное выражение улравnяющей конструкции тем же самым, if

что и уcnовное выражение в цикnе while?

О: Это совершенно одно и то же, И хотя в главе 3 мы использовали его только для того,

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

различного вида. Вы увидите это позднее.

206

zлаsа4

whi le путем использования сравнений


реальные и nракти.,еские nрuложеНUR

Логика в проверке на Аостоверность AaHHblX формы «Отправка ЭJlектронной

nOIlTI»I»)

Элмеру необходимо проконтролировать достоверность данных, полученных от формы sendemail.htm1. прежде чем отправить любое электронное письмо. Фактически отправка электронных писем должна полностью полагаться на проверку достоверности данных . Чего мы в действительности хотим от РНР, так это принятия решения, основанного на достоверности данных , полученных сценарием

sendemai 1. php.

Нам не06ходим код с таким алгоритмом: «Если данные достоверны, отправляйте электронные письма • . Но вначале мы должны извлечь данные из формы и присвоить их значения паре переменных.

$subject $text

=

=

$_POST['subject'];

$_POST['elvismail'];

Нам не06ходимо проверить, содержатся ли данные в каждом из этих полей ввода формы. Логика такой проверки должна выглядеть примерно так:

ЕCnИ в поле формы «Тема» содержится текст И в поле формы «Содержание» содержится текст,

TorдA отправить электронное письмо Или можем попробовать противоположный спос06 и проверить, не являются ли 06а эти поля ввода формы пустыми. В таком случае мы можем вывести пользователю предупреждение

06 ошибке:

sendemcil.html

ЕCnИ в поле формы «Тема» не содержится текста И в поле формы «Содержание» не содержится текста,

TorдA вывести сообщение об ошибке Проблема этих двух примеров заключается в том, что их логика требует от нас проводить два сравнения в одной управляющей конструкции

Одно из возможных решений

-

i f.

использовать две управляющие конструкции

i f.

Напишите две управляющие конструкции

i f,

в которых проверяется,

являются ли оба поля ввода формы «Тема электронного письма» и «Содержание электронного письма» пустыми . Выведите с помощью

команды РНР

echo сообщение об ошибке.

вы здесь

207


функции isset{} и empty{)

~8Hoe задаqu Напишите две управляющих конструкции

i f,

в которых проверяется,

являются ли оба поля ввода формы «Тема электронного письма»

11

~)O

и «Содержание электронного письма» пустыми . Выведите с помощью

OM~IA1,a5t 'l!\op~

команды РНР echo сообщение об ошибке.

:fIраЬЛя')<)\AJ\j)О

~

I(OtI.C'VII:P~I(Uf.A)O if €ttjfТlpu.

I I

Д€e сле.9у)ОЩuе "О.9~я,.9 0.9 Uttd pкb1.e

if.,( $.~.~~j~~.t. :=7~. иав~~I.<.~. !1р.~з~"!1)~~~...~..~~~:,,!!y~. ~.~r.~.~~'.. .. :'~~U~~~K~~" . i·f· '<$.t.~t..~:=:.:.'.).[ ... .................. .. .. ... ........ ..... .................. .......... .

t'\ep€ou

(€ttjfТlP~ е)'

...

r€f~: :::>S~:~~:~~::::о~==~:::~:з~7~"u~-<ьr Ч'n\одЬ\. дbtлo. €bI.t'\оЛttеНд

JС\кС\н.~u€С\е1Т\СЯ €н.JI'Iрен.н.я.я. у"ра.€лЯ,roщQЯ коttс1Т\РУКu,uя if,Q г..эе - €ttеl.UНSl.Я.

I(OJМ.tt.9 C1 e~o.

PHP-фУНКЦИН ДЛЯ проверкн переменных Использование оператора

== для проверки пустых строк работает, но существует более

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

isset () проверяет, существует ли переменная, то есть присвоено ли ей какое-либо значение. Функция empty () идет на шаг дальше и определяет, присвоено ли переменной пустое значение, что определяется в РНР как О (ноль), пустая строка или значения

false

или

NULL.

давайте посмотрим, как эти функции работают:

(' ,

или"

,,),

3Н4~eн.u.e "еремен.н.оЙ

$у2

- н.е l1ycvr-:.;

С1Т\рокС\, oн.Q

со.э е ржu1Т\

1Т\екс'УУ\. Т10з'УТ)ОJ.·

.71т\О усло€н.ое

€btfdж.ен.u.е

uмee'YТ) JН4чен.u.~

~

208

lлава4


реальные и пракmuческuе прuложенuя

я ПОНf!Лд. мы можем uспоt\ьзо~аmь ~YHKции issd()

u emry() ()t\f! тоГО, чmооы nrO~erumb ()ocmo~erHocmb ()анных not\eй <<1ема ,MeкmrOHHoro письма» u «Со()erжанuе ,мектронного письма». Это верно, но только отчасти. В действительности нам необходимо только убеДИТЬСtl в том, что эти полtl формы не пусты, а ДЛtl такой проверки функции

empty()

вполне достаточно.

Переменным

$subj ect и $text присваиваются значения элементов $_POST [ 'subj ect ' ] и $_POST [ 'еl vismai l' ] суперглобального массива $_POST. Если вы будете проверять их с помощью функции isset (), она всегда будет возвращать вам значение true независимо от того, содержат они какие-либо полезные данные или нет. Иначе говоря, функция

isset ()

не покажет вам разницы между

пустым полем ввода и полем, в которое введены какие-либо данные. Функция

empty () проверяет, действительно ли поле ввода пусто

или нет, что как раз нам и нужно для контроля достоверности.

ч>ункчus ~t( ) npoвepgem. eюyecrnsyem лu nеременна9

u

nрuaюeно лu

eU

k.akoe-лU50

ЗН8.чeнuе.

ч>ункчus

empty< ) npoвepgem.

cogержum лu nеременна9

1ft 8W~iit1h,

Zl111blX ~011ГOCO~

~: Зачем вообще тогда нужна функция isset()?

О: Функция isset () крайне необходима, когда вам нужно узнать, сущестВУlOт ли интересующие вас данные . Например,

вы можете проверить, переданы ли вам данные формы в результате запроса

POST, отправляя функции isset () $_POST. Как вы убедитесь

k.akue-ЛU50 нenycтыe gaнныe.

в качестве аргумента переменную

~МЯ no,.6amllllb

удобным на практике.

позднее в данной главе, это оказывается исключительно

Перепишите две управляющих конструкции

i f,

в которых проверяется,

являются ли оба поля ввода формы «Тема электронного письма» и «Содержание электронного письма» пустыми. Но на этот раз используйте в условном выражении функцию оператора тождества

empty ()

вместо

(==).

вы зiJееь

J>

209


оператор отрuцанuя (!)

~e"ae зааачu Переп"ш",е Две управляющ"е 'ОНПРI"""" ''''''ры, проверяе"., i f••

являются ли оба поля ввода формы «Тема электронного письма» и «Содержание электронного письма» пустыми. Но на этот раз используйте в условном выражении функцию

оператора тождества

empty ()

вместо

(==).

~..i.f..(~~p.~~($.~~~j~c;:~H.( ............... ................................................ . 0I'1~'YI\0P

€~дO:xC;€~~::x

~..i.f·.(~~. mp.i~($.tMt)).[ .... .. ........ .. ... .. ..... ... ................... .. .... .. .... ...... .

. . . .~.Ф~. :~.3<:'.~~.~~.~1')~ ."!!I.~~.~. ~I?.э~r~~~ .-!.Мк-mp.~I:t:f:I:C?~9.

€btрdжен.u..Я.x .~~~.~~:~.~~.!.~.~" ОС""'" d.МеIOtе'Yl\Ся. Н.д.}

~~~~~yНJ(Ui'UiHHHHH

А

nL

-

"1'..vIt>KOU

..

1(0.9

~ ЦJМeКШ1GJt

&QI'f мы QОЛЖНы &ЫТ10лнumь

Heкomorble QeUсm&uя, еслu поле &&ооа

c:pOrMbl tlС nycmoe~ CytJ.\ecm&yem лu срункцuя notem~у()~

Нет, зато существует простой способ реверсировCП'It яоrику

ЯlOбоrо

ycnoBHoro в... ражени ••••

оператор отрицани •• i f, может

Мы знаем, что условное выражение, которое управляет конструкцией

иметь значение либо true либо false. Но как быть, если логика диктует нам проверку значения, обратного тому, которое дает условное выражение? Например, было бы полезно знать, что поля ввода формы Элмера не пусты, перед тем как отправлять огромное количество электронных писем с данными

формы. Проблема в том, что никакой функции notempty () не существует. Решение заключается в использовании оператора отрицания

(!),

который

превращает

true в false, а false в true. Поэтому выражение! empty () вызывает функцию empty ( ) ,а затем меняет результат, который она возвращает, на противоположный.

:t1.~;:~:

((\t'empty ($sub) ect))

\

210

глава

{

~o ~сло€н.ое €bt.pct.ж.ен.u.е

Сl"lpctШU€dе'Yl\: «llоле €€ОЭd Ф?рМbL

.,.е1М.. элеК'YI\rоКJ-W~О t'\uсЬ1М.. н.е l'1~c'Yl\0e.7::o uлu «Соэе.рЖU'Yl\ лu Э'У!\О t'\оле I(dI(Ue.-ЛU~О Эdн.н.btе.7::0

4


реал"Нblе

u npoкmи.,ecKиe nрuложенuя

Заполните пустые строки в коде сценария

sendernail . php так, чтобы электронные письма $ subj ect и $ text присвоены непустые Используйте управляющую конструкцию i f и функцию ernpty ( ) .

отnраВJIЯЛИСЬ только тогда , когда обеим переменным значения.

о о

Ma~M~tl...v;$.COM n.pcoмanbНO: только ДПЯ пcжynaтeлeй ЭЛllElра Й Состаеьте и omраеьте электронное письМО дnя пoкynaтeлe , внесенных в лмет рассЫЛIOl.

Тема зneктpoнtЮlO nМCbМ8:

i...

письма:

<7php $frorn = 'elrner@rnakerneelvis.com'; $subject = $_POST['subject']; $text = $_POST['elvisrnail'];

sendemcil.html

if ........................................................ . if ......................................................... . $dbc or

= rnysqli_connect('data.rnakerneelvis.com', diе('Ошибка соединения

с MySQL-сервером.

$query = "SELECT * FROM ernail_list"; $result = rnysqli_query($dbc, $query} or diе('ошибка при выполнении запроса

'elrner', '};

'thеkiпg',

'elvis_store'}

к базе данных.'};

while ($row = rnysqli_fetch_array($result)} $to = $row['ernail']; $first_пarnе $lаst_пarnе

= $rоw['first_пarnе']; = $rоw['lаst_пarnе'];

$rnsg = "Уважаемый $first_пarnе $lаst_пarnе, \п$tехt"; rnail($to, $subject, $rnsg, 'Frorn:' . $frorn}; echo 'Электронное письмо отправлено: ' . $to . '<br />'; rnysqli_close($dbc};

7>

вы зае,,,

211


сценарий sendeтail.php -

теперь

( контролем данных!

3апопните пустые строки в коде сценария

sendemail . php так, чтобы ~neKTpOHHыe письма $ subj ее t и $ t ext присвоены непустые значения. Испоnьзуйте управnяющую конструкцию i f и функцию empty ( ) .

отправnяnись тоnько тогда, когда обеим переменным

о о

эneктроннoro письма:

I3oсклuUft"ll1елЬн.btй jнal(

ре.€е.рсuру е"ll1 ЛО z. u ку e.'I!\ptyO.

ФУКl<u,uu

nep€oe усло€к.ое €btраже.нuе. t)po€e.p5te'l!\, к.е t)puc€oe.нo ЛU

t)epe.Me.кн.oU $subje.ct t)yc'I!\oe. jмче.нuе.. ,

<?php

.

$frorn = 'elrner@rnakerneelV:LS.com'; $subject = $_POST [ 'subject ' ] ; text = $_POST[ 'elvisrnail']; i f

.

, А се.uЧd.С ~ I1po€ Ke."II1 - О"IТ)Лu.Ч о н.о . t)~ e.k~~e.$~UCf)oe.н.o fIU ~че.к.u.е u e.xt I1YC"II1 oe.

...е.СЛu.

I t:. ~ .c..e:mp:t~C~~v.b;).el<t.} .. .. ..... ...... .. .. .... ..

.

sendemciI.hlml

МЬ!. oJ1)l<,Кbt jd~uCQ'I!\b оэк.у :it)g.а€л!,--,ou.J{fIO KOkt'l!\p'YKu,u.-,о '! € дЛОК коэа ~~~z.ou,

c:u..(!e.lIIpt i1 C$:teJ(:t)) . .......... .. .. ... ...... ........ . /~~d~~~~~~u~o~~Мo $dbc or

= rnysqli_connect('data.rnakerneelvis . com', diе('Ошибка

соединения

с MySQL-сервером .

'elrner', ');

$query = "SELECT * FROM ernail_list"; $result = rnysqli_query($dbc, $query} or diе( ' Оmибка при выполнении запроса while ($row = rnysqli_fetch_array($result)} $to = $row['ernail']; $first_narne = $row['first_narne']; $last_narne = $row['last_narne']; $rnsg = "Уважаемый $first_narne $last_narne, \ n$t rnail($to , $subject, $rnsg, 'Frorn : ' . $frorn}; echo 'Электронное rnysqli_close($dbc } ;

212

глава

4

' theking',

o€epK}

'elvis_store'}


реальные и nракmuческuе nрuложеНUR

-Тест-драйв ПровеРltте, контроnмруется nм ДOCТOBepHOCТlt данн",х попей форМ.... Измените код сценария sendemail . php, используя управляющие конструкции i f, чтобbl контролировать достоверность данных полей формы перед отправлением элеКТРОННblХ писем.

Загрузите новую версию сценария на ваш ве6-сервер и откройте страницу

sendemail . hnml

в браузере. Убедитесь в том, что вы оставили хотя бbl одно поле ввода пустым, и нажмите кнопку ~Отправить».

ТолЬко t),'IС1I1QЯ C1I1~ttu.up €MeC1I1 0 t)О.9111€ержз е нuя. "'IТ\oг.o

J

cpctK1I1Q, Ч"'tIiо

ЭлеК1I1рон.н.ое tщсЬмо

01l1t)FQg'лен.о н.е dbt.ло.

Но KQl{oe-лu.dо соодщен.u.е од ошu.дке dbt.ло дЬ!. t)олеJн.ее IlYc"'IТ\ou

C1I1 FQttU.u,bt.

выздесь

213


РQЭZОВОР В тесном кругу

-..----.............-----.--:

kчmо еслu &HaWeй cf0I'Me byuem MHOfo полей &&ООа:?

-.._----

~~

Мы uолжны дуием &клaUы&аmь множесm&о У"l'а&ляIOU.\UХ консm!'УКЦUЙ ~ оона &umю,

.... ,. .......1 JII __ "~

чmОдЫ nl'0&erumb ()ocm0&erHocmb их &ах:?

с--

....,

';

___-" _-\

..

.... '.: ....

...

__

~.;....

... ; ....

:.....,;..:......_-""-". ....-:. ~ •...

...•; .... . ._.

;

о о

"

..........

TQKOe. дoJЬu.toe. КОJ1Uче.С"W\€О if (!empty($last_name))

€лож.е.ннЬх )'I1~€ЛЯ)<Х.ЩJ.X

{

if (!empty($when_it_happened)) if

(! empty ($how_lo ng))

{

i f (! empty ( $how_many) )

{

KOKC"W\P~KUPUif

jQ"W\Р:ВкЯ.е."W\ O"W\слe..жu.~кuе.

~ coO"W\€ё."W\C"W\€uSt O"W\К~)()I.ЦШ( \.t

jQкpbt€Q)()I.ЦШ( фU~~РнJ:яx

скодок. Джо: Я думаю, ты права. Если мы хотим убедиться, что все эти поля ввода данных не пусты, мы должны вложить управляющую конструкцию

i f

для каждого поля.

Фрэнк: Если мы сместим каждую строку кода для каждой управляющей конструкции

i Е,

все ли будет в порядке? Джип: Технически

-

да. Я хочу сказать, что код определенно будет работать независимо от того, сколько управляющих

конструкций i f мы вложим одна в другую, но меня беспокоит то, насколько это затруднит чтение и понимание кода с такими многократными вложениями. Простой поиск соответствия открывающих и закрывающих фигурных скобок может оказаться серьез ной проблемоЙ. Фрэнк: Это точно. Я думаю, даже простое смещение кода может серьезно усложнить дело ... Представьте себе, что десять полей ввода данных повлекут за собой десять управляющих конструкций i Е, вложенных одна в другую , с десятью уровнями смещения кода. Даже если мы будем смещать каждую конструкцию к смещению блока кода в ней на 20 пробелов. Кощмар!

i f всего на два пробела, это приведет

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

10 символов табуляции против 20 пробелов.

Не так уж и плохо.

Джип : Ребята! В конце концов проблема заключатся не в том, как смещать строки кода при вложении друг в друга множества управляющих конструкций

i

Е. Просто такое множественное вложение управляющих конструкций

if

само

по себе не слишком хороший стиль программирования . Рассматривайте это в таком аспекте, что в действительности мы говорим об одном логическом условном выражении, а именно: • все ли наши поля ввода данных формы не пусты?. Проблема состоит в том , что условное выражение включает проверку десяти различных данных, вынуждая нас разбить весь ПРОI{есс на десять управляющих конструкций

ФРЭНК: Я понял . Все, что нам необходимо, конструкции

-

i

Е.

это найти способ проверки всех десяти данных формы в одной управляющей

i Е, так?

Джип: Точно.

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

214

глава

4


реал"ные и nракmuческuе nрuложеНUR

Множественная проверка на достоверность

с помощью Jlогических операторов АМD н Вы можете создать условное выражение для управляющей конструкции

OR

Аoruческue

i f с проверкой

onераторы gaюm

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

надостоверность:

!empty ($subject)

и

!empty ($text).

5ООМОЖнocmь

В первом примередваэтих

выражения 06ъединяюrcя с помощью логического оператора ЛNО, код которого выглядиr как

БОлее э.лera.нпuю

&&.

ЛО2.uЧескuД ~до.,олкu.)I'}елЬкbte круглbtе C K OdI(U.9d.}O'IТ} C<XJga58J11b AN{) ----........ 1)0КЯ)l'}Ь, '-hI)0 o.,e~"'II'I0E O)I'}рu.u,qн.u.я. Ol)epa"Yr\Op. ~ ОlТ\НDCUlТ\ся. lТ\0~1( cpyкA:u,u.u e"Yr\p-tуО. ynpar.л9ЮЦJUe .

.

lf «!empty($subJect»

L

..

~&

(!empty($text»)

if.

KOНCtnnvк\JUU 'f';--

{

Э'w\о ~Слo€НDе €1яpd.Жe.кu.е. ""О2.Эd u "Yr\оЛЬко ""огЭd

~~e"" u.мe1Y\P JкdЧекu.е. tru.e. KOZqct Оде .,e.peмe.Ннbtx АoruческUn $'subje.ct И Иехt u.мe)<itY\ нoe..,~c"yr\f:,te. 3Кl\чеlшЯ.. AND (:..~ Логический оператор ЛNО рассматривает две величины, которые могут принимать значения onepa1t1Op ,Ш true

или

false,

имеют значения

и возвращает true тогда и только тогда, когда обе из рассматриваемых величин true; во всех остальных случаях он возвращает false. Следовательно, оба поля

ввода данных формы должны иметь непустые значения для того, чтобы условное выражение

KogupyetnC9 как.

&&

.....'11

а .лoruческ:uu

приняло значение true и был выполнен блок кода управляющей конструкции i f.

onератор

Логический оператор OR, код которого выглядит как 11, также рассматривает две величины,

(u.лu)

-

как.

которые могут принимать значения true или false, и возвращает true тогда, когда любая из рассматриваемых величин имеет значение true, и только в случае, если обе они имеют значение

false, он возвращает false. i f «! empty ($subj ect»

11

-

11.

/

э-n,о не Чu.СJJo о.эuннaэu,a"lТ\Ь, fIт10 :fie.

(! empty ( $ text) ) )

€ep"IТ\UI<c.Vbнbte чер,"'II1Ь1., слеэytOOJ.uе оэН,Q ~pгoй. Си.мВол €еР"IТ\UI<<1JbНОЙ чер"'II1Ь1. ОЭU"'ll1 с S!. Нt1Ж4"'111uе.м lUk:I€tA.U.I.! одf>d."'II1 НО Й Н,QКЛОн.ной чеР"IТ\Ь1.I1pu. Нt1Ж4"'1110й КМ€uще ~ift.

l'

э-.т,о УСЛО€НDе €Iя~кu.е дY.g elТ\ ~ 3КQЧекu.е true :n\ozqct, 1(02..9'\

01\.

л~ UJ l)epe.ft\eннblx $subject

ИЛИ $-tеХ1 uмee"" Нoel)yc"Yr\oe зн.dЧен.u.е.

Таким образом, блок кода этой управляющей конструкции i f будет выполнен тогда, когда

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

имеются непустые данные, а в другом

- нет. Например:

Т10ле €€оэа ф<>рМbL «Тe}Ad Э леl\fТ\РОн.нDго

i f (empty ($subj ect) ,&& (! empty ($ text) »

".

{

.,;

l)ucb}Ad:l> qолж.k.о dt:~;'IТ\b I)~C"'II\bt.М. i:\ I)Оле

ф<>рМbL «'СоэерЖдн.uе элек"'II1РОНКОz.о

1)U(~b}Ad» - Нokl)~c"'ll1bt.М. Ч"'II\О~ €ce jслo€ное ~ж.ен.uе u.МеJJo змЧен.uе true.

Так как в этом условном выражении используется логический оператор ANb, то для того, чтобы был выполнен блок кода управляющей конструкции i f, оба составных условных выражения , расположенных как слева, так и справа от оператора

AND, должны

иметь значение

true. В данном случае это означает, что поле формы

письма. должно быть пустым, а поле формы .Содержание электронного письма. реверсировать подобную проверку перемещением оператора отрицания

i f «( !empty($subject»

empty($tex~)

Логические операторы AND (&&) и OR (11) позволяют

логики которых без их использования потребовала бы дополни~ьных, часто очень запутанных управляющих

.Тема электронного

непустым. Вы можете

(!) от правой функции empty ()

к левой.

~~o УСЛО€НDе ~кu.e dY.ge"n! uмe"Yr\b .3НQЧекu.е tru.e lТ\oJbl(o € lТ\o,М сл Чctе

~

создавать очень МОlЩlые условные выражения, реализация конструкции 1

{

-

I'\оле €€o~ ФОр.м.bt «TeJ.4,Q Элеl( I'J О ,еслu.

l1u.cb~» дY.gelТ\ Н,eI)YClТ\br.м.

lТ\p нн.ого

«СО.9 еРЖ4кu.е JЛ с\ I)ОЛе ФОр.м.bt I)yc"n!tk eК"Yr\p0нн.o~o .,u.cb~» -

f.

вы эдес"

215


усmронumе вложенные управляющие конструкции if

Перепишите выделенные серым цветом фрагменты кода сценария

sendemail . php

так, чтобы в них использовались логические операторы вместо вложенных управляющих

конструкций

i f.

< ?php $from = 'elmer@makemeelvis.com'; $subject = $_POST[ ' subj ect']; $text = $_POST ['elvismail'];

~O и""",. Ол .... 1_ О , ......\Мu.~. оже.~е .Уt'\pct~ля.щu.е

..1111 t

if

(1€Щ\ptУ($suЬjесЧ2 i f (!e:mpty($text)}

$dbc or

{

~

{

I(OKC'VI\P'yI(u,uu.

if·

= mysql i_connect('data.makemeelvis.com', diе('Ошибка

соединения

с

nереt)u.шu'Vl\е.

MySQL-сервером.

$query = "SELECT * FROM email_list"; $result = mysqli_query($dbc, $query) or diе('ошибка при выполнении запроса

к

'elmer', 'theking', ');

базе

данных.');

while ($row = mysqli_fetch_array($result)) $to = $row['email']; $first_name = $row['first_name']; $last_name = $row['last_name']; $msg = "Уважаемый $first_name $last_name,\n$text"; mail($to, $subject, $msg, 'From:' . $from); есЬо 'Электронное письмо отправлено: ' . $to . '<br 1>';

?>

216

zлава4

1(0.9

с u.Сt)О.i1b.30€Qн.u.е.мло~u.чеСI(u.x ot'\epct'Vl\opo€.

'elvis_store')


реальные

u nракти.,еские nрuложенuя

-lеСТ-JJ.раЙв Убедитесь в том, что II0rические операторы в сценарии «Отправка Эllектронной почты)) работаlOТ так же,

как и ВIIоженные упраВII.lOщие конструкции И змените код сценария

if.

sendemail . php так, чтобы для контроля

достоверности данных полей перед отправлением электронных писем

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

i f . Перепроверяйте

решение этого упражнения

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

sendemail . hnml в браузере. Убедитесь в том, что вы оставили хотя бы одно поле ввода пустым, и нажмите кнопку «Отправить» . Сценарий все еще

не позволяет отправлять электронные письма, если какое-либо из полей ввода формы не заполнено?

JiG Obl~itG't1t.

ZVl1bJX ~011ГOCO~

'9;Имеет ли значение, в каком порядке 3аписаны условные

выражения, объединяемые лоrическими операторами && или 11 в управnяющей конструкции

if?

О; Да. Смысл здесь заключается в том, что зти два оператора заканчивают процесс проверки так скоро, как зто только

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

будет

fal se, позтому процесс про верки

на зтом прекращается,

и правое условное выражение игнорируется. Аналогично принимается решение в случае, если левое условное выражение

в операторе OR имеет значение

true.

'9;я видел PHP-КОд, в котором используются лоrические операторы AND и OR вместо && и

11. Как они работают?

О; Логические операторы AND и OR - практически то же самое,

условное выражение просто игнорируется. Например, если при

что и логические операторы && и

проверке двух условных выражений, объединенных погическим

друг от друга в приоритетах относительно других операторов,

оператором

но если вы будете внимательными с использованием скобок

:: а 1se,

&&. левое условное выражение имеет значение

нет никакого смысла продолжать проверку, так как при

любом значении правого условного выражения общее значение

11. Они немного отличаются

при составлении своих условных выражений, то не увидите никакой разницы между ними.

8ыздесь

217


усmронumе вложенные УnРОВЛRющuе конструкции if

Перепишите выдепенные серым цветом фраrменты кода сценария

sendemail . php

так, чтобы в них ИСПОПЬЗ0вапись поrические операторы вместо впоженных управпяющих конструкций

i f.

<7php $from = 'elmer@makemeelvis.com'; ОТ (1) ль е'УУ\Ся. $subj ect = $_POST [ , subj ect ' ] ; Ot)epa'YY\0..p O"lY\pv.up.НUSI., u.лv. N _ . , v.cl"I0 3:; $text = $_POST [ 'elvismail' ]; ЭЛЯ-l"Iроgеркv. к.el"lyc'YY\bu< t)олеu. ввоза заНJ-\.btx· if

~ ii!~l;i::::~;=;:~~:) +

МЬ!. Можем UCt)OJbJ0€o.'YI'\b Ot)ePQ о AND

fcЯ 1:~€ePKЦ O~OЦ)( у:лo€нbtx,€~-;'~~Iнuй

~ О.9Н: u .'f\ро.€ляющеu KOН:C'YI'\Py;JМ:'f. if.сС!е:щрt~С$SUЬjес.t1).&&.с'е'nlrtу($tехt))) { Не jd.~bI.€ai1'YY\e: .9€a сu.м€оло. &&, КdI"lU~ ................................. $dbc or

~................ .

./

~~~;r:::~';e~orAND~K ж коэv.РУем

= mysqli_connect('data.makemeelvis.com', diе('Ошибка

соединения с MySQL-сервером.

$query = "SELECT * FROM email_list"; $result = mysqli_query($dbc, $query) or diе('ошибка при выполнении запроса

к

'elmer', ');

'theking',

базе данных.');;

'elvis_store')

~cb КО.9 €K.YWIeu.

фv.г.урнbtx СКОдОК

.9 0лже н. ~bt'Yl'\b c#u.н.::J'YI'I

while ($row = mysqli_fetch_array($result)) ~ле€о н.о. 0.9u.н. ypo€eН:b $to = $row[ 'email']; ~ см,.еЩенuя. 'YI'\aK Как $first_name = $row['first_name']; сеUЧас он. PQС"ОЛОЖен. $last_name = $row['last_name']; €o н.оо. '€. _ $msg = ·УважаеМЫЙ $fist_name $last_name,\n$text"; I(O~ ~po. ~юw,еu mail($to, $subject, $msg, 'From:' . $from); € 'YI'\Р.УКI.J,UЦif€меС'Yl'\о echo 'Электронное письмо отправлено: ' . $ to . '<br / >'; .9 УХ. Как Э'Yl'\О д'btло "реЖ;9е. mysqli_close($dbc);

-:-

Так КаК сеi1Чо.с.:J КdC ОЭКd Уl1ро.€ля)O(.lJ.o.Sl. кон.С'УУ\рукu,uя if·

~ 'УУ\О 1,1. ее jd.крbt~)O(.IJ.ая. фv.г.урн.о.я CKO~Ka 'YI'\0же. ОЭн.о.·

.1.. ................ .. ....................... ............ . 7>

218

zлово4


реольнwе и nрокmuческuе nрuложенuя

Форме ВВОАа Аанных нео6ХОАима 06ратная СВЯJЬ Элмер €u.эu."tI1 Э"tl1у

Код нашего сценария sendemail . php делает очень полезную работу, проводя проверку I1YC"tl1J~O C"tl1fC\КUu,y данных на достоверность, так что не будет отправлено ни одного электронного письма, если в полях .Тема электронного письма. либо .Содержание электронного письма»

t')осле 0"tl1t)P<:1€1<u. mopМbt нд' . €

не введено никаких данных. Но когда проверка данных на достоверность не удается, '1"'и h и'" сер ер ... ооб он. .• Оп.л"tI1wt н.е щает Эл меру о причинах этого. Все, что он получает, u.м это пустая веб-страница. ...-/ ee"tl1. t')OЧему "tI1C\1( 11 p0U.CX0.9u."tI11 u

сценарии ничего не с

-------.

Что npoцcxooцт~

Я пытаюсь цспользо~ать с~ою но"Ую форму, ц ~ce, Что Я получаю, ~ 31110 пустая странцца.

о о

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

false (неверные

данные), ничего не произойдет и Элмер останется в неведении по поводу того,

было ли отправлено письмо, и если нет, то почему. Ниже приведен сокращенный

код, объясняющий проблему пустой страницы:

<?php $from = 'elmer@makemeelvis.com'; $subject = $_POST['subject']; $text = $_POST['elvismail']; if ((!empty($subject)) && (!empty($text))) $dbc = mysqli_connect('data.makemeelvis.com', mysqli_close($dbc); ?>

'elmer',

'theking',

'elvis_store')

Нu.Чег.о н.е I)Pt0u.cx0.9u.'Y!\, еслu. f'ра€Л5l.)ОЩеu.

if

KoKC'Y!\EYKu,u.U. н.е У,9С\е'У!\С51. 6'bI.t)ОЛКU'У!\Ь dЛОК КОЭС\, ИмеНiW 1)0 Э'У!\Оu. rtрu.чu.н.е u. г.ен.ерu.руе'У!\Ся. rtyc'Y!\C\5I. C'Y!\PdКUUP, ког..9а KC\Ku.e-лu.dо u.j н.eo~x0.9u.мb1.x .9aкн.bu< rtp0rtyw,eн.bt.

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

выздесь ~

219


инвертированное условное выражение else (иначе)

Это не будет работать, потому что КОд, помещенный

-

непосредственно поспе закрываlOщей фиryрной скобки упраВnRlOщей конструкции Размещение команды

echo

If,

будет BblnOIlHRТЬCR всеrда.

непосредственно после закрывающей фигурной

скобки управляющей конструкнии i f означает, что она будет выполняться после обработки этой конструкции , но это будет происходить всегда, независимо от того, выполнялся ли блок кода управляющей конструкции i f или нет. Это не то, что нам необходимо. Мы хотим, чтобы команда

echo

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

i f

принимает значение

false.

ЕCnИ в поле формы «Тема» содержится текст

/

V

И в поле формы «Содержание» содержится текст,

TorДA отправить электронное письмо

Х ИНАЧЕ вывести сообщение об ошибке Управляющая конструкция

else

i f предлагает необязательное ключевое слово

(иначе), за которым следует код, выполняемый в случае, если условное

выражение принимает значение

false . Следовательно,

наши команды на

вывод сообщения об ошибке должны быть размещены в выражении е 1 se. В этом случае сообщение об ошибке будет выведено, только если одно из полей ввода данных формы окажется IIУСТЫМ. Просто напишите ключевое

слово

else непосредственно после закрывающей скобки управляющей

конструкции i f и затем альтернативный блок кода, ограничив его фигурными скобками.

220

глава

4


реальные и nракmuческuе nрuложеНUR

Ниже приведен новый код сценария Элмера конструкцию

i f

sendemail . php, использующий управляющую

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

Используя магниты, поместите нужный код в нужное место.

что и переменная $subject,

и переменная $text пусты

~.~"~""~""""~~"~"~"""II""III!II!!II"""""""~ / / Переменная $sub' е

<?php $ from ' elmer@makemeeV1S . сот' ;. $subject = $_POST['subject']; $text = $_POST['elvismail'];

отлично ,

отправляйте электронное

else

//

мы знаем,

echo

что или переменная

'Бы

забыли

ввести

'Бы

забыли ввести

$subject,

тему

или переменная

электронного

$text

письма.<Ьr

пуста.

Давайте узнаем,

какая

/>';

else {

echo

содержание

электронного письма.<Ьr

/>';

else

while ($row = mysqli_fetch_array($result)) $to = $row['email']; $first_пamе $lаst_паmе

= $rоw['first_паmе']; = $rоw['lаst_паmе'];

$msg = "Уважаемый $fist_паmе $lаst_пamе,\п$tехt"; mail($to, $subject, $msg, 'From:' . $from); echo 'Электронное письмо отправлено: ' . $to .

mysqli_close($dbc) ;

?>

вы здесь

221


ynpQJКHeHue решение

Ниже приведен новый код сценария Элмера конструкцию

i f

sendemail . php, использующий управляющую

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

Используя магниты, поместите нужный код в нужное место.

<?php $from = 'elmer@makemeelvis.com'; $subject = $_POST['subject']; $text $_POST[ ' elvismail']; ,' empty ($subj ect) что и переменная

II

мы знаем,

и переменная

$text

пусты

empty ($ text)

emptY($subject)

узнаем,

$subject,

что или переменная

$subject,

или переменная

$text

пуста.

Давайте

какая

empty ($subject)

echo 'Бы забыли ввести тему электронного письма.<Ьr 1>'; else {

...........

$text

пуста

~---~~~~,

.................................................................

ы ' забьiiIJ1 ввести содержание электронного письма.<Ьr 1>';

else //

Все отлично,

отправляйте

к ЭYl\о.м~ momet-tYl\~ t)осле

while ($row = mysqli_fetch_array($result)) $to = $rOW['email']; $first_name = $row['first_name']; $last_name = $row['last_name']; $msg = UУважаемый $fist_name $last_name,\n$text mail($to , $subject, $msg, 'From:' . $from); echo 'Электронное письмо отправлено: ' . $to . '<br W

mysqli_close($dbc) ;

?>

222

глава

4

;

t)po€epKu €cex uкbtx

€о.з.мОJК,КDСYl\еU JIObt Yl\ОЧн.о 3Нl1.eм, ЧYl\о все

t)оЛ51 Эdкн.bu< форJw\bt. Jdt)олн.енbL

1>';


реальные

u пракmuческuе прuложеНUR

~и 3mU &лож~ные У"rа&ляк>\Uuе КОНCtn!'>'Кuuu ~ с КЛIOЧе&ым сло&ом tLse 33mt')'uняк>m ч~uе UnOHUM3l-iuе щwаruя.

Я не хоmел Оы KOfua-лuOо uмemb Uело с noooOHbIMU щwаruямu! Ио HwOXOOUМO y"~umb, пока kmo-нuOуuь не &ы&uхнул ше M03f1.L

Хороwий CI'ИII" проrpaммиро.ани •

....pa_aeTctI

TalOКe и

ТОМ, ЧТО код

доn_ен быть как мо_но боnее ПроCТЫlМ Дn. чтени. и понимани

••

Особенно это касаетс. cnучае. &по_ени. раэ.nичн",х конструкций одна

• ApyrylO.

Слишком большое количество инвертированных условных выражений

else i f

во вложенных управляющих конструкциях

делают код трудным для чтения и понимания .

Возможно, это не имело бы значения, если

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

когда-нибудь понадобится изменить форму

ввода данных и добавить новое поле ввода, написание кода проверки достоверности может

превратиться в достаточно сложную задачу, так

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

вы здесь

223


очистка кода if

qu,С~J\ъщu,tом

C11t,rJJfb11l,t "l;ogOМ~11f~J\jIjO~Gii,

l;O]-fс11t,k1l;~U,u, [р

.ваша заgача - urpaffib РОЛЬ уnрав.лsющеi1 KOHCffipYK:UUU tf U расчuщать запутанные

вложенные KOHCffipYK\JUU

IF

U

ЕLS. Е _

Переnuшuте Kog так. чтОБЫ

Co€e'tТ\: еероя'tТ\н.о,

еt:я мо.же'tТ\е

J €оо3ще 030UiТ}LLCb ~ де.} e)se'

UЗsa5uтьС9 от вложеннЬ1Х.

KOHCffipYK\Jui1.

но

ysegumeCb.

что он равотает nравuльно.

if (empty($subject) && empty($text)) { echo 'Вы забыли ввести тему и содержание электронного письма.<Ьr />'; else ( if (empty($subject) II empty($text)) { if (empty($subject) { echo 'Вы забыли ввести тему электронного письма.<Ьr /> ' ; ~ else echo 'Вы забыли ввести содержание электронного письма.<Ьr />';

else { // Все

224

zлава4

отлично,

отправляйте

электронное

письмо


реDльиые и

npDKmU.,eCKue nрuложенuя

Испытайте упрощенный код управnяющей КОНСТРУКЦИИ чтобы у6едИТltСЯ

Измените код сценария

if,

том, что он выполняется как положено.

sendemail . php так, чтобы в нем использовались i f подобно тому, как было написано

управляющие конструкции

ранее, но с упрощенными вложениями управляющих конструкций

if.

Обратитесь к следующей странице, если вы сомневаетесь в том,

какие изменения необходимо внести.

Загрузите новую версию сценария на ваш веб-сервер и откройте страницу

s endemail . hnml в браузере. Поэкспериментируйте со сценарием, отправляя форму на сервер с заполненными и пустыми полями ввода данных.

Выводит ли сценарий сообщения об ошибках?

~: Неужели небольшое количество уроеней вnожения имеет такое уж orpoMHoe значение?

О: ЭТО зависит от обстоятельств. Если вы разрабатываете

~: Как работает else? О: в управляющей конструкции if ... else инвертированное условное выражение соответствует тому,

код. который только вы и будете видеть, и считаете, что

чему не соответствует прямое условное выражение.

сможете точно помнить в течение ближайших шести месяцев,

~: Гм••• отлично. 0значает ли ЧТО Я

ее .... вам вдруг понадобится обратиться к нему для внесения и-.енениЙ, за что отвечает каждая его строка, то пишите

с IUlQжениями этих конструкций, раз вам так проще.

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

310,

одни управnяющие конструкции

MOry

вкладывать

if ••• else в друrие?

О: в принципе, вы можете это делать. Но со всеми

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

выздесь

225


очuстка кода if

чu,с1ЫЬльщu,~ом

С11l,r1lfЬ1М YtogOм с111r~J\jП()~Gu, t OlfC11l,k!tUaU,u, Ваша заgача - urpatnb РОЛЬ Уnра5А91Ощеtt

KOHCffipyк.uuu if

бложенные

расчuщать запутанные ELSE. _ KOHcmpyKUuu IF u

u

Переnuшuте Kog так. чтОБЫ

rr

~o€ell\: €еРОЯll\н.о,

tlbt Можеll\е ) €ООdще odOU"II'\u.cb

~ де,3 ~se'

UЗ8аБUтьС9 от бложенных

KOHCmpyк.uutt. НО

ysegumecb.

что он равотает nра5UЛЬНО.

if (empty($subject) && empty($text)) { echo 'Вы забыли ввести тему и содержание электронного письма.<Ьr / >'; else { if (empty($subject) II empty($text)) { if (empty($subject) { echo 'Вы забыли ввести тему электронного письма . <Ьr />'; } else { echo 'Вы забыли ввести содержание электронного письма.<Ьr /> ';

else { // Все 1

отлично,

отправляйте

электронное

письмо


реальные и nрактuческuе nрuложенuя

я rlOmj?flC~. I<cr()a fI уэдыл &&ecmu &o/0j?MY meмy элекmj?онноrо nUCbмa, mo получил эmу cmj?aнuцy. Но Kor()a fI нажал КНОПКУ «Наз<ю)'>, мне nj?UUJЛОСЬ &&ooumb &се э"екmj?ОННое nUCbMO зэно&о.

7vrId C"YI\Pdl-ШlJ,d.

СООдЩdе"Yl\ Элмеру.

Ч"t!\ о 01-1. сэеЛdf1

I-I.ell Рd€UЛbКD, 1-1.0 I-ШЧег.о долее.

Проверка данных на достоверность в сценарии

Эnмера «Отправка эnектронной почты» работает, но сценарий Когда сценарий

Mor бы деnат" боnее поnеэные вещи.

sendemail . php

видит недостоверные данные

формы, он выводит сообщение об этом, но этим и ограничивается. Например, в нем нет ссылки на форму, которая его вызвала. Более того, когда Элмер возвращается к странице формы, используя

средства своего браузера, информации, которую он только

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

Что, по вашему мнению, может улучшить обработку ошибок в сценарии «Отправка электронной почты», сделав его более полезным?

8ыздесь ~

227


восстоновление HTML-КОiJо формы

о

О

17bfЛО Оы 3<)oro~o noкa~mb 410rMY ~Mecme с cooornet\ueм 00 OLииОке. Раз~е мы не можем ~bI~ecmu 410rMY ~HO~b, UСnОЛЬ3Уfl KOмaн"Qy echo, еслu meмa :MeкmrOHHOfO nисьма uлu efo сооerжанuе nycmbff-

&ыnо бы действитеnьно поnезно вывести форму вновь, так как это избавиnо бы Эnмера от необходимости возвращаТЬСА к ней, ИСПОnЬ3УА средства браузера.

Поэтому в дополнение к выводу сообщения об ошибке, когда одно или несколько полей формы остались незаполненными, мы должны также восстановить НТМL-код формы из РНР-сценария,

используя для этого команду

echo. Этот код показывает, что РНР

имеет возможность генерировать достаточно сложный НТМL-код:

(

7vnО1Т\ ?Н?-КОЭ г,ен..ерu.ру е1Т\ НТМL-срорму t'\олкос1Т\Ь)О. t{d Чu.l-tdя. с 1Т\ег.а <fоr1Т\ >•

echo '<form method="post" action="sendemail.php">'; echo ' <label for="subject">TeMa label><br />';

электронного письма:</

echo' <input id="subject" name="subject" type="text" size="30" /><br />'; echo' <label label><br />';

7vnU. смеще

н.u.5l

ке одЯJct1Т\ельнbt.. ко t'\о,3€ол5!.)O"Vf\

echo' <textarea id="elvismail" name="elvismail" rows="8" cols=w40 w ></textarea><br />'; ~<input type="submit" name="Submit" vаluе="Отправить"

л~чш.е €u.эе1Т\Ь

/ > '~

НТ

echo

C;""M(L""\ID\J '" "'JIJ

-коэа.

fоr="еlvismаil">Содержание электронного письма:</

-----'</form>';

т: а!( !(а!(Ч.3Н4Ченuя. t)aw.мe'tY\~o€ HTML-!(оQа ,,1_ "-,,1_1,· о .J

oг.paН1t er=L .9~оU"-VIJV\Lt !(a~' ЧI(QМLt, t)роще

LtСt)ОЛЬ'з 0 €а'tY\Ь 0.9~нbt.e l(а€bt.ЧI(Lt .9л5!. oг.paН1t Че.н.u.5!. !(c:tЖ:90U t)ОЛКОu. С1Т\РОI<u.

HiML-!(°.9а .

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

что-то в РНР, не значит, что вы должны это делать. В данном случае

дополнительная сложность написания НТМL-кода - это проблема. Генерировать такое большое количество строк кода с использованием команды echo - в действительности не слишком удачный выбор ...

228

глава 4


реальные

u nракmuческuе nрuложеНUR

НеО6ХОАИМ простой ВХОА В РНР и ВЫХОА ИJ него Многие часто забывают, что РНР-сценарий

-

BPНP~puu БЫ можете

это просто НТМL-страница,

содержащая РНР-код. Любой код в РНР-сценарии, не заключенный между тегами

зaкpbmatnb

MOКU РНР-кogа

<?php и ?>, рассматривается как НТМL-код. Это означает, что при необходимости вы можете закрыть блок РНР-кода и написать блок кода на HTML, а затем

gлs вьmogа

вернуться к кодированию на РНР. Это является исключительно удобной техникой

qJp8ГMeнt1106

НГМL-кogа.

для вывода фрагмента НТМL-кода, который при выводе с использованием команды РНР

echo

получится слишком громоздким ... как наш код формы

азamем

«Отправить электронную почту~.

ot11Кpbmatnb

ux

51Ю6Ь.

ФОflAd 1(0.9 UЕуе"у!\ся I(ф(

<?php $from = 'elmer@makemeelvis.com'; $subject = $_POST['subject']; $text = $_POST['elvismail'];

н..ор.малЬкbtu. HTML-I(0.9,

"y!\QI( I(QK

Э"у!\о"у!\

1(0.9

еQСllоло.ж.ен.

~н.e PHP-"y!\ez.o€. if (empty($subject) && empty($text)) // мы знаем, что и тема электронного письма, и его содержание пусты echo 'Вы забыли ввести тему и содержание электронного письма.<Ьr />'; ~?> :-"'о!,!\

-

':-2,

7)

~:,~, pb&C\e'YТ\

: :. -? -l(oЭ Q • -:ж

~ :з g рС\щС\я -..::с Х HTML.

(empty($subject) echo 'Вы забыли

&&

тQI( KdK JON.:ft.. €ce еще €н..yvt\рu

(!empty($text))) (

ввести тему

электронного

письма.<Ьr

((!empty($subject)) && empty($text)) ( echo 'Вы забыли ввести содержание электронного (empty($subject) && empty($text)) { // Все отлично, отправляйте электронное

/>';

дЛОI«(.1 КОЭd

УIlРQ€Л5llOW,еu. Kokc"Y!\PYI(~U

if,

письма.<Ьr

письмо

/>'; НТМL-'коg дУ.9 е"У!\ €bt€oэu'УТ\Ь срорму, еслu 'УТ\олЬко bdQ 1l0Л5l срормь!. ОС'УТ\dн..yvt\с5l

н.е3Qllолн..ен.н.btМu..

тег. (?~p o"Y!\l(pbt€cte'YТ\ н..о€bt.u. PHP-дЛОI(.

Напишите, какие, по вашему мнению, имеются

Тс1к КС\К мbt. €ce

ограничения в этом коде. Как бы вы устранили их?

еще €н..yтeи. дЛОI(С\ K0.9 Q )'t)РQ€ЛЯ}OW,ей

if.

кон.С"У!\РУКЦ"Щ мbt. .90л.ж.н.bt .3Q I( рЬ!."fТ)b ег.о,

l1epe.9

"fТ)eM

~9"Y!\и. .9d.ЛЬше.

KQK выздесь ~

229


предотвращение повторения кода с помощью флаzа

МСПОЛЬJуйте флаг АЛЯ преАотвращения

п~я повторения КОАа

Проблема предыдущего кода заключается в том, что он должен выйти из РНР-интерпретатора и повторить НТМL-код по созданию формы в трех различных местах (по одному разу на каждый случай ввода недостоверных данных). Мы можем использовать переменную, принимающую значения

truel false,

как флаг (сигнал), чтобы отслеживать необходимость повторного вывода формы. Позднее в коде мы можем

проверить значение этой переменной и вывести форму повторно, если оно будет

true (флаг установлен) .

Поэтому мы должны начать выполнение сценария, установив значение f а 1 se для переменной

$output_form (сбросить флаг), и затем изменить это значение на true (установить флаг) в том случае, если какое-либо поле формы останется незаполненным nеР€ОН4ЧdЛbкое

и нам необходимо вывести форму для заполнения повторно.

€ €

l"Iере'мекн.оЙ $outt)t~c tr~н.u.e

~ JfЩЧеf-Ш5{ fo.Rse ~Н4Чо.е"Yrl, чmо

ИИИЦИОIIИЭОЦИ. переменной $output_form Фl~

значением false

€ ~узе"Yrl g-bt€oзU."YrIЬСя.,

ес J}e о~н.UI(н.е"Yrll"lродле'м с IipObepl(OU 3<1.н.н.bt.x н4 зос-mо€еркос"YrlЬ.

Еспи в поле формы «Тема» не содержится текста

Эvt!u. соодщен.uя. / и в поле формы «Содержание» не содержится текста од ошu.дl(о.х _ V .2.0rдA ~ти сообщение об ошибке, дуэY"Yr! сле~l(о. и воить значение true переменной $output_form

О"Yrlлu.Ч<I."YrIься. € Jo.€u.cu..мoc"Yrlu. 0"YrI "YrIo~o, 1(00I(ие

И В поле формы «Содержание» содержится текст

:л~.~оэо. ~orдAвывести сообщение об ошибке, .0 н.е!о.liолн.ен.н.bl.мu.. JY\VI.

~

Еспи в поле формы «Тема» не содержится текста

~

присвоить значение true переменнои $output_form (сли I(о.кu.е-лu.до

ОС"'lY\<l.Лu.с

~

1i0Ля. форМbt

Еспи в поле формы «Тема» содержится текст

И в поле формы «Содержание» не содержится текста ~TorдA вывести сообщение об ошибке, ;::;: ~

~

ОС"'lY\о.н.Y"Yr!ся.

н.еJо.liолн.е~ t)epeMeн.н.ou

~oЫ ut_f оr 1Т\

рисвоить значение true переменной $output_form дуэе~ lipu.c€oerw Jн.ачен.tlе $i:rue.

(слu. одо. I')оля.

Еспи в поле формы «Тема» содержится текст

€€оэо. фор.мbt ,3d.l')олн.еt-ibt,

элеК'lТ\рон.н.ое l')u.cbMO

/,

V

01Т\l')ро.€ля.е1Т\Ся.. / V

И в поле формы «Содержание» содержится текст

TorдA отправить электронное письмо

ко фор~

€bL€'ез ека

н.е dуэе"'lY\ ... lioKd'

у

Еспи значение переменной $outgut_form равно true TorдA вывести форму

\"--

Но. liослеэн.е,М Э"'lY\о.lje кон."YrIроля. ЗОС"YrIо€еркос"'IY\u. зо.н.н.btx

Iiро€еря.е"'lY\Ся. Jн.ачен.u.е $output_for"Yrl, '-fvr\odbt €bLЯ.сн.u."YrIЬ, н.ужн.о лu. €bt€оэu."'IY\Ь фОР''му эля. u.Сliро.€лен.u.я. €€0.90.. ~ л~о,м слуЧо.е Н4М н.еодхоэu..м HTft\L-l<oЗ эля. lio€"'IY\0PКOzo €bt€оэо. ФОрМbt. ко "'Iy\олы(o оэu.н. pCIJ. 230

zлава4


реальные

u nракmuческuе nрuложеНUR

Мспользуйте ПОВТОРНЫЙ код HTML-формы только ОДИН раз OnpegеЛ99

Создание нового кода проверки достоверности данных в РНР требует создания и инициализации новой переменной $output_form и затем изменения ее значения

З85UC'U.Мocmb

в зависимости от результатов контроля достоверности данных. Наиболее важным

5b15Oga НГМL-кogа

здесь является то, что форма выводится повторно (ДЛЯ исправления недостоверных

om

данных) только в том случае, если значение переменной $output_fonn равно true.

<pJ\8Г8.

уcmaнaмшае-мoro

Bynpaм9lOUJUX

к.oнcmpyк.lJ'U9К и. мы npeg0tn5ращае-м

n06mopeнueKoga

if (empty($subject) && empty($text))

//

мы

знаем,

что

и тема

s

{

электронного

письма,

и

его

содержание

наше-м cueнapuu

пусты

",; ;"ho 2 "; за ~~ilИ ввести тему и содержание электронного письма. <ЬЕ / >' ; t ii$б'1ilt;n:uеfQ~ ::=(\1tj';'\l~ ~ А.\ n. €ae.М rtepe.МeнrtDu. 31-{tj.чекuе ru.e, }

o,,~«« ~"<~о~ ~_*~,,t""~,~, ~;Д

есЛJ.

----i~~~~~6;,С~;,:~ОМ:f~~;€:?КD,

i f (empty($subject) && (!empty($text)))

е.эе

пР

~ u.CI"\()Q~u."Yf\b O~KJ I

{Ч'YI\ОJ1С"Yf\~ЪJМOЖКDС"Yf\

электронного письма.<Ьr

/>';

Т(\кже IlPu.c€(\U.€(\e.M Г)ереме.н.н.оЙ JНДЧе.н.u.е. if ((!empty($subject)) && empty($text))

echo

'Вы

забыли

ввести

}~~tif$~

содержание

true, еслu. "Yf\e.мct элек"УУ\ронно~о Ilu.cb.мct н-е €€e..g eнд .

электронного

письма.<Ьr

/>';

~ ~~ч~С~~/Je~~~%€~~€€~l:~еНJ-l.OЙ соэер,Ж(\кuе эле.К"Yf\рон.н.О20 l"\u.cbIЛд.

if ((!empty($subject)) && (!empty($text)))

//

Все отлично,

•~ ,.

~~ _ _'Iffi:!}_1'W ?>

{

электронное письмо

I

МЬ!. I"\OI(UН-~Лu. РНР-КО.9, ко €ce, "hт\o I"\pe.9~c"YY\~ye'!.'l фu.2~fН-ОЙ скодке. ~KP (\)ОЩе.u. ~г)Р(\~J1я.~)() KOKC"YY\PYKu,u.)() if. СЧu.)Тj(\е"уу\ся.

IЛ /,-I\AJ;UiА KOн.G"YY\pYKU,u.5l \JUQt:.\JЛс. (

o"YY\h-ося.щu.мся. к ее dЛО.!i:t ко.9(\.

v,., ~

э"уу\о mI'IL-к0.9

'~"" "'-'.'" НТМL-коэ ФОРМbt €€оэ(\ .9 ФtН-bIx "уу\олы(o 0.9u.K

P(\j, "YY\ctK KctK

мbt €мес"уу\tJ.Лu. €c)() ЛО2Щ(~ Оt)ре.9еля.~)()

ег.о Г)оя.€лен.u.е. € e.9u.h-с"УУ\f:енн,У)() Il е ремен.н.у)() .$Ou.tpuCfor"Yf\.

8ыздесь

231


данн",е форм", все еще пропадают

Но&ая <fюrма ЛflWе, tio Я nосmояtitiо ()олжw

&&o()umb 33tio&o ~ачwuя nолщ KomOrbIe Оылu ззnолtiwы nrа&uлbtiо

tiaК3tiytie. Эmо rа3<>raжaem.

НТМL сам по себе не может сохранить данные. Когда Элмер отправляет форму ~Отправка электронной почты~ на сервер с незаполненными полями,

sendemail . php перехватывает

ошибку и генерирует новую форму. Но она генерируется НТМL-кодом, который не имеет ни малейшего представления о значениях данных, введенных Элмером ранее. В результате как часть процесса проверки данных на достоверность Эл мер получает совершенно пустую форму, в которой отсутствуют данные, введенные им ранее.

Эmо соодщен.u.е од ощu.дке

Дaн.нbt.e. KO"Vl'\0Pbt.e Эме? ~~ел

.9de"Vl'\ Элмеру .3Н4"V1'\Ь. ЧYr\о

~ фОfМj H4Kdl-tjl-tе.

Ol-t ОС"Vl'\d6'u..л ЧdС"Vl'\Ь 110лей форМbt

~~~----------b~e.3a~~__

-1r,

I Отправить I Элмер СЛУЧdЙI-tQ

sendemc:iI-Pt1>

sendemciI.hlml

ОС"'II}d.€u..л J)Т}u. 110Ля. l1yC"'ll}bt.мu.. ЧYr\о

"VI'\el1epb l1 o'Yl\OMj J"VI'\O

со€еrщеl-tl-tо l-tQ6'dЯ ФОрм,

ФорМd. д~

l1 е реЭdН4 сu,еН4Р ЩО

sel1c:fe"Vl'\d.iR.php 110сле "VI'\ozo. Kd.1< Эмер Н4Ж<:lJ1 1<I-tQI11<У «:O)Т}I1Pd.€u."VI'\b:O.

Мы не можем уйти от того факта, что новая форма должна

генерироваться в РНР-сценарии. Но у нас должен быть способ запомнить данные, которые Элмер уже ввел накануне, и ввести их в новую форму,

чтобы Элмер сосредоточился на вводе данных только в те поля формы, которые он по ошибке оставил пустыми ...

232

глава

4

,


реальные и nракmuческuе nрuложеНUR

~MII ."8fioмamь Нарисуйте, как должна выглядеть форма Элмера после того, как он отправил ее на сервер, эаполнив только первое поле ввода данных.

Затем напишите, какие, по вашему мнению, должны быть внесены

иэменения в оба файла

(HTML

и РНР), чтобы обеспечить новую

функциональность.

IОтправить I

sendemcil.html

выэде,ь

2ЗЗ


заставьте вашу форму «помнить» свои данные

~ремя nорабоmаmь

Нарисуйте, как должна выглядеть форма Эл мера после того, как он

"

отправил ее на сервер, заполнив только первое поле ввода данных .

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

(HTML

и РНР) , чтобы обеспечить новую

функциональность.

СООдшрtuе

од ошuдке €ce ~r-----~--_ еще €bt€0.9U'Yl\c51.

~

._.г--__ ... н.о cu,eн.o.pua jc\110МНШI3Ф·UФtе

~o 110ле .9 d н.нblx СРорМЬ!. €ce еЩе н.е 3dI10лн.ен.о ...

J<o'Yl\0pbte Э"лмер €€ел н.о.Кdн.ун.е, u €СYr1d€UЛ

IОтправить I

sendeпкil.pt1)

. P.ttP:-:-~I,A,~~r-~iA.~~Р.~)I').~ .Cf~~~~~':I~ ... .... .... . .~.~~~р.1,tf.~~4~.ф.9r-~ .~9:% .~~ ... .... .... . .к~~ ..э9/. mc;t.~.~. !19.~Л~ .~IJ.~~~~. ф9.р.~....... .... ·~ . ~.~p.~~r-: л :Y.I'I~~..~~~. ·y~~~r·I,t·~· ~~~m ...... .. . ..э9.~m'f.\ .1:<. .~.~..э~~. ф9f.~" .~~'m~p.~ ... .~.~I,A; .~~:9~tФt: .~. ~~~/. ~I:t: .~9.~m .~~m4~1,A;1I}~ ... . ..r.ro~.~~..~. ~9Юr\~~m~m~~~~~ .I)~.!J~ ....... . .mС??Э4•. .!<.C??J).4..~~~ .1.'\p.~.9~)I')Y.~. ·1).C?~~~r·t:tP· · · · ····· ·?~~~p.I,A;p.~ml? .~rJ.'l~: .~~. p.f?~~:Y.I'I .......... .... . ·!1r·<?~~f?J.'I~}~~~/.!<'9m9f.~ :9~~.~ .. .... ..... ..

.~. ~.I:?!-. !1~mqp.t:W. ~<?.91,A;1I}~ .~~/.'j~ .. ... .. . .~~.9~.~..<?.9~~....... ........ .. ... ........ ..... ...

234

zлава4

lJ.X

€ срорму.

sendemciI.hlml

·P.93.~ . ~~Э~!!\ ·?~~r~p.~~'YI)k. ф.9f.~~ .... ...... ... . ·~!ЗЭ4.~~..1,t.~K.ffi9~1,A;1I}м.I?t:tP ............... .... .. .

.~..ч.~!1<?~3<?~~tЩ~. mf::-~I,A,~I:t:4р.~.... .. ... .. .. ..... . .'YI).С?~~~.I.'\9!.I!'!-9.У:Y.l'lI?,1:<? ~~~ч.:Y.I'II?У~... ... .. ..... .. .~.ф;\.~ . ~~.I)~~'!')ФR'М:Y.'IR .~ .I)р.~э.<?~'m~~ч.:Y.'II? .. ·~9~~~'YI)k. r.~.f ::~.I,A,f?t:t4p.I,A;1<? K~K ~~!З:9.ч.ml? . .ф.9р.~~.. m~~. ~. ~9~~m~ml;>..f?~.~~.. ... ... ·~ ·r·~3~!.1km4m~..fHP. 7.~~~~p~~..~f?~. :9~yт~ .. . .K9· ~~f?~~~· ~~.9f?·~ ·~·~r·~'j····· .. ·.. ·· ·~~~.'!'). ~~.I)~.!JI;>J~~4ml;>..~.~ .Y~9.~~. F:9~'m~•.... . .~~?:9. ~~9~~..э9.~m~~~ .~f.~эуm~~ ... .. .. .~~~"!')~~.9. Щ~k.~~э.~: ................. .................... .


реальные и nракmuческuе nрuложеНUR

Форма ввода данных,

которая ссылается на себя Как это возможно: удалить файл

sendemail . html

НГМL-qюpма вюgа из уравнения

формы ~Отправка электронной почты!>? Ответ заключается в том, что

gaННb1X. reнepupyeмast

в действительности мы не убираем никакого НТМL-кода, а просто передаем

PНP~pиeм.

его генерацию РНР-сценарию. Это возможно потому, что в конечном счете результатом интерпретации РНР-кода является НТМL-код

-

точно такой

же, какой содержится в HTML-фаЙлах.

кomорый к тому же

u

ОБраsaтывает ее

UЗ5eCtnНд. как qюpма. ССЫлaIOl ча9С9 на

Но.м долЬш.е

t-t.e

t-t.ужеt-t.

фduл sеlldе1Т\di~.~i:1Т\~.

Для. 1Т\0z.о '-hт\oдb!. IIОЛУЧLl.1Т\Ь

-ces9. -

~

.--~ ------,.--_.",.

форМУ €€ОЭd Эdн.н.btx,

\10}ib 3 0€G\1Т\ел)О Э ОС1Т\G\1Т\ОЧt{O

3dг..рузU.1Т\Ь PHP-сu,екдрu.Ui дG\н.н.Ь!.е ФорМbt t)ереэа-н.bL

I~ I

Пее.€окдчG\ЛЬн.о сu,екдрLl.u.

€~о.эLl.1Т\ <fюj>Му I оdРG\дG\1Т\bt.€С\ е1Т\ ЭG\н.н.bLе \10сле

LI.

1Т\ому же Сd.}Л.ому сu,екдрщо, KO"l'l\opbt.u u.x odpG\дct"l'l\bt.€ae"l'l\ LI. € СЛУЧG\е ощuдкu. €€0.9G\

\1ере.9 dЧU cpopМbt н.а cep€ep.

~ реJулЬ"l'l\G\"I'I\е odpC\do"l'l\KLl. CPop.мbt. ЛLl.до О"l'l\\iр'G\€ляе1Т\Ся.

€bt.€0.9L1."I'I\ форму €н.o€b н.о кд .7"1'1\0"1'1\ pctJ с .9C\~LI., KO"l'l\0pbt.e dbVJu. €н.eceн.bt. Il РС\€йЛЬн.о НДЦ С\н.yt-t.e.

sendemcil.php

~ .7леК"I'I\рон.н.ое \iLl.CbMO, ЛLl.dо €bL€о.эLl."I'I\СЯ соодщен.u.е

од ОЩLl.дке €MeC1Т\e с срормоа. эля u.cll ро.€лен.u.я. .7"УТ\IJJ( ощu.dок.

Для того чтобы понять, как все это работает, представьте себе, что происходит, когда Элмер первый раз загружает страницу (сценарий). Генерируется пустая форма в виде НТМL-кода и выводится в окне

браузера. Элмер заполняет' поля ввода данных и нажимает кнопку ~Отправить!>. Сценарий обрабатывает свою собственную форму и выводит сообщение об ошибке, если какие-либо поля ввода остались пустыми. Более важно то, что сценарий выводит форму вновь, но на этот раз она включает все данные,

которые Элмер ввел правильно. Можно создать форму, которая будет достаточно интеллектуальной, чтобы запомнить данные, которые были введены в нее в предыдущий раз. В англоязычной литературе такое свойство определяется словом

sticky,

которому нет аналогов в русском языке в этом контексте.

срормы1 мorym nOMНUть

gaHHble.

кomорые

nОАЬЗО5аmель 55еА

nра5UЛbно.

Что, по вашему мнению, может

улучшить приложение Элмера, чтобы его форма помнила данные, которые он ввел накануне?

выздесь ~

235


заставъте вашу форму ссылаться на себя

Передайте атри6уту

actlon

ИМЯ сценария

Как мы уже видели несколько раз, значение атрибута

<form> -

action тега

это имя РНР-сценария, который обрабатывает данные

формы. Присваивание имени сценария

sendemail . php атрибуту action работает отлично, позволяя ему обрабатывать свои данные, и это первый шаг на пути придания форме свойств запоминать

данные, введенные накануне. Фактически атрибут

action уже

Такой код будет работать при условии, что вы не будете переименовывать сценарий, забыв при этом

соответственно изменить значение атрибута action. Но существует более надежный метод, который будет работать независимо от подобных обстоятельств, так как он не полагается на имя конкретного сценария. Он основан на использовании встроенной в РНР суперглобальной переменной $_SERVER [ • РНР_SELF' ] , которая содержит имя текущего сценария. Вы можете заменить имя сценария, которое вы присваиваете атрибуту

act ion, на значение

переменной $_SERVER [ • РНР _SELF' ] и больше не беспокоиться по поводу

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

$_SERVER [ • РНР_SELF'] - это переменная РНР. Это означает, что вы должны использовать команду чтобы ее вывод интерпретировался как

HTML-, а

f

~Mec'YТ\O 'YТ\O~O "tn\Одbt ,Ж,е.С'УТ\КО ,3ctt'\ucbl.€d'YТ\b € KO~ u.МЯ. сu,еК4 u.Я., €b!. Мо,Ж,е.'УТ\е coodLU,u'YТ\b ему, Ч'У!\О bL

Он. ссbVldЛfя к4 сед Я, U~t'\ОлЬ3:tЯ ~1"ерг.лодd.Лbн.~)О t'\еремен.н.у)О $_SERVER[ РНР _S LF .

<forrn action= n <• •I~llrа,_jЧJmIL_1#,В1tОd= "post" >

Конечно, использование суперглобальной переменной $_SERVER [ • РНР _SELF' ] вместо имени сценария не является потрясающим достижением, но это один из многих приемов, которые позволяют делать ваши

сценарии более удобными в сопровождении.

СynергЛОБаЛЬН89 nереА\енна9

$J)E.I\VEl\rPНP_SELF1 COXp8.Нgem

UA\9

текущего cueнapU9.

236

zлава4

echo.

не РНР-код. Например:


реальные

u nракmuческuе nрuложеНUR

-Тест-драйв Про.ерьте но.... й, сс...nаIOЩИЙС. на

caMoro

се6. сценарий

с упучwенной nоrикой контроп. досто.ерности. Измените код сценария

sendemail . php,

используя переменную

$ ои t ри t_f orm для

избирательного вывода формы ввода данных, как показано несколькими страницами

ранее. Измените также значение атрибута action тега <form> так, чтобы форма ссылалась на себя. Вам больше не понадобится файл

sendemail. html, так что можете совершенно sendemail . php на ваш

спокойно его удалить. Загрузите новую версию сценария

веб-сервер и откройте сценарий в браузере. Как он выглядит?

НС\чк.ем с г.M€к.Oг.o. Бbtc"ll\ро

сэ емем €ce, Ч'tr\о к.еодхоэцмо, Ч'tr\Оdbt cu,eMPu.u. ,3dt)Омu.н.ал c€oи.

J

эак.нbtе. Напишите, почему, по вашему мнению, сценарий выводит

сообщенне об ошнбке вместе с пеРВ\>IМ выводом формы:

выздесь ~

237


nРО8ерка переменнои $_ POST['subтit']

Проверка: 6ыла ли форма отправлена на сервер Проблема в том , что сценарий не видит разницы в том, была форма выведена в результате первоначального вызова сценария или отправлена на сервер с неполными данными . Поэтому

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

Помните, что, когда форма передается серверу для обработки с использованием метода POST, ее данные сохраняются в массиве $_POST? Если форма не была отправлена на сервер после заполнения, то в массиве $_POST не будет никаких данных. Говоря другими словами, массив

$_POST не будет инициализирован . Догадываетесь, какую функцию нам необходимо вызвать, чтобы проверить, инициализирован ли массив $_POST?

СynерглОБаАЬН89 nеременназ

$J~SТ nOO6OJ\ge111 нам npoвepвmь. БЫМ ЛU qюpма

nepegaнa на сервер после Sнeceнug

gaHHblK

Так как на каждой форме есть кнопка, в результате нажатия которой форма передается на сервер для обработки,

то наиболее простой способ убедиться, что форма была передана на сервер, ли элемент массива

-

это проверка, инициализирован

$_POST для этой кнопки . В этом случае данные - это всего лишь ярлык, появляюшийся

на изображении кнопки в окне браузера, и сами по себе никакой ценности они не представляют. Для нас важно, инициализирован ли элемент массива

$_POST [ , submi t ' ] . Положительный ответ на этот вопрос означает,

что форма была передана на сервер, после того как она была выведена для заполнения. Убедитесь только, что значение

'submit' соответствует атрибуту name кнопки

«Отправить~ вашей формы.

Не Быае'th,

Ziif11bJX ~011YOCO~

'9; Как знание того, что форма была передана на сервер '9; Тогда почему бы нам не проверять на инициализацию после внесения данных, поможет нам воспрепятствовать

действительно важные данные вместо ярлыка кнопки

~BOДY сообщения об ошибке?

~править>>?

и; Причина, по которой сообщение об ошибке выводится

и; Было бы вполне приемлемым проверять

неправильно, закnючается в том, что сценарий не может

определить, была ли форма передана на сервер после внесения

инициализацию переменной $_POST [ 'subj ect ' ) или $_POST [ 'el vismail' ), но только для этой конкретной

данных или она выводится впервые. Поэтому нам необходим

формы . Так как практически каждая форма имеет кнопку,

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

нажатие которой отправляет ее на сервер для обработки,

раз, и в этом случае совершенно нормальным является тот

факт, что все поля пустые -

это никакая не ошибка. Мы должны

и, как правило, ее атрибуту пате присваивается значение

, submi t "

то проверка на инициализацию элемента массива

проверять данные на достоверность только в тех случаях, когда

$_POST [ , submi t ,] дает вам надежный способ определять,

форма передается на сервер после ее заполнения. Именно

что послужило причиной вывода формы, для всех сценариев.

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

238

zлава4


реальные

Счеяарutt S gетаЛ9}\

«OmnpaSKa

u nракmuческuе nрuложеНUR

электрояяоtt почты»

<?it~{$from f&'$~d~' 1З) ~ fj3~1~t1~~ltу']I-(qЕчен.u.е t}eoe""eн.нou = 'elmer@makemee l vi s.com'; '" СЛцср

$subj ect = $_POST [ 'subj ect ' ] ; $text = $_POST [' elvismail' ] ; $ output_ f orm = f а 1 se;

rtере.эc:tl-(q ~ серее €

I

Ор#4 н.е ~

1-(qЖ<:t'r!)UЯ 1<1-{011l(I;. Т(\.... р еЗ,'1J1b'r!)q'r!)е

t}eoe"el.lLt ... a н.е 01 ~ VJflhоq€ц'r!)Ь», :>..... " I ,.\ '~A I ~ .. ,ч (ge'r!) u.н.u.u,tActлUJцро€<Жd.

if (empty($subject) && empty($text)) {

//

мы

есЬо

знаем,

'Вы

что

и тема

электронного

письма,

и

его

содержание

пусты

забыли ввести тему и содержание электронного письма.<Ьr

/>';

$output_form = true;

if (empty($subject) && (!empty($text))) ( echo 'Вы забыли ввести тему электронного $output_form = true;

if «!empty($subject)) && empty($text)) есЬо

'Вы

забыли

ввести содержание

письма.<Ьr

/>';

(

электронного

письма.<Ьr

/>';

$output_form = true;

if (empty($subject) && empty($text)) ( // код для отправки электронного письма

Эmа фШ:tрКdЯ. CI(Odl(a JcU<pt:&e:m MP€j)O 1Iра€ля.~}О

l(он.С"YI\р:tI(ЩА.}О if, КO"IТ\орая. 1IF,€ля.е"Yl\ I)POu,eC.C.OM € 3d; ucu.мoC"Yl\u O"IТ\ "YI\o~o. dbt.nct JU фоg,о.<а O"IТ\Kp,bt"Yl\a эля ввоза ~КНbLX UJU I)epe~ t-Щ с.ербер эля OdpadO"lТ\KU I)ос.ле ~оэа ~.

Е~лu.d СРОр#4 н.е dbl.лq l)epe.9aн.a н.а cep€ep .9ля

if

:>

($output_form) {

о p~ O"IТ\l(и 110сле €в0.9 a .9aн.н.btx, НQМ Оl1ре.9 еле н.н.о н.eoox0.9 UМO ее

0"YI\l(pbt1l'\b.

<form method="post" action="<?php echo $SERVER['PHP_SELF']; ?>"> <label for="subject">TeMa электронного письма:</lаЬеl><Ьr /> <input id="subject" name="subject" type="text" sizе="ЗО" /><br /> <label fоr="еlvismаil">Содержание электронного письма:</lаЬеl><Ьr /> <textarea id="elvismail" name="elvismail" rows="8" cols="40" ></textarea><br / <input type="submit" name="Submit" vаluе="Отправить" /> </form> <?~hp

выздесь.

239


сдеЛQumе поля вашей фОРМ&I (заnомuнающuмu»)

Оmлuчно. Иmак, теперь мы можем опrе()елumь,

~

Koroa cporмa nepe()aemcs:l на cep&if' ОЛs:l nrO&epKU оанных, U&bl&ecmu пrа&uльное cooOw.eнue оООUJшfке. Но мы 0О cux nor не соелалu, чmоОы cцeнaruu 3сЗпомuнал уже &&е()енные значенus:I полей cpOrMbI, так &е()ь:? Это верно. Опредеnение, Дntl проверки, а

KorAa

KorAa

форма передаеТСtl на сервер

ВЫВОДИТСtl впервые Дntl запоnнениtl

ее попей, очень ва_но, но нам все еще необходимо найти метод, позвоntllOЩИЙ выводить однажды внесенные данные. Знание того, что форма передана на сервер для проверки данных, является

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

выводимой формы. Вы можете занести определенные значения в поля формы,

используя атрибут

value HTML-Tera <input>.

Например, этот код установит

значение поля ввода данных формы с использованием атрибута

value:

Эmо ,зМЧен.u.е .жес"\'l1КО Jr.:\К~U-J>0€r.:\Ноо. u он.о €ce2.9~ ~.Y.ge"\'l1 "\'I1Q1(UМ Ilpu- Кr.:\Ж:90Jv\ fГbtf5'O..ge cpopМbt. '+' •

<шрut

пате=" subj ect·

~ .

':И':,:;w><:::::"*":-:;::>.t:::::,~<N~'it , w.~~:<,

.'. ,

, .~.

.. -...

~

type=" text " ~»11l~~~~" fJ2Е1'lt?9~аж\t':! ';.>

Но мы не хотим жестко устанавливать определенное значение . Мы хотим ввести значение PHP-переменноЙ. Как это возможно? ВСlIомните, как в других ситуациях

Tr.:\K Kr.:\K

JoЛbt

t)ер,екл)Очu.лu-сЬ нct РНР. Ч'Yt)одbt.

мы использовали команду

echo для того, чтобы динамически генерировать HTML-KO/t

из РНР. В этом случае мы можем использовать команду echo для того, чтобы динамически присвоить значение РНР-переменной атрибуту val ие, как показано ниже:

fWecJ1Jt.i JIid 'fшше

~%~:":L eVjo.<input name="subject" КОIМ.КЭbt.

0Л ,Ж..t-\.bt. "\'I10..9 U-СIlОЛЬ.30€d"\'l1Ь "\'I1ec.

?f*'r.

"\'I1U-l)diехtdrеdJoЛbt

type="text"

с ~ _~~7~;:~:0;;;'0

J

val ~<?pJ:ip' eci!,l9i"",~s~~ctt ,, ?>"?,

..~

А ..9ля. €ОJ€раЩен.u.я. МJa.9 к HTML-K0..9~ МЬ!. JdKpbt.€deM РНР -к 0..9 с t)омощЬ)О "\'I1e2d . >.

<

Для. 1l0Ля. €€o..9o.

3Н4 УеJШе IJrе...цеliJ(Ос/

Форма Эл мера может быть модифицирована аналогичным способом ДЛЯ

использования всех преимуществ такого запоминания данных.

<form method="post" action="<?php echo $SERVERf'PHP_SELF']; ?>" > н.е U-Сt")ОЛЬJуе.м QYr)fu-dJY'1 <label for="subject ">Тема электронного письма:</lаЬеl><Ьг 1> yC\~иe, Q €bt€оэUМ ~ """ o:;~nput i ? = :', s~t;.;j:ct" паmе=" sy,~j ect" type=" text" size=" 3 О" Jмчен.u-е ll e peJv\eНoou iYй~uе"'''<?lJ]; e,gho эuЬj.ес ti ?>:4 /><br /> ~iexi .меЖ:9.У "\'I1e2dМu<label for= "elvismail" >Содержание электронного письма: </ <texiC\rer.:\ > label><br /> u- </iextdreC\>. < еа id=" elvismail" name="elvismail" rows="8" cols="40" > ~ Р ерцо ~ ext ; ?;k /textarea><br /> <input type="submit" паmе="SllЬmit" vаluе="Отправить" /> </form> #

240

zлава4


реальные

u nрактuческuе nрuложеНUR

' -Тест-драйв Проверые, наскоnько данные, однажды введенные Эnмером, эапоминаЮТСII на самом дenе.

Измените код сценария sendemail . php, используя переменную $_POST, чтобы проверить, была ли форма передана на сервер после внесения данных или она выводится впервые. добавьте также код, для того чтобы значения полей, уже введенных однажды, запоминались и помещались на свои места. Загрузите новую версию сценария

sendemail . php на ваш

веб-сервер и откройте сценарий в браузере. Поэкспериментируйте с разными значениями полей, в том числе попробуйте оставить одно или оба поля пустыми, и отправьте их на сервер несколько раз.

kx,как глупо с моей cmopoHbI оыло ocmaBumb соuер>канuе nUCbMa nycmbIM, К счасmы{), Bnpwb я эmоГо

Оолы.1Jе не uOnYlJ..\y,maK как моя о/орма menepb 3Haem сВое uело. Я mаК>Ке не uоЛ>Кен BBouumb )ЭноВо uанные, KomopbIe Я OuuH раз уже ВВел праВильно,

CO~)

Cu,eн.apuu «01l\\jPd€Kd элеюТ\рокн.оU \jоЧ'1Т\bt» 1I\eMpb €bL€OjU"'lТ\ сооdщекu.е од ou.tudl<e, есЛU

Элмер OC"'lТ\d~U1l\ Kdkoe-лudО \,,\оле tyjC"'lТ\bI.М. I-lО Ol-l \joMt-Ш.1I\ 3t-W.чен,uЯ Эdн.н.bu<, €€'e.g e н.н.bu< IIрd€uлы-lo.

выздесь

241


KoziJa удачные удаленuя становятся неудачнымu

Некоторые покупатеJlИ все еще сердятся Про верка данных на достоверность прошла большой путь, чтобы удовлетворять претензии

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

о котором мы говорили ранее в этой главе?

От: Элберт !<рмсли<еlьеrt@kresteesprockеts.Ьiz> Тема:Сnaм7

Дата: 24 октября 2008 (. 12:23:33 РМ CD~ Кому: Элмер Пристли elmer@makemeeIVl5.com

7nt 0 "Yl\ 1l 0 l(УIlQ"YI\елЬ

Элuep!

'h!to он. 1')0ЛУЧQе"Yl\

Прекрати пажалуйстз рассылать cnaм. Я не ПPCm1В 1'01"0. чroбы ПOJ1YЧaтb

от тебя сОобщения о р'аспрое.ажах. но не nocыnaй ~~ oднoro"'ICI@~ зneктронноro письма кaждbIИ раз. KOIJ\II yы XCЮ!t1I>

""""""'.u мне о 1'"

Твой вeptiЫЙ. но раздраженныМ ~ Элберт.

н.е.9 0€олен, 1l 0"Yl\0МY

0.9н.o€peMeн.н.o 1')0

н.есI(олы{o

O.9н.o~o

I(OI')Uu.

U "YI\O~O

Же элеl{"YI\РОн.н.о~о

l')ucbМQ Элме~.

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

В чем проблема, нужно просто использовать страницу/сценарий .Удаление электронного адреса., которые мы с вами рассматривали в предыдущей главе, так?

К сожалению, все не так просто. Удалив Элберта с использованием его адреса электронной почты, мы удалим все записи с таким адресом электронной почты из таблицы email_list. В результате он больше не получит ни одного электронного письма от Элмера. Нам необходим способ, позволяющий удалять ЛИUDIие записи с адресом электронной почты Элберта, обязательно оставляя при этом одну.

npu UСIlОЛЬ.3 0€Ф\.U.U C"II'\PQн.uu,bt а:У.9QЛен.uе элеК"lТ\РОкн.оz.о ~peCQ»,

KO"ll'\0py)O #J.1t РQССМd"ll'\РU€QЛU мakG:M~EL.V;$.coм € tч~е.9bt:9уw,еu. z.M€e, Ввeдln8wec nrтpoмнoii_дnя ___ и.3 dQ,3bt. ЭФI.н.Ьt,х ЭлмеРQ ~ _ _ noчтw: дУЭY"YII УЭQЛен.bl. €ce .3<:\IlUCU~ i ~.biz С YKQ,3Qкн.bLМ ~peCOM J (~ элек"YI\РОкн.оu. I')o'h!tbt., Q Э"ll'\О co€ceM н.е "11'\0. К Чему #J.1t

C1nrе~Я.

~,.r.:~~~ Как Элмер сможет удалить все, кроме одной, записи таблицы, которые имеют одинаковые адреса электронной почты?

242

глава

4


реальные

u nракmuческuе nрuложеНUR

r

м. ..11rоелема ;,аключaemся &том, чmо &mМЛuце uмиmся несколько ;,аnUСЩ но не cYU.\ecm&yem нuкэкоrо сnосоеа

оmлuчumь и)( ()j?Yf от ()j?Yfa. Не uмея сnосоо'а &ы()елumь кажQyю из ни)( о

uн()u&uQyально, &rе.3ульmаmе люооrо ;,аnrосэ 'p~~ oyQym уuалwы оиu &се.

--~

Джо: Может быть, наша форма ~Добавление адреса электронной почты. должна проверять, не существует ли уже в таблице запись с таким адресом электронной почты, перед тем как добавлять запись с данными на нового покупателя? Это бы решило проблему, не так ли? Фрэнк: Великолепная идея.

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

last_name?

Джип: Я думала об этом, но использование фамилии потенциально даже хуже, чем использование адреса электронной почты. Что произойдет, если мы захотим

удалить из нашего листа рассылки кого-нибудь с именем Джон Смит и сделаем такой SQL-запрос:

DELETE FROM email_list

WНERE

last_name

= . СМИТ'

Джо: Мы удалим из нашей таблицы записи не только Джона Смита, но и Уилла Смита, Мэгги Смит, Эмми Смит... Фрэнк: Ох, я не вижу в этом ничего хорошего. Записи с одинаковыми фамилиями встречаются чаще, чем с одинаковыми адресами электронной почты, а с одинаковыми именами - и того чаще. Мы можем потерять десятки и десятки записей в результате выполнения всего лишь одного запроса.

Джип: Точно. Мы не можем рисковать, используя ограничивающее условие WНERE, приводящее к тому,

что в результате выполнения запроса будут удалены записи, которые должны быть сохранены. Мы должны быть уверены в том, что точно указываем на ту единственную запись, которую намерены удалить.

Джо: Так как же нам, черт возьми, быть? Мы не можем использовать ни

email,

ни

last_name,

ни

first_name

в ограничивающем условии WНERE .

Фрэнк: У нас нет возможности использовать колонки нашей таблицы. Похоже, что у нас вообще нет никаких шансов .

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

не означает, что мы не можем добавить такую колонку.

Джо: Добавить новую колонку? Так ведь мы уже решили все вопросы, связанные со структурой таблицы .

Фрэнк: Так-то оно так. Да только то, что у нас получилось, не отвечает нашим запросам . Конечно, ты прав, было бы значительно лучше, если бы мы подумали об этом в самом начале и соответственно построили структуру нашей таблицы, но еще не поздно исправить ситуацию. Джо: Хорошо, но как мы назовем нашу новую колонку? И какие данные будем в нее помещать? Джип: Раз ее функция будет заключаться в уникальной идентификации каждой записи в таблице, мы могли бы назвать ее identifier (идентификатор) , или просто i d для краткости. Фрэнк: Отлично, и мы можем заполнить колонку id различными числами, уникальными для каждой записи. А когда возникнет необходимость в удалении какой-либо записи, мы сможем составить запрос DELETE, основанный на значении этой колонки, а не на адресе электронной почты или фамилии .

Джо: Точно. Это действительно отличная идея, не так ли?

8ыздесь ~

243


добавление nервuчного ключа к таблице

3аписи та6лицы ДОЛЖНЫ уникально идеНТИфицироваться Идея сохранения данных в базе заключается в том, что позднее вам может по надобиться извлечь их оттуда

для просмотра и/или дальнейшего преобразования . С учетом этого становится очевидным, насколько важно то, чтобы каждая запись в таблице могла быть уникально идентифицирована. Это дает вам возможность получить доступ к одной конкретной записи (и только к ней!). Таблица Эл мера

emai 1_1 i s t

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

величинами. Это предположение подтверждается до тех пор, пока никто ошибочно не подпишется на лист

рассылки во второй раз. Но когда кто-нибудь сделает это (а это произойдет обязательно!), его адрес электронной почты будет сохранен в таблице дважды ... И на этом вся уникальность заканчивается!

'lто та6J1Ица 3J1мера СОАержит сейчас: fir$f':'ц(iщ. '" )

~

@ ,

);

last':l)ome

emai :

Денни

Баблтон

denny@mightygumba".net

Ирма

Верлиц

iwer€aliensabdudedme.com

Элберт Ирма

Крисли ~ Крисли

НесколЬ КО чело€ек мог:jYf\ u.мe1Т\b

oэU.Мко€btе u.МeM, t)ОЭ1Т\ОМУ Э1Т\о. колон.кd н.е може1Т\ сЧu.1Т\d1Т\Ьс5l

УЭdЧн.Ь!.М €btд0POM эЛ5l одес"еЧен.u.5l yн.u.K QЛbн.ос1Т\ (А.

и хо1Т\я.

~ € долЬшu.н.С1Т\gе ~ СЛУЧd,еg о.эресо.

elbert@kresleesprockets.biz

\

elbert@kresleesprockets.biz

элек"VflрОн.rwu. t)оЧ1Т\bt

\

н.е t)О~1Т\ор5l)QYr\С5l,

То Же самое зэесЬ: фdМu.лu.5l 1Т\ф<ж,е к.е одеСt)еЧu.€i'dе1Т\ ун.u.калЬн.ос1Т\lA..

мbt н.е можеМ

ро.ссчu.1Т\bt€о.1Т\Ь, Ч1Т\о 1Т\о.к дуэе1Т\ gcez-,9o..

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

Сервер баз данных

MySQL предоставляет вам

возможность создать колонку, содержащую целые числа,

уникальные для каждой записи. Такая колонка также из вестна под названием «первичный КЛЮЧ1> .

'lто АОJlжиа СОАержать та6J1Ица 3J1мера:

~

I /" i~' '\·

\

firscnome

!ascnome

email

Денни

Баблтон

denny@mightygun1ball.net

2

Ирма

Верлиц

iwer@aliensabductedme.com

3

Элберт

Криспи

elbert@kresleesprocket5.biz

4

Ирма

Крисли

elbert@kresleesprockets.biz

Дуdлu.ру}ОШ,u.еС5lЭ dнн.bt.е

е ЭРУ2-Ш< КОЛон.ко.х

доЛЬше н.е OI(d,зbt€i'd}O)1J

~

'\. тet)epb, КО2-Эd Э1Т\d колон.кd соэерЖlA1Т\

ун.u.кQЛbк.btе Jмчен.u.я., мbt можеМ dbt"lТ\b

y€epeк.bt, Ч"IТ\О Кd~dя. .3d"u.cb € мшеu "IТ\dдлu.u,е

э еUС1Т\€u.1Т\елЬн.о ун.u.калЬМ.

244

глава

4

'"

еЛu.5lн.u.5l н.а ун.u.Кd.ЛЬк.ос'Vl1Ь

3d"u.ceU, "О1Т\ОМУ 'hr\o

ее оdеСl)еЧu.еdе'Vl1 н.оеая колон.кd

iJ.


реальные и nракmuческuе nрuложенuя

Эй, reHuu!lbl же ;,tIaewb, чmо еслu мы xomUM ~Hecmu uзмененuя ~ cml?)'Кmyl'Y mаалuцы, то UОЛЖНы уuалumь ее с помощью ззnроса 'DЮf' lA'(;L-e UnomOM &occ0:?Uamb с нуля. Ьанные с ёЮресамu зла-;mрOl1НОй nочmы Элмера uсnаряmся!

Эro верно: в резу"ьтате ВЫПOllнени. 3Clпроса данные будут yтeptlHbl. Но в

SQL

DROP TAВLE

все

ecrь дрyroй 3Clпрос, С помощыо

котороro вы можете внecrи иэменени. в cyщecrвyющую структуру

та6nицы 6ез каКОЙ-lIи60 потери данных. Этот запрос начинается с ключевых слов ALTER TAВLE (изменить таблицу), и мы можем использовать его, чтобы создать новую колонку без предварительного удаления таблицы и потери данных . Ниже ноказано, как выглядит общий формат запроса ALTER TABLE, испuльзуемuго для добавлеllИЯ новой колонки :

ИМ5t "YI\о.длuu,bl., C"YI\PjK"YI\jP<:\ имя I(ОЛОt-U<U" / ' I(O"Yl\0POil эоJl.Ж,Н4 дbL"YI\Ь / ' l(o-mор<:\я'~ОЛЖн.а

~

lЛУ"ек.ен.а.

TAВLE имя_таблицы

ALTER

~

ADD

дbt-mо .9 0 &:t€леНd..

имя колонхи тип колонки

тU,I") .9o.~ M€Oи колоt-U<U,J

Мы можем использовать запрос ALTER TABLE для того, чтобы добавить новую КОЛОIIКУ С имеllем id в таблицу email_list. Мы определим INT как тип данных для колонки id, так как целые числа очень легко использовать для поддержки уникальности. Кроме этого, R заllросе необходимо указать некоторую информацию, которая по казана ниже :

ИМ5\. -mо.dлu.u,bt.

~o Zoо€орU,-m Myso.L :fеЛUЧu'€о.-m Ь JНd.Чек.u.е,

c"Yr1P)'I(-mуРу

Мь.. XOI'I'\UМ эодct€u.-mЬ н.o€Y)O coxp<:\Н5teM~e € .9<:!.н.нои. I(олоt-U<е, нd. ~9U.к.u.U,Y

I(o-m0pou. мЬ.. xo'tr\l,.V'.,\ ~ КОЛОК.I(у с u.MeKeM id. lJ.,}mek.u.-mЬ. ~ ~

ALTER

TAВLE

email_list ADD id •

ADD PRIМARY КЕУ ( ~d)

. _ Н едолЬw.оu фрctг.мек."YI\ коЗct,

J

4.... J

эля. КctЖ:90U .3o.tju.cu., I(Ог.эct он.а .90dctg'лЯ,е-mся к -mctдлu.u,е. ~

INТ

l'

NOT NULL

~::JSQ..l, Ч"II\о н.о€а.я. колоКJ<Ь эоJPY..нD. dbt"fТ\b

ЛОН-l(u. г.о орlЛ~

1(

l1ep€ou. 1'\0

" ../

11 0 РSl.Э К)' € C"YI)pYK"YI)ype "fТ\ctдлulфl.. 7vY10

€ f..teu dY.9j)1) К,еО6Я,Jd'Yl\еЛЬНDе условuе. НD ХОРОЩШl С'YI\uлb

COXEC\k.5(-m Ьс Я, u,еЛbtе

у запроса ALTER

FIRST,

к'mоче€ое сло€о FlRST (l1ep€bt.O.) СООдЩctе"fТ\

~IO-m "\'Т)u.tj ~ctн.нbtx

о 'У\10м, Ч"tт\о

AUTO_INCREМENТ

ЧU,СJk:\.

I1рог.РQММU.роео.кu.я. t1реэt\ОЛctzctе'Vfl p<\3MeLЦeНJ.A.e колоКJ<U uэен."YI)UфuКd."fТ\ОРct l'\ep€Ou. \,0 1'10Ря.эку.

TABLE длинное продолжение

потому, что должен быть создан первичный

ключ с достаточно специфическими свойствами . Например, ключевые слова NOT NULL

~d()dUJ,ct'}OW,u.il

(не пусто) сообщают MySQL, что в новой колонке id обязательно должны быть данные-

i~j so.L о 'Y!\0i-",. t.hт\o

вы не сможете оставить ее пустой . Следующее ключевое слово AUTO_INCREMENT (автоматическое приращение) описывает особенность колонки id, заключающуюся в том, что в нее автоматически будет добавляться уникальное значение при создании каждой нuвой записи. Как следует из смысла этого ключевого слова, при добавлении в таблицу v 6 М SQL б .d

rШ€ctя' колоt-U<ct я€лЯ,е"Yl\Ся' , " Ч "-.м tjepf.)l.A. \Ц;I\

I

к л)Очом.

Б л

о ее '\ '\ \j~9~ooKO 00 ЭYr\ом, ~JК~ctлЬн.о череj

се кук.эу!

новои записи сервер v

U

аз данных

у

автоматически при авляет единицу к значению •

послед неи введен нои записи и сохраняет это значение в колонке 1

d

б

1

U

до авляемои записи.

И наконец, ключевые слова АОО PRlМARY КЕУ (добавить первичный ключ) говорят серверу баз данных MySQJ_ о том, что значения колонки id являются уникальными.

Вllрочем , только уникальностью данных не исчерпывается все понятие первичного ключа ... выздесь

245


все о первuчных ключах

Первичные ключи 06еспечивают уникальность Первичный ключ - это колонка в таблице, которая уникально определяет каждую запись таблицы. В отличие от обычных колонок, которые также могут иметь ограничения на содержание уникальных значений, только одна колонка

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

Пер1шчньri1 КЛЮЧ -

конкретной записи.

это колонка

Для обеспечения такой уникальности первичных ключей MySQL налагает ряд ограничений на колонку, которая объявляется как первичный

s вашей tna5AU\je,

ключ. Вы можете рассматривать эти ограничения как правила, которым

кom0ра9 geмem кажnvan за.nuсь ~;,,;;;.

8I!!,...-

необходимо следовать, когда вы имеете дело с первичными ключами.

y':!!!!s;aAbнoil

Пять правил, касающихся первичиых ключей:

Данные в первичных КnlOчах не должны повторяться. Две разные записи не должны иметь одного и того же значения первичного ключа. Никаких исключений в этом правиле не допускается . Первичный ключ в данной

таблице всегда должен иметь уникальное значение.

Первичные КnlOчи не MOryт быть пустыми (иметь значение

NULL).

Если первичный ключ будет оставлен пустым (NULL), то он может оказаться неуникальным, так как другая запись потенциально может тоже иметь пустое значение

первичного ключа. Всегда присваивайте уникальное значение первичному ключу.

Первичным КnlOчам должно быть присвоено значение при добавnении новой записи. Если бы вы могли добавить запись без первичного ключа, то подверглись бы риску получить запись со значением первичного ключа

NULL,

что, в свою очередь, могло

бы привести к нарушению принципа уникальности первичного ключа.

Первичные КnlOчи должны быть максимально эффективными. Первичный ключ должен содержать ровно столько информации, сколько необходимо для поддержания его уникальности, и не больше. Вот почему целые числа

-

хорошие

кандидаты на роль первичных ключей. Они позволяют очень эффективно обеспечивать

уникальность, не требуя большого количества компьютерных ресурсов.

Значения первичноrо КnlOча не MOryт быть изменены. Если бы вы имели возможность менять значение первичного ключа, то рисковали бы присвоить ему по ошибке значение, которое уже используется для другой записи .

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

КОЛОКJ<(\ id € 'YI\c:lдЛLtU,е Элме~ Н.е со.эер)/Ш.'YI\ I')О€'YI\оря.)(XJJ,ш<ся. .9C\нн.bt.x, ЦМее11\ .3l-lQl.{ен.uе.эля ;;,. Кd.Ж:90Й 'зс\I')LAСU, (ЛI)U, 31-lQЧеl-l.U.5!. ) YC11\c:lI-lQ€лu.gq)(JV!) ся. ct€'YI\OJ.'l411\LA.ЧеClЩ

KOг.~ к.о€c:lя. .3с.1l')цсЬ .эодd.€ля.е11\С5!. € 11\d.длu.~у), к oMt')ctK'Yl\I-lQ

LA. н.е LA.,JМен.я.е11\Ся.. Велщолеt)к.о!

246

глава

4

1#.

id

1i1'$t_lШme

fc5t_lШmе

emaii

1

Денни

Ба6nтон

denny@mightygumball.net

2

Ирма

8ерnиц

iwer@aliensabdudedme.cam

...

"


реальные и nракmuческuе nрuложенuя

-Тест-драй в Измените таблицу Элмера и попробуйте добавить новую запись с первичным ключом.

Используя инструментальную программу, такую как

MySQL-терминал, или вкладку SQL-программы

phpMyAdmin,

введите запрос ALTER TABLE, чтобы добавить колонку с именем id, которую объявите первичным ключом:

ALTER TABLE email list ADD id INT NOT NULL AUTO_INCREMENT FIRST, ADD

PRlМARY

КЕУ

(id)

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

запроса INSERT (обратите внимание на то, что первичный ключ в запросе не упоминается):

INSERT INTO email_list VALUES

('Дон',

(first_паmе,

'Дрэппер',

lаst_паmе,

email)

'drарреr@stеrliпg-соореr.соm')

И, наконец, отправьте на сервер запрос SELECT, чтобы увидеть

содержимое таблицы и наблюдать новый первичный ключ во всей его красе! На всякий случай, если вы забыли, вот запрос SELECT:

SELECT * FROM email list

НО~Я, КОЛОНКd. id Я€Ля'е'lТ)Ся'

d.€'IТ)ОЦНКfемеК'IТ)КD_~Й~'~~~~~~~~~ ______________~:::::::::::::::::::::::8 t')03'Yr)OMy ока r-:

ОС'IТ)dе'lТ)СЯ

YНUl<cVЬКDй эЛЯ

КО€ОЙ Jc\t)ЦСu..

выздесь

247


раиоеор в тесном кругу

XOFUJo.l€fItf?b кaжi)ая 3311ОСЬ rnaOЛUЦbl uмшn унuкaлt>НblU l1ер&UЧНblU ключ.

t<aK ~mo нам 110МОжem? 3лмер &Се fU.\e уuаляem, осно&Ь!&аясь на aUrea ~лекmrюнноu noчmbl.

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

электронной почты .

Фрэнк: Правильноl Поэтому нам необходимо изменить форму так, чтобы пользователь вводил идентификатор покупателя вместо его адреса

электронной почты. И все проблемы решены!

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

о структуре базы данных. Может быть, нам нужно пересмотреть форму так, чтобы на ней перечислялись имена и адреса

электронной почты вместе

с кнопками снезависимой фиксацией напротив каждой записи? Вот здесь я сделала для

вас небольшую схему.

311.с:1Ченце I<н.o11l<u.

с н.еj<:tfS'u.сu.мой

фu.l<с"u,uеЙ дУ.9 е..,."

Соо..,."н.осu...,."Ься. СО JI1.c:IЧенцем

u..9 е н...,."u.фu.к"..,."ор".

Фрэнк: Хороший эскиз, только как все это поможет Элмеру указать запись покупателя, которого он хочет удалить, используя его идентификатор?

Джо: Гм ... А что если мы используем идентификатор покупателя в качестве значения кнопкн с независимой фиксацией? В этом случае он не будет виден, но сценарий станет иметь к нему доступ. Джип: Отличная идея. Тогда мы могли бы генерировать форму автоматически, в цикле, используя результаты запроса

SELECT, чтобы получить все данные,

и создавая для каждой записи кнопку

с независимой фиксацией.

Джо: Orлично. Но что будет происходить при нажатии кнопки .Отправить.? Какие значения примут элементы массива

$_POST?

Фрэнк: Подожди, Джо, мы узнаем все это через минуту. давайте начнем с того, что создадим ту часть

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

248

слава

4


реальные u nракmuческuе nрuложеНUR

Магниты РНР и MySQL Используйте магниты, изображенные ниже, чтобы закончить код для сценария «Удаление

электронной почты», который должен представить перечень покупателей из базы данных

Элмера вместе с кнопками с независимой фиксацией. Имейте в виду, что этот код должен только

создавать форму. Не думайте пока о коде, КОторый отвечает за непосредственное удаление

записей из таблицы.

. h -"350" alt="" style="float:right" 1> <: rng src="blankface.jpg " widt~="161" .h:l g . t;h="229" height="32 " border="O" аlt='сделайте <;rng narne="elvislogo" src="elVlslogo.glf Wl~ вы хотите удалить из листа

<;>выберите , пожалуйста , адреса электроннои почты, которые ;:

нажмите

кнопку

«Удалить».

меня Элвисом"

/>

рассылки,

</р>

< forrn rnethod="post" action=" ..... . . . .... ... .. .

........ .. .. ">

<? php $dbc = rnySQli_connect('data . rnakerneelvis . com' " , ~ 1 rnе r' or diе('Ошибка соединения с MySQL-сервером . ), // Ввод записей покупателей . вме~те"с кнопками $query = "SELECT * FROM ernall_llst ; $result = rnysqli_query($dbc , $query);

с

'theking',

'elvis_store')

независимой фиксацией .

while ( .... .. . . ... ...... . = rnysqli_fetch_array($result)) echo ' <input type="checkbox" value=",

. . . . .. ..... . . . .................... ...... . .. . .. ... ... .

naтe="todelete(J"

/> ';

echo .... .... .. ..... . . . . . ........ . ............... ... . .. .. . . . . .... ... . echo echo • echo ' <br / > • ;

rnysqli_close($dbc) ; ?> <input type="subrnit"

пате="

"

vаluе="Удалить'

/>

</ form>

> . ~ ..•..•...... ....•.•.•.. ........ . /

выздесь ~

249


РНР &MYSQL магниты решение

MarHumbl РНР u MySQL Используйте магниты, изображенные ниже, чтобы закончить код для сценария «Удаление электронной почты», который должен представить перечень покупателей И3 базы данных Эл мера вместе с кнопками с независимой фиксацией . Имейте в виду, что этот код должен только

создавать форму. Не думайте пока о коде, который отвечает за непосредственное удаление записей И3 таблицы.

, h -"350" alt="' style='float:right" /> /> <img src="blankface,jpg" widt,h="161' ,b:~9~-b="229" height='32" border="O" аlt=nСделайте меня элвисом n <img name= "elvislogo " src=·elv~slogo.g~f w~ _t е вы хотите удалить из листа рассылки <р>Выберите, пожалуйста, адреса электрОННОИ почты, которы и нажмите кнопку «удалить». </ ~ р_ > ______~ ,

_.

<form method="post" act~on- ,

есЬо $ SER~R [ , РНР _SELF ' ] ; - ~

< ?php

Г-;:-\ " > •• _

j4КЛ)ОЧен. МеЖS~

Форм ссbtJ1c!.е1У\Ся' н4 седя'.

<?~~c

= mysqli_connect('data.makemeelvis,com'"

kll1poeннbtu РНР-КО,Э

'~ .9 0ЛЖ-ен. d!:'I;'II}b

,1У\ег.QМи. <?f*1p и. (>,

, 'theking',

' ~lmer'

'elv~s_store )

or diе('Ошибка соединения с MySQL-сервером. ),

// Ввод записей покупателеЙ,вместе.с кнопками с $query = "SELECT * FROM emall_l~st ; $result = mysqli_query($dbC, $query); while ( есЬо

независимой фиксацией,

Г$li3ro,w) = mysqli_fetch_array ($r;..:e::s.:u....l~t:). . ): '-':",,--r--r-"1r---\

".

" name="todelete[]' />';

~~~~~~*~~~~Г:-t-.-I"'-""'''.~~~. ' '~:тtnо мес1У\О, ~эе 3н.с\Чен.u5i. firBt_name t}

\iер~и.чКD~О КЛ)ОЧd.

есЬо

,.;

,~".~~1-~~~~r:-1~r·' ~

есЬо есЬо

есЬо

'<br /> ' ;

KКD\iКd.М с н.е3d€и.сu.моu

cpu.KCd.UjJ-еU, :тtnи.

СО",Эd.е1У\СЯ KКDI'1Kd.

3н.с\ЧенuЯ,

cpu.КСdu,и.еU,

f'IObt.

СМожем

и.С\i ОЛЬ3 0 €d.1У\Ь ,ЭdЛее,

КО~,Эd. д~,Эем ~,ЭdЛя'1У\Ь

3d.t1и.cu. \')ОКУ\id1У\елеu,

?> <input type=nsubmit n

\iри.с€оен.u.я. 3н.с\чен.шl

'"'" ДлЯ, Kd.:>!<SOU j41'1и.си.

С н.е3d.€и.сu.моU

mysqli_close($dbc);

и.сt10ЛЬ3~)О1У\Ся' эля

пате="

.I

*"

l Bubmit МЫХд

n

vаluе=nудалить'

/>

01'1 ре,ЭелЯ,еМbt.е 3н.с\ ЧеНJ.J.Я.Мu..

Э1У\u.ми. ;

•.

</form>

~ МОЖ-е1У\е ,Э<l1У\Ь Э1У\ОU KКDI)Ke ЛJQdое u.мя.. ~~~

Не .}:1дЬ\Й<lU"ll}е "II}оЛЬко, Ч'tr\о он.о ,Эол)j(,КD cOO"ll}€e"ll}c"II}€o€<I"II}b и..эен."II}и.фu.Кd."II}oр,у элемен."II}d. MCcu.€d.~. POSТ если. €b!. реШU"ll}е I)РО€~РЯ"ll}Ь I)ОJЗн.ее, dbtJJct ли. q:юрм O"II}hp<t€'ленд нд cep€ep

,Эля I1po€epкu. ,Эdннbtx u.ли. €tЯ€о,Эи.1У\Ся'

ЭЛЯ l)е.р€ондчdЛbКD~О u.x .}:1н.есенuя.,

250

zла8а4

,•,


реальные и nрактuческuе nрuложенuя

от кнопок с нuависимой фиксацией к ИАеНТИфинаторам понупатeneй Код, который генерирует кнопку с независимой фиксацией в сценарии

почты~,

-

• Удалить адрес электронной

это почти обычный НТМL-код. При этом В качестве значения атрибута value тега < input >

используется значение первичного индекса соответствующей записи . Однако для кнопки снезависимой

фиксацией имеется небольшое, но очень важное отличие от обычного НТМL-кода. Возможно, вы заметили квадратные скобки

( [ ] ) в конце имени

кнопки с независимой фиксацией. Они имеют очень важное значение.

echo '<input type="checkbox" value='"

. $row['id ' ] . '" name=" t;ode l ete ( " > ';

Квадратные скобки в конце имени кнопки с независимой фиксацией влекут

за собой создание внутри суперглобального массива $_POST еще одного

массива, в котором сохраняются значения атрибутов value всех нажатых

.

~

К€dЭРd.""IY\кbtе СКОдКLЛ KorLu,e~

u.мeКu кн.Оt'\КLЛ € С н.еv~d.€LЛСu.моu

кнопок с независимой фиксацией. Так как значение атрибута val ие каждой ~КСd.u,LЛеu. лекym 3с!.

codou d.€""IY\О).\Q""IY\LЛЧеское

- это значение первичного индекса соответствующей записи, каждое зиачеиие массива todelete является кнопки с независимой фиксацией

СО.3Зd.Н-lЛе эл~-rен.""IY\d ).\QСШ€d. tode..{ete со

идентификатором записи, которую иеобходимо удалить из таблицы.

3к.d ЧеН-lЛе.м LЛзен.""IY\~cpu.Кd""lY\ОРd

••iI&a&ii""'i'l'•••

Это дает нам возможность получить в цикле значения всех элементов

массива todelete и создать SQL-запрос на удаление всех покупателей, помеченных в форме на удаление.

coo""lY\€e""lY\c""lY\€Y)OUJ.,eu. .3dtjLЛСLЛ.

~,,~~o"~r~·:~~~~~

~Ms:EI..v;s.coм

Кd..Ж:9d.Я. I(H-Оt'\I(d. с н.е.3d€LЛСu.моu. cpu.KcdlJ.,!.Aeu. созер)fШ.""IY\ змЧеН-lЛе LЛзен.""IY\LЛcpu.Кd""lY\ОР d ,

К KO""lY\0p0MY можн.о t"\ОЛУЧLЛ""IY\Ь 90c""lY\~t'\ чере.3 с~t)eр~лодdЛЬкbtu. ).\QССLЛ€ $_P"OSТ.-'_____.~-__

Нам осmалось mолько uспользоl!1аmь цuкл

whfLe, иля moro чmоды nол~umь значatuя кажиоrо U3 злемatmоl!1 мзссul!1а todeLcle, u уиалumь ззnuсu тех nокynаmелeii, чeii uиatmuфuкаmор соиержumся 1!1

сооml!1emсml!1yюU-\ем злемatmе мзссul!1а. г--_.4.II!!~!t!!i!.lJ!l!gl!llJl!l!l'll!!!~"IIIIIII!I"""JiiA'J'

М... моrnи

6 ...

испоnьэоваn. цикn

whlle, но существует Apyroro типа.

60nее

тонкое решение: испоnьэовать цикn

Цикл foreach - это вид цикла, разработанный специально для извлечения значений элементов массива. Все, что вам необходимо в случае использования этого цикла,

-

это указать массив и переменную, которой будут присваиваться

значения элементов этого массива в процессе прохождения цикла. РНР

будет последовательно проходить все элементы массива

-

один за другим.

Нет никакой необходимости в проверке условия.

Напишите, как, по вашему мнению, цикл

foreach

будет проходить по элементам массива, содержащего идентификаторы покупателей Элмера:

8ыздесь

251


анатомив цuкла

foreach

ПРОХОIКАение по элементам массива в цикле Цикл

foreach

последовательно проходит все элементы массива

-

foreach

один за другим . При этом

нет никакой необходимости в проверке каких-либо условий или подсчете числа проходов.

По мере прохождения каждого из элементов массива значение этого элемента сохраняется во временной переменной . Если, предположим, массив сохранен в переменной

$customers,

код вывода каждого из его элементов будет выглядеть примерно так:

Сле€С\ € КРУZЛЬ!.х с.l{одl{С\Х УКC\Jb!.€С\е"t!\Ся. uМЯ. .м4ссu.€С\.

r.tforeaCh -

~ ($customers as

По мере !)рОХОЖ9ен.u.я. череJ кС\.жэbtU О'tY\.9еЛЬн.btU

Г

эле.мен."t!\ J..\ctCClA.€C\ JндЧе,НJ.е Э"t!\Ог,о элемен."t!\С\ дуэе"t!\ €peMeн.н.o СОХРG\н.st"t!\Ься. € \'1еремен.н.ои с "t!\C\I(I).M u.м.eн.eм.

$customer) (

echo $customer;

~ НС\Хоэя.сЬ €н..:1"t!\Рu. u,u.I{M, €b!. мож.е'Yl\е !)ОЛjчu."t!\Ь ЭО С'YI\j\'1 к КС\ЖЭОМ)' элемен..'YI\J' .м4СЩ€С\, u.Сt)ОЛЬ'зУЯ t\epeMertH.j)O,

) ;

uМЯ. · КОrl\ОР ОU €b!. rl\олы{0 Ч'Yr\о одъя.€u.лu..

Итак, если вы хотите пройти в цикле через все идентификаторы покупателей, сохраненные в массиве

tode1ete суперглобального массива $_POST, можете создать следующий код с циклом foreach:

//

Удаление

записи

из

таблицы

Нd.Xоэя.сЬ €н..yvr1рu. u,щ(М,

~ НС\Хоэя.сЬ €н..:1"t!\Рu. U,U.KM,

};

По мере прохождения

€b!. MoJК,erl\e )'эалUrl\Ь u..3 "Yf1С\длu.u,bt ЗС\\')u.сЬ л~оzо I)ОКУI'1C\"t!\еЛ)L цикла переменной $de1ete_id присваивается

значение каждого элемента массива по одному за раз.

мbt МОЖем 1l 0Л\JЧlJ.rI\Ь J ЭОСrI\У!) 1( I{С\ЖЭОМУ

u.эен.rI\u.фu.КС\"i!lОРУ ГjОКУГjС\"t!\еля.

u. У,Эб.fIU."Yf1Ь

u..з "Yf1С\dлu.u,bt ezo JctГjщ.Ь.

SdeIete_id

~

мarsM~EL.Vj$.COМ

_,.......III . . .

ВwOopm.~_.."oммooI-·

amJIi"I ..

МЬ!. со.3эалu.

~

Э"tI\О"Yf1 .м4ссu.€ rl\C\I( Ч'Yr\Оdbt € н.ем

".......-re lIНOf8Y .~•• lIf 1ImM-... ......niфIj,- ... I!I - .... __ ИpIIo lItPIIЦ

"ьф

O~КpocIW~

t!I . . KpocIW . . . . .-л ~1IiI: !!f ДонДp:Jmep ф_. . . . 9 - (Yдonm~

соэе.РЖс'..лu.сЬ

SJ)OSтnodelete1

u.эен..rI\u.cpu.Кdrl\ОРЬ'L \ . rl\ОЛЬКО rl\ex

Теперь все, что нам необходимо, - это добавить внутри цикла foreach код, создающий запрос DELETE для каждого выбранного значения кнопки с зависимой фиксацией в форме « Удаление адреса электронной почты» . Отправка запроса

на сервер баз данных MySQL приведет к фактическому удалению соответствующей записи из таблицы еmа i 1_1 i s t.

252

глава

4

\')ОК)'f\С\'VI\елеU. эля.

KOrl\0Pbtx кн..оt)КGI С н..езС\€u.сu.м.оU фu.ксаu,u.еU

дbtМ Нt.1.ЖС\rI\GI

(€btdpc\н.d) .


реальные

Закончите код нового, улучшенного сценария Элмера

u пракmuческuе прuложеНUR

rernoveerna i 1 . php так, чтобы

в результате его интерпретации отмеченные пользователи были удалены.

$dbc or

// //

= mysqli_connect('data.makemeelvis.com', diе('Ошибка

соединения

с

MySQL-сервером.

'elmer',

'theking',

'elvis_store')

');

Удаление записей покупателей (только в том случае, если форма была отправлена на сервер для выполнения).

if ( .. .. . . ......... .. .......................... . ) { foreach ($_POST['todelete'] as $delete_id)

echo

// //

'Покупатель(ли)

удален(ы)

.<br />';

Ввод записей покупателей вместе с кнопками с для отметки удаляемых покупателеЙ.

$query

=

независимой фиксацией

·SELECT * FROM email_list";

$result = mysqli_query($dbc, $query); while ($row = mysqli_fetch_array($result)) echo '<input type=· checkbox· value=·'

. $row [ , id ']

. ,.

пате=·

todelete [ ]. / > ' ;

echo $row['first_name']; echo

$row['last_name'];

echo

$row['email'];

echo '<br />';

mysqli_close($dbc); 7>

• <input

type="submit" name="_submit_"

vаluе="Удалить"

/>

</form>

выздесь ~

253


измененн",й сцеНQРUЙ removeemQil.php

Закончите код Hoвoro, Уllучwенноrо сценария ЭlIмера

removeemail . php так, чтобы в реЗУllьтате ero

интерпретации отмеченные ПОllьзоватеllИ быnи удаllены.

$dbc = mysqli_connect('data.makemeelvis.com', 'elmer', 'theking', 'elvis-ptore') or

diе('Оmибка соединения с MySQL-сервером.

ИС I1 0Jb'з'уU"ll'\е

');

У,9<1ЛЯU'УУ\е

.3 мЧе н.u.е

мремен.н.ой

1101<Y!1ct'YY\eJleu. 'YY\oJbI(O ~/ Удаление записей покупателей (только в том случае,

// если форма была отправлена на сервер для выполнения) .

fl

~ 'УУ\ОМ c1lJ*1e.. f есЛJ. форNd :1. l1 e pe,9QНd

isset($_POSТ['sub"ll'\it']) (,...........................................)

~

€~ ;г--

Ч'УУ\О bI. pct"ll'\b 1l 0Jb,30€ct"ll'\еля. эля 'y~eКU5t

foreach ($_POST['todelete'] as $delete_id) {

нd ctep ~

u.c11O

~

{

$d~ete_id nЛSl "II'\O~O,

J<:\':!.~.~~..~J?~ПI .~~~.~<:1.i.~,,"~~~~.~~~.~~.., :..$.4~~~.~=~~. !............................. .

eнustl

."!':'~~.<:\!i:::<:\':':~.~~~ ~~~~:. ~~~~~~~............................................................................

... ?~.~i.7.~~~.~~~ .~~r.~~ .~..~.7.~~.':~.;........................................................ . echo

// //

'Покупатель(ли)

удален(ы)

.<br />';

Ввод записей покупателей вместе с кнопками с независимой фиксацией для отметки удаляемых покупателеЙ.

$query = "SELECT * FROM email_list"; $result = mysqli_query($dbc, $query); while ($row = mysqli_fetch_array($result» echo '<input type="checkbox" value=" , . $row['id'] . ," name="todelete[]" 1>'; echo $row['first_name']; echo

$row['last_name'];

echo

$row[ 'email'];

echo '<br />';

~

Коз' ~eKepupy~u'U кн.оtжU, с KeJ<:t€u.cu.мou фu.l<сctu,uеЙ, u.СI10Jb.3,УеМbtе.эля 0ll'\Мe"ll'\l(u'

mysqli_close($dbc);

I(ctнвU,зct"ll'\О€ м 'у,9<:I.Лен.u.е, 'YY\0lY\

Же cQМbtй.

?>

<input type="submit" name="_submit_"

vаluе="Удалить"

1>

</forrn>

removeemail.php

254

гЛQ8Q4


реальные и nракmuческuе nрuложеНUR

-Тест-драйв Проверьте, как работает ТОIlЬКО что оБНОВllенный сценарий ЭlIмера «Удаllение адреса Эllектронной почты». Измените код сценария

removeemail . php так, чтобы он генерировал кнопки снезависимой

фиксацией для выбора покупателя на удаление вместо старого текстового поля для ввода адреса электронной почты. Затем добавьте код для удаления учетных записей отмеченных покупателей после передачи формы на сервер для исполнения. Измените также значение

атрибута

action тега <form> так, чтобы форма ссылалась на себя.

Теперь, после того как сценарий

removeemail. php использует форму, ссылающуюся на себя, removeemail. html отпадает и вы можете его новую версию сценария removeemail. php на ваш веб-сервер и откройте

необходимость в присутствии на сервере файла удалить. Загрузите

его в браузере. Пометьте нескольких кандидатов на удаление и нажмите кнопку ~Удалить~. Форма должна немедленно измениться, отражая удаление покупателеЙ.

MaYsM~EL.v;$.COМ 8ы1iep1ne. noanyiIcта. адрес:а ЭI18ItpOIttOЙ ПОЧТЫ. IIIJIOIIbl8IЫ xcmne yД8JМ!Ъ 113 nиcтa paccыI1III. м _IIf8Q1011ty 'YДlll1lllЪ).

8ДeнtмБll5matt~·net 8_1!epIIЦ~·aIIII

8~КpoIcI1II~·biz ._Кpмc/III~biz

~:-~.aIIII После 'YI'\020

I(QI(

€b!. lloMe'Yl'\UJlu

1l 0 l(ytlФI,еля ка У.9t1Лен.u.е

u н.d.ж.ctлu Ю-lOIlI<У «У.9t1ЛU'YI'\Ь», ,3Qllucb ftr\020

уче'Yl'\Нd.Я

IlOl<ytlФУ\еля У.9QлЯе1Т1СЯ

UJ 1Т1QdлuuJ;я.. NN Хж '. •• •• • • • •

выздесь

255


110лНосmыо nerелоnаmuл се,ОIO СРорму «f<)аленuе мреса злекmронноu nОЧmы».

~ремя отОохнуть. & зvрае,сmе,уem Лас-~erас, оетка!

-_.

~.~","I;wмdnoчtw.

==-":':'''.~1Мm P8CCWfD, о в-.w.rc.._

c ... ~-.

.••.., ......_ =-I ,,.с...

... 'G ;w.epц. .....

;. ,.. ..... ~<8IIJI8'.-

(- >

256

"

глава

4


реальные ц пракmuческuе nрuлож€нuя

Ваш инструментарий РНР и 8ы получили еще

опыта в РНР и

MySQL

HeMHoro HOBoro

if, else

MySQL в процессе

перевода веб-прило_еНИR Элмера на полностью новый уровень ..•

.

УI1~€ЛЯ)ощ~Я l(он.С1I\Р~I{u,uя .· . · ." PH~ , l'\оз€оЛSlem ppU~'iJ\b

if

~~=:-:=-:-:---~~,...;;. ~;;;:;;с;;,J решеl-Ш.е, &\Juр~ее9Я,~,,# npo€epKe UC1I\~ . '. u ~q)( лu~й €bl.pd.Jt(.eНJJ.Я..

O!'to сейф

uз ~сло€н.о~о €~Ж;~, к 01l\opoe !"'o)К.ell'l tlpU;НJ;.i.JМ\1Тjb , оэн.о UJ #'jX з~Чекu(l: {rue.

СUСlI'\щw,.) Ми. fdise. (лО~)1 u dЛОКct КОЭct, К01I\орьш "ф €btI'\олн.яе.1I\С51. € lI'\o/t\ С!IYЧd.~, есЛU 'jсло€н.ое. €~ctЖe.rше ;( 1'\~e.1I\ 3I'lc;1..чеtШеtruе.· "К .""

у'npct€ЛЯ~ctя. 'коIiС1l\Р'jI(~;РН1>

'f

Ui.U(JlЦl.lecKct5I. хон.c"tl\?'jКUfJ.Я. рнр, К01I\оpctЯ \10з€оляе.11\ €O.М l1,ослеэо€о.11\е.лы-to I1РОХОЭlA1I\Ь 1"\0 ЭЛе/t\еl-t1Т'\~ ~ССlЛ€ct деЗ UСl'\ олЬзо €ctl-Ш.Я КdКОг,о-ЛUдО 'jсло€н.ог.о €bf.pct~!-щ'я'. 1'н.ymеlA Э'rl)ог.о щ.u<М €b!. j,\O.ж,е1Т\е 11 0Л'jI.lu'Yl\Ь j0C'i'l\'jI'\ 1{1(G\Ж:90/t\'j

~сш€а.

11 0J€оляе1l\ ~ I1PUJ-W..М4l1'1Ь, щ , РdJЛul.l~ €u,9bt реше.foUJ.й; '. к Э'YI\оi1 кон.с1Т'\~'jКцu.u. /t\o.>lte.lI'\ '

~Yllb эомвле.~J(Л)Oчевое cJ1o€o e:..vsе"t"iосле. ко"уу\орог.о

слеэ'jе.1!\ dJIb'Ще.рНА'iJ\U€~i1 · ало)( I(,оэct, ko-m о рlii1 €bu)олttЯе.1r\СЯ € 1Тj0M СЛ'jЧd.е, .есЛu. 'jслo€н.ое €~.ж.eкu.е t\p~e11\ з~~е.tШе Jctlse. ,

O~e.f41!\Opbt СР~~I-teН:я..

~ог,уrfJ UСt'10ЛЬзq~mЬся

. '. 51:

к:он.сmР'juро€dкllЯ эсло€~ . .

€bt.f..4ЖеКUi1, ,€ KOlI\c,>p/;1!.x Сf4€НЦ€ct)C)ТIСя. рС\3лuчнbtе. 3Нd.Чекu.я. 0IW;,ЧctC'i'l\О Щj~ОлЬз'j}O]rlСЯ €bt.~)f(,енцЯ.х KQ.к.c'm""U ' н •• ,


5 fflOO'}'h,fl с g'fllflfbJMU" COXffllfGlflfbJMU, ~ pfli1,i\U

+

*- KorAII nро"о 61136' * ДОИИ",Х иедоеrоrОlfИО

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

но как обстоят дела с бинарными данными? (кажем, такими как изображения в формате JPEG или документы в формате

PDF. Есть ли смысл в том, чтобы хранить,

например, картинки , изображающие коллекции редких гитарных медиаторов, в таблице базы данных? Чаще всего нет. Данные подобного типа обычно сохраняются в виде файлов, и будет лучше, если мы оставим их в этих файлах . В этой главе рассказывается, как совместно ИСПОЛЬЗ0вать данные, сохраненные в файлах и базах данных, ДЛЯ того чтобы создавать РНР-приnожения , забитые под завязку бинарными данными .

это новая глава

259


«Гитарным воинам» нужны изображения, подтверждающие рейтинги

Виртуальным гитаристам нравится соревноваться Очевидно, что искусство для искусства не всегда устраивает, поэтому игроки новой популярной игры «Гитарные войны» без ума от соревнований

Прu.ложен.u.е «ГU'IТ)ctpн.bt.e €oЙн.bt.» 1'10J€оля.е"Yl'1

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

1'1 0лЬJо€ct"Yl'1елям

отправляют свои рейтинги на сайт «Гитарные войны», обязанности по

СclМОС'lТ)оя."YI'1еЛЬн.о

техническому сопровождению которого возложены на вас. Имеется проблема, .9 0dct €ля.'IТ)Ь c€OU реЙ'lТ)uн..гu. связанная с тем, что к настоящему BpeMeH~ не существует хорошего способа tf ct"}U.COK peЙ'lТ)ин..~o€. для проверки достоверности вводимых реитингов.

.' Гитарные войны. Список рейтингов вaивыlВЭТOIIСШlС1еpeйтииroВ? \. Добро пOPJlowь, гитар!Iый Вова! Твой реЙТlllll" бьет реКОРд. зарегиС1"р8рО __ ... _ ..•_ ..._._._ \ .~~~.А~~с.80й~ .В-='П'И~I.:._._ ..._ ._ . _ - _.... _··_·

., 127650 Мы.: Пuo д*асториус

, Даха: 2008-04-22 14:37:34

\ 98430

и..-: НевилЙОхавсов <~------------------1~--------­

!\ Даха: 2008-04-22 21 :27.~4 ! 345900

Эдди ВанИJ]JlR J.. Мы.: Даха: 2008-04-23 09:06:35

! 282470 " Мы.: Бепита Чсви

.:~--------_ _ _ _ _ _'

\ Допа: 2008-04-23 09:12:53

'\ 368420

И>d: Дmтои СКIoIDсов

I Даха: 2008-04-23 09: 13:34

~•.--~!!I!''''' Белu"Yl'1ct, ск et)'IТ)u. Чн.о н..ct C "YI'1poeн..н.bt.u. рокер

Тенет можно помелат..

«ГU'IТ)ctpн.bt.x €oЙн..» ,

Пока что исполнители просто пересылают свои рейтинги в виде простого текста, и разгорелось много споров о том, чьи рейтинги

подлинные, а чьи

-

нет. Существует только один способ положить

конец всем этим спорам и обеспечить легитимность чемпионату «Гитарные войны» ...

260

zлаваS

~

_ _ _ _ _ _~


работа с данными, сохраненными в файлах

-

Доказательство подлинности Визуальное подтверждение высокого рейтинга

.. Гитарные

вот что нам необходимо,

-

чтобы проверить, чей рейтинг подлинный, а чей

в изобраJКении

-

нет. Поэтому приложение

войны. должно предоставить пользователям возможность загружать

IIзображение, подтверждающее их рейтинг, когда они присылают свои рейтинги

на сервер. Это значит, что список рейтингов будет содержать

персчень не только рейтингов, имен и дат, 110 и изображений, подтверждающих подлинность этих данных.

11

е

Э ОС1Т\оеерl'tос1Т\lJ.

?о е?ка оgеэ е w-w. 5l с 110MO\JJ.,b)O ЭG\t-U{bi.x, I1рО.о. 110КG\3dЛd, Ч'Ут\0 ЭЭЭlJ.

<p01Т\oг..~~

:'UI 'Чd.е1Т\ е «\lJ.1T\G\?\-U?1.X

11 POC1flO мош.еГV"'" eoU.MX»,

345900 Има: Э,цц ВaиuJJJl Дата: 2008-04-23 09:06:35

Итак,

I?bI xomume скэ)3ть, мне ufj?amb эту !1ьесу?-110ЛНЫU оОлом.

нужно научuтЬСfI

. 282470

, Има: Бcвиra Че8. дата: 2008-04_23 09: 12:53

.368420 и...: Amтo. свкпсо.

, Дата: 2008-04-23 09: 13:34

Реu.1Т\lJ.rtг. БеЛtA1Т\bt

\lоэлш.tj,W1Д, g ЧеМ Mo)\(.I-lО ~деЭtA1Т\Ьс5l dЛG\ZОЭd.р5l I1рtAсЛG\I-U'WМ~

е)О tЛ3О д pa)\(.eкu)O, 11 оэ'VТ\lSержэd.)O\JJ.,eMy ее реu.1Т\lJ.k.2.

вы здесь ~

261


схема nрunожеНUR «Гитарные воины})

ПРИJlОllениlO нео6ХОАИМО сохранять ИJо6раJlения в настоящее время рейтинговое приложение ~Гитарные войны. следит за тремя видами данных: датой и временем ввода нового рейтинга, именем человека, загрузившего этот

рейтинг, и самим рейтингом. Информация вводится через форму, которая является

частью пользовательского интерфейса этого приложения. После передачи формы

на сервер все данные сохраняются в таблице с именем gui tarwars.

Гитарвые воlШы.

Добавь свой реЙ'ПJИГ Сna",,60 ]а 10, '"" ,1OOбu... с80il pdinlвr\

262

zлава5


ptl60mа с данными, coxpaHeHHIII"U. файлах

7frt0'Yfl tL9 ен:'lrlщptщctlТl ОР

Я~ляеlТlСЯ I")еp€цчнbv.\ I(J1}OЧом. € lТIctdlkA.u,e

ц ct€lТIом.ctlТlЦ ЧеСI(Ц

г.енерЦf~еlТlСЯ зля 1(c:t.Ж:9 0U Jctt}ЦСu.

-

guitarwars

Эwtо lТIоЧНctЯ. ЭctlТl"

ctat.

(ц ~рем.я), когЭct

SCOt'8

Поко д,.осториус

127650

Невнл Йохансон

98430

Эдди 8онилли

345900

peиlТlЦНZ дbr.л

2

l")epe.9clIi. t1рu.noJlC.eн.що

3

2008-04-23 09:06:35

4

2008-04-23 09: 12:53

Бenито Чееlot

282470

5

2008-04-23 09: 13:34

AwтOH Симnсон

368420

6

2008-04-23 14:09:50

l(енниЛевиц

«ГЦlТlctрн.bte €oйн.bt:o.

После ~O.9" цМeнu. ц peЙ'lТ\цн.гct ц Кt:UfGct'lТ\ц5{

I{н.оtжц <t:До~€цlТlЬ:О

н.o€btй peu-mцнz I1РОХО.9 ц-m I1po€epl{Y КQ .9 0ClТ\o€epн.oClТ\b,

8 lТI",dlkA.u,e 3Ui1",rWctrs lТIctKJIC.e coxf:tH-ЯЮ'IТ!СЯ цм.я ц peиlТIцн.г ЭЛЯ Кc:t.Ж:9 0Й .3ct!']цсu.

ц 3dlТ\ct ~o.9'" _<JO.н.нbtx .9 Одct€ляеlТ\СЯ -g lТ\"'дЛц\~

3Ui1",rw",rs.

вы эдесь ~

263


nрокомменmuруumе код

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

..

<html xmlпs;"httр:llwww.wз.огg/1999/хhtml" xml:lang; en <head>

_

<titlе>Гитарные ВОИНЫ: <link rel; " stylesheet

С

.. lang="en">

рейтингов</titlе>

r

ПИС~~t xt/css" href="style.css" 1>

type-

е

</head> <body> С сок рейтингов </h2> <h2> Гитарные воины. пи _ I Твой рейтинг бьет рекорд ,

~ .fvr\O"Yr\ фо.ЙЛ tte"Yr\ н.еоdхоэu..мос"Yr\1.A

<р> ДоБРО пожаловать , гитар::: ::~~ГOB? Если так, просто

зарегистрированный в этом спи

_

<а hгеf;"аddsсоге.рhр">добавь свои р

styfe.CSS

ейтинг~/а> в список . </а>.</р>

6'ttoCI.A"Yr\b

<hr 1>

lA3 me h.el-Ш5!..

<?php 11 Соединение с базой данных. , 'admin ', $dbo ; mysqli_ connect( . www.gu1tarwars.net , 11 Извлечение данных рейтингов из базы $query; "SELECT * FROM guitarwars:; $data ; mysqli_query($dbo, $query) ,

'rockit',

t)ОЭ'VI\ОМУ 6'bt

' gwdb ' );

н.е ЭОЛЖн.bt О н.еМ

dеСt)ОI{ОI.A'VI\ЬСя..

MySQL

11 Извлечение данных из массива рейтингОВ в ~~~ . 11 форматирование данных записей в виде кода

echo '<table>' ; while ($row ; mysqli _ fetch_ array($data» 11 Вы вод данных рейтинга. "> " есЬо ' <tr><td Clas~="sco~e:nfO$ro~('score ' ] . ' </span><br />'; есЬо '<span class= score row[ ' name ' ) . '<br /> ' i echo '<stгопg>имя:</stгопg> " $$ [ ' date ' ] . ' </td></tr> '; echo ' <stгопg>дата:</stгопg> . row

> :

}

echo '</table> '; mysqli _ close($dbc) ; ?> </body> </html>

'. .·...... J.H.H.

Полностью код для веб-приложения

guitarwars

-

id

CIate

1

2008·04·22 14:37:34

Пока Джостариус

2

1 27650

2008·04·22 21 :27:54

Невнл Йохансон

98430

nome

«Гитарные войны. доступен для загрузки

3

с сайта по адресу

2008·04.2309:06:35

ЭДЦН Ваннми

4

345900

2008·04·2309: 12:53

Белита Чеви

5

282470

2008·04·2309: 13:34

Аштон Симпсон

6

368420

2008·04·23 14:09:50

Кенни Левиц

64930

www.headfirstlaЬs.com/books/hfphp

264

index.php

*' ~.

глово5


работа с данными, сохраненными 8 файлах

<html xmlns="http : //www . w3 . org/1999/xhtml" xml:lang="en" lang= "en"> <head> <titlе>Гитарные войны. Добавьте свой рейтинг</titlе> <link rel="stylesheet" type="text/css" href="style . css " /> </head> <body> <h2>Гитарные войны . Добавьте свой рейтинг</h2>

<?php if (isset($_POST['submit ' ]» // Извлечение данных из суперглобального массива $_ POST $пате = $_POST['name']; $score = $_POST[ ' score']; if (!emptY($name) && !emptY($score» // Соединение с базой данных $dbc = mysqli _ connect ( , www.guitarwars.net "

' admin ',

' rocki t "

' gwdb');

// Запись данных в базу данных $query = "INSERT INТO guitarwars VALUES (О, NOW() , mysqli_ query ($dbc, $query);

' $пате ', '$score')";

// Вывод пользователю подтверждения в получении данных есЬо '<р> Спасибо за то, что добавили свой реЙТИНГ!</Р>'j echo '<р><stгопg>Имя:</stгопg> ' . $паmе . '<br /> '; echo ' <stгопg>Рейтинг :< /stгопg> ' . $score . ' </р> '; echo '<р><а href="index . php "><< Назад к списку рейтингов</а></р>'; // Очистка полей ввода данных формы = "О; $score = О"; $пате

mysqli~close($dbc) ;

else ( echo '<р сlаss="еrrоr">'Введите , пожалуйста, всю информацию, необходимую

I

'для добавления вашего реЙтинга.</Р>'i

?> <hr /> <form method="post" action="<?php echo $_SERVER['PHP_ SELF ' ] ; ?>"> <label fог="пamе">Имя : </lаЬеl><iпрut type="text" id= "name " пате="пате" value= "<?php if (!emptY($name» echo $пате ; ?>" /><br /> <label fог="sсоге">РеЙТинг:</lаЬеl><iпрut type="text " id= "score" name="score" value="<?php if (!emptY($score» echo $score; ?>" /> <hr /> <input type="submit" vаluе="Добавить" name;"submit" /> </form> </body> </html>

addscore.php

выздесь ~

265


nрокомменmuруumе код {(Гитарных воин»)

в припожение по сопровождению рейтингов «Гитарные войны» необходимо внести изменения,

чтобы оно могпо ИCnОПЬЗ0вать загружаемые файпы изображений, подтверждающие ПОДIIинность рейтингов. Просмотрите и прокомментируйте ту часть припожения, которая должна отвечать за ИСПОПЬЗ0вание загружаемых ПОПЬЗ0ватепями файлов изображениЙ.

И,30д~жен.u.е,

1- xml:lang=-en· lang =-en - >

I"IО~"IY)€еРЖ:9d.щее

<htm1 xmlпs=-httР:/!www.w) .org /1 999 / xhtm

<Ьеаф

<titlе>гктарные войны.

СПИСОК рейтингов</tit l е > - -t t/C5S. href= - style.css· /> ех .

peu"lY)uнz, .9 0 лжн.о

<1ink. rel=-stylesheet· type-

<Ьody>

йтинro8 </h2>

СУl"lерг.ло &:v1bн.btй

<Ь2> ["и'l'арные ВОЙНЫ . СnИСОI't. ~! твой peйтиИI' БЬеТ рекорц. ~вaJlНbЙ

rюaanoВCnЪ, :rитарный.

<P>,J)J6po

в этом сrмсже рейтингов? EcJtи так. npocтo <а

href=-addscore. php->добаВЬ СВОЙ

~ccи€ ЧJVIJI"\I::х.

$_POSТ.

рейтинГ</а> в СnИСОJC. <! р> <М

I"IO-'!УЧен.о чере,3

abt"lY)b

</Ьеаф

1>

<?php

<html xmlns;"http :

11 соединение с базой дакных . , • admin'. ' rock:it'. $дЬс = mySQli_connect(·www.gu1tarwars . net •

<head>

11 извлечение данных рейт~roв из ~ЗЫ МySQL $query = ·SELECТ * FROН gu1.tarwars .• $data = mysqli_query($d.bc . $query).

<link rel;"stylesheet" </head> <body>

<titlе>ГИтарные

11 извлечение дaJiных из массива реЙТЮlroв в ци= . 11 Форматирование данных записей в виде кода

<h2>Гитарные войны .

свой р€ЙТинг</titlе>

" text/css " href; "style.css " />

~.90~ уде.9 ЦYr\ЬСя., ч-rr-

Доба,Ei;"е свой рейтинг</h2>

LI.МS: ($data»

масси в а

l

I ВЫВОД дaкных рейт~нга . • >' . ho ' <tr><td class= scorelnfo • '<span class= - score - >' . $row{ 'score'

~hO

фQйk

~~~~~~~--~--~----~ ~ОdF~~

~]

ttyc"lY)Oe.

к.е

есЬо ' <strоng>Имя:</strоng> ' .' $row{ ' ~=e ' } '<strong>naTa:</stronq>

$_ЮSТ

' admin' ,

. $row[

' rockit '

базу данных

то

gu Harwars VALUE

mysq ,_чuеry ,чuеry) ; 1/ ВЫВОД пользователю подтверждения в / / 8ыво ПОльзователю подтв е ж

о

I <р> Спасибо за то , что добавили свой рейтинг ! < '<р><strопg>Имя : </st rопg> • . $пате . ' <br 1> '; '<strопg>Рейтинr:</st rопg> $score . ' </p>' ; < ><а hre . Наз

=.'

I

реЙТингов</а></р>';

У< l"Iещн'О~О

~

I

$~~:7 ; ; ": : . ~ После УСl)еШtto~о ,3<1€ершеtw..St ydеЭUll\еGb,

gui tarwara _____

id

daIe

1

2008-<)4-2214:37:34

2

2008-04.22 21:27:54

3

2008-04.2309:06:35

4

2008-04-23 09: 12:53

5

2008-04-23 09: 13:34

~ ..... _"'

Поко Джосторнус Heeнn Йохансон Эддн8анНII/!И бмlfТО Чееи AwтOH СНМПсон КенниЛе...ц

а полей ввода данных формы

//

.3<:\1 ерщен.u.я. I"Ipou,eCCd..

' \ 127650 98430

345900

_ ~

е ($dbc) ;

Чщо~, ,3<1I)O~eмbI.e ФОР/О\ОU,

оЧuЩекbl.. else echo '<р class: "error"> ' Введите,

необходимую

• .

'для Добавле~;;;~F.~Й~J:si.9~~эi>вОJbКD Kp<1l1\KW>\ lI\<U< ( ~ НоеМ ное l)ереЧuСЛSt)01l\СЯ uмeнh коЛОtwК

282470 368420

"пamе"fоr;"пamе">Имя : </lаЬеl>< i прut type;"text " value;"<?php if (!emptY($name)) echo $name; ?>" /><br /> <l abel fоr;"sсоrе">Рейтинг : </lаЬеl><iпрut type;"text" id;" score" lue;"<?php if ( ! e mpty($score)) echo $score

<input type=·submit· vаluе="Добавить· narne="submi </form> </body> </html >

266

zлава5


ро60mо С данными, coxpOHeHHblMU 8 файлах

Планирование JаГРУJНИ ИJо6раJRений на сервер «гитарны e войны )) Хотя подцержка загрузки файлов может показаться не такой уж и сложной задачей, приложение должно

быть изменено в ряде аспектов. Исходя из этого, составление плана операции перед углублением в ее детали выглядит достаточно разумной идеей. Давайте наполним эту идею содержанием, обозначив конкретные этапы, которые необходимо пройти, чтобы обеспечить загрузку файлов изображений для приложения .Гитарные воЙны~.

Испоnьзуйте запрос ALTER дnя Toro, чтобы добавить в табnицу коnонку

screenshot. Во-первых, таблице необходима новая колонка для сохранения имен изображений, подтверждающих подлинность рейтинга.

Измените фо

реЙтинr» ДОБРМУ «дОбавь свой ,

ДIIя ввода заr

авив еще од

Так как мы предполагаем хранить ~

изобра

каталоге, все, что нам необходимо

В веб-странице .Добавь св

все файлы на диске в одном сохранять в таблице,

-

~

-ения.

Имеется форма для

это имя

v

v

ОИ реитинг. уже

ХОдимо модифи

ее и добавить ПОЛе вв

г--------------------...L-, чтобы

INSERT,

добавить имя Фciйnа изображения в коnонку

б

поэтому вам необ до авления рейтингов,

файла (а не его путь) .

Напиwите запрос

но попе

PYJКaeMoro файnа

screenshot.

О

ода имени Ф

ЦИровать

но должно Согласовыв аила. предоставления польз аться с браузером для выбора файла дл ователю ВОЗМожности v

я загрУзки.

Изображение:@Ыбермте фай~

u

phizsscore.gif

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

таблицы

scre ensho t

gui tarwars. Измените rnавную страницу приnо~ения phizsscore.gif

«rитарные войны» так, чтобы на неи появиnись изображения, подтвержда~щие подnинность рейтинrов поnьзоватеnеи .

Последний пункт перечня изменений, которые необходимо внести

в приложение, связан с файлом

i ndex. php страницы . Гитарные войны». Измените его так, чтобы на странице были выведены изображения , подтверждающие

подлинность каждого рейтинга.

вы здесь ~

267


uзменuте (ALTER) вашу таблицу

&аза данных рейтингов должна быть изменена в дополнение ко всем изменениям, внесенным вами в РНР-код, для II0ДI\ержки

изображений приложению «Гитарные ВОЙНЫi> в таблице

gui tarwars

необходима новая колонка, в которой будут сохраняться имена файлов изображений, подтверждающих ПОl1,Линность рейтингов. Составьте SQL-запрос,

начинающийся с ключевого слова ALTER и Пo:lволяющий изменить таблицу во множестве интересных аспектов, включая добаВJlсние новой КОJlОНКИ. Вы уже использовали запрос

таблицы

ALTER ТABLE в предыдущсй главе для изменения emai 1_1 is t. Давайте кратко II0ВТОРИМ , как работает этот заIIРОс.

Ai.~jm ТАВЧ3 gui tarwars .illl;!;~I~_· score

КлroЧе€btе сло€(\ DROP СО\..UJYIN,{,У.9d.Лu'"YI\Ь

~олоНJ(У) озКQЧcl)О)Т), 'J'ir}o g реJ~лт,)Т)d'tf\е ~btIlОЛН.ен.u51. Jcll1pocC\ колою< 3 e .У.9d.леКQ UJ )Т)Qд;jU,upt. С\ Y.g 'lТj 1I 0 лн..ОСIr\Ь)О Возможно, это опасный пример, так как он показывает, как удалить колонку II0ЛНОСТЬЮ, ВКТIЮЧая данные,

coxpalleHHbIe

в ней. Тем IIе

Запрос

ALТEl\

ucnользуemС9

gA9

uзмeнeнuэ

структуры вазы

gаиныl\. ~

за КЛ)ОЧе.€bt.М сло€ом А\..ТЕК

ЧdС"Yl\О слеэуе'tf\ кл)Оче.€ое. сло€о TA~lE, I(o'tf\o~oe YKdJbt.€C\e."YI\, ЧYr\о u',3Мен.ен.u.st дуэym. KdCC\"YI\bc51

С1Т\рУК'tf\ууbt 'tf\С\длu'u,bt. Име.е.'tf\с51

«Гитарные воЙны~. Это делается путем добавления КТlючевых слов

'tf\С\кже ~ОJl"lо.жн.ОС'tf\Ь u',3Мен.5l'tf\Ь C'tf\pyk-mуРУ €ce.Й ddJbt ЭС\нrWtx, U,сt\ОЛЬ.3js<' € 3dllpoce кл)Оче€btе. сло€с\ А\..ТЕК DA1AMSE, н.о .7"У1\о уже

ADD COLUМN, что является одним из способов изменения структуры

эру~С\51 U,С1Т\Орu5l.

менее вполне возможно, что вы столкнетесь с ситуацией, KOГ)la у вас

возникнет такая необходимость. Но чаще вы будете сталкиваться с необходимостью добавлять колонку, как в случае с IIриложеllием

таблицы с помощью запроса

ALTER.

---------------- ..-...~~~~~~--~~...-~ . .

COLUМN (добавить колонку)

ADD

г~RОР COLUМN

\ (удалить колонку)

и тип данных, которые будут в ней

\ Удаляет колонку (и все данные, сохраненные в ней) \ из таблицы . Просто укажите имя колонки после \ ключевых слов DROP COLUМN.

сохраняться, после ключевых слов

\

Добавляет новую колонку в таблицу. Просто укажите имя колонки

ADD

\ \

COLUМN.

Д~J'1Н~,_Т'АВ~~ ЯU i"t а~wаrs ~DD qoblJМN aq:e TINYINT

ALTER TABLE gUJ,t arwars DROP age

СОLtJЮ!

\

~~"". . . . . .----~L-~~M~DI~~-~-OLUМN--------------~ (модифицировать колонку)

CНANGE COLUМN (изменить колонку)

Изменяет тип данных колонки и ее позицию в таблице. Просто укажите имя колонки и новый тип данных,

Изменяет имя и тип данных колонки

которые будут в ней сохраняться, после ключевых

в таблице. Просто укажите старое имя

колонки, ее новое имя и НОВI>IЙ тип

!

слов MODIFY COLUHN. дЛЯ того чтобы изменить

после ключевых слов CHANGE COLUМN.

позицию колонки, укажите имя колонки и ее позицию: абсолютную (FIRST (первая) - единствеНIIЫЙ выбор

ALTER TABLE guit; C).rwars

(AFTER (после) другой существующей колонки,

данных, которые будут в ней сохраняться,

.

I;CtrANGE. COЬUМN score hi9h....~core IN'l' 268

zлава5

при указании абсолютной позиции) или относительную

указанной по имени) . ALТE;H TABLE gu i tarwars МООIРУ COLUМN date DATETrмE АРТЕН аяе


работа с данными, сохраненными 8 файлах

Напишите SQL-запрос. в результате выполнения которого в таблицу

gui tarwars

будет добавлена новая колонка с именем

screenshot.

Убедитесь в том. что вы выбрали для новой колонки тип данных

MySQL.

соответствующий тому типу данных. которые будут в ней

сохраняться. Затем напишите другой SQL-запрос. который позволит

вам проверить структуру таблицы и убедиться. что колонка была добавлена успешно.

Нс.ЩUШU"Yl'lе J.gecb SQ.L.-J~t)poc, € реJулЬ"Yl'l~"YI'Iе ' €(:it.t)олн.ен.u.я. I(O"Yl'l0P-о-zо->~..... .. .. ..... ... ..... .. ........ ..... .... ... .. ......... ............. .. ...... ..... .. .... ... .... ... ....... .. .

дуэе"Yl'l.90д~€лен.Q н.ob'~51 колон.к~.

~

H~t)uUJ.u"Yl'le €"YI'I0p0u.

... ...... ...... ..... ........ .. ........ .... .. ........ .... ... .... ... ...... .... ..... .... ............. ..... .. ..

.. .......... .. ....... .... ... .. ...... ...... ...... .. ..... ... .. .... ... .................. .. ....... ..... ... .... .

SQ.L-.3~t)poc.

вы здесь ~

269


заточите свои карандаш решение

~W'HU'

,.aaqU Напишите SQL-запрос, в результате выполнения которого в таблицу

guitarwars

будет добавлена новая колонка с именем

s creenshot.

Убедитесь в том, что вы выбрали для новой колонки тип данных

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

..:J.....!~~~~-+~3:i---I~K KQK КОЛОНJ(Q н.o~.

oКQ ЦМее"Yl'\ I1YC"Yl'\bI.e JКQ Чен.uя эля. €cex JQl)tAceu.. KO"YI'\0pbte dbuJtA

в "YI'\Qdлuu,е КQ ,Мо,Мен."YI'\

ее .90dQ€лен.tA5t.

ИСПОnЬ3

JER

ДII_ тоro, чтоб.. добаВИТЬ в тa6nИЦУ KOIIOНКY screenshot.

270

lлаваS


работа с данными, сохраненными 8 файлах

-Тест-драй в добавьте колонку

screenshot

в таблицу

gui tarwars.

Используя инструментальную программу

ALTER, чтобbl добавить

колонку

MySQL, Вblполните запрuс screenshot в таблицу gui tarwars.

~може."YI)е

Затем Вblполните запрос DESCRIВE, чтобbl просмотреть структуру

СНдЧOJ1d.

таБЛИЦbl и убедиться, что колонка добавлена.

"YI)Ф~лu.u,у

cOJ.9o."YI)b

9uii.o.rwo.rs,

зо. Z РУJU.€

3 Fе.3~лЬ"Yl)о."YI)е

11 pu.мe рь!. 1{ 0.90.

?b<tt10Лн.е.нu5!.

.<lля. IlРu.л о же.нu.я.

~t"ipoco.

«Тu."YI)o.pкbte

)ISCRI~r:~ ., о К d.Jd.t-I.d. н.о€о.я.

€oйнЫ», u. Jo."YI)e.M €bttJолнu"Yl)Ь QL-Jo.l1 рос

s

I<:ОЛОн.ко..

UJфа.й.ла.

ЭUitо.rwо.ГS.S9~·

~: Новые коnонки, добавляемые

Если вы не укажете, где должна быть

О: Да. Это. безусловно, может быть

с помощью эапроса ALТER, доnжны

размещена новая колонка, по умолчанию

сделано, для чего вам придется

noмeщаться в конец табnицы?

она будет добавлена последней в таблице.

воспользоваться SQL-запросом

О: Нет, они могут помещаться куда

f: Что произойдет с существующими

того, чтобы вручную загрузить файлы

эаписями данных рейтингов после

изображений на веб-сервер и затем,

расположения колонок не имеет большого

добавления новой коnонки?

воспользовавшись SQL-запросом

значения. Иначе говоря, вы можете

О: Так как запрос ALТER оказывает

изображений в уже существующие

угодно. Но имейте в виду, что порядок

.:оздавать свои запросы так, что данные

будут выводиться в любом порядке,

влияние только на структуру таблицы,

~оторый вам необходим. Но, возможно,

новая колонка

вы любите порядок во всем, в том числе

иметь пустое значение для всех записей,

и в расположении колонок в таблице.

которые были в таблице на момент

В этом случае можете добавлять колонки в определенное место в структуре

FIRST

или AFTER, чтобы разместить новую колонку относительно уже существующей:

TABLE guitarwars COLUМN age TINYINT AFTER

.~..:.. TER .~.=J

ее добавления . Хотя имеется возможность добавлять данные во все новые записи,

таблицы. Вы добьетесь этого, используя в запросе ALТER ключевое слово

screenshot будет

пате.

значения колонки

screenshot для всех

предыдущих записей будут пустыми.

f: Существует nи способ добавить

UPDATE.

Нет никаких препятствий дЛЯ

UPDATE, внести

имена файлов

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

свои собственные файлы изображений. И они смогут делать это, используя усовершенствованный сценарий

«Добавь свой рейтинг», который вы сейчас создаете ...

имена файлов изображений в коnонку

5Creenshot предыдущих эаписей? вь, здесь.

271


добавление иэображениu с помощью формы «Добавь свой рейтинг»

Как получить файл из06раJКения от ПОЛЬЗ0вателя? После добавления к таблице новой колонки мы готовы сосредоточиться на задаче загрузки пользователем файла изображения . Но как это сделать? С помощью Действительность возвращает нас к форме ~Добаuь свой рейтинг~,

FTP? Телепатии? u которой мы можем

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

Прu l1ереэаЧе формы ка cep€ep

Осоден.н.ос'УТ\Ь 3'УТ\ой I(КDf)KU

'УТ\У.9 а JctZРУЖ4е"Yl'\Ся.

jdклroЧ<\е-vr\с5t € 'УТ\Ом, Ч'tr\о

rpu

dUкapнhtu файл

u.,30dрctжекuя.

ее к.а.Ж4'УТ\Ш).

jt)fdf;'леrLU.е l1 е р еэ ае'УТ\С5l_ dpdjjepj U Оllераu,u.ожоu ШС'УТ\еме. Оdbt.чк.о IIри. ее

_.)

к.а.Ж4'УТ\UU €bt.зbt.€dе'УТ\Ся.

эuалог. t)OUCKd сраUлd, UСIIОЛЬJУя. КО'УТ\орЬtд

110ЛЬ.30€ct'УТ\елЬ .мо.ж.е'УТ\ к.а.й'УТ\и. к.у.ж.Н.Ьtд фаЙЛ к.а. ЭUСК е,

Ве6-сервер Итак, новое поле ввода предоставляет пользователю возможность найти на своем компьютере файл для загрузки, а что же дальше?

Поле ввода имени файла для загрузки также берет на себя функцию загрузки файла на сервер, в каталог, откуда

изображение, сохраненное в этом файле, может быть выведено как часть рейтингового списка приложения ~Гитарные войны~,

Является ли такая функция загрузки файла своеобра:шым расширением

HTML?

Ничего подобного.

HTML-Ter <input>

поддерживает поле ввода имени файла и работает совместно с РНР, позволяя загружать ука:'IaННЫЙ в поле ввода файл. Но прежде чем мы перейдем к стороне дела, связанной с РНР , давайте посмотрим повнимательней на само ноле ввода имени файла, ..

272

zлава5


работа с данными, сохраненными 8 файлах

Р %рма ..,A,a;asь aюi1 pei1muw» 1\ gemaлsк

ЭvIIо Ф<>р~, ссbtЛd)6UJ,ct5lc5l ка ced5l.

v~luе;·З2768·

_.'hoO·"oo"" .e,ion·".?php

<label

/>

echO~ SERVER['PH~']'

~

?>">

fоr="пamе">Имя:</lаЬеl>

<input type="text" id="name"

пате= "пате "

value="<?php if (!empty($name)) echo

$пате;

?>" 1>

<br 1> <label

fоr="sсоrе">Рейтинг:</lаЬеl>

<input type="text" id="score" name="score" value="<?php if (!ernpty($score)) echo $score; ?>" 1> <br 1> <label

fоr="sсrеепshоt">Файл изображения:</lаЬеl>

<iJ1put t;,y pe=" file-

ы=· screenshct· пате""

sc:reenshot· 1>

<hr 1> <input type="subrnit"

~

ЭvIIо t'\оле €€оэct u.Мeн.u. ф<:\i1М.

vаluе="Добавить"

name="subrnit" 1>

t\олI-lOС"tl\Ь)О I\ОМ~ct~ееся.

ка эu.ctЛо~ Ollepd.~OНКOu.

< / forrn>

cu.c"tl\e.мbt. KO"tl\OpbtU.

1I 0 J€оля.е"tl\ \')ОЛЬJоеd."tI\ел)О Н.d.X oэu."tI\Ь u. ebt.дu.pd."tI\b к.у.жк.bt.i1 фd.Uл ка эu.ске.

Измен

ОРМУ «Добавь свой

рейтинr», добавив еще одно

попе ДЛЯ ввода заrружаемоrо

файnа изображения.

8ыздесь.

273


сохранение имен фаЙnОILиэо6РQЖений в базе данных

имени фаила

до6а8лени~ ИJо6раJКения 8 6aJV AaHHblX нмз ~ttAa U306p8Жeнu9

Простой загрузки файла изображения на веб-сервер

с использованием формы недостаточно. Нам также необходимо

сохранить имя файла в новой колонке

ucnользуetnC9 как

screenshot, чтобы

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

INSERT,

но в нем не принимает никакого участия новая

guitarwars VALUES

(О,

NOW() ,

~ ,-/-

3

'$naшe',

1NSEl\Т

nри coxpaнeнuи

gui tarwars, используя

6

saзe

gaнныx.

screenshot:

INSВRT INТO

часть запрос».

'$score')

~----------....

мЧекu.е КОЛОКJ<U id УС'"t!\<:tм€лu.€<:tе'"t!\Ся. <:t€'"t!\ОМd'"t!\uЧескu череJ Mex<:tt-WJМ AVTO _INCRE.МENT JМЧен.u.е О uzн.орuруе'"t!\ся.. Он.о .'11<<:tjbt€<:tе'"t!\Ся. З.9есЬ I)O'"t!\OMy, Ч'tr!о

фОРма J<:tl)poc<:t '"t!\редуе'"t!\ ГWlU.чu.я. I<<:tKozo-лu.~о JМЧен.u.я.

f"ySQ.\"-ФУНХu,ця tЮW() UС\1ОJbJуе1l\Ся. эля,..Эомвле.t-ШЯ Yl\eKYUJ,w< э<:tYl\bI. u fSpeмeнu..

€ Э'"t!\ОМ Mec'"t!\e.

Так как в этом SQL-запросе значения данных перечислены без укаэания //Д//,Н.-r/-l-FO////A;

#

///,"'/.4'a~д?Л'с"Rа?АЯ?&?,т.к-R.4'd'd'd'd.t'C'~A'ot:"C'z~<7J<7d'<7,c

НО мы только что добавили новую колонку, что означает, что запрос больше работать не будет: в нем нет значения для колонки screenshot. Поэтому добавление к таблице имени файла изображения как части новой записи рейтинга требует добавления еще одного значения в запрос INSERT:

INSBRT

INТO

guitarwars VALUES

(О,

NOW(),

'$naшe',

'$score' ,

!'

3<;tl)ucu, 1( OYl\OPbte. dbtЛu € YI\<:tdлuu,е м MOMett'"t!\ эод<:t€лекu.я. I{ОЛОНХU screel)~ot, uмe)(Тtl\ llyc'tТ\bt.e ,3мЧекu.Я..

\ \

Т10Ря.эоl<. в KOYr\0P OM ~ llереЧUСЛЯ)(Тtl\Ся. i- ЭYl\U ,3мЧеt-ШЯ. оЧен.Ь

€ct.ж.ек, I)ОСКОЛЬКУ

I"\PU в~олк.ен..u.u. j<:tI)POC<:t СЧUYl\<:tеYl\Ся.. Ч'tI'\о эаНJ-tbLe сле.э~ € Yl\oM .ж.е \1Оряэке, Ч'УУ\О U I{ОЛОНХU в CYI\pYКYI\ype 'tТ\<:tdЛU$

в ре'зУЛЬ'tТ\<:t'tТ\е €bI.I)ОЛн.екu.я. j<:tllp0C<:t INSERT ~ в I(ОЛОНХУ screel)~ot н.o€oo. J<:tI)UCU эомвляе'tТ\Ся.~· uмя. ф<:tйм UJодрdЖекu.я..

274

глава 5

На"

RТ,

чтоб... до6авlfПt ИМII фома из06ражени. в КОJlОНКУ screenshot.

, ,


ptl60mа с данными, сохраненными 8 файлах

ОпреАеление имени заГРУJИаемого файла

'.........

Запрос выглядит неплохо, но мы до сих пор не знаем, какое же имя

:;;,:~ ::::.:;.:,:.:~:: .. ..

;- _ ............

~

имеет файл изображения. Вполне можно предположить, что поле ввода

-

-~"'"I---"', 1j 8 ..

формы как-то предоставляет доступ к имени файла, но как? Ответ связан

\.,

со встроенной суперглобальной переменной $_FILES, во многом похожей

."' .'

на суперглобальную переменную $_POST, которую мы использовали

~lЯ получения доступа к данным формы. Как и переменная $_POST, переменная $_FILES является массивом , и его элементы содержат

< input type="file" name="screenshot" />

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

$_FILES['screenshot·] ['name']

$_FILES[·screenshot·] ['type']

~ MIME 'YY\u.!) 3dг.р~.ж.ctе.мог.о

фdilЛd. в ~кн.oM с~чае 6If.

$_FILES[·screenshot·] ['size']

('

phizssc~jf

"-Р<\3Мер ~г.РУЖ4емог.о файла (в ~a'YY\ax).

Это файл UJоdра.ж.ен.uя., KOYl\OPbt.u

$_FILES [ • screenshot.] [ • tпIp_name' )

Т10лн.ое. u.мя. вре.!"е.кн.о г.о ~ ~UЛd.. 1)0.9

Jd г руЖ4е.YI\С5!.

d~г.о.эар5!. t)ол)О €€О.эа цмe.н.u.

KOYl\OPbt.М сохран.ен.

на серве.ре

фаQ~ КQ <f:юрме.. $_FILES [ • screenshot • ] [ • error' )

СynергЛOGaAbныtt М8CCU5 $_AI.E.S

l

nOOlЮAgetn

nолyчumь

gocmyn

$_FILES, безусловно, очень важна, но в данный момент нам необходимо только имя файла изображения, которое может

О загружаемом tpaШе. .... .... ....

----------

в СЛ~Чdе. ~,,!)e.Lt.lМй 3dг.р~зкu. ЭYl\О'УУ\

..7ле.ме.н.YI\ JЛ4ссu.вd 1)e.u.~e.'YY\ з нач е.н.u.е О (коЛЬ). 'Ест же Jdг.r~3Кd фdilЛd н.е. ~.9dЛdсЬ КО.9 oUiu.дKu..

Вся информация, содержащаяся в суперглобальном массиве

к uяqюpмаuuu

,,

3dг.~Жае,мJ;W. фd.

быть сохранено в локальной переменной и использовано в SQL-запросе

_ _ _ • $screenshot

($ screenshot)

INSERT.

$_FILES [ • screenshot • ) [ • паше' ] ;

вы здесь.

275


храните данные внешних файлов во внешних файлах

Мuнуточку, НО мы СОХранилu ~ Оау. vaHHblX только

uмя фаuла U3QОражet1Uf! ... о

kкaK же сам фаLiл?-

о

Данные, содержащиес. во внешних фаЙllах,

06ычно так и ocтalOTc. в них, даже в ПрИllожени.х, ИСПОllЬ3УlOЩИХ 6азы данных. В этом случае данные

-

это набор пикселов, из которых состоит изображение.

Он сохранен во внешнем файле в формате GIF, JPEG или PNG (существует множество других форматов) . Хотя во многих базах данных

в

MySQL)

(

в том числе

предусмотрена ВО:iМОЖНОСТЬ сохранять бинарные данные (например,

изображения) в полях типа

BLOB (Binary Large Object, то есть "большие INT, CHAR, VARCHAR

бинарные объекты>.> ), операции с данными тина

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

Еще одной причиной, почему в веб-приложениях изображения не сохраняются

AIS вьmoga u.зa;paжeнus

на вe&<mpaнtnJ}' gooтwnoчно

тоАЬКО ССЬ1ЛКU

на qвt'1A u.зa;paжeнuэ.

сохранею.ьru. нa~ 276 глава 5

в базе данных, является то, что в этом случае было бы труднее кодировать в

HTML вывод

их на экран . Вспомните, что

HTML ссылается

на изображения

через имя внешнего файла, в котором это изображение сохранено. Поэтому в НТМL-теге, выводяшем на экран изображение, используется имя файла изображения, а не сами изображения.


работа с данными, сохраненными в файлах

~МЯ nap.6onмmь На главной странице приложения «Гитарные войны»

(index. php)

все еще не выводятся иэображения, подтверждающие подлинность рейтингов. Закончите код, чтобы они выводились.

<?php //

Соединение с базой данных

$dbc = mysql i_connect ( , www.guitarwars.net "

//

Извлечение данных рейтингов из базы

'admin', 'rocki t "

'gwdb');

MySQL

$query = $data = mysqli_query ($dbc, $query) ;

/ / Прохождение в цикле ПО массиву записей рейтингов. / / Форматирование данных записей в виде HTМL-Koдa. echo '<table>' ; while ($row = mysqli_fetch_array ($data) ) //

Вывод данных рейтингов

echo '<tr><td class=" scoreinfo" >' ; echo '<span class="score">' . $row[' score'] . '</span><br />' ; echo

'<strопg>Имя:</strопg>

echo

'<strопg>Дата:</strопg>

' . $row[

. '<br />';

' . $row[ 'date'] . '</td>';

i f (is_file ( .............................. .

echo '<td><img src='"

'пате']

&&

filesize ( '"

) > аlt="Подтверждено"

О)

{

/></td></tr>';

else { echo '<td><img src="unverified. gif" alt= "Не

подтверждено!

" /></td></tr>' ;

echo '</table>' ;

mysqli_close($dbc); ?>

вы здесь.

277


заточите свои карандаш решение

ХШ8"U8 заа8'lU На главной странице приложения «Гитарные войны»

(index. рЬр)

все еще не выводятся изображения, подтверждающие подлинность рейтингов. Закончите код, чтобы они выводились.

Для. Уl1рощекust K09d ~ к.е UСl1оJbзуе.м 3.9..есЬ

€~жен.uе

or die(1,

КО'УТ\орое €bt€оэu'УТ\ соОдщен.uе

од ошuдке € слу~е. еслu gbtr)олн.ен.uе ф~КJ(UJ..W.

<?рЬр

н.е узаС'УТ\СSL 1X>J,МO.ж.н.о, €bI. JdX01Т\u'YТ\e ЭОдd€U'УТ\Ь ег.о I"\PU

€кЛ)Очеки.u ~oг.o коза € c€oe I1рu.лoжен.uе. н.о с зан.н.ог.о

/ / Соединение с базой данных

MoMettl'I\c::t ~ дуэе.м I"\POI1YCKc::tl'l\b ег.о эля- K~'YТ\KOC'YТ\u..

$dbc = mysql i_connect ( , www.guitarwars.net "

'admin', 'rocki t "

'gwdb');

SQ.\..-3c::t"'poc, € pe3YJb'YТ\c::t'YТ\e €bU)offieкust

//

Извлечение данных рейтингов из базы МySQL 1(000000p0Zoo ~€~;I(c::t'lO'YТ\Ся. заl-l.Нbtе ш. П

• • $query = ...~~ю.. ~. ~~~ .9.,:,-.i~~~~~~~

.,1 ~ peu'YТ\u.к.г.(){), с(){)ершекн.о к.е UJ,Мe........."c""

..... '

$data = mysql i_query ($dbc, $query) ;

/ / Прохождение в цикле по массиву записей рейтингов. / / Форматирование данных записей в виде HTМL-Koдa. есЬо

. <table>' ;

while ($row = mysqli_fetch_array ($data) ) //

Вывод данных рейтингов

есЬо

'<tr><td class="scoreinfo">';

есЬо

'<spanclass="score">' • $row[ 'score'] • '</span><br />';

есЬо '<strопg>Имя:</strопg>

' • $row[

есЬо '<strопg>Дата:</strопg>

7mc::t

'пате']

' • $row[ 'da

'

• '<br /

9Эук.к~ "'рo€еря.еl'l\.

Ч'УТ\О в ЖАl'I\Ся. фc::tuле ~o~ l-ШSl е созер

.

"

• '</td>';

J.~~~.C~~!:~~':I.~.<?~'J) fileSiZe( ... $r~~C$.c;;r~~!'I~~~ о '<td><img src="'. $rОW['sсrееr'l~оt'J~lt="подтвержде~;'" -/:~/~d></tr>~

i f (is_file(

&&

............................ ...

~ l'I\c::tдлuu,е в I(ОЛОКJ(е scree",~ot coxpc::tк.eн.o

u..мя. фctUМ U30дpc::tж.еtш.st.: I1OЭl'l\€еРЖЭc::t)OW,ег.о l'\O~cl'l\b Эc::tн.н.ог.о peu'YТ\uMc::t. есЬо

'<td><img src= "unverified.gif" alt= "Не

подтверждено!

Измените rnaB

" /></td></tr>' ;

ницу

приnожени. «rитарн..е войн... так,

чтоб.. на ней ПО.виnись ИЭображени. по!'тверждаlOщие подпинность

реитинrов ПОnьэоватеnеЙ. ?>

278

глава 5

'


fЮ60та с данными, СОХfЮненнымu. файлах

-Тест-драйв Добавьте НОВЫЙ рейтинr в приnожение «rитарные ВОЙНЫ», которое уже ВЫВОАИТ иэображеНИII, ПОАтверждающие подnинноcrь реЙтинrов. Если вы еще не сделали этого, загрузите примеры кода для веб-приложения ~Гитарные войны» с сайта по адресу

www.he adfirs t labs.com/ books / hfphp. Этот код находится в каталоге chapterO 5 и включает главную ве6-страницу (index. php), сценарий ~Добавь свой рейтинг» (addscore .php) и каскадные таблицы стилей (style. СББ). Первое, что вы должны сделать ,

-

это внести изменения в сценарий

addscore . php,

которые

обеспечат форме ~Добавь свой рейтинг» поддержку загрузки на сервер файлов изображений, подтверждающих рейтинги . Это включает добавление в форму новых полей ввода данных,

корректировку тега

< form> и проверку того, что переменная $screenshot имеет какое-либо

непустое значение. Затем необходимо добавить в сценарий SQL-запрос INSERT, добавляющий новые записи рейтингов.

Теперь нужно перейти к сценарию index. php и добавить новый код, описанный на предыдущей странице, чтобы при открытии сценария на экран вывдилисьь изображения, подтверждающие подлинность рейтингов ДЛЯ всех записей.

Загрузите все эти файлы на ваш веб-сервер и откройте сценарий

addscore . php в браузере. index. php

Введите новый рейтинг и нажмите кнопку .Добавить» . Затем переЙдите к странице и проверьте новый рейтинг

.•.•.. '"

"',<;;

"'"

368420

ИJa: AпrroВ CJomСОВ

~: 2~'!.:()4-23 09:13:34

L.. ...... - . _......

64930

ИJa: I<eвви Левип

Дата: 2008-04-23 14:09:50

г···_··"'·-·····-

":

'·1865·80

И.N.I: фиц ~B

ДIПа: 2008-04-24 08:13:52

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

вы эдесь.

279


заzружаемые файлы сохраняются во временном каталоге

Kvaa деваются заГРVJИаемые

на сервер файлы?

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

файлы должны сохраняться в тот же каталог на веб-сервере, в котором размещены наши РНР-сценарии . Оказывается, это совершенно неверное предположение. Форма «добавь свой рейтинг!> дает возмuжность пользователю выбрать файл на своем собственном компьютере, но загруженный файл сохраняется во временном каталоге. Он создается на сервере автоматически и обычно имеет бессмысленное имя, состоящее из случайного набора букв и цифр. Такой подход порождает проблему для интерпретации кода файле

< img> в нашем index. php, так как в атрибуте src тега < img > указано короткое

(без каталога) имя файла, и это дает серверу основание считать, что файлы изображений раСllоложены в текущем каталоге , то есть в том же самом каталоге, в котором размещены РНР-сценарии.

Пеr.€ОНДЧdJIЬн.о фdЙЛ UJОдр~жеf-lliЯ,

110~"tТ\€еРЖ:9Q}ош,е20

~eu"tТ\u.нz, Р~СI)ОЛожек.

€ I<~I<ОМ-лu.dо Кс.\"tТ\с.\лоzе нд 1< оMt)b )(ТtI') е ре

t)ОЛЬ30€с.\"tТ\еля..

........ ~

"....-

280

глава

5

Э"tТ\ct cpopt-'a €b!.€°.9u-.n сSl

€ р е зулЬ'У!\ct"tТ\е €t;;t\jолк.ен.u.5l сu,ен.а.рu.Я. _ _- ctddscore·P"P·


работа с данны u,, сохраненными 8 файлах

Даl РНР предоставnяет вам возможност.. КОНТРОlIироват.. процесс сохранения фаЙIIОВ. Тем не менее вы не можете контролировать расположение каталога для первоначального сохранения загружаемых файлов. Но вы можете пере местить файл в другое место, после того как процесс загрузки завершился . РНР-функция

move_uploaded_file (),

используя исходное место расположения файла

и место его назначения , выполняет задачу по его перемещению:

~OMec1Т\O~ НдJН4 Чен.u.я

~ЙJk:l

u.3 0d Pcl-жен.uя, €i{Л}оЧcl)OOJ,ее. u.мя "ОС1Т\оЯн.н.ог.о 1(С\1Т\clЛо г.ct

u.

u.мя

сС\Мог.о ф<1.ЙЛcl.

, ,,

I

I

index.php move_uploaded_file()

В l(С\чеС1Т\€е I(cl1Т\clЛОг.С\ mo-же1Т\ dbt1Т\Ь u.с" оЛЬз о€С\н. Л}Оdой I(cl1Т\clЛог. н.ct ce.p€epe

€Q-Жк.о 1т\олы(,' Ч1Т\Оdbt У €QC dbtл .эля н.ег.о .эОС1Т\УI1 н.ct

3C\Ilu.cb.

'IQQJt)j!q(

'

~

phizsscore.gif

phizsscore.gif вы здесь

281


никаких гnynwx вопросов

lfG SbJ~iiG't1I,

ZV11blX ~011rOCO~

~: Разве я не могу изменить первоначальное место расположения загружаемых файлов, изменяя файл

php.ini?

О: Да. Инициализационный файл РНР (php. ini) может быть использован для изменения первоначального места расположения

загружаемых файлов через его опцию

upload_tmp_dir. Но если

вы арендуете виртуальный сервер у хостинговой компании, у вас

может не быть доступа с правом записи к этому файлу, что означает,

что вы все же должны будете переместить файл в свой собственный каталог с помощью сценария РНР.

~: Почему первоначальный каталог для загружаемых файлов называется «временный»? Он удаляется после того, как файл перемещен И3 него?

О: Нет. Каталог называется .временным» в том смысле, что он не рассматривается как окончательное место расположения

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

~: Почему я не могу просто оставить файл во временном каталоге?

О: ВЫ можете это сделать. В этом случае необходимо добавить

значение переменной

[ , tmp_name']

$_FILES [ ' screenshot ' ]

к имени файла изображения , чтобы к нему был

доступ во временном каталоге. Но имейте в виду, что в общем случае

у вас не будет полного контроля над именем и расположением каталога. И, что более важно, в некоторых системах временные каталоги могут периодически очищаться . Другая потенциальная

проблема заключается в том, что временные каталоги могут не быть доступными для всех, поэтому вы не сможете ссылаться на них из НТМL- кода, на чем базируется ве6-приложение «Гитарные

войны » И большинство других РНР-приложениЙ. Перемещая файлы из временного каталога, вы получаете полный контроль над тем,

где конкретно они будут размещаться и с каким уровнем доступа .

282

lлаваS


работа с данными, сохраненными 8 файлах

ОmлUЧtlо. \I1maк, я 3НЭЮ. как

~ьзэ~нblf.на~ срatlлbl. Эmo OO1cm&umtлbtlO хороою. но я ()о C1DC не uмeю HU малейUJefО noняmuя,

nor

(ие OНU Ооджны t'асоолаfЗmbCSt

KCUКДOMY ПРИJIОJКениlO необходим KaтCIIIOr Возможно, необходим

-

Images.

слишком громко сказано, но очень важно

орraнизовывать все составные части своего РНР-приложения настолько тщательно, насколько это возможно, так как загрузка

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

напрямую, по крайней мере, что касается имен файлов и их количества. Поэтому очень хорошо сохранять их отдельно от других файлов приложения .

После всего сказанного становится очевидным, что нам необходим каталог

images, в котором

будут храниться файлы изображений,

загруженные для приложения .Гитарные войны~ . Этот каталог при

необходимости может также быть местом расположения других

изображений, используемых приложением.

ФdКYI\uЧескu. I(dYl\dЛОг. iYl\ct~eS

к.е доЛЬше л)Odог.о эруг.ог.о I(dYl\dЛОг.ct,

н.о oh.ljo-мог.аеYl\

€ орг.ан.u.JdЩ,Щ

IjРUJ10.ж.еН1.LЯ., COdU.pct51 €ce фctG.Щ u.3 0d рct.жен.u.u. € оэн..о-м MecYl\e. вы здесь ~

283


соэаание каталоzа аля загруженны x файлов uзображений

Создаиие места ДЛЯ заГРУJКеииых файлов ИЗО6раJКеиий

:1vrio

Каталог images почти ничем не отличается от любого другого каталога на веб-сервере, ~a исключением того, что он должен быть размещен в главном каталоге веб-приложения €еd-кd.Yf\c!JlО G. t'lРuJ10жекuЯ, или в одном из его подкаталогов на веб-сервере. Обычно его создают как подкаталог главного веб-каталога приложения, но при желании вы можете создать более сложную

е KOYf\OPOM

иерархию.

р(.lJМещен.bt.

Если ваш каталог

images размещен в главном каталоге веб-приложения на веб-сервере,

можно ссылаться на файлы изображений из РНР-сценария следующим образом :

ИМЯ срай.лQ одЪеэu.н.ен.о с LtМeн.eM Kd.Yf\c!JlOz,d., одрd.JУя. t))'"YI\b. $screenshot;

Г

$target

РНР -сu,еК4РШ,А.

екЛ'~чd.я.

\t'ldex.ptp.

ве6-сервер

QmageS~izsscore.gif ") I

Путь $target образован конкатенацией новой константы, которую мы намерены добавить в сценарий. Она имеет имя

GW_UPLOADPATH,

каталога

и ее значением является имя нашего

images. Как и переменная, константа содержит

данные. Но значение константы не может быть изменено, после того как оно установлено. После ввода в форму

«добавь свой рейтинг» имени файла изображения оно добавляется к имени каталога images, образуя полное имя файла, или путь. _~"'"."'11~-~

Есnи РНР-приnожение размещено в nlOбом

M8cre, кроме Bawero nOKanbHoro KOMnblOTepa, вам

3ctг.j>ужекНЬt.е cpctuлbt

UJоdрd.жек.u.Ct l\еремеЩd )OYf\ся.

е Kd.Yf\c!JlOG.

понадобите., как минимум, ИСПОnЬЗ0Вать ПР дn. Toro, чтобы создать KaTanor Image.

ссbLf\d.Yf\ься.

Для создания каталога

НТМ\.. <iYf\Э> move uploaded file (

images

в веб-каталоге nриложения на вашем

iYf\dэеs, г.э е ко. к.u.x .можеYf\

эля. €bL€оэd.

Yf\ez.

-

-

веб-сервере вам необходим доступ

UJоdрd.жен.u.Ct $_FILES['screenshot·](·t~p_name· l ,

к его файловой системе. Для этого

ко. ЭКрd.н..

вы можете, например, использовать

любую FТР-утилиту.

284

глава

5


работа с данными, coxpaHeHHblMU 8 файлах

с1h.~Jfb~ рчi1,l\ОМ u,до8rч~GlfUt}I, дчZU~GlflfЫМ lfч CGr~Gr .ваша зagaча

urpamь роль qJe.-n.лa. UЗOБpВ.ЖeнUSJ.

-

nogmвepжgaющero nogлuююcmь peilmuнra. загруженного на сер5ер.

u UЗ06ра3umь nymь.

npox.ogum s npouecce pasomы npuложeнu9 ci'umapHbIe ю\lны». Начepmume CIIO\l путь через sce эmаnы npuлoжeнUSJ. не З85ЫS вазу gaHHbIx.. к.om.opыi1 qJe.Ш

Рассужga\lme maк.. как рассужgaл

,._"~....... . .БЬ1 загружeнны\l qJe.ш!

... d. '-i\-UJ.'Yf\е

:'!'!\С)09а\

phizsscore.gif

~ phizsscore.gif

:~=blc:e:.~~tir " м._

.~~:~..... ::~ ..

: ~~-~~,.._

..

:~

$screenshot

= $_FILES['screenshot']

INSERT INТO guitarwars VALUES (О, NOW(),

['паше'];

'$name', '$score', '$screenshot')

guitarwars $tteenshof

phizsscore.gif

вы здесь.

285


будьте файлом uзображеНUR, загруженным на сервер решение

с11t.aJfb1h,G ф~i1,лом. u,зоБГ~~GlfL4jI, 3~Zkt~GlflfbJM H~ CCГ~CГ .8awa зagaча -

urpamь рсмь

cpaw.a U306p8ЖeНU9.

nogmвepжgaющero nogлuннocmь peQmuнra.

cepsep. u UЗ06p8ЗUПlb nymь. npoxogum 6 n~ p8БOtnЫ npuюжeнug .umapныe lIO\l}lbl)t. ::.-_ __ Начepmume C1IO\l nymь через

зarpyжeннoro на

к.omopыi1 сраш

6W - ЭYl10 НdЧcU1bкbl.e

!!се эmanы npuлoжeншt

dук€/;;я. слое 6uitC\r WC\rs

не зa6bI6 вазу gaнныx.

Рассужga\lme maк. как рвссужgaл

(<<[uYl1C\pнbt.e €oaнbt.::I».

БЫ зarpyжeнныn сраШ!

Oнu ОjНdЧС\)(]'/!\ .3.9есЬ. Ч'II)о ЭYl1С\ кон.СYl1С\н."fI\Q

&рауэер

.........

r\oМii

t1рu~е.)fШ."fI\ t1рuл о женu)О.

dote

4

файn изображения из

4Q08.()4.23 ()9; 12:53

$

2()Q$.()4·~$. Q9: ~з,з4

6

2ОО!i..()4,i/Э

7

2008-04-2408; 13;52

для

заrруж:аемых файnов в постоянный

KaTanor

файnов изображений . глава

5

для

K<>I'e

2OGS,()4.:'2;! 09:0«3$

nepeMe~Ii~I~~~~~ BpeMeHHoro KaTanora

286

3

пате

14:09;50 Фиц Ланрстон

186580


работа с данными, сохраненными в файлах

ест-драйв ПОС8llите заrpуженнwе файnw изо6ражений, подтверждаlOЩИХ рейтинr, на их nocrOtlHHOe меао житепьства, в их со6crвеннwй KaTanor Дntl размещениtl файnов изо6ражениЙ. Внесите в сценарий addscore . php изменения, касающиеся использования константы GW_UPLOADPATH и сохранения загруженных файлов изображений в их собственный каталог. Вот фрагмент кода, который должен быть изменен: <?php //

ИНицИ ализация

~дш

к он станты.

имя каталога

' images I } ' /

i f (i s set($_ POST['submit ' ) )

//

содержащей

"р/",аеиых ф аЙ лов !f30БFа~

~ne ( ' GW_ UPLOADPATH ',

(

И з в лечение данных из супер глобал ьного масси в а

$_ POST

$narne = $_ POST [ ' narne ' ) ; $scor e = $_ POST [ ' score' ] ;

$sc r eenshot = $_ FILES( 'screenshot' ] ( ' name'] ; i f (! empty ($пarnе) && !empty ($score) && !empty ($screenshot) )

/ I Перем ОСТОЯННЫЙ каталог ДЛЯ файлов изображений $ ta rget = GW_ UPWADPATH $screenshot; i f (move_uploa е _ е $_ FILES['screenshot'] ['tmp_name'] , $target) 1/ Соединение с базой данных $dbc = mysq l i _ connect ( . www . guital:wars . net ., ' admin 1 . ' rockit 1, ' gwdb'); / / Запись данных в базу данных $query = " INSERT INТO gui tarwars VALUES mysqli_ query ($dbc, $query) ;

(О , NOWO,

'$пarnе',

'$score')";

/ / ВЫВОД пользователю подтверждения в получении данных echo '<р> Благодарим вас за то, Ч ТО добавили свой НОВЫЙ рейтинг ! < / р > '; ech o '<р><st r опg> Имя : </strопg> ' . $пате . '<br /> '; echo ' <strопg >реЙL;liil1 < '.at i! ев;" $score . '</р>' ; ech o '<img src · ' . GW иРLOАОРАТН . $screenshot . ,аlt=-Изображение, подтверждающее подлинность рейтин г а- I ><br 1> ' j echo ' <р><а href= - index.php·><< Назад к списку рейтингов</ а></р > , ;

!)

В сценарии

index. php также используется константа GW_UPLOADPATH,

Не забудьте

внести касающиеся ее изменения и в этот сценарий. После внесения всех этих

изменений загрузите сценарии на ваш веб-сервер и попробуйте опять ввести рейтинг.

3Qг.уужен.нbl.Й н.а cep€ep фQuл u.Jод~.ж.ен.u.я.,

\iО.9"1f\€еРЖ:9а)ОЩег.о

\iО.9 Л u.н.н.ос"tl'\Ь реЙ"tl'\w{z'd,

"tI'\el)epb €lЛ,9ен. н.а г.M€н.oЙ С"tl'\ран.uu,е \iрuло.ж.ен.u.я..

Для. CYf)C\pbtx 3ф)lЛсей ре~"tI'\uн.г.оg,_9Ля. I<O"tl'\opbtx tpaUЛbL UJod-рct.ж.ен.u.й,

\i О.9"t1'\€ер.ж..9 d }ош,ш< 11 0.9ЛЩ{Н,ОC"tI'\b ,

O"tl'\~)"'tI'\C"tI'\€Y)Q'/l'), €bLf5o,9u"tl'\ ся. UJодрd.жен.u.е с ФрCIJОй

«Не I')О.9"t1'\€ер.жэен.оl» вь, здесь.

287


никаких глупых вопросов

~; Если файл

php.ini

может быть

использован для контроля над местом

размещения загружаемых файлов, эачем тогда перемещать эти файлы?

О; Потому что не всегда имеется

возможность вносить изменения в файл

ph;:>. ini . И даже если у вас есть такая возможность. вы рискуете получить

проблемы. если возникнет необходимость переместить приложение на другой сервер.

Иначе говоря. приложение будет зависимо от пути. контролируемого внешним

файлом

php. i ni.

в отличие от пути,

контролируемого внутренним кодом РНР вашего приложения .

~; Почему дата вводится приложением, а не пользователем?

О; Дата является важной частью

рейтинга и определяется моментом.

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

зарегистрировавший свой рекорд. получает всю славу и преимущества.

Чем полагаться на пользователя

в вопросе даты регистрации рейтинга. мы можем просто использовать дату

и время поступления рейтинга на сайт

как дату и время его официальной регистрации . Это уменьшает опасность того, что появятся недостоверные даты

регистрации рейтингов. и повышает уровень доверия к перечню рейтингов

со стороны пользователей. Пользователи

таких приложений всегда будут искать какие-либо лазейки для получения преимуществ, поэтому необходимо сократить их количество настолько,

IfG SbJ~a.G1h,

Z1111bJX ~011YOCO~ l1} •

·Р • Разве у пользователя нет

возможности переписать чей-нибудь

файл изображения, подтверждающий

проблема здесь заключается в том. что

О ; Да. Проблема связана с тем. что файл

изображений на экран в главной странице

index. php. HTML-Ter < img> разработан

изображения, подтверждающий рейтинг. сохраняется на веб-сервере под тем же

таким образом. что он использует ссылку на имя файла изображения. сохраненного

HTML-KOA для вывода загруженных

на сервере. а не на бинарные данные.

в поле ввода имени загружаемого файла. Поэтому. если два пользователя загружают

содержащиеся в базе данных. Поэтому. если вы измените таблицу gu i t а rwar s так.

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

на момент загрузки времени в секундах

в начало имени файла. как показано ниже:

чтобы она смогла хранить бинарные данные изображений рейтингов, то столкнетесь с серьезной проблемоЙ. связанной с извлечением их из таблицы в формате, необходимом для вывода на экран с использованием HTML-коАа.

Фую<u,uя 1ilТ)eO н.е €btt)олн.яе-m

f{i).KcJ.l\oU ролu-. цроме lТ)oй '-tm o J . $screens r,ot; ~н.u-цctЛЬн.btx .9ct н.н.btx в результате интерпретации "'- € ctK U-З€~СIТ)н.о. € pect;;bfiou ЖL\'\н. .. этого кода имя файла будет ' \ ремя. .9~u.же'l!1СЯ lТ)оЛЬко €t)epec. 1221634 560phizsscore . gi f вместо t)ОЭ~ОМУ 3Н,QЧен.u-е. €ОJ€рctш,ctе .....;с : phizsscore. gi f, где число 1221634560 ЭIТ)ОU фун.цu.,u.еЙ. "OClТ)o5('н.н.o $target

о G\v_U?rдlI.D?fl.TH . t ~ me ()

является текущим (на момент генерации имени файла, то есть

на момент загрузки)

oН,Q я.€ля.еIТ)Ся. U-СIТ)ОУfiU-кdм

€oJpctcyrIctelТ)!

~ .. КnIOЧЕВЫЕ МОМЕНТЫ

временем. выраженным ~

в секундах.

l1}.

.Р • Могли бы

• . Запрос ALТER используется для того. чтобы изменить структуру таблицы базы данных MySQL. например. чтобы

добавить новую колонку данных.

мы сохранять

непосредственно в базе

С небольшой помощью РНР и

MySQL HTML-Ter < inpu t >

данных «Гитарных войн»

может быть использован для загрузки файпов

само изображение,

изображений на сервер .

подтверждающее

рейтинг пользователя?

того, чтобы сохранять информацию о загруженных

Стандартная РНР-функция

move_uploaded_file () но.

gaHHblX. ОБычно ygОБнее UCnOAb306at11Ь БаЗЫ gaHHblx gю coxpaнeнus s них ссылок на uмeнa sнешних qxt.Uл06.

gaHHble.

даетвам

возможность перемещать файлы на сервере и играет

ключевую роль в обработке загружаемых на сервер

кorgа gело касаетсэ БUнарных

cogержащux. этu Бuнарные

Суперглобальная переменная $_FI LES служит для на сервер файлах .

gaHHbJ)\ ОЧень ygОБНО xpaнut11Ь текстовые gaHHMe.

5

приложение «Гитарные войны» использует

самым именем. которое пользователь ввел

в saзax

глава

сохранять бинарные данные. Но основная

рейтинг, путем загрузки файла с таким же

именем?

насколько это возможно .

288

О; Да. База данных, являясь исключительно гибкой системой. позволяет

файлов .

В большинстве ве6-приложений считается очень важным сохранять все файлы изображений. используемые приложением. в отдельном каталоге. обычно с именем

i

rnа 9 е s . Особенно важно это для файлов, загружаемых

пользователями этих приложениЙ .


работа с данными, сохраненными 8 файлах

~ l(oIiC"IY\~IiYI\e

Мне н!,а&umся nщ чmо uмя

кamaлorа ()ля х!'аненuя ?>Э~Нbf)( на cer&er

G\>'-UPLOADPATH

4>аUло& сwеркumся &Koнcmaнme, но почему она

D

соэерЖu."IY\Ся. UМSI.

со,()aemcя &()&ух мronax: indйC.f1hf1 u addscort.f1hf1:?

К~"IY\С\.Ло~.эля х~н.ен.uя

Чmо n!'ou3Qooem n!'u u3М€l'leнuu 3n1oro uмeнu:?

J~гуужен.н.btx Н,Q cer.€ep

~uло€ UJодРФf(.ен.uu.

d.f <n. (

'''''_OP'''A'>PAТII', iшa '

1'-;11

Фукхu,u5l defil'\eO ~ UСl'\ оль зуе"'l'l\Ся. ЭЛЯ "'I'I\O~o. Чv!\ОдbL СО.3Эd."'I'I\Ь u ш-tuЩJ.d.ЛUJuро€о:mЬ

L

::J

••• ' ' ) I

3мЧекu.е КОн.С"'l'l\~н."'I'I\

.

имя KO"'l'l\0pOe н.е мож.е"'l'l\ дbL"'I'I\Ь кон.СYl\~н."IY\bL. UJМeн.eн.o ... На "'1'1\0 оМ U КОн.С"'l'l\d.н."'I'I\d.!

КОн.С"'l'l\~н."'I'I\У·

Еспи им. KaTallOra иэменитс., .... ДОII.Н'" будете иэменить код. д.ух местах... Ду6l1иро.ание кода

-

очень nllоха. практикаl Итак, внутри каждого из отдельных файлов

index . php и addscore . php

константа GW_UPLOADPATH работает хорошо. Но инициализация этой константы осуществляется в каждом сценарии, и это означает, что

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

11 инициализация константы, содеРJlащей

1/

• ката "ога пля загружаемых файлов изображении '].mages)' ::>

~ ine ( 'GW_U1?LOADPATH',

KoIiCYl\~IiYI\~ w-ш.u,u.С\.ЛUJUРО€~М Э€~-Ж9bL. u Э'VI'\О ОJн.dч~еYl\. ЧYl}о 0эн.d U

Yl\d.

ж.е

I{OIiCYl\d.Ii"'I'I\d. ЭОJl.)/(.Н,Q

------А t)оээерж.u.€d.YI\ЬСя. € э€ух pctJн.bt.x MeCYl\~.

Для решения проблемы дублирования кода нам необходимо инициализировать константу в одном месте.

/ I Инициализация константы, содержащей / / имя катаЛога для за

I/

гpy~aeмыx файлов изображений,

efine ('GW_UРLOАDРДТИ ' , de 1. _

'irnages/')' 8);

аксимального размера файла

,

Где бы вы инициализировали эту константу: в сценарии

или в сценарии

index. php addscore. php?

Почему?

addscore.php вы здесь ~

289


совместное использование данных с ПОМОЩЬЮ включаемых файлов

ООщие данные ДОЛЖНЫ ИСПОЛЬJоваться совместно Когда речь идет о данных, используемых совместно несколькими сценариями

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

CPat1AbI. ucnользуемые

Вы моrllИ 6ы инициаllизировать данные В сценарии //

C06МeCInНO

index.php ...

ИНИциализация

...

нecкOAbКuми

к о н с т а н ты.

cueнapusми

содержащей

/ / имя каталога для загружаемых файлов define ('GW_UPLOADPATH', 'imagesf');

изображен

nрuложema gоАжны1

5b1ffib

index.php ••• но TorAa

gocmynны

AЮlЮМУ

u3

них БеЗ

gysлup06aНU9

ttoga.

друrие сценарии не 6удут иметь доступа к этим данным.

Q о Инициализация совместно используемых данных в каком-то одном сценарии не дает ожидаемого результата, поскольку другие сценарии

не имеют к ним доступа, в связи с чем эти данные фактически

не являются совместными. Решение этой проблемы заключается

addscore.php

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

rGW_UPW~~~~)

----;:/

~-----~

index.php

addscore.php Как Ж8 мы сможем сдenать данные доступными ДВУМ сценаРИRМ, не инициаllИЗИРУR эти данные

ни В одном из них? Обеспечение совместного доступа к данным заключается в использовании включаемых файлов, содержащих РНР-код, который

при необходимости может быть включен в любой РНР-сценариЙ.

290

глава

5


работа с данными, сохраненными в файлах

Совместные данные включаются в сценарий

в тот момент, когда они тре6уются I Iспользование добавляемых

файлов

-

Вк..лючаемые

это очень мощный механизм, потому что вы

создаете их однажды и затем включаете их код в любые сценарии по необходимости, что позволяет очень эффективно использовать совместный код. Константа GW_UPLOADPATH

<раtlлbl nm1ЮA9Юtn

~\Ожет быть инициализирована в добавляемом файле, формируя таким образом ~набор

ООМ\ectnно

переменных уровня приложения~.

UCnOAb3058.t11b

<?php 1/

//

ttog Инициализация

имя

константы,

каталога для

содержащей

нескОЛЬКUМ

загружаемых файлов изображений

de f ine ( 'GW_UPLQADPATH',

'images I ' ) ;

Ct,JeНaрuзм.

?>

require_once ( 'appvars. php 1) ;

oddscore.~

require_once ( 'appvars. php' ) ;

index.~ !1

JfG ubJ~itG'}1t,

)Jодct€ленu.е ctppvctrs.Dh~ g.9p'~~цe cu,e~pu.u. 11 6 з150л я-е"'tТ\

u.м u.С\iолЬзо€ct-mь l")er.eMeк.нbte, J..

u.WJ.u,u.ctлu.зu.ро€ctн.нЫе I

€ ctppvctrS T .р.

ZVl1bJ.x ~Ol1fOCO~

~; Послушайте, а действительно ли зти «переменные уровня приложения» являются константами?

О

; Иногда да. Но здесь все в порядке. Нашей целью

~ является дать строгое определение разницы между "1еременной и константой. Мы всего лишь пытаемся найти "о место, где мы могли бы поместить код для совместного .кпользования всеми сценариями приложения. И таким местом .вился для нас сценарий appvars .php.

1}

;

",р Код в добавляемом сценарии должен быть ограничен ТOnbKo данными?

О ; Совсем нет. Любой РНР-код может быть помещен в свой

'9; Почему РНР-выражение, обеспечивающее добавление

к сценарию совместно используемого кода из другого сценария, называется require_once?

О

; Имя «включить файЛ» (inc 1ude f i le) происходит

от РНР-выражения inc 1ude (включить), которое выполняет функцию, подобную функции выражения require_once . Разница заключается в том, что если файл, указанный в выражении require_once, не будет найден, то будет выведено сообщение об ошибке. В случае же использования выражения

inc 1ude ошибка выведена не будет. Слово опсе (однажды) в зтом выражении означает, что код будет добавлен в сценарий только

однажды, даже если 3ТО выражение встретится в нем (по ошибке)

более одного раза. Иногда вы увидите использование выражения

include вместо выражения require_once для включения

:обственный сценарий и добавляться в другие сценарии

не слишком важного кода, например чистого НТМL-кода,

'риложения, если использовать выражение

не используемого в критических ситуациях. В РНР также

requi re_once.

1>актически использование разными сценариями приложения :овместного кода является очень распространенной практикоЙ. Это часто очень помогает в вопросах организации кода всего

используются выражения include_once и являются вариантами выражений require_once и include.

require.

которые

'риложения,

вы здесь

291


выражение require . аnее

Рассматривайте выражение

require _оп се

как «вставить»

Количество добавляемых файлов не ограничивается единственным файлом, они могут появиться в любом нужном вам месте сценария. Вы можете рассматривать выражение

require_once

как выражение «вставить>,> ,

заменяющееся содержанием сценария , на которое оно ссылается. В случае

с приложением «Гитарные войны>'> переменные, необходимые для соединения с базой данных , также могут быть помещены в добавляемый файл . Теперь уже содержание двух добавляемых файлов будет включаться в другие сценарии в те места, где они требуются.

~----------------I

requ i

<7php жащей ~""'I'+ // Инициализация константы, содер .г. // имя каталога для загружаеМых файлов изображении define( ' GW_UPLOADPATH ',

re - once('appvars.phP');

_______--

' lmages/');

7>

э-md z-лоdaлbкая. l1ереме.~я. созе.Р)/Ш)ТJ

€dжнbtе ЭdНJ-lbtе у ро€н.я. 11 рu.ложеt-U..LSt,

J<o)ТJopbLe н.еодхоэu.мbt

U сu,екарщо

it1dex,p"p, U сu,екарщо dddscore.p"p,

require_once('connectvars.php'); <7php // Инициализация констант, содержащих // информацию, необходимую для // соединения с базой данных define('DB_HOST', ·WWW . quitarwars.com.); deflne( 'DB_USER', ' admin ' ); define('DB_PASSWORD' , ' rOCkit'). define( 'DB_NAМE', ' gwdb'); ' ~r-__ 7>

~Me.C)ТJO )ТJOгO 'h'r\odbt. эудЛUРО a)ТJb MpeMeн.нbte, н.еодхоэuмbt.е эля. соеэuн.ен.u.5t с ddJOu. Эd.н.rWu<

~J ~" . .~~§

fAiiiliillilff1 connecм:rs.php

€ Ka~OM cu,eкapuu, мbt. МожеМ

l')e.pertec)ТJu ux gэодd.€ля.еМbt.Й фdu.л U UСI"\ОЛЬjО€d"tТ\Ь COeMec"tТ\н.o.

вы1ажeнuеe

l\EOUU\E_ONCE g0Ба5Age1tl СО6Местно иCnОАЬ3уемьro Kog в gpyrue CUeнa.PUu 292

lлаваS


работа с данными, сохраненными 8 файлах

<?php г

// //

Инициализация

константы,

имя каталога для

,

содержащей

загружаемых файлов изображений

L _de.!.in~ ( ~W.,2 P~A~A!.H'...:.. '~m':2e :.C !..: _ г

, .J

--------------

// Инициализация констант, содержащих // информацию, необходимую для / / соединения с базой данных define('DB_HOST ', .www . quitarwars.com . ); define('DB_USER ' , ' admin ' ); define('DB_ PASSWORD', ' rockit') ; define( ' DB_NAМE 'gwdb ); _ _ L _ ___ _ _ ', __ _'_

D о

.J

// Соединение с базой данных $dbc = mysqli_ connect(DB_ HOST , DB_ USER , DB_ PASSWORD,

DB_NAМE);

// Извлечение данных рейтинго в из базы MySQL $query = "SELECT * FROM guitarwars ORDER ВУ score DESC , date ASC "; $data = mysqli_ query($dbc, $query); // Прохождение в цикле по массиву записей рейт ингов . // Форматирование данных записей в виде HТМL- K oдa . echo '<table> ' ; while ($row = mysqli_ fetch_ array($data)) // Вывод данных рейтингов echo '<tr><td class="scoreinfo"> ' ; echo ' <span class="score " >' . $row[ ' score ' ] . ' </span><br /> '; echo ' <strопg>Имя : </strопg> ' . $row[ ' name ' ] . ' <br /> ' ; echo ' <strопg>Дата : </strопg> ' . $row['date ' ] . '</td> '; i f (is_ file(GW_UPLOADPATH . $row[ ' screenshot']) && filesize(GW_ ~PLOADPATH . $row[ ' screenshot ' ]) > О) { echo ' <td><img src= "' . GW_ UPLOADPATH . $row['screenshot ' ] . аlt="Подтверждено " /></td></tr> ';

емом

файле константу

и присвойте ей значение имени каталоrа Дn.

заrружаемых фаЙл~в.

Добавьте в сценарии

_

код, обеспечивающии ее совместное

использование.

}

else { echo '<td><img src= "' . GW_ UPLOADPATH . alt="He подтверждено! " /></td></tr> ' ;

о

' unverified . gif '

.

'"

}

Ой, еще 0.9UK кo€bt.u ЭW\d.t)I HeI{O'Т\0pbt.e J":9d ЧU ке "'С\I( леZI{О

echo ' </table> ';

t)MкupO€d.W\b, t)ОЭW\ОМУ

mysqli_ close($dbc) ;

index.php

dY.9bW\e €cez~d. zoW\o€bt. l{oppel{W\upo~d.W\b схему

c€oeг.o t)рUЛОж.еI-W.Я. t-tC\ леW\}

J-Тест-драйв

Создайте два добаВnRемых файnа Дn. приnо_ениg «rиторные войны» И откорректируйте друrие сценарии, обеспечив совместное испоnьзование общих переменных. Создайте два добавляемых файла appvars . php и

connectvars . php и введите в них код, require_once в сценарии

показанный на предыдущей странице. Затем добавьте выражение

index . php и addscore . php так, чтобы содержание обоих добавляемых файлов было включено в эти сценарии. Загрузите новые версии всех сценариев на ваш веб-сервер, проверьте работу формы <lдо6авь свой рейтинг» и главной страницы. У6едитесь в том, что все в порядке с новой органиэаЦИОНIIОЙ структурой, основанной на совместном использовании данных с помощью

добавляемых файлов.

вы здесь ~

293


еыроженuе

ORDER ВУ

порядкv Распределение ПО вр_м_ии

это все,

когда речь идет о рейтингах Наконец-то приложение ~Гитарные войны. позволяет пользователям загружать на сервер файлы

изображений, подтверждающие их рейтинги. Хотя это и является существенным усовершенствованием приложения, оно не решает проблему, на которую пользователи периодически жалуются, а именно отсутствие определенного порядка, в котором их рейтинги появляются на главной странице. t •...,.wc ...... · 'II_ ............

.:f~;;~ Д~~аЙ~еftu'е

... '-hт)o €~ЛЯЭu''УУ1 pe.u.'Y\'\U,f{z,Q 'У\'\е\')е.рЬ О'УУ1ЛU, Ун.о

;~

... -.......

:::1~-

-.......

CO\')rO€o~"eYl\c~ .9 0 &€лен.u.ем cpct~

.3"

U,СКЛ)ОЧен.u.ем

'YY1 0 Z.0,

.........,...,...,. . ............

,~ '

ftO€OZ.O

u''з0~р'Q.жеlW.Я.,

'-hт)o

~eu.'YY1u.нzu'

\')О.9'У\'\веr~)ОЩег.о

€bt€o.95!.'YY1 C 5!.

ЭYl\О'У\'\ реu'У\'\U,ftг. ...

у ~Я WUHCm~HOU

maкoй t'WmUHr с U~t'aжetiUем, nООm&epжQзю1J.lUМ ero nоолuнносmь, но почему я oкa~ &самом КIЖue cnucкa:?

dеСI1ОРЯЭО Чн.о( о

..... .. ---

60<'1)0

,......",

--11\6-"'"

*"I1~II;I)~

Гитарные

J

~ Это верно, список выводится на экран как попало. Рейтинги

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

вопрос вас вообще не интересует. Это не тот случай, поэтому нам необходимо принять меры, чтобы записи в результате запроса следовали в определенном порядке. Выражение, начинающееся с ключевых слов ORDER ВУ (в порядке ... ), позволяет упорядочить записи в результате запроса .

294

глава

5


работа С данными, сохраненнь,ми 8 файлах

Магниты РНР

u MySOL

Проверьте, как работает выражение

упорядоченные запросы

ORDER ВУ, создавая с помощью магнитов SELECT, в результате выполнения которых будут получены

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

от

ASCending (возрастающий), DESC -

от

ASC -

сокращение

DESCending (убывающий) .

вы здесь.

295


магниты РНР и MYSQL решение

Магниты РНР

u MySOL

Проверьте, как работает выражение ORDER ВУ, создавая с помощью магнитов упорядоченные запросы SELECT, в результате выполнения которых будут получены

показанные ниже результаты. Подумайте также, какой из запросов в большей степени отражает главную идею приложения «Гитарные войны». Примечание: ASC от ASCending (возрастающий), DESC - от DESCending (у6ы й) .

Уl"\~яэочеtillе

1"\0 Э4Yf\е сЯ u. 11 оu.з€оэu.Yf\сЯ Yf\олЬко 9.ЛЯ 341"\u.ceu. оэu.НдКо€btМu. .3 ЧеtшЯМu. peuYf\u.н.z.o€. ~ Э4ru«JМ слуЧ4 е Yf\4Ku.x J41"\u.ceu ",-еYf\. н.о он.и. €I"\олн.е Moг-'j'tТ\ t)ОЯ€u.Yf\ЬСЯ. ког.Э 4 cl"\u.COK СYf\4н.е1У\ ЭОСYf\4Yf\ОЧн.о долЬшuм.

296

глово5

сокращение

.3аt)5!.Yf\4Я н.еоdхоэt.tМ.4

.3э есЬ Э_Л5!. РС\Jэ еле н.u.5l э€ух уро€к.еu уt)оря.эочu.€ан.u.5l.


работа с данными,

coxpaHeHHblMU 8

файлах

Награды самым лучwим гитарны M воинам После того как мы разобрались с упорядочиванием рейтингов, теперь можем сделать неожиданное улучшение списка рейтингов путем перемещения наивысших рейтингов в самое начало списка . Гитарный воин с наивысшим

рейтингом заслуживает права находиться в заголовке списка, чтобы все видели, ",о самый сильный гитарный воин и против какого рейтинга придется воевать,

чтобы его победить.

; Гитарные !оЙиы.

, СПИСОК реитингов ! Добро по.anоаат. , гlП~выА вони! ТВОЙ е этом списке pc~8 . ~n_~ T~,... . ....

3аZОЛО€ОI< CI1U.CI<d. peU'Yl'\u.ftZ.o€

.

н.cJ.zлЯЭк.о

.g eMoKC'YI'\pu.pye'Yl'\ н.cJ.u.€btсшu.Й

peU'Yl'\u.ftZ.. I')ОI(d.,3bt€d.я. u,еЛЬ. 1( I(O'Yl'\0POu. ду.9У'У1'1 С'Yl'\ре.мu.'YI'\ЬСя.

zu.'YI'\d.pк.bte €Ou.к.bt € c€oeй дорьде.

:; 345900 ... .... _ _ :з

: Дn. : 2008-04-23

HG БЫ~ClG'}h,

Z'if11bJX ~011ГOCO~

'Р: Мноrие рейтинrи все еще не подтверждены. Разве зто не проблема?

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

рейтинге.

вь, здесь ~

297


доtЮеленuе немного С55

Форматирование (пи(ка рейтингов

(

помощью НТМL и

[55

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

HTML, и CSS.

Заголовок генерируется как строка

НТМL-таблицы, а для визуального выделения его из общего фона к нему применяется особый СSS-стиль. Этот стиль,

topscoreheader, должен

быть добавлен в файл каскадных таблиц стилей приложения ~Гитарные войны~

style. css.

Тек c"tl) Jctг.оло€кct €b1.pct€Ku.€cte"tl) ся.

Эv!)о"tl) КМсс с"!Т\цля. .уже u.С\10лЬ.зо€ctЛся. эля.

б'~елен.u.я. соодщен.u.u. од ошu.дкctX € сu,ендрu.u. «ДОдct€Ь c€oй реu."!Т\u.нz ».

.error { font-weight: bold;~------------------~~ color: #РРОООО;

\')0 u,ен."tI)ру.

.topscoreheader - - - - t l 7 text-align: center; font-size: 200%;~--------~------___---t--.L_'-. background-color: color: #рррррр;

Удеэu."!Т\есЬ € "!Т\ОМ,

'hr\o Для. л~чшег.о €btgеленu.5l "tI)eKc"tl)ct 3ct г.оло(Гкct € ег.о н.ct\1u.cctкu.u. u.С\10лЬз~еi'\\Ся. делЬtд шрu.cpm н.ct черrtом сроке.

\10 срct€кен.що с pctJMePOM шри~ ОСi'\\ctлbrtог.о "tI)еКС"!Т\Q

.scoreinfo vertical-align: top; padding-right:15px;

styIe.css

Эv!)u. э€ct клctССct с"tl)цлеu. уже u.С\10лЬjУ}ОУ(\Ся. эля.

<роРМct"tl)u.ео(s'ctн.u.я. "tI)eKC"tI)o€

peu."tI)u.нzo€, €b1.€оэuмbtx н.ct г.лct€коu. с"tl)рctн.u.u,е. Сценарий

index. php уже генерирует

НТМL-таблицу, содержащую список

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

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

while

проходит через все рейтинги по порядку,

поэтому нам необходимо найти способ как-то подсчитать эти проходы цикла и сгенерировать заголовок только в первом из них

298

zлава5

p.ctJМe~

шрu.Cf.:rn}ct j>елu.чек

.score { font-size:150%; color: #36407Р;

...


работа с данными, сохраненными 8 файлах

Измените код в файле

i ndex . php приложения

« Гитарные войны » так,

чтобы добавить форматирование заголовка списка в соответствии с классом (55-стиля

topscoreheader. (овет: не забывайте, что заголовок списка рейтингов

-

зто часть состоящей из двух

колонок HTMl-таблицы, в которой располагается список рейтингов.

Прохождение

// //

в

цикле по массиву

Форматирование данных

записей

записей рейтингов. в

виде HTМL-Koдa.

echo • <table> ' ; $i =

О;

whilf# • .!.~;-Я~.:'.. !1!~.~9.~~.~~~~'?h~~::::;-~~ ($data) ) //

Вывод данных рейтингов

if ( .............. .. ) {

echo '<tr><td class="scoreinfo">'; echo '<span class="score">' echo

'<strопg>Имя:</strопg>

echo

'<strопg>Дата:</strопg>

$row[' score'] '

.

. $row[ 'name'] '

. $row['date']

' </ span><br /> ' ; .

'<br /> '; .

'< / td> ';

i f (is_file(GW_UPLOADPATH • $row['screenshot']) && filesize(GW_UPLOADPATH . $row[' screenshot']) > echo '<td><img src="'

. GW_UPLOADPATH .

аlt="Подтверждено"

О)

$row['scr~enshot']

/></td></tr>';

else echo '< td>< img src= "' alt="He

. GW_UPLOADPATH .

подтверждено !"

'unverified.gif'

/></td></tr>';

.1 ........ ........ ... ..

echo '< / table>' ;

index.php

ВЬlздесь

299


упражнение решение

Измените код в файле

index . php приложения

« Гитарные войны » так,

чтобы добавить форматирование заголовка списка в соответствии с классом (55-стиля

topscoreheader. к

VПi>~

Совет: не забывайте, что заголовок списка рейтингов -

это часть состоящей из двух

колонок НТМL-таблицы, в которой располагается список рейтингов.

3'lr\o t)epeMeKJ-V:\Я.

$i -

КcrtI\ОраЯ. сЧU1l\4е1Т\ коmчеС1Т\gо

н.u.b. UJ.I.I<lld ~ JN>!жем uсt)ОJb~1Т\Ь ее_ qля. :gогд

~(~;t.~t)~еЭЕ;m1Т\Ь ~e~~e u3 I-ШX, KcrtI\0FM~ соcrtl\fS'em с1Т\ ~1Т\

II

t)еp€bШ (kti'~) peи1Т\\'\кz' по массиву записей рейтингов.

Прохождение

записей

в

виде

К

=

о;

мu€&tсщее его .3МЧен.u.е,

!10Э1'I\0МУ UМeнн.o € Э'II'\ОМ Mec'll'\e н.eoдx0.9UМo .3QI'1UCQ'II'\b HTML-I(0.9 .9ля. €/;я..€О.9Q 'зQZОЛО€I(Q cl'1ucl(Q.

while ($row = mysqli_fetch_array($data))

if

€J

{)

НТМL-кода.

echo '<table>' ; $i

$'

OZ.9Q 1 PQ оно О, .мbt 1'I\0Чно .3мем, что ЛrlОМ !1Р ОХО.9 е u,uIUkt .мbt PQCC,МQ'II'\pu€cteM l'1 ep€y>o }Qt'jucb реСпу\u.н.г.ct, 1(000000pou COO'll'\€e'll'\c1'l\€ye1'l\

(..$.i..7.7..0. ... ) (

..~.4.<?:~. tp~. ~{~9.~~p.c:'~:: ~ ;,..~ .~.~~~.~:7)9.p.~~.l?r~~~~(~ Н~~~~.\щ:9: .p.~Q.m~: ....... . .....$rОwгsёо.rе.'Т: .•<'/td>.<Н.6'; ....................................':... ':":-...-:'М'

"---

..........................._ " ) . . . . . . ..

echo '<tr><td class="scoreinfo·>';

Кмсс

echo '<span class="score">'

topscorel-tectde.r

echo

'<strопg>Имя:< / strопg>

echo

'<strопg>Дата:</strопg>

$row['score']

.

. $row['name'] '

'</span><br 1>'; .

. $row['date']

'<br 1>'; .

Оl'1р езе.ле.н. € фctu.ле

sty.fe.css.

'</td>';

i f (is_file(GW_UPLOADPATH . $row['screenshot']) && filesize(GW_UPLOADPATH . $row['screenshot']) > echo '<td><img src="'

О)

. GW_UPLOADPATH . $row['screenshot']

аlt=·Подтверждено"

1></ td>< / tr>';

else echo '<td><img src="' '" alt="He

. GW_UPLOADPATH •

подтверждено!"

'unverified.gif'

1></td></tr>';

.1$.\t:t~ 3МЧен.u.е сЧе1'l\ЧЩQ

~елu.ЧU€Qе'll'\Ся. м e.9u.н.uu,y

OXo.9O€ u,uI(M

echo ' </table> ' ;

эоо

zлава5

1(0Ku,e I(Q.жgого IlРОХОЭct. Yn,01'l\ 1(0.9 ЭI(Чu€ctЛiн...",ен. 1(0.9:1 $i = $i + 1;

Index.php


работа с данными, сохраненными в файлах

-Тест-драйв Упор.дочьте список рейтинrов и продемонстрируйте всем наивысwий реЙтинr. Внесите в файл index . php изменения , касающиеся упорядочения результата запроса SELECT, затем добавьте код, который генерирует заголовок списка рейтингов. Загрузите

откорректированный сценарий на ваш веб-сервер и откройте его в браузере, чтобы

убедиться в том, что наивысший рейтинг выделяется на общем фоне страницы.

( HdU€btcWUu.

реu.lТ\uкг. lТ\e\1eeb jdя.€ля.еlТ\ о седе 2-j>0Мl<о U я.рКО

€' cd}ll.oM €epx~ cI"\UCKd.

Это, конечно, круто, Что CnUCOK

menerb УГlОряVочен ...

lОлько, )Наете лц людоu U3 Этuх нenоотl?ержvенных peйmuHrol? может

дыть nоVVельным.

Это верно, с неподтвержденными рейтинrами надо раэбиратьс•• Но не все сразу. Похоже, возникла еще одна проблема, мешающая пользователям загружать свои файлы изображений , подтверждающие подлинность рейтингов ...

вы здесь.

301


добавление огроничениu роэмеров для файлов uзображенuй

\ Гитарные войны. •Добавь свой рейтинг _ __--. ..:

Им

:3':911 Xecml

.",..

---.,

.. ....

.... ,

,,

, \

efhelshugescore.pdf

\

но это даже и не файn из06ражениgl у нас имеется проблема, которая заключается в том, что приложение не только отказывается

загружать некоторые файлы, но и не сообщает пользователю, по какой причине. Хорошо то, что приложение отказывается загружать некоторые файлы , в данном случае потому ,

что он слишком велик (помните, в коде формы мы ограничили размер загружаемых

файлов величиной в

,, ,, ,

\

Файn не тоnltко cnиwком веnик по размеру,

I

32 КбаЙт) . Но нам необходимо ясно проинформировать пользователя,

по какой причине это произошло. И это не все. Мы не хотим, чтобы пользователи загружали

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

Итак, проверка файлов изображений, подтверждающих рейтинги, во время их загрузки на сервер сценарием

addscore . php должна выполнять две задачи. Во-первых, она должна предотвращать загрузку больших файлов, сообщая пользователю, что размер файла превышает

32

КбаЙт. И во- вторых, она не должна допускать, чтобы

пользователи загружали любые другие файлы, кроме

изображений . Сценарий ~:Добавь свой рейтинг. должен

ево'

..

"'

IГитарные войны.

I

Ir

j Добавь свой рейтинг ;

_ _-

_ _-

Извините. IЮ1НИЮrа ошнбktl apJI загруэхс файла и:ю6ражсlDt.I.

/-'-"-,....

..... _~...

....

, ИМJI: :ЭТо. х.... . i Рейтинг: "SOOOiiO'--'-',

...

-

...

.....

...

I Иэображение:~fО~ фaanнеllWбpoн i '8 - . . . _.__... -._-_.-

проверять как размер файла, так и его тип.

~o соодщек.u.е од ошu.дке f/ldJ\O 'h!\o ~0€ОРu."II'\;--8III!!!!• •!!~!!!!!!"l'1~!!'JII!!.~ь.~. !r t) ОЛЬ3 0€GI."II'\ел)О 110 'f)оеоэу "If\o~o. 'h!\o O~ эеЛGl.е"ll'\ к.е'f)РGl.еu.лbк.о I1pU. JGl.zpYJKe c€oe~o peu"ll'\u.кzGl..

302

lлава5


ие60Аьшие

работа с данными, сохраненными 8 файлах

Допускаются только'lфайлы изо6раIКений Итак, как именно мы будем проверять в сценарии ~Добавь свой рейтинг. , что загружаемые файлы отвечают требованиям размера и типа? Ответ заключается в использовании встроенной

суперглобальной переменной $_FILES, с помощью которой, если вы помните, мы определяли ранее место временного хранения загружаемых на сервер файлов, чтобы затем перенести IIХ в каталог

images . Теперь

мы намерены использовать эту переменную, чтобы узнать размер

1 Mdo.U"YI\ '" , OJМ Р J; е.льJо доЛЬше .3. 0I\jС"YI\u.МО г. о $_FILES [ 'screenshot' ] [' size'] ~ ~~ 3~ gЗ2 Кдо.u"YI\ (1 280 lt't-? do.U"YI\ ",1 280472 ~ э~t 122 ~do.UYf\ uJll.A 1250 Kdo.U."YI\).

и тип MIME загружаемого файла.

Z

Р

е

о rtvIUла. l')oe~btUlde"Yl\

-

ТI.A\') Э-тог.о фctйм PDF, Ч'tI)о $_FILES [ , screenshot ' ] [ 'type ' ]

Mapp!icatiQтi/J?qf

н.е сооYf\€е-тс-т€уе-т 'ml.Al1dМ ~йло€

UJодро.жен.u.й, -тo.l{u.м 1<0.1< GIF, JPEG

u.лu.

PNG.

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

32

тех типов, которые могут быть выведены в браузере. Файлы следующих

типов MIME обычно используются в веб-программировании :

$_FILES['screenshot'] ['type']

GIF Фо.uлbL 1.A3 0д р,о.жен.u.U,

JPEG

\')О:t"Yl\€ер.ж:эо.~w< peu."YI\I.AНZu..

~.~-------------'~

~Р'МЯ nopa6omamb

Напишите управляющую конструкцию

i f,

с помощью которой

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

константы GW_МAXFILESIZE. Имеется в виду, что значение размера файла и его тип были предварительно сохранены в переменных с именами

..~~ ..!........ .... .....~~~~.~:~~.~~~~~.~.~:.~.~.~.~~:~.~~~~.~~~~.~.~.~~~~~.~~~~~.~~~.~: ............ .. ... ..

)

{

вь, здесь ~

ЗОЗ


добавление 8 nриnожение проверки параметров файлов

~ешеное зааа~~ишите управляющую конструкцию Н, с помощью которой организуйте проверку того, что загружаемые файлы изображений, подтверждающих '"

Н

рейтинги, действительно являются файлами изображений и их размер больше

el(o"y!)opbte

dPQYJepbt UCt)OJJbJY)O"\Т} Э"У!)О"У!)

"Y!)Ut)

О байт, но меньше, чем значение константы GW_МAXFILESIZE. Имеется в виду,

что значение размера файла и его тип были предварительно сохранены в переменных с именами

$screenshot_size

и

$screenshot_type

соответственно .

~I~I .9ля ..~ ~ .. !.cc.$.s~r~e.r.d!QLt~re..~.=:. :imc19~/9if:). JJ. .c$.sc.re.eJ1Sto.t~t~p.e..=:::7. \'ttId9e./jre.~,J·I1.· РQСt)ОJн.ct€ctн.uя (~ ...1.. ~:t -- '. _1· ') I1 ($ ..1. Lt -- 'i I ')) && UJоdJXI.ж.ен.uй · ... .. .. у .sc.re.eJ1:tt(). ~- ~~:-: .. \lI1d9~· pJ р.е·9· .. .. .sиее.t\~Q. у ре. .-:-.7• •. )У\с19·е pn 9 . ..

~ptG~ftI4"Y!)~ .. .... ... ...( $.$.vr.~~n~Q~_~\~.~ ..~ ..o). ~8... ($~~x~~n~~t_~j?;~.. ~.7..G.W.J.Iл.ХF.l~f:$.1Д:) ).1 ...\ ... .

<?P~~ Инициализация содержащей имя каталога дляконстанты, загружаемых файлов изображении,

~

_

//

/1

""------

и константы, содержащей значение максимального

раЗ~:~:п:~~~~_UРLOADРАТН',

'images/'); define( 'GWJW(FILESI ZE ', 32768);

/1 32

TQI< I<QI< Э0t)УС"у!)u.мbtй ;'"ld.I{СUJ.I.c::tЛbк.bt.й

pQJМep фctilм t)ОЯ€ляе)1)СЯ "Y!)et)epb

кв

~олее ~e'м € о.9н.о,м 'меС)1)е € cu,eн.d.puu

«ДОdct€Ь c€oй ре il"Y!)uкz», ес"У!)Ь сМbl.сл Э'vr\о Jн.ctчен.uе € l(ortc"Y!)Qrt"Y!)e.

?>

Соодщен.uе од ОЩUdl(е

Проверка параметров файnов во время JаГРУJКИ деnает сценарий 60nее надежным

l')oMoгoQe"y!) I')он.я."у!)ь,

I(Ql{ue €u.9bt фctйлоg к.еэоI')УС"у!)u.м.bt эля.

Простая проверка прошла долгий путь, чтобы сделать РНР-приложение более

JctGpYJl{u.

интуитивным и простым в использовании, не говоря уже о том, чтобы повысить

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

арные ВОЙНЫ. Добавь СВОЙ рейтинr "----~

ФаЬ. noa'I'МP....IO. . . . pdtТJPI[', ;&ОJIJIC" бwт • .....ом no6p8aaIU

•+--- GIF. JPEG ... I'NG•• <то Р'_ •• ,..,_................ 32 Кб............. __ .... Има:

iЭiёiiXiiii8

Pdiтивг: ;

..·..· - -..·

5OfJOOij'''-_ .... -

_

.

ИэобраеВRе:~~ ..............

---.........-

......

-

.......

-

.......

о

elhelshugescore.pdf 304

zлава5

jocobsscore.png


ро60то с аонными, COXPOHeHHWIIIIU 8 фаЙЛQХ ~e.9u:VI'\e ~p.мa1'l\u€н.oe

сооdщенu.е Од ОШUdl{ е

€ 1'1\0,", СЛ~Чdе.

еслu срам н.е 1'I\0~O "YТ\u.I)cI. UЛU uмee1'l\

слuшко,", dОЛЬШОЙ pcI.,3Мep.

~

i f (!empty($name) && !empty($score) && !empty($screen ot)) ( i f «($screenshot_type == ' image/gif') II ($screensho _ type == 'image/jpeg ' ) II ~ ($screenshot_type == 'image/pjpeg') II ($scree shot_type == ' image/png ' )) & ($screenshot_ size> О) && ($screenshot_size GW_МAXFILESIZE)) ( i f ($_ FILES['screenshot'] [ ' error'] == О) { // Перемещение файла в постоян // каталог для файлов изображений $target = GW_UPLOADPATH . $screenshot ; i f (move_ up1oaded_fi1e($_ FILES[ ' screenshot'] ['tmp_ name ' ], $target)) // Соединение с базой данных $дЬс = mysq1i_ connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAМE) ; // Запись данных в базу данных $query = "INSERT INТO guitarwars VALUES mysq1i _query($дЬс , $query); //

Вывод пользователю подтверждения

есЬо

'<р> Спасибо

за то,

в

(О,

NOW() ,

'$name ',

'Он будет npосмотрен и добавлен к списку

' <р><strопg>Имя : </strопg>

есЬо

' <strоng>Рейтинг : </strоng>

'

. $name . I

'

.

рейтингов

как можно

ввода

данных

скорее .

</p> ,

' <br />';

$score . '<br /> ' ;

echo ' <img src="' . GW_UPLOADPATH . $screenshot . " аlt=МИзображение , подтверждающее подлинность рейтинга echo ' <р><а href="index.php " >&lt ; &lt ; Назад к списку рейтингов // Очистка полей $name = " "; $score = О"; $screenshot =

'$screen hot')";

получении данных

что добавили свой рейтинг !

echo

' $score',

ый

"

/></р> ' ;

</а></р>' ;

формы

mysq1i_c1ose($dbc); e1se { echo

' <р

else {

class= "error ">

есЬо

Извините ,

' <р

возникла ошибка при загрузке файла изображения.</р

сlаss="еrrоr">Файл, ' быть файлом 'и

его

размер

не

(GW_МAXFILESIZE

// Попытка удалить временный файл изображения , @un1ink($_FILES[ ' screenshot'][ ' tmp_ name']) ;

echo

'<р сlаss="еrrоr " >Введите , рейтинга .

пожалуйста,

подтверждающий рейтинг,

изображения должен

/

1024)

в

форматах

превыmать

.

'

должен'

GIF, JPEG ' .

или

. PNG,'

Кб.</р>' ;

подтверждающий рейтинг пользователя

всю инФормацию для добавления вашего

< /р> ' ;

addscore.php

305


тест-драйв сценария addscore.php

-Тест-драйв Добавьте в сценарий «добавь свой рейтинr» проверку фаЙIIов изображений, подтверждаlOЩИХ рейтинrи, при заrрузке их на сервер. Внесите в файл

addscore . php изменения, касающиеся проверки файлов изображений,

подтверждающих рейтинги , при загрузке их на сервер . Загрузите откорректированный

сценарий на ваш веб-сервер и про верьте работу формы ~Добавь свой рейтинг~ как с допустимыми, так и с недопустимыми файлами изображений (размер файла больше допустимого максимума и файл недопустимого формата).

'9:Почему для изображений типа

MIME?

JPEG

используются два

О: ЭТОТ вопрос лучше задать разработчикам браузеров, которые по каким-то причинам решили использовать

разные типы МIME для JPEG-изображениЙ . Для того чтобы быть уверенным, что проверка файла

JPEG будет

'9: Почему переменная GW_МAXFILESEZE помещена в файл appvars.php, хотя она используется только в сценарии addscore.php?

О: Хотя и справедливо утверждение, что файл

appvars . php необходим только для того, чтобы размещать в нем данные, которые совместно используются

проводиться на большем, по возможности, количестве

несколькими сценариями, но зто также хорошее место

разных браузеров, необходимо проверять соответствие

для инициализации любых констант. В 3ТОМ случае

файла обоим типам.

размещение константы GW_МAXFILESEZE в файле

ер: Какая необходимость в проверке того, что размер

appvars . php облегчает ее поиск, если вы захотите

файла изображения больше О байт? Разве не все файлы изображений больше О байт?

О: Теоретически - да. Но технически вполне возможно

создать на сервере файл нулевой длины. Например, такое произойдет, если пользователь укажет для загрузки на

сервер имя файла, который не существует на локальном компьютере. Для предотвращения подобных инцидентов

сценарий

addscore . php ведет себя осторожно

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

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

файла изображения, подтверждающего рейтинг пользователя .

'9: Что делает строка кода

@unlink()?

О: Встроенная РНР-функция unl ink ( ) удаляет файл на сервере: в нашем cnучае -

подтверждающего рейтинг

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

unljnk ( ) ,

путем введения перед ее именем символа @. Вы можете

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

306

глава

5


работа с aaHHbIMU, сохраненными 8 файлах

Список рейтинrов доя.ен быть расчищен. Хотя загрузка файлов на сервер стала более надежной благодаря их проверке, мы больше не можем игнорировать проблему неподтвержденных рейтингов. Новый рейтинг с загруженным

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

могут не быть подлинными. Приложению теI(УЩu.U мu.€btcшu.U реU1Т\u.н.z «Гитарные войны>,) необходим способ, н.е t)ОЭ1Т\€~Ж:9ен.. '-hI\О н.е позволяющий удалять старые рейтинги. €н.УШdе)Т) долЬшог.о эо€ерu.я.

Э yг.u..м t) ОЛЬ3 0 €d"'tl'\елям.

34:5900

guitarwars id

-' Э-

__

Дno, * t.....2З 09:06:35

dote

name

$core

2008-04-22 14:37:34

Пако Джасториус

127650

2008-04-22 21 :27:54

Невил Йохансон

98430

2008-04-23 09:06:35

Эдди Ванили

345900

2008-04-23 09:12:53

Белита Чеви

282470

2008-04-23 09:13:34

Аштон Симпсон

368420

2008-04-23 14:09:50

Кенни Левиц

64930

2008-04-2408:13:52

Фиц Лайрстон

186580

'.

i

phizsscoгe . gif

Напишите, что бы вы сделали, чтобы удалить неподтвержденные рейтинги из списка:

вы здесь ~

307


ао6Qвленuе страницы «Админ »

План создания страницы «Админ») Так как нам всего лишь необходимо удалить из базы данных

неподтвержденные рейтинги. вполне резонно было бы запустить инструментальную нрограмму

SQL и

вручную удалить записи из таблицы ,

используя несколько запросов

DELETE. НО вполне возможно . что это

Bes-nРUЛОЖemI9 часто 6КЛЮЧaюm

каждый раз, когда вам необходимо техническое обслуживание вашего

u cmpaнuчы с gocmynOM

веб-приложения. Главная мысль заключается в том, что создаваемое

всех.

не последний раз , когда вам приходится удалять записи. Кроме того,

не слишком весело обращаться к инструментальным программам

SQL

приложение должно предоставлять возможность про водить его

U

gлg

cmранuчы

gocmynOM

техническое обслуживание с минимумом препятствиЙ .

с

Что нам необходимо, так это страница, к которой имел бы доступ

agMUнucmpamopa.

только веб-администратор и которая позволяла бы удалять рейтинги ...

кomорые

Страница «Админ»! Но нам нужно быть очень внимательными и четко различать , каки е части приложения относятся к поль з ователю . а какие

-

gлg

UCnОЛЬЗyюmС9 тоАЬКО gлg

к администратору .

страницы ' преАнаJначенны e АЛЯ ПОЛЬJоватenей

технuческой noggержк.u сайtna. C"W\Pdн..uUP «Дoдa€b C€Oй peU"W\UK2.:O U 2.м€н.ая. C"W\Pdн..uup «fU"W\dPк.btx €Oйн.:o

PdJectdO"W\dкbt эл~ '11\02.0, ~ чmо~bt I')ОЛЬ30€d"W\елЬ МО2. 3d 2.РУЗU"W\Ь н.а cep€ep c€Oй реU"W\uн.г. U I!pocМa"W\pU€d"W\b CI')UCOK €cex реU"W\uн.г.o€.

--186580

."".:1.....

·14 0t1:13:S

Эта страница только АЛЯ администратора сайта:

..... :/-': .

Гитарные

..'

I

tr НdЖА'II\uе KKOI')KU С Ke3d€ucu.М0u. cf>UK cdu,u.eu. «УэалU"W\Ь» I')рu€~эе"W\ к JЭdлен..u)О coo"W\~e"W\ c"W\ts'y)OVJ,е u. .з<щucu..

308

глава

5


робота с данными, сохраненными в файлах

Напишите, что необходимо делать сценариям «Админ» И «Удалить рейтинr» для

Toro, чтобы

обеспечить приложению «Гитарные войны» функцию удаления реЙтинrов. Затем нарисуйте схему, как удаление рейтинrов повлияет на записи таблицы

gui tarwars

и файлы

изображений, подтверждающих рейтинrи, связанные с ними.

odmin.php

Веб-сервер

removescore.php

guitarwars id

dote

nОlЩ'

score

1

2008-04-22 14;37;34

Поко Джосторнус

127650

2

2008-04-22 21 ;27;54 _

Не вил Йохансон

98430

3

2008-04-2309;06;35

Эдци 8аннллн-

345900

4

2008-04-2309;12;53

Бел нто Чеви

282470

5

2008-04-2309; 13;34

дШТОН Симпсон

368420

6

2008-04-23 14;09;50

Кении Левнц

64930

7

2008-04-2408; 13;52

ФНЦ Ло_рсто"

186580

sc:reеП$hot

phizsscore _gif

вы здесь ~

309


упражнение решение

Напишите, что необходимо делать сценариям «Админ» и «Удалить рейтинг» для того, чтобы обеспечить приложению «Гитарные войны» функцию удаления рейтингов. Затем нарисуйте схему,

как удаление рейтингов повлияет на записи таблицы

gui tarwars

и файлы изображений,

подтверждающих рейтинги, связанные с ними .

Гитарные

воины. u

Ад

МИННСТрирование рейтингов

. Ниже приведеи списа. peItrи,нro , ИспользyIПе эry Cl]J8IIItЦ)\ •

ирило_еим .гитарные войиы»

. _ - _ . _ ....: .. ~.~~~~~~~ один щ иеcl'oлыо реltrинroв.

~DIТOB С.ипс:ов

2008-04-2309:]3 :34 368420 _ .... ~.....-

м- в.н_т._

2008-04-23 09:06:35 :л_т. Че._ 2008-04-2309:12:53 , -Ц л••рстон 2008·04·24 08:13:52 п."о д.. 2 <тор_ус 008-04-22 14:37:34 . Не._л Йохансон 2008·04-2221 :27:54 . Кенн_ Ло._ц 2008-04-23 14:09:50

Ве6-сервер

345900 282470 186580 127650 98430 64930

... _ ...... _ ..... _ .... -

YJ алить

~

~~~p.~ц .~ф!\i~:~r· rJ~r.~~~~!1~~"!I:I. p.~ц~~~.. ~<?~ .I)~~J~~~~~!'.~R-. ~. ?:':4:I)~p.~~I?Y.I~~i;i........... . «Уэ~~:v!\~.~..9!.'~. ~:i~~ .<?!'1p.<?~~ .p.~.~~~~: .. .

~~!'J~r·<?~I?Ч1~~j~~··· · ~~"!!I· ·~·~':А,~~r~~··········

«Уэ~~:v!\~. f.~9:"!!I~~"""" " ' " ........ ............... ..

у, .!i,!8Лнть YJ ИТЬ

~

~ .

Гитарные войны. УдалЬние рейтинга

admin.php

В.. yllCpCllw. ~ТO ... дciсп"-"О xanne yjI8JI..... 3'ТОТ ре

~~~~p.1:t9. r~~~y.~~~~r~·~r. P~.~~t)~~~~~~~. cP.<A~~~~~9~~~. ~~~~. f.~9-~~.......... . I:tj.~~~~~~~.~~.фq~ .......... . I:tj<?~~~~! э.<?!<.<:'J~:t?Щ~~.<? ~~~ ........ . 1)?.9:'!~<?:v!I.~( .\!-. ~~оэ.\!-:v!I..<?~C?~~~~~.... ....

trm<

.?

111 •

Гитарные войны. Удаление рейтинга РсiiтиllГ 368420 Aurroва СИ":nСОIIА успешно удален .

s~~цe .Ад"и~С1Р!!!ЮIIOUfII~_~lI'I1oнгоа»

I)?Э:v!l~~р.~~~~. ~.\!-Э~~~:'!1~~"""" " "

removescore.php

guitarwars 1

2008-04-22 14:37:34

Поко Джосториус

2

2008-04-2221 :27:54

Невнл Йохансон

98430

2008·04-2309:06:35

Эдди 8анa.tЛли

345900

4

2008·04·2309: 12:53

Белито Чеви

282470

6

2008·04-2314:09:50

К"нниЛевиц

64930

127650

I~

~7~~2~00~8~.0~4~-2~4~0;8:~13~:5~2~~~ф~и=ц~Ло~"~рс=То~н--4-1~8~6~58~0~--h-----f~ р izsscore.gi

310

2лава5

)


работа с данными, сохраненными в файлах

СоJДание на аранице «Админ») гиперссы lки АЛЯ удanения рейтинга ХОТЯ ответственность за непосредственное удаление рейтинга лежит на сценарии

<!: У далить рейтинг~,

нам

:tе06ходим также и сценарий <!:Админ~, который предоставит возможность выбрать рейтинг для удаления. Сценарий

admin . php перечисляет рейтинги

всех пользователей с гиперссылкой

сlJX>ки рейтинга. По этой гиперссылке сценарию

<!: Удалить рейтинг~

«Удалить~ для каждой

передаются данные о рейтинге,

J.;оторый должен быть удален. <?php require_once('appvars.php'); require_once('connectvars.php');

II

Соединение

II

Извлечение данных из

с

admln.php

базой данных

базы данных МySQL

$query = ·SELECT * FROM guitarwars ORDER

ВУ

score DESC, date ASC";

$data = mysqli_query($dbc, $query);

II

Извлечение данных

II

Форматирование

из

данных

массива рейтингов записей

в

виде

в цикле.

кода

HTML

echo '<table>' ; while ($row = mysqli_fetch_arraY($data))

II

Вывод данных

рейтинга

echo '<tr class="scorerow"><td><strong>, echo '<td>'

$row['date']

.

echo '<td>'

$row['score'].

$row['name']

'</strong></td>';

'</td>'; '</td>';

echo '</table>';

mysqli_close($dbc); ?>

<а hrеfs"rешоvевсоrе.рhр?id=5&datе=200804_23%2009:13:34&nаше=Авhtоn%20 Siщрвоn&всоrе=368420&всrееnВhоt="

вы здесь.

311


3HDKOMcmBO с 3DnpO'OM

GET

Сценарии могут Обмениваться ДРУГ с ДРУГОМ ИНформацией Для того чтобы удалить рейтинг из списка, сценарий «Удалить рейтинг~

должен знать, какой рейтинг необходимо убрать. Но это решение принимается в сценарии «Админ~ . Это влечет за собой вопрос: как сценарий «Админ~ сообщит сценарию «Удалить рейтинг~, какой именно рейтинг он должен удалить? Такой обмен информацией может быть осуществлен путем добавления данных о рейтинге, который должен быть удален, в строку

URL атрибута href

в тегах < а

...>Удалить< I а >для

каждого из рейтингов,

перечисленных на странице «Админ~. Если вы внимательно проанализируете

U RL дЛЯ

всех рейтингов, вы заметите, что в каждом из них записаны данные

соответствующего рейтинга . <а href="removescore.php?

sсоrе=Зб8420&

~

A'II]pu~yYr\ href ~ег.С3. <ф (VR.L) сс~е'll]Ся. н..d сu,еН4РUU

re'll]ovesc.'ore nh

v..Ji\Я. ;Q~:;:r: н.о СО<JеF.ж.и.~q~кж-е К ег, .3я. мра.

.9c:ttutGt.e о peu-rrjuнze,

эр~г.оU 3Кt:1KOCM&) d.Мl)ерса.н..Э d

запроса

~mтои С.мисок

п.ко "-сто

~алить

'

2.Ullepc'cbtJlKe

н.е 1Т\ОЛЬКО 01Т\KpbL€ae1Т\ сu,еН4рu.U «У.э ал u.1Т\Ь реU1Т\u.н.г.».

).'.0

J

1Т\акж,е 01Т\l')ра€.hя.е.1Т\ .эан.н..btе, сu,еН4Р ЩО, € €u..э е

€bt.jbL€ae.MOMY

.3al')pOCQ БП.

.

Итак, данные переданы с помощью

« Удалить рейтинг~

GE.T.

2008-04-23 09:13 :34 36~·~; .... ·-;;;;;;;:;: ..··_....·_ .. ··_....·_..: 2008-04-23 09:06:35 345900 ус ить Белит. Чеви 2008-04-2309:12:53 282470 ~ Фиц Л.ipстов 2008-04-2408 :13:52 186580 ~ ....... риус 2008-04-22 14:37:34 127650 ус ал;;; j Невил Йох.исов 2008-04-22 2) :27:54 98430 ~ ! Кеиии Левиц 2008-04-2314:09:50 64930 ~

ЩелЧОК кн.Оl')коU MbtuJ.u н4 Э1Т\ОU

Y..9cV1e Нo

0"Y11.9

gaHHbIMU 5 5uge

~ !Гитарные воины. Администрирование рейтингов _..... _ ...... _ ... _.~...~""~~o удалмть ОДИН w н"скошко реlПииго

KO'll]of>bLй .9 олж-ен. dbt'll]b keodxoal.AМbte

~e.Кt:1 d"Yf\

g.лst ОМ\ена

Ни,.е ирИВ<дсн список реAтиuгo ИСIIОш.зyJlте Э1j' • ПРИnОЖСRRI d'иraрные войн..,.

••••••• ••-'l'!l!I.!,,"""-

~.II.I!I!"" I}ереэа.~с ~ guэ е I)dpbt:

ucnо.лЬ305аН

МИ В.вилли

screenshot=

Я.

.может 6ы111ь

"i

id=5& dаtе=2008-04-2З%2009:1З:З4& name=%dO%90%dl%88%dl%82%dO%be%dO%bd%20 %d0%al%dO%b8%dO%bc%dO%bf%dl%81%dO%be%dO%bd%oa&

ДQI-U-Ibtе

Ul\L cueнaрuз

URL, но как сценарий

сможет воспользоваться ими? Доступ к данным,

переданным сценарию с использованием

URL,

может быть получен через

суперглобальный массив $_GET, который очень похож на суперглобальный массив $_POST. Добавление данных в

URL гиперссылки является тем же

самым, что и использование запроса GET в веб-форме. В традиционном НТМL-запросе GET данные формы автоматически отправляются сценарию,

обрабатывающему данные этой формы, как часть

URL. Мы делаем то же самое, создавая вручную наш собственный запрос GET в виде индивидуального URL.

...

t')

"

...

t')


работа с данными, сохраненными в файлах

Запрос POSТ может быть инициирован тоnько через форму, В то BpeМII как GEТ может быть создан В виде

URL.

До сих пор мы отправляли сценарию данные через веб-форму, в которой сценарий указывался как атрибут

action для кнопки

«Отправить~.

После того как пользователь заполнил поля данных формы и нажал кнопку «Отправить., данные формы отправлялись на сервер в виде запроса

POST.

Проблема в том, что страница «Админ~ не использует форму для инициирования сценария

сценарий через

URL.

«Удалить реЙтинг~.

Она просто ссылается на этот

Поэтому, для того чтобы отправить данные сценарию

на обработку, нам не остается ничего другого, кроме как добавить эти данные в качестве параметров в URL. Именно здесь очень удобно применение запроса GET, так как он обеспечивает доступ к данным , добавленным к в виде параметров. Так же как и при использовании запроса переданные сценарию через запрос

GET ,

URL

POST, данные,

доступны в виде элементов

суперглобальноro массива, только его имя $_GET вместо $_POST.

Гитарные Войны. Администрирование рейтингов Ниже приведен Список реАтинro

Исполъзyllте эry страницу

8 ПРИЛо..еmц «Гитарные воАвш

_ ....._._ . . _.._. ~ ~.""~.~еобх.".~.". ~,':1I1ПЬ

, Гитарные войны. Добавь CBo~pe~~~:. .

I

-

и,;~:.···-··· ·-·······.\~

~~ ._.---;

Рейтинг: ~---..., \ ИзоБРlII<еRRе: ~фaiJJ ~, """"" •.а'

'1

Аштоu С • .,псов 2008·04.2309:13:34 368420 --; ..~-;~ ЭМИ Вавилли 2008·04·23 09:06:35 345900 ~ Белита Ч 2 Д8JlИТЬ Ф евв 008·04·23 09: 12:53 282470 Уда,1ИТЬ П вц Лаiрстов 2008·04·2408 :13:52 186580 ~!алиl'Ь а!СО Джастор.ус 2008· 04·22 14:37:34 127650 ус алить Нев." Йохавсов 2008·04·2221 :27:54 98430 ~ К_ввв Ле.иц 2008-04-23 14:09:50 64930 ~

. несколько реЙ11lнroв ...._ ..... _ ..... -

i . . _. . ._ . . . _. . _ . . _ . . _ . . _ . . '8 l1ер еЭ dЧd Э dКнbtx g VR\.. ОС~Ul,ес"у!\€ля.е"У!\ся Через .3 а !'\рос

GYT: g Э"у!\оМ

СЛУЧdе Эdru-t.bLe с ох Pdн.5l)O'/f\ ся.

~~~~~:Л$О~aJb~ОМ ~GП.

вы здесь.

313


GET против POST

О 'ЕТ и Р05Т Разница между з апро са м и

GET и POST не сводится просто

в механизмах пер едачи данных с ф ормой или

к разнице

URL. Действительная

разница заклю чается в разни це в намерениях , с которыми делает ся

тот или иной запрос. Запрос GET обычно используется для получения

!фа

muna

вes-зanросов.

Cl.T

данных с сервера, при этом состояние сервера остается без изменения . U rosт. ynрамшоm с другой стороны , запрос POST используется обычно для передачи данных на сервер, что влечет за собой изменение в состоянии сервера CnОСОБОМ ОБМена как результат обработки им получен ных таким О~,~азом данных. gаннь1МU межgy

POST

ачи данНЫХ на сервер,

перед бо изменениЯ в состоянии И спользуется дляакие - лИ б б

влечет за со оИ к v

cueнapus.мu

что

бавление даннЫХ в азу.

GET Обычно используется для получения данных без

r;газания каКого-либо влияния на состояние сервера

сервера, например до быть возвращены в ответе. Данные также могут GET запрос POST может

ля передачи небольших количеств данных также

В отличие от запроса пользованием атрибута лькО с ис быть сделан то . оме того, в отличие б-фОРМЫ act~on. Кр се POST передаютСЯ ве анные в запр О от запроса GET Д м для просмотра.

~;ZHb удобно использовать запрос GET, встраивая , данные в URL. В Отличие от запроса POST

.

,запрос GET находит большее применение при , передаче небольших количеств данных.

в виде, недоступно

_<о'

.,

lfG БЫiJt1G1h.

"

Z11'\1blX /с10'\1УОСО/с1

'9: я видел веб-формы, в которых ислользовался зал рос

GET.

Как это работает?

О: и запрос GET, и запрос POST имеют свои области применения,

ка кого-либо влияния на состояние сервера . Поэтому GET является идеальным методом для со ставления информационного запроса к серверу, в результате выполнения которого состояние сервера

остается неизменным. К таким запросам можно отнести , например,

и звлече н ие записе й данны х из таблицы базы данны х. С другой

когда дело касается веб-форм. При создании веб-формы выбор

стороны, метод

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

и зменяют состояние сервера , таки е, например, как добавление

данные, в то время как значение атрибута

данны х в таблицу базы данны х с помощью SQL-запроса

action определяет имя

POST больше соответствует запросам, которые

сценария, который должен получить эти данные для обработки :

или удаление их с помощью SQL-запроса

<form method= "post " act i on=" addscore. php">

Д ругое отлич и е между запросами

DELETE. В

I NSERT

результате

выполнения обои х SQL-запросов состояние базы данных изменяется .

POST заключается в том, GET, видны в URL, переданные с помощью запроса POST, GET

и

что данные, переданные с помощью запроса

После того как для передачи данных формы будет нажата кнопка

в то время как те же данные ,

«Отправить», будет запущен сценари й

скрыт ы от прямого просмотра и поэтому немного более защищены .

addscor e. php, а данные формы будут переданы ему через суперглобальный массив $_ POST. Но вы могли бы с таким же успехом написать тег <f orm>, как показано ниже, причем в этом случае сценарий сможет получить

доступ к данным формы уже через суперглобальный массив

$_GET:

<form method=" get " act i on=" addscore .php">

'9: Вот так! Значит, не имеет значения, какой из методов запроса использовать,

GET или РОSТ?

О: Неверно. Выбор метода имеет значение, и значительное. Запрос

GET обычно

314

используется для получения данных без оказания

lлава5

'9: Как эта разница между запросами при передаче данных через

URL?

GET

и РОSТучитывается

О: Прежде всего вы можете передать данные сценарию через URL, используя только запрос

GET, следовательно, запрос POST отпадает GET предназначен исключительно

сразу. Более того, раз м етод

для запросов, которые не изменяют состояние сервера , значит

нет необходимости создавать какие-либо формы , связанные с SQL-запроса м и

INSERT ,

или

DELETE ,

или чем-нибудь еще, что

приводит к изменению со с тояния сервера в сценариях , которые

получают данные через свои

URL.


ра60та с данными, сохраненными 8 файлах

Беседы у вамина Сегодня

вечером:

и РОВТ

GET

РОВТ:

GET:

Так ты говоришь, болтают, что все, на что я способен, - это только задавать вопросы, но не давать на них ясных ответов. Это правда?

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

Ладно, это правда, что я действительно

не намерен быть причиной каких-либо

изменений на сервере, будь то удаление файла или добавление записи в таблицу базы данных. Но это вовсе не означает, что я бесполезен.

Все, что я знаю,

-

это то, что огромное

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

своего друга Формы, в то время как для меня Форма

-

не более чем случайный знакомый.

у меня есть и другие друзья, например

и занимаются этим. Если бы сервер оставался

все время в неизменном состоянии, вот была бы скукотищаl

URL.

Ладно, тогда у меня к тебе вопрос. Как ты

Таким образом, ты считаешь, что твой

сможешь предпринять какие-либо активные

.круг друзей. как-то компенсирует твою

действия в относительно стесненных

обстоятельствах, скажем, когда рядом нет

неспособность к активным действиям? COMHe~cь.

Формы? Знаешь ли, иногда Страница не считает

нужным создавать себе дополнительные проблемы, привлекая Форму.

Послушай, Форма

-

мой друг, и я уже

давно принял решение не делать ни одного

Успокойся. Я лишь хочу обратить твое

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

внимание на то, что хотя я и могу только

но я никогда не предам своего друга.

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

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

Ладно, будем считать, что я одобряю твои действия.

Рад это слышать. Было приятно побеседовать с тобой ...

вЬlздесь ~

315


как работает сценарий removescore.php

POST

БЕТ,

и удаление рейтинга

Мы установили, что удаление рейтинга в приложении «Гитарные войны!> начинается с гиперссылки «УДaJIИТЬ!> на странице «Админ!>, которая указывает на сценарий

« Удалить рейтинг!>. Мы также знаем, что данные рейтинга могут быть отправлены сценарию « У ДaJJ\ПЬ рейтинГ» через URL. Но здесь возникает нроблема, связанная с тем, что в результате выполнения запроса

GET

на сервере не должно произойти никаких изменений, в том числе

УДaJlения рейтинга . Возможное решение заключается в том, чтобы не прои зводить никаких изменений на сервере ... пока. Что если сценарий «Удалить рейтинг!> выведет страницу запроса

подтверждения до того, как "роизведет само удаление рейтинга из базы данных?

Вмес1Т\О 1Т\ог.О 'hr\o~bt Гитарные войны. Удаление рейтинга

~е~езле~ОJ3QЛЯ1Т\Ь

-

В .. уаерс:ММ ...ТО ... дейcrаител.1tО J.0'[1I"I'C yn&ll1Ifi :tТOТ peJl11lRr и

7

... : АDl1ОН с.....сои

Дата: 2008-04-23 09:13:34 l'elТll8r: 368420

реU1Т\шtг. u.J д~b!. 3 ct кн.btx, С1Т\РQl·ШUp. JctliPOCct t)О31Т\€ержзен.u51. .9 ct е.1Т\ t)о/Jt,JО€С\1Т\ел}О

б'ОJМо жн.ОС1Т\Ь

@Да О Нет

liОЭ1Т\€ерэu.1Т\Ь 1Т\ctl{ое

~)

:УЭQЛен.u.е.

Страница зап'роса подтверждения выводит на экран данные по рейтингу, который должен быть удален, с помощью формы , использующей пару кнопок с зависимой фиксацией «Да!> И «Нет» . Выбор кнопки

«Да!> И нажатие кнопки «Удалить!> приведет к фактическому удалению рейтинга. В случае выбора кнопки «Нет!> удаление не состоится .

Если рассматривать это в понятиях запросов

GET и POST, с ценарий « Удалить рейтинг!> может вывести GET, сделанный из сценария «Админ» . Но так как

страницу запроса подтвержде ния как ответ на запрос

страница запроса подтверждения сама содержит форму, она может сделать свой собственный запрос

POST, когда будет нажата кнопка «Удалить» . Если форма ссылается на себя, то этот же самый сценарий

(removescore . php) сможет обработать запрос POST и

выполнить фактическое удаление рейтинга

из базы данных . Ниже нриведены отдельные этапы этого процесса.

о в реЗУII ..тате щеllчка кнопкой мыwи по rипеРССЫIIке «VдаIlИТ"»

Нмеетcs юз.можнOC1t1h

на странице «Админ» запускаете. сценарий «VдаIlИТ" рейтннl'»,

который ПOllучает через запрос GП данные об удаll.емом реЙТНнrе. U g8)Ке е Сценарий «VдаIlИТ" рейтинl'» ИСПОllltЭует данные об удаll.емом рейтинrе, переданные ему через суперrllобаll ..НЫЙ масси. $_ GП, чтобы создат" страницу запроса подт.ерждени. с формой. о Сценарий .Vдanит.. рейтинl'» запускаетс. .но.", на этот раз

через запрос

POST,

ПОllltЭо.атеllем, нажавwим кнопку «Vдanиn.»

на форме страницы запроса подтверждени ••

О Сценарий «VдаIlИТ .. рейтинr» удаll.ет рейтинr из базы данных. Кроме

Toro,

с веб-сер.ера удаll.етс. TalOКe фаЙII изображени.,

подт.ерждаlOщеrо реЙТинr.

316

zлава5

реко.мeнgyетcs

6

нек.omорык

случ89К ogнO.мy

u

то.му же

cueнaрuю ornвeчаmь на ОБа запроса:

СЕТ

u POSТ.


работа с aaHHblMU, сохраненными 8 файлах Давайте посмотрим поэтапно, как

разворачиваются события в процессе удаления рейтинга из базы даннЫХ ...

Гитарные войны . Администрирование рейтингов ~~eв CIl8COl: PeitnIIIr08 Dp8JIOПII8I сГиаpвwt .....11»

__ ._~~'.:~~к..~~ ~ o.uв""; Вean&ID pcIIпro8. AarrOII с...... 2008-04-23 09:13:34 368420 y~. _ . . _ . •. ia.--"'~ ЭМа

........

2008-04-23 09:06:35 2008-04-2309:12:53 . . . Лаlpcтoll 2008-04-2408:13:52 П...о Д-стараус 2008-04-22 14:37:34 НеВ.... 80U8CO. 2008-04-22 21 :27:54 Кеа•• Ле... 2008-04-23 14:09:50 lieлп. Ча.

345900 ~ 282470 ~ 186580 ~ 127650 ~ 98430 Ущвть 64930 ~

I

~ ... $_ровт

POSТ

J

$_GET

гита1)ные войНЫ. удалъние рейТИНГ~ __ yjUIJI...... 3'nJI' p"Irn<Kr1

Дa~e коЛоt-U<u. scree!'\sI!o"t

1hIy.cpc8.., ....... ~

эля. Э'Vr\ог.о peu'Vr\uкza o'Vr\C ymc'Vr\€~)(Тt!\. 0.эu.н. u. 'Vr\0'Vr\ же. cu,el-ld.pu.u реd.г.u.руе'Vr\

)aI\P OC ~ СI\ оЛЬ .3~e'Vr\ с-Я. эля. ytl\~CKd. сu,екарuя. :.: уЭd.Лu.'Vr\Ь peu'Vr\u.кz» (OI\5I.'Vr\b!) u. ":реэd.Чu.

,. /

<

эа.~ о peu'Vr\u.кz e ,

removescore.php

KO'Vr\°Pbt.i1

I\O-р'а.3н.<>МУ

€ .3d.€u.cu.мoc'Vr\u. o'Vr\ 'Vr\0гoo, I\ОЛУЧu.л он. .3d.I1p'0 c БЕТ u.лu. POSТ.

к..еодхоэu.МО jЭd.Лu.'Vr\Ь.

Гитарные войны. Удаление рейтинга

----~

Ре.ЙТИиг

368420 Аurroна CHNJlCOHa успешно удаде" .

< :$ НаЩI:~~!~.ерсmиro.)t

removescore.php

вы здесь ~

317


еще о GET и POST

не БЫ.&!rJ..G')1t,

64t'l1bJX ffi o'l1focoffi ~; Как может один и тот же сценарий обрабатывать и запрос GEТ, и запрос

POSr?

О; ЭТО связано с тем, как он вызывается. Сценарий «Удалить рейтинг» вызывается двумя различными способами. В первом случае вызов

происходит в результате щелчка кнопкой мыши по гиперссылке

«Удалить» на странице «Админ», при этом все необходимые сценарию данные добавляются к

URL. Так как данные добавлены к URL, запрос

рассматривается как GET. В результате обработки этого запроса сценарий генерирует веб-форму, атрибут

GET

action тега <form> которой

ссылается на этот же самый сценарий . Поэтому, когда пользователь

нажмет кнопку формы «Удалить», сценарий вызывается во второй раз.

Но в отличие от первого вызова

URL уже не выглядит столь

необычно

(с данными, добавленными к адресу сценария), поэтому запрос не рассматривается как GET. Теперь это уже запрос

POST, и данные $_POST.

рейтинга посылаются на сервер через суперглобальный массив

~; Значит способ, с помощью которого вызывается сценарий, определяет, что конкретно он будет выполнять?

О; Да! Когда сценарий видит, что данные переданы ему в составе URL в виде запроса GET, он знает,

что должен вывести страницу

подтверждения, а не удалять какие-либо данные из базы. Поэтому данные, переданные в составе массива

$_GET,

используются

только для составления страницы подтверждения и не оказывают никакого влияния на состояние сервера.

Когда же сценарий видит, что данные переданы ему в составе запроса

POST, он знает, что должен удалить запись из таблицы базы данных. Поэтому он извлекает необходимые данные из суперглобального массива

$_ POST и

создает SQL-запрос

DELETE FROM, в

результате

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

с веб-сервера.

318

глава

5


работа с данными, сохраненными в файлах

ОпреАеленне рейтннга АЛЯ УАалення После того как составлена схема процесса удаления рейтинга, мы можем сосредоточить свое внимание на той стороне приложения, которая связана

с базой данных. Сценарий « Удалить рейтинг» отвечает за удаление рейтинга, что означает удаление записи из таблицы рейтингов базы данных. Если вы помните, SQL-запрос DELETE FROM позволяет нам убрать запись из таблицы. Но прежде чем удалять запись, мы должны определить ее. Это достигается путем включения условного выражения WНERE в запрос DELETE FROM. Например, в результате этого запроса исчезнет запись, в которой колонка пате имеет значение «Аштон Симпсон»:

DBLВTB FRОИ guitarwars WНВRВ паше

~ Pe.JYJJb"lr)d"lr)e. €btt)олк.еНU51. Э""Ii\ого Jdt)POCd dу.эе"lr) У.9dЛе.Н4 Jdt)Ltcb, € КО"lr)oрой I(ОЛОНJ(d Г}d"lr)е. ЦМoee"lr)

JН4Чен.u.е. «ALIl'II1oK CЦМot)COK:O.

'ЛШтон Сиипсо.'

=

После КЛ)QЧе€bt.к сло€ DELETE

f\..

~----------_ _ FROM .90Лжк.о сле.90€dYf\Ь

u.мst Yf\dдлu.u,bt, ЧУт\одbt. дbt.ло ЦJ€e.CYf\KO, u.J КаКой Yf\адлцLфt.

guitarwars

к.ужно У.9dЛЦYf\Ь .9aк.к.bt.e..

имя t)ОЛЬJо€а"lr)еля. г} рцмен..я.е"lr)СЯ ЭЛЯ Уl{ dJaНU5l., I{аl{це ре.Й"lr)Цк.гц

dbt.Yf\b У.9dЛе.н..bt..

Однако с этим запросом связаны определенные проблемы. В мире,

ИСt)О.лЬJО€Qн.u.е. дН4 Чен.u.я

в котором живут миллионы гитарных воинов, есть вероятность

существования более чем одного Аштона Симсона. В результате

реЙYf\Ltк.гd € .9 0 Г}олк.ен.u.е

выполнения этого запроса будет удалена не одна запись, а все записи,

1{

в которых колонка пате имеет значение «Аштон Симпсон». В запросе

должно быть больше информации, чтобы удалить нужную запись: DBLBTB FRОИ guitarwars WНВRВ паше

=

цмe.н.u. Y"IrIочн..я.еYf\

llе.ре.че.нЬ реЙ"lr)Цк.го€ ЭЛЯ У.9dЛе к.u.я..

'ЛШтон Сиипсон' AND

L

Лог.ЦЧескцЙ ollepdYf\op AND 2

2008·04·2221 :27:54

Невм Йохансон

98430

3

2008·04·2309:06:35

ЭМИ Ван ""ли

345900

4

2008·04·2309: 12:53

Белита Чеам

282470

5

2008·04·23 09: 13:34

Аштон Симnсон

36842()

6

2008·04·23 14:09:50

Кенни Jlевиц

o4YJO

7

2008·04·2408:13:52

Фиц Лайрстон

186580

V

ОIlр,е.9 еляе"lr), ЧУт\о Jdllucb dY.g e"lr) O"Ir)€еЧd"lr)Ь "lr)реdо€ан.u.я.м условного

€bt.ражен.u.я. JdllpOCd "lr)oZ.9a, I(ог.9с.1

Ik' phizs.score.gif

ц цмя., ц ре.U"Ir)Цк.г cooYf\€e"lr)c"Ir)€Y)Q"Ir)

дdЭаННbtМ дн.а Чек.u.я.м,

тe.lleeb, l(ог.Эd u. u.мst, u. рейYf\Цк.г .9 0 л.жк.bt.

cooYf\€eYf\cYf\~o€dYf\b дdЭан.к.btJv\ JН4чек.u.я.м. €ероя.Yf\НОСYf\Ь случайк.ог.о У.9dЛек.u.я. долее ЧеМ О.9к.оЙ JallUcu. сущеСYf\€ек.к.о уменЬшu.лaсЬ. 8ыздесь ~

319


добавление выражения

LIMIT к запросу DELETE

Установка предельного количества удаляемы x записей

с помощью выражения

LIMIT

Использование з начений и колонки пате, и колонки

определения записи на удаление

-

score

как основы для

это хорошо ... но не слишком . При разработке

приложений необходимо любой ценой стремиться к уменьшению риска, а здесь

все еще остается небольшой риск удаления нескольких записей с одинаковыми именами и значениями рейтинга. Решение этой проблемы заклю'шется в том, чтобы ограничить их количество одной записью. Это может быть сделано с llOМОЩЬЮ выражения

(предел):

LIMI T

DELETE FROM guitarwars WНERE пате = 'Аштои Сиипсои' AND score = '368420' Число, следующее после ключевого слова

LIMIT

устанавливает количество удаляемых записей

(в данном случае одну) . Таким образом гарантируется, что в результате выполнения этого запроса будет удалено не более одной записи. Что, если существует две записи с именами ~Аштон Симпсон»

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

guitarwars ..

.x/'id

(

-....

"' д. ~,'

+'

),

">;

'Щ

,

<:;:;'

M'·~

name

5Core

1

2008-04-22 14:37:34

Пако Джасториус

127650

2

2008-04-2221 :27:54

Невил Йохансон

98430

3

2008-04-23 09:06:35

Эдди Ванилли

345900

4

2008-04-23 09:12:53

Белита Чеви

282470

5

2008-04-2309:13:34

Аштон Симпсон

368420

о

Lvvo-v.. - L.J ''':V''' :JV

r<..енни Левиц

C>4Y.JU

7

2008-04-2408:13:52

Ф и ц Ла й рстон

186580

,

rs2 3

2008-11 -04 1О : ОЗ : :l I

I

$CI'8nshot J

Д€Q рей"y!)UКZQ с оэuнд

)

U 3 нд <.Jе НUЯМu

рей"у!)lЛ КZQ Я€ЛЯ)OYl)С5, ГiрОdлемой ЭЛЯ

phizsscore.gif

..

I-\ШТО Н L импсон

К-Qшег.о

Jc>84:lU

КО€bt.мlЛ

lAМeк.o,.д.'\u

аshtопssсоге . jрg

г)

DELETE.

3 QГi POCQ

Напишите, что произойдет с этой таблицей, когда будет выполнен приведенный выше запрос

DELETE.

Как сделать,

чтобы удалялся именно тот из двух рейтингов Аштона

Симпсона, который должен быть удален?

320

глава

5


робота с донными, сохраненными 8 файлах

Ане л~UJe лu UСТ1Оль:;о&amь uие.иmuфuкamоl'

t'wmuнfЭ &усло&ном &ЫI'aжet1uu WH~~ 3Зf11'0С3 'P~~ fКOM~ Эmо мorло Оы помочь &oOl'emeнuu y&ef'eнH<Xmu &том, чmо мы уuаляе.м UМet1HO тот rwmuнr,

коmol'ЫЙ uолжен Оыть уuален, не maк лu~

да, это обеспечит такуlO уверенность. Идентификатор это самый nучwий способ опредеnит.. рейтинr Дn. удаnени

-

••

Обеспечение уникальности - одна из главных целей в создании первичных ключей для ваших таблиц. Колонка id таблицы gui tarwars является первичным ключом, поэтому ее значение является уникальным для

всех записей таблицы. При использовании этой колонки в условном выражении WНERE SQL-запроса DELETE FROM мы устраняем какие-либо сомнения, касающиеся вопроса о том, какая запись должна быть удалена. Ниже приведен новый SQL-запрос, в условном выражении которого

используется колонка

DELETE FROM

id для обеспечения уникальности:

guitarwars

WНERE

УЭQJ1ен.u.е ~ниbI.x,

Уверенность в том, что колонка

дdJtAР::I)ОЩееся.

id действительно является первичным

нd llеp€tAЧн.ом

ключом, влечет за собой уверенность в том, что в результате

I(л)ОЧе,1l 0J€оля.е'Vr\ ll o€bLctA'Vr\b 'Vr\оЧн.ос'Vr\Ь Оllреэелен.uя ,3QlltACtA, 11 р еэНJ::\,3Нd Ченн.оЙ эля

выполнения этого запроса будет удалена только одна запись. А что если вы не создавали эту базу данных и уникальность не была реализована правильно? Тогда будет иметь смысл использование выражения

LIMIT. Логическим обоснованием этому может служить следующее

::IЭQJ1ен.uя.

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

DВLETE

FROM

guitarwars

WНERE

id

= 5·

..

~

Никогда не вредно выражать в явном виде то, что вы ожидаете

...

~

получить в результате выполнения SQL-запроса, и в этом случае

~rа.ж.еfШе \,l/1\П 1С11'\~Нd€лu.€~е11'\ ~ я.€н.оМ €u.эе 11'\0, чmо € rеJулЬ11'\~11'\е

€bt.t)олн.еfШSI. .3~l')rOCd н.е мож.е11'\ dbL11'\b УЭQJ1ен.о долее оэн.оЙ .3~I')u.cu..

выражение LIMIT обеспечивает дополнительную степень безопасности запроса

DELETE. вы эдесь.

321


закончuте сценарий reтovescore.php

Магниты РНР

u MySOL

Сценарий rernovescore php по т

фрагментов кода. Исполь'зуя MarH~T~1 з::~:~:~~ :~ив нем не хватает некоторых важных

«Гитарные войны» возможность ИСТР~БЛЯТЬ Н

фрагм,.енты и предоставьте приложению

енужные реитинги .

<htrnl xrnlns="http : //www.w3 .0rg /1999/xhtrnl " xrnl:lang="ru' lang="ru'> <head> http-еquiv="Сопtепt-Туре"

<rneta

<titlе>Гитарные

войны.

content="text/htrnl; charset=utf-S" 1>

Удаление рейтинга</titlе>

<link rel="stylesheet" type="text/css" href="style.css" 1> </head> <body> <h2>

Гитарные

войны.

Удаление рейтинга

</h2>

<?php . .... . ....... . . .. . . ........ ~ 'appvars.php');

... . .. ... ....... ... .. ...... ! ' connectvars.php'); if (isset($_GET[ ' id']) && isset($_GET['date']) && isset($_GET['narne']) && isset ($_GET [ , score' ]) && isset ($_GET с II Извлечение данных $id = $_GET['id'];

рейтинга

из

................. J ))

суперглобального

(

массива

$_ GET

$date = $_GET['date ' ]; $narne = $_GET['narne']; $score = $_GET['score']; ..................... = $_GET[.................... ]; else if (isset($_POST['id']) && isset($_POST['narne']) && isset($_POST['score'])) II

Извлечение данных рейтинга из

суперглобального массива

$_РОВТ

.................. . = $_POSTl ............... .J; $пarnе = $_РОВТ['пarnе']; $score = $_POST['score']; else { '<р сlаss="еrrоr">Извините,

echo

i f (isset if

($_РОВТ

($_РОВТ[

[ , subrni t ' ] ))

ни одного рейтинга не

выбрано для удаления .

(

'confirrn'] == ................ )

II

Удаление

II

подтверждающего рейтинг

с

сервера

файла изображения,

@unlink(GW_UPLOADPATH . $screenshot); II

Соединение

с

базой данных

$dbc = rnysqli_connect(DB_HOST, DB_USER, DB_PASSWORD,

322

zлаsа5

DB_NAМE);

</p> , ;


работа с данными, сохраненными 8 файлах

//

Удаление

рейтинга

из

базы данных

$query = ' . ........ . . . . .... .. . ..... 9ui tarwars mysqli_query ($dbc , $query);

wнERE

.. .... .... . . ........ LIMIT .. .. . . .. ' ;

mysqli_close($dbc); //

Вывод пользователю

есЬо

страницы подтверждения

'<р>Рейтинг со значением $пamе

.

'

для пользователя

' . $score

был успешно удален из

базы данных.</р>';

else есЬо

'<р

class='error'>

Рейтинг не удален.</р>';

else i f (isset (. ...... .) && isset (. ... . ... ... .) && isset (. ......... J && isset($score) && isset($sreenshot)) { есЬо

'<р>Вы уверены ,

есЬо

' <р><strопg>Имя :

'<br

что хотите удалить этот рейтинг?</р>,

</strong> , .

/><strопg>Рейтинг:

$пате

.

'<br

;

/><strопg>Дата:

</strong> , . $score .

</strong>,

есЬо

'<form method='post' action=' removescore.php'>, ;

есЬо

'<input type='radio' name='confirm'

есЬо

'<input type='radio' name='confirm' value='HeT' checked='checked' />

есЬо

'<input type='submit'

есЬо

'<input type='hidden' name='id' value=' , . $id .

есЬо есЬо

'<input type='hidden' name= .............value=" . .............. . . . . />'; '<input type='hidden' name='score' value=" . $score . , . />';

есЬо

'</form>';

есЬо

'<р><а

vаluе='Да'

vаluе='Удалить'

href= ... . .. . . .. . .. ... .... .. ;><<

/>

. $date .

'</р>';

Да

'; Нет

<br />';

name='submit ' />';

Назад к

"

/> ' ;

списку рейтингов </а></р>';

?> </body> </html>

вы здесь

323


ЭQкончите сценарий removescore.php

Магниты РНР u

MySOL

Сценарий removescore рЬр по

фрагментов кода. ИСПОЛЬ~УЯ MaГH~~:1 з;:~:~:;~ :~ив нем не хватает некоторых важных «Гитарные войны» ВОЗможность ИСТР~БЛЯТЬ нену фрагм.енты и предоставьте приложению жные реитинги.

<html

xmlпs="httр://www.wЗ . оrg/1999/хhtml"

<head> <meta

http-еquiv="Сопtепt-Туре"

<titlе>Гитарные

войны.

xml:lang="ru" lang="ru">

content="text/html; charset=utf-8" />

Удаление рейтинга</titlе>

<link rel="stylesheet" type="text/css" href="style.css" />

БкЛ}ОЧен.u.е ~Uло€

</head> <body> <h2>

Гитарные

войны.

Удаление рейтинга

</h2>

cu,ef-td.pu.e€ с оdщu.мu. 3d.н.н.bi.Мu.. 11 ри. Э-)1)ОМ

u.Сt)оЛЬ.зуе)1)с5t €bLРd.жен.u.е

<? h

re9u.ire_ot)ce.

....

require_once

~1I"",,"

~,connectvars.PhP');

i f (isset ($_ GET [ , id' ]) && isset ($_GET [ 'daf't.:. e_'...........::.:::....;::.::;,:;=..:..:::.

isset ($_ GET [ , score ' ]) && isset ($_GET [ • screenshot· / / Извлечение данных рейтинга . . $date = $_GET [ ' date' ] ;

$пате = $_GET [ 'пате' ] ;

_ _!I!!8I'J/If!I!!!II еlве

(

~

'а $_GET'

\

Б cu,ef-td.pu.u. €bLt)ОЛНЯ}O)YjС5t pd.Jн.bte cpp'd.~MeK)1)bL КО3с!. € .3d.€u.cu.мoc)1)u. 0)1) )1)0~0. € pe.3>~Jib)1)d.)1)e

$id = $_GET [ 'id'] ;

'score'] $_ GET <..

)

J

Kd.KO~O .3d.t'1POCd. (GIТ u.лu. РОSТ) он. dbI.Л €btJ€d.Нo

•screenshot •

if (isset($_POST['id']) && isset($_POST['name']) && isset($_POST[ ' score']»

(

// 1J .И. t:л.~.ние данных рейт~ . и:з суперглобального массива $_POST .... $id . . .. = $_ POSTl ... ~ . .J; PHP-ЭLAреК\'Т)LA€d. @, 110.9d.€Л5{}ОЩС\5{ $п . е''" _POST [ ' пате' ] ; ощu.дке. 7n)0 н.eoдxo.9u.мo 11 LA €'b!.J

€bL€0 d g ~ соо Ще н.LA5t Од 110'YТ)OMy Ч\'Т)0 #ь!. МОЖем €~з€o. ь о е фун.кLI,LAu. UI1~il1k(), н.есущеСYr1g~}ОШ,ег.о ..... ~i1лo. • 12j) ___~OMee .9ЛL~ У.9dлен.LA5t 't"-< "1 СЛу"К.\е #ht н.е

$score = $_POST [ ' score' ] ; else ( echo

xo'YТ)!JJv\, Ч\'Т)0 bt 110ЛЬJО€d.'УТ)ель €u..9ел .7'\'Т)0 соодщен.uе. '<р сlаss="еrrоr" > Изв

ите ,

ни одного рейтинга не

i f (is et ($_POST [ , submi t ' ] ) ~

$_POST [ 'confirm'] ==" . • Уев'

if

/

Удаление с сервера Ф

подтверждающего рейтинг

..

.} (

выбрано для удаления.</р>';

Cu,ef-td.pu.u МОЖе)1) dbL11)b u.Сt)ОЛЬ30€~н. зл5t У3d.Л е н.u.5t Л}О~О~О peu.)1)~d., t)ОЭ-11)ОМУ

. . ажеНJИЯ фс1.UЛ UJодрС\жен.u.5t, e~o

@unlink(GW_UPLOADPATH.$screenshot);

t)О.9)1)€еРЖ:9d./ОЩе~о, ОЛЖен. дЬ!;

11)С\КЖе ~d.Леu

'"

u. :w..30 ~ "1

o"lТ\

СОС1У\d.Ыid.Я

ЧС\С_"IТ\Ь о Щег.о r,pou,eccC\ \!Qd.Лен.u.5t

/ / Соединение с базой данных peU11)u.~d..,}J $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAМE};

324

zлава5


J,

jld:JIMIT

mysqli_close($dbc) ; Вывод пользователю страницы подтверждения

//

echo

'<р>Рейтинг со $пате

. '

значением'

. $score . '

для пользователя

был успешно удален из базы данных.</р>';

else echo

'<р

class=~error">

Рейтинг не удапен . </р>,

;

else

&&

echo

' <р>Вы уверены,

echo

'<р><strопg>Имя:

' <br

что

хотите удалить этот рейтинг?</р>';

</strong> , .

/><strопg>Рейтин г:

$пате

.

</strong> ,

' <br

/><strопg>Дата:

$score.

</s trong> , . $date .

' </р> ';

echo ' <form method="post" echo '<input type="radio"

naтe="confirm"

echo ' <input type="radio"

naтe="confirm"

/>

Нет

<br /> ';

echo ' <input type="submit" echo ' <input type= "hidden"

пате = "r-""'--.><.a""t:~ ­

echo ' <input type="hidden"

пате=

echo ' <input type="hidden"

naтe= .",.lIrl

/> '

i

echo '</form>';

echo

' <р><а

?>

J

1:'

href=. < "admin • php" :- >& ' т цдй.д Ii ; 17

; <

Назад к списку pej~T>OO'OB

< / а>< /р> ' ;

</body> </html>

ru.t1ерссbt.лl(d кс\ C'Y!)pqкul.ftj

«Аэми.к» одлег.Yqе'У!)

€ОJ€pqщекuе

1(

removescore.php

н.ей.-··---НескоЛЬко CIO)bi..'mb1:.x rtолеu

ЭЛя. rtе.реэачu. эакн.bt.x ('1

, id '

КаК Чd.С'У!)Ь

POSТ.

\ НедолЬшое. колu.Че.С'У!)€о Мd.г.н.u.'Y!)o€ ОС'У!)dЛосЬ н.е.u.сrtОЛЬJО€d~

Jdrtpoca

C'Y!)Pdн.u.up Jdllpoca

IlО.9.'У!)€еРЖ:9ен.u.я.

€~0.9u.'У!)Ся. 'У!)олЬко € 'У!)ом СЛУЧdе, е.слu. €ce Э'YI)u. rtepeмeннbte u.мe.)O'YI) н.еI1УС1Т\bt.е ,3КС\ЧеtШst.

вы здесь.

325


окончательный тест-драйв nриложения «Гитарные войныJ>

-Тест-драйв Добавьте сценарии «Удалить рейтинr)) и «АдмиН)) К приложениlO

«rитарные войны)), чтобы ПОllвилась возможность удаЛIIТЬ реЙТинrи. Создайте два новых текстовых файла:

removescore. php и admin. php, добавьте

в них код, который мы с вами только что рассмотрели. Загрузите все эти файлы на

ваш веб-сервер и откройте сценарий

admin . php

в брауэере. Щелкните кнопкой мыши

на гиперссылке <iУдалить>.'> для того рейтинга, который вы хотите удалить, и затем

подтвердите удаление этого рейтинга в форме страницы подтверждения <iУДалить рейтинг>.'>. Вернитесь на административную страницу, чтобы убедиться, что рейтинг, о котором шла речь. действительно удален . После этого откройте главную страницу приложения <i[итарные войны>.'>

(index. php)

и посмотрите, какие изменения произошли на ней.

НО€d.я с~рФшu,a

::::.:.... . ---, . .- . .----.

v:--

~::::

...

__ "-<=-_

=-":"..::.. . '·'iIIII""_~---~;' ''' Ъ:~i~:'Нr.

:-:"3::....::..::-..:-:.:-=

\,.--

НО~d.Я

Kd.K эЛЯ

' УЭd.Лен..u.я.

Hd. z.м€н.оu. c"YТ\j'd.н..u.u,e

t)реЭОС~d.€ляе~

н.еl"\оэ~~е е:ж:эен.н.btx реu.~~н.г.оК

о о

~ эля. l"\олуЧе~

t)р~о.жен.~ «Гu.~d.pн.bte

€Ou.н.bt» "yт\et1epb €~Э~ "ут\олЬко lIоэ~€ер.ж:9ек:н.btе

....---

~-

ЗctКон.н.btе z.u"YТ\o.pн.bte Гкropвw. _ ..... Со.со. ре""""". €OlAн.bt эо€ольн1:it: oн.u~=-~~"='!~~~""'..::r-­

g~эя.~ 'tТ\el1epb 'tТ\олЬко peu'lТ!~

Неi\оэ~€еРЖ:9ен.н.bI.e ~o ес"УТ\Ь ~e, эЛЯ 'Lfy.nr")I~I.J(

o~cJ'ТIc~€Y)<JYr\ фctu.лbt

~.306ро..жен..u.u., i\оэ"УТ\€ер.ж:9d.)ОЩUX ~"УТ\и. реCi~u.н.z.u, "YТ\et)ep'b УЭd.Лен.bt ~J щс~е.мbt.

zлава5

t10э~€еРЖ:9ен..u.я

~~oz.o.

"yт\~н.г.~.

t"i O~'IТ!ee р.жэен.н.bte

326

t"\реЭОС~d.мяе'!Т\

€ОJМО.жн.ос~Ь

реu.~u.н.г.d., ~d.K

C~Pd.н..u.u,a.

эЛЯ УЭd.Лен.~

-

реu'!Т\~н.г.»()

1I1111111111~....,н.ен.у.жн.оz.о

аэМ~С~Рd.~~€Н4Я z.~t)ерссbtЛК~

«УЭd.Л~~Ь


работа с aaHHblMU, сохраненными 8 файлах

к POCC50pg РНР

u MySQL

Устали загружать файлы на сервер? А как насчет того, чтобы загрузить кое-какие

знания в квадратики, собранные в головоломку? По

rop"SOHTan ..

1. Это значение должно быть присвоено атрибуту type тега <input>, чтобы создать поле ввода имени загружаемого файла.

4. Разработчики ве6-приложений обычно сохраняют на сервере файлы изображений в каталоге с именем

_ _ _ __

б. Информация о загруженных файлах сохраняется в суперглобальном массиве

$---7. Выражение с этим ключевым словом используется в SQL-запросе, чтобы

изменить структуру таблицы базы данных.

8.

Выражение с этим ключевым словом

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

10. Это

РНР-выражение используется для

включения кода из другого сценария .

12. Добавляемые файлы очень удобно применять для _ _ _ __ использования данных несколькими сценариями.

По верт"каn ..

2.

Выражение с этим ключевым словом

используется в SQL-запросе для

предотвращения удаления более чем одной записи из таблицы базы данных.

3.

Это выражение РНР используется для

инициализации константы.

S. Это

ключевое слово используется как

часть SQL-выражения, обеспечивающего расположение записей в результате запроса в нисходящем порядке.

7.

Выражение с этими ключевыми

словами используется в SQL-запросе для

добавления новой колонки при изменении структуры таблицы базы данных.

9. Когда файл загружается на сервер в результате обработки формы, он помещается во

______

каталог

на этом сервере.

11. Весьма

полезные действия, которые

рекомендуется производить над только

что загруженными на сервер файлами.

вы здесь.

327


кроссворд решение

КРОСС60РУ РНР

328

глава

5

u MySQL.

Решенuе


работа с данными, сохраненными в файлах

Ваш инструментарий РНР и

MySQL

Не стесняйтесь и возьмите в руки виртуальный ящик для инструментов.

Вы не только стали любимым человеком для виртуальных rитаристов, но также

накопили еще

HeMHoro HOBoro

опыта о РНР

и MySQL: изменение структуры таблиц, заrрузка файлов на упорядочение

329


6 д~~u,11t,~ ~~\Ue6o l1fu,l\oJJelfu,j{

С.,,,,оЙ,е,

~

.,,0 вее он" т

ИClмереи",воеnоп"зовtn'WII

*-

ваш"м" ena60erllM"

DbIcmpeнbKO l?;,оораться Ha~epx, nереклlOчuть несколько

-+

телetpонных npo~o()o~, u этот 3дхолустныu горо()иl.UКО

nepecmaHem nOHUMamb, Что npoucxo()um.

Воши родители были праВЫ: никогда не разговаривайте снезнакомыми людьми . Или, по крайней мере, не доверяйте им . Ну и, конечно же, не давайте им ключи доступа к данным вашего приложения, полагая, что они будут делать то, что положено. Мы живем в жестоком мире, и вы не можете рассчитывать на то, что все

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

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

ЭТО нов ая глава

ЗЗl


«Гитарные воины» nодверглись хакерекой атаке

День, КОГАа vмерла

MVJblKa

Эх, время, когда наш молодой виртуальный рок-вундеркинд купался в лучах славы, оказалось слишком коротким , потому что наивысший

рейтинг ~Гитарных войн., принадлежащий Джекобу, как-то вдруг

исчез вместе со всеми другими рейтингами. Как будто какие-то дьявольские силы вмешались, чтобы разрушить приложение ~Гитарные войны. и не дать возможности гитарным воинам соревноваться в Сети. Несчастные виртуальные гитаристы

и все это отражается на вас

-

-

это несчастные пользователи,

несчастном разработчике приложения!

Гитарные войны. Список рейтингов.

~;~:~~~~=~Т::;::';=~. --_...... ...... ....._....._ .. ~~!:~;~Д;':~~ВОЙ ~~ B.~~o.~.

__

3mo неспrаР1wлuею!

На ~ЛG\€~u. ci'Т\eaк.u.u,e к.ei'Т\ peui'Т\u.~oK l"\oi'Т\oMY '-hI\о ок.и. дbV1u.

У.9G\Ленbt UJ дG\3bt.

.9а н.н.Ь\.Х!

Я mrY()UЛСfl не покла()аfl рук.

чmоОы cmamb самым лучwuм rumarHbIM Р10ином, а сeUчас MOU reUmuHf uсчf3. о о

332

глава 6


защита вашего приnожениR

Куда делись рейтинги?

:)qIiPOC SELfCТ

Mbi знаем, что главная страница приложения «Гитарные войны» пуста, но означает ли это, что и база данных также пуста? Запрос SELECT может

l')ol(d.3bt€~e"tТ\, ЧYr\о

"tТ\~дЛUu,a ~uit~r'W~rs

\"VI::Ic;v\J,J."-ГV'-V l')yc"tТ\~: €ce

Wi~iW~;;~~;;;;;;;;::::::::=======-----------------~~~

uсчеJЛШ

~

Как-то получилось, что все записи рейтингов были удалены 113 таблицы

guitarwars

базы данных. Могло ли произойти, что

кто-то использовал наш сценарий «Удаление рейтинга» , чтобы

совершить такое злодеяние? Нам необходимо защитить рейтинги!

Просмотрите предложенн ые ниже варианты, выберите те из них, которые вы могли бы использовать для защиты рейтингов приложения «Гитарные войны» от злобных виртуальных гитарных ненавистников,

и напишите, почему вы выбрали именно эти варианты. Соsдание системы реrистрации

Защита паролем страницы «Администрирование рейтинrов»:

ПОЛЬЗ0вателей с предоставлением

топько чеповек, который

только отдельным ПОЛЬЗ0вателям

SHaeT

паропь

(вам!) привилеrий администратора.

(вы!), сможет удапять реЙтинrи.

Проверка lP-аАреса компыоера,'

Ликвидация самой воsможности

пытаlOщеrося попучить доступ к странице

~

«Администрирование рейтинrов)), и предоставпение

TaKoro доступа

удаления реЙтинrов.

только

опредепенным компыоерамM (вашемуl).

вы здесь.

ЗЗЗ


защита рейтингов (Гитарных воин»

~Ш'НU' 38a8'lU Про,.о,".,е предпоженные н.же "р.,н,", выбер.,е ,е н.,. ••

которые вы могли бы использовать для защиты рейтингов приложения

« Гитарные войны» от злобных виртуальных гитарных ненавистников, и напишите, почему вы выбрали именно эти варианты .

~ce вctрu.ctн.lI'\bt. lI'\ctK u.лu.

3ащита паролем страницы

«Администрирование рейтингов»: только человек, который знает пароль

(Bbll),

сможет удалять рейтинги.

~че peUJ.d.)OVr\ t)родлему. lI'\ОЛЬКО 0.9кu долее ЖU,3н.еСt)осодкbt.. ЧеМ

.~Щ~1'I~ .1).C:\f.9.~~ .~)!'\~~ . . . ...• ... ••... . . . .

~11~.~mр~р.~I:Щ~. r~~1I)~9~~ . :-:: .......

эr~·"е'J

.~.<? ~С?f.~Щ~~ ·r·~щ~·~~,· .I)~~~~ ....... ....... . . .~C? .9~ .~..~flЩl;Щ9.~. ~~.<?~.I!o. .~mr~

....

jQщ~еll'\ cctUll'\.

Создание системы регистрации

пользователей с предоставлением только отдельным пользователям

(BaMI) привилегий администратора •

.~? ~!.'!l:~.~~ .r.~~~.~~,. ~. ~~.~ ................ ·r~~·~r~~У.~:v.r!·"!!IЩ~"!!I·~~~·~~ .. ·.·.·

Проверка IP-аАреса компьютера, пытающегося получить доступ к странице

«Администрирование рейтингов»,

·!\~~p.~~ .~..~9.~щ~.~~~9: ....... ... .. . ·€.~R.9~P.~€~.': . ~r~1'I~p.~. €<?Ц.~~ ... .. .

.~r~~~~~~~ .~Щ~~~. ~~i;i.~~!.....................

и предоставление такого доступа только

определенным компьютерам (вашему!) •

.l'r~~r.~~. ~~~p~~. ~Щ~~~. ~~.~.~~~r.<:\..9ctell'\ .r~3::i~~~"!'): .~..9~~~~ .~f.~~~~~ ........ .~~!l:~~.~ .~~~.~. ~r.~~. ~ .?t:t: .~~~~ оЧеНЬ лег.ко UJ.Мекull'\ЬСя. (в lI'\OM Чu.сле 1)0

'~'~~рш~~ .~. ;;'в~~~щ~6" ';m .~~ ·~·р~ч~).

Ликвидация самой возможности удаления реЙтингов •

.!l.ч-х€~~~.~Q.. ~~~~.~m~.~~:Y!'Ib ·r~9:~~1!o. .p~~~~..<?!З~J !1p.<?~-!!~~, ....... ... .

..~,..~~~ .~~.~.C?~m~:.~.9~~~~ .~~~~cll'\b

·~m~. f.~~"!!I~~ .~. ~p.~.9~~~.~..~~~~! 'hrIoдbt ·:1!I.Y~~.~. :YJ\~~~~~~ .t:I.<?.99~r~:1. ~.~:YJ\ct.

3З4

глава 6


защита вашего nриnожениR

3ащита от наwествия 6аНА 3J10YMbIWJleHHnOB Простой и прямой способ быстрой защиты приложения .Гитарные войны. заключается в использовании НПР-аутентификации с проверкой имени пользователя и его пароля при попытке открытия

страницы .Лдминистрирование рейтингов • . Основная идея этой

технологии заключается в том, что для получения доступа к критическим CnОСОБ за:UJUtnb1 ctnpaнu'цы1

функциям приложения, таким, например, как удаление рейтингов,

С UCnОAЬЗ05aНUeМ РНР.

администратор должен ввести определенные секретные данные .

Если страница защищена с использованием НПР-аутентификации, при попытке ее открытия появляется окно диалога, запращивающее имя пользователя и его

пароль. И только после ввода правильных данных будет предоставлен доступ к защищаемой странице. В случае .Гитарных войн. вы можете предоставить такой

доступ ограниченному количеству пользователей, потенциально

-

только себе!

тel)epb межзу

t)О)1ЬJО€<:I1Т\елем

u.

с1Т\р<:lНJ.A.u,еЙ

«А.9~С"II').Pu.РО€Ф{uе р еu1Т\UНZОff.o

НД)(О.9 U1Т\сЯ ОI<НО

httr-<:Iynlен.1Т\U­

фu.I<<:Iu,uu.

k:-----/

После 1Т\ог.о 1<<:11< С1Т\рФiUU,CI

«А.9~НJ.A.С"II').Pu.ро€Ф.u).е реu1Т\u.н.г.оff.o С1Т\cI.J1C\

3<:1~~еККОЙ,JCI~~е~ С'Yl)С\Лu. 1Т\dl(Же

~e .9<:1кнЬ!х.

2Q08.Q5-0120:36:07

_-

.

200a-0.s-0120:36,AS

А-о6'-

3897..0

2008.Q5-0120:37:02

-"""-

2008-05-0120:37;23

....'0 .27_

17

" ••

2Q08.D5-0120:37:AO

10

2O()6.O.S.0120:38:23

gu1tarwar8

.. ;1

1s

.....

20()8..0.S-0120:38«1

.....

-. . n-_ -"""""'" к-л.-

282"70

-

u.

рей1Т\u.н.г.u.

j

-~

-~ """-"'Чl --.~ _

. ~

.86500

....30

........-.~

2..3360

~.~

вы здесь.

335


uсnonltЗоеонuе HTTP-оуmенmUфUКQЦUU

3ащита страницы «qминистрирование рейтингов» ПРИJlОlКения с(гитарны e войны») НПР-аутентификация работает следующим образом. Когда пользователь пытается получить доступ к странице, защищенной методом НПР-аутентификации, такой как наша страница .Администрирование рейтингов., появляется окно диалога, запрашивающее имя пользователя и его пароль.

Бp<tJJер

~d СJ1ерг.лодCVJb~я. t)eремеННt:\я.

UСt)ОЛ:)jу е"Yr1

"Yr1dl{oe ОI{КО ЭЛЯ Jdt)poCd цмeкu

<:~ержu"Yr1 uмя. t)ОJJbJО€d"Yr1 еля., Wеэен.к.ое € окн.е .9UdЛог.d

~

dy-тен."Yr1 UфuкdLl,Ltu.

t)олЬJo€ct"Yr1еля.

t

u I1dРОЛЯ, I1pe~e Чем I1реЭОС"Yr1d€U"Yr1Ь .....: к Jdщuщен.к.оi1 n.c-.: [ . C"Yr1p<tкuu,e. ~ о э-wn.,,;...,....~noponoilj8~

ЭО С"Yr1у!1

Для. у!1рощекu.я. t)dPOJb l1ере~е"Yr1Ся.

(о- ) ~

€ н.еjdШUФРО€dн.к.ом

€uэ е .

Эmd Су!1ерг.ло&vbНd9. l1epeMetUWt C0.g ep')fW.l!\ I1dP0 .rb, €€е.эеННbLi1 € Окке .9UdЛOtd dy-теКl!\u.cpu.кdLyJ.U­

РНР вступает в игру, когда возникает необходимость в доступе к имени пользователя и его паролю, которые он ввел в окне диалога аутентификации.

Они сохранены в суперглобальном массиве $_SERVER, аналогичном другим суперглобальным переменным, которые мы уже использовали ($_POST,

$_FILES и т. п.). РНР-сценарий может проанализировать имя пользователя и его пароль, введенные в окне диалога аутентификации, и на основании

результатов такого анализа принять решение либо о предоставлении этому пользователю доступа к защищенной странице, либо об отклонении запроса. Предположим, доступ к странице .Администрирование рейтингов. разрешен пользователю с именем .рок. и паролем .ролл •. Ниже показано,

как будет открыта страница .Администрирование рейтингов • .

336

глово6


защита вашего приложениR

l{G 8bJ~itGTh.

Z1t11blX ffio11roco~

'9; Полностью ли ищищает НТТР-аутентификация?

О; и да, и нет. Все зависит от того, чего вы хотите достичь в защите своей

информации. 1ОО%-Й защиты не существует в принципе. Поэтому все, о чем мы можем говорить,

-

это степень защиты. Для защиты рейтингов приложения

,Гитарные войны» НТТР предоставляет приемлемый уровень. Вы можете

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

-

такими,

например, как финансовые.

'9; Что ПРОИ30Мдет, если имя пользователя и/или его пароль будут введены неправильно?

О; Браузер эмитирует небольшой электрический разряд через мышь. Нет, никакого болезненного воздействия не будет. Обычно выводится

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

Насколько жесткой будет информация, содержащаяся в этом сообщении, зависит исключительно от вас.

'9;Требуется ли при НПР-аутентификации вводить и имя пользователя, м его пароль? Что, если я введу только пароль?

О; Вам не требуется вводить и имя пользователя, и его пароль. Если вас интересует только пароль, проверяйте только суперглобальную переменную

;: _SERVER [ , РНР _AUTH_PW' ] . Больше о том, как проверяется эта переменная, чуть дальше

...

'9; Как на практике ищищается страница с помощью

НПР-аутентификации? Необходимо вызвать РНР-функцию?

О; Да, нужно. НТТР-аутентификация включает обмен информацией между браузером и веб-сервером с использованием НТТР-заголовков. Вы можете рассматривать НТТР-заголовки как краткие диалоги браузера с сервером. Браузер и сервер достаточно часто используют НТТР-заголовки для

обмена информацией вне контекста РНР, но РНР позволяет вам отправить НТТР-заголовок для осуществления НТТР-аутентификации. Нам придется

углубиться немного больше в понимание НТТР-заголовков и их роли

Когда конкретно должна

в НТТР-аутентификации применительно к РНР.

состояться НТТР-аутентификация для доступа к странице

«Администрирование рейтингов»?

вы здесь ~

ЗЗ7


аутентификация и HTTP-заZОnО8ки

HTTP-аутеНТИфикации тре6уются HTTP-заГОnО8КИ Основная идея, лежащая в основе НТТР-аутентификации, заключается

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

после того, как пользователь введет правильное имя и пароль , отправляет

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

текстовые сообщения , содержащие особые инструкции о запрашиваемой

все bes-cmраНUUbl nepegaюmcs с ПОМОЩЬЮ

Н 1 1P-загОАО6КОб.

или передаваемой информации.

Ве6-сервер

~О'Yl1l-ЩdОр НТТР-Jо.г.оло€ко€

о

Od~clJye'Yl1 J..~C

&раузер

€ед- с'Yl1ро.кu

запраwивает у сервера страницу, передаваА

ему нескоnько

НПР-заrоnовков,

отвечает набором . . . .... Сервер HnP-заronовков,

/

~ ~-=-_

"-_ _",, за которыми (при уcnовии ввода правиnьноrо имени

содержащих

поnыоватеnА и

наименование

cnедует запроwеннаR страница.

Tpe6yeMoro файnа и ИМR сервера.

&раузер попучает НПР-заrоnовки и страницу,

KOTOPYIO

выводит на экран.

338

lлава6

ero паРОnА)


защита вашего nриnожениR

АнamомШI HITP-загОАО6Ка НТТР-заголовки тщательно следят за тем , какая информация и как проходит

в прямом И обратном направлении между браузером и веб-сервером. Индивидуальный НТТР-заголовок чаще всего состоит из пары ~имя/значение~, которая определяет

конкретные сведения

-

такие, например, как формат содержания веб-страницы (НТМЦ.

Определенная группа НТТР-заголовков посылается на сервер как часть запроса

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

БоЛЬщuн.с1'l\€О НТТР-Jctг.оло€ко€ UJ I)ctp «"UМSI./Jн.ctЧен.u.е~, г,ае Jн.ctЧен.u.е

Пеp€Ьц1 HT'rP-J<tгОЛО€ОI( Н,е '1Р:ЭС'll'1d€ляе'll'1

coc1'I\O.5{1'I\

О"ll'\.9еЛ.5{е1'l\С.5{ 0"rrI ~ен'И Э€oe1'l\o чueIII.

GET / index. h

7mO"rrlHTTP-Jdг.оло€ок Оt)реаеЛ.5{е:m дOd.~зер,

User-Agent: Mozilla / 5.0 ... Accept-Charset: 180-1 ... Cache-Control: по Accept - Language: de, еп; q=O. 7 ..•

J€

сэ ем щu.il

I

jd.I"\POC .

~y цмя/jКt:lЧен.u.е». j<.\'1poc C'll'1pdн.u.LI,bt БЕТ. JffjO

оп:

~P/1.1

200

0;->

~ Th 01 ~y 2008 11:22:09 GMT Date: и, Server: АрасЬе / 2 . 0.54 ... x-powered-Вy: РнР / 5 . 2 . 5 psfer

Epcoдi ng' фJ;)d

~tent-Тype :

text / htffi!

.7mO"ll1 HTTP-Зctг.оло€OI( zo€opU"'ll'\

дрctузеру. ЧYr\о соэеРЖ<:tн.u.е l)ере.эфl.О € €u..э е НТМL-ко.э ct , € ГlРO"rrlu.€ОI)ОЛО.ж.н.ос"'ll'\Ь, СКct.ж.eм, I)POC"'II'\oмy

"'II'\eKc1'l\Y,

Понимание действия НТТР-заroловков в приложении ~Гитарные войны~ имеет для нас значение потому, что через них реализуется механизм прерывания сервером передачи

страницы и формирование требования о том, чтобы пользователь ввел свое имя и пароль прежде, чем страница будет передана. Иначе говоря, вы должны тщательно разобраться с этими НТТР-заголовками для того, чтобы защитить страницу с помощью НТТР-аутентификации.

вь, здесь

ЗЗ9


интервью с НТТР-заzоловком

НТТР-Jаголовои: пристальный ВJГJlЯД Интервью этой неделИ:

По какому поводу вся эта суета? Кoppecnoндeнт редакции нead

Rrst:

Похоже ,

НПР-эаroловок: То же самое и здесь. Браузер говорит

вь) привлекаете большое внимание , когда дело касается

серверу, чего он хочет, составляя запрос и ОТIIравляя его

аутентификации веб-страниц . Это действительно

в виде з аголовков.

оправданно или вь) просто ишете повод для своей

пятнадцатиминутной слаВbI?

корреспондент peдaICЦИИ нead

Rrst: Интересно.

Но я СЛblШал , что и сервер также может отправлять

НТТР-эаroлoвoк: О, конечно, это оправданно . Вы наверняка

заголовки. Я думал, что серве р отправляет только

считаете само собой разумеюшимся, что я играю решаюшую

содержание страниц .

роль в передаче каждой сушествующей веб-страНИЦbl. Поэтому я не сомневаюсь, что вь) могли бbl сказать: веб

НПР-эаroловок: Хороший вопрос. Дело в том, что я важен

вряд ли смог бbl существовать , не принимай я в этом участия. И без меня не обойтись значительно дольше

также 11 для другой СТОРОНь) этого диалога, потому что

сервер должен делать больше, чем просто перегнать

пятнадцати минут , даже если моя роль и преувеличена .

браузеру содержимое страНИ1lbl . Без дополнительной информации браузер просто не будет иметь представления

Корреспондент редакции нead

о том, что ему делать со всем те м , что он получил .

First:

Хорошо, так в чем же

на самом деле заключается ваша роль?

Корреспондент редакции нead

First:

Что это должна бblТЬ

НТТР-эаroловок: Вы ДОЛЖНbI понять , что И браузер,

за информация?

и веб-сервер - это не ЖИВblе люди и они не могут звонить друг другу по телефону или обмениваться теКСТОВblМИ

НТТР-эаroловок: Bo- пеРВblХ , формат содержания

сообщениями.

type).

(Content

Это, возможно, самая важная информация,

но сервер также отправляет и другие данные, такие

корреспондент редакции нead

First: Боже мой!

как размrр страНИЦbl, дата и время передачи и т . д .

НТТР-эаroловок: Да, я знаю , это звучит немного

Корреспондент редакции нead

обескураживающе , но маШИНbI действительно не могут

отправляется сама страиица?

Rrst: А когда же

обмениваться информацией между собой так, как это делают люди . Но браузер и сервер ДОЛЖНbI обмениваться

НfТP.ЭCJroI1OIIOIC: Сразу после того как сервер ОТIIравит меня,

информацией, и они делают это с моей помощью.

он передает фактическое содержание странИЦbl, будь то НТМL-код, PDF-данНblе ил и изображения в формате GIF ,

Корреспондент редакции нead

J PEG ...

First: И как же это

происходит?

НПР-эаroловок: Когда кто-нибудь вводит

URL в адресную строку браузера или щелкает по гипеРССblлке на веб-странице, браузер составляет запрос GET и отправляет его серверу . Этот запрос состоит из нескольких заголовков, содержащих

информацию о нем . Заголовки содержат такие данные, как наименование и адрес запрашиваемой страНИЦbl , тип

браузера, с которого бblЛ отправлен запрос , и т . п . Корреспондент редакции нead

First: Я до сих пор н е могу

Корреспондент редакции нead First: Хорошо, я начинаю понимать вашу роль, когда речь идет об обblЧНblХ веб-страницах. А как обстоят дела с аутентификацией? НПР-эаroловок: Для страниц, требующих аутентификации, мои функции остаются такими же, как

и для обblЧНblХ страниц, за исключением одного: я слежу

з а тем, чтобbl дать знать браузеру, что запрашиваемая им страница защищена и требует аутентификации. В этом случае браузер запрашивает у пользователя данные для аутентификации.

понять, поч е му э то все так важно.

Корреспондент редакции нead

НТТР-эаroловок: Ладно . Как вь) думаете, является

и пароль?

ли важной для официанта кафе информация о том,

что вь) хотите большую порцию ванильного эспрессо с молоком?

First:

Вы имеете в виду имя

НПР-эаroлoвoк: Совершенно верно . А дальше уже

РНР-код на сервере решает, праВИЛЬНblе ли имя и парол ь

передаНbI с браузера, и, если все в порядке , отправляет

Корреспондент редакции нead он же должен знать , чего я хочу.

Rrst: Конечно ,

запрошенную страницу .

Корреспондент редакции нead

Rrst: Великолепно!

Благодарю вас за разъяснение.

НПР-эаroловок: Никаких проблеJ'.1. Это часть мое й раБОТbI.

340

глава

6


защита вашего nриnожениR

Ра60та с H1TP-JаГОЛО8ками

8 РНР

Используя РНР, вы можете очень легко работать с заголовками, присланными сервером, что дает возможность выполнять задачи, управляемые заголовками,

к которым относится и НТТР-аутентификация. Встроенная функция

header ( )

~lOжет быть использована в РНР-сценарии для передачи заголовка с сервера браузеру.

~l.JU9

headerO

nmЮAgeI11

вам

[lIlIIIi<'content-туре: text/html'); Функция header () немедленно отправляет НТТР-заголовок с сервера

"должна вызываться до того, как само содержание страницы будет отправлено браузеру. Это требование является очень строгим. Если хотя бы один символ

cmga58.tnb

U otnnpaIWJmb HI 1P-зaroЛО5КU 113 РНР~рш

"ли даже пробел будет отослан до отправки НТТР-заголовка, браузер отбросит его и выведет сообщение об ошибке. Поэтому вызов функции должен предшествовать любому НТМL-коду в РНР-сценарии:

text/ht.ml· } ;

<html xmlns=''http://www . w3 . 0rg!l999(,xhtml'' xml:lang="en" lang="en" >

</html>

"'се зmu rЗ3fо&оrы !10 !10&оиу 11Г1Р-3ЗfОЛО&КО& очень uHmerecHbl, о

НО как мы можем UС!10ЛЬ3Q&зmь

ux иля 3ЗLJ.\umы сmrанuц с !10МОLJ.\ЬЮ зуmенmшрuкацuu:f

вЬlздесь ~

341


как НТТР-заголовкu реалuзуют аутентификацию

АутеНТИфикация с ИСПОЛЬЗ0ванием НПР-заголовков Веб-сервер Защита страницы «Администрирование рейтингов~ приложения «Гитарные войны~,

реализуя аутентификацию с использованием НТТР-заголовков, требует понимания нескuльких типов НТТР-заголовков (фактически

-

двух), которые дают знать браузеру,

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

«Администрирование рейтингов» и управляют передачей страницы браузеру.

НТТР/l.l 401 unauthorized WWW_Authenticate: _

Basic rеаlm=·Гитариые воины

"

Чтобы оопучить ДOCJYl1' 'Т,,", c:rpaнкцo, ... ДОЛ"''''

:"ci:.;.э:=;;:r .ГlIТ3p>tыe _ы.

~:,===::",H на С8рsop

-_...

.,---

Имя:

~-------~

Пароль:

( . ...

[ ] ЭаI10МНИТЬ

::

J

naРОЛЬ • мен&ДIЩIe паро",," на сервере

6рауэер

,Длg запроса gaННb1i\. нeosx.OgUMblX. gлg

аymeнmuфuкauuu mpesyюmcs gвa cneuuaльных.

Чтобы инициировать аутентификацию, требуются два НТТР-заголовка, которые выполняют две специфические задачи:

. ~ 7tт)01l1 HTTP-,}::I.г.ОЛО€ОI( .9de1l1 dpaYJepy t)ОНЯ1l1Ь, '-hтjo .----------:-:--. .9 d н.rtoMy t)ОЛЬJО€d1l1 ел)О иТТР/1.1 401 unauthorized ~ t)ре.90С1l1d€Л.5I.е1l1С.51. .9 0C1l1Yt)

Н 1 1Р-зaroловка. ~О1Т1НТТР-3dг.ОЛО€ОI<

IiРОGU.1Т1 дf.dуз е р r)Оllbt1l1d1l1 ЬС я.

dj'lY\ eI-l1l1u.cpu.u,u.роеcl.1I1Ь \iользоеcl.1Т1еля..

\iреэлож.u€ е.му €€ес1Т1u. u..МЯ. u. tldроЛЬ.

342

zлава6

~

1< JdЩLWJ,ен.rtоЙ С1l1 рфшu,е. WWW-Authenticate: Basic

rеаlm="ГИтаРlDlе ВОЙ!DI"

ФРcl.3d ~sic red)1I1 С3ащu.ще.l-l!-ld.51.

одЛcl.С1l1Ь) €ceг.o Лu.шЬ СЛУЖu1l1 u..g e I-l1l1 u.фu.к 0.111 ором .7111 о u. 1{ OfU( pe1l1 !-lO u. ~еI-l1l1u.cpu.l<du,u.u. u. t)ОЯЙЛ.5I.е1l1Ся.

~ Оl{н.е .9u.алог.с1. с1.j'IY\ен.1I1u.cpu.I<с1.u,u.u..


защита ваше20 nриnожениR

После обработки НПР-заголовков аутентификации браузер ожидает результатов диалога с пользователем, который проходит с использованием '

окна аутентификации. При этом действия браузера могут разительно различаться в зависимости от действий пользователя ...

Гитарные войRы. Администрирование рейтингов. ное ....-.. CIIIICOI: PatrIaU1I8 . . . . . - «ГIrraPU.e ........

~~~,~~~~~~~~:

Если пользователь введет правильное имя

и пароль и затем нажмет кнопку ~Войти»,

сервер отправит браузеру содержание страницы ~Администрирование рейтингов», и пользователь получит

возможность удалять рейтинги так же, как и в предыдущей незащищенной версии .

Если пользователь введет неправильное имя и/или пароль и затем нажмет кнопку

~Войти», сервер сообщит браузеру, что необходимо запросить эти данные

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

пользователь будет вводить неправильное имя и/или пароль. Иначе говоря, если

.. П.pщJЬ 6111'" OЩI88118Н . . -Р ........МФ\ЮО.- 8М,II8. .. ..

пользователь не знает правильного

ва

и....'

Ес.лu €€ез е н1:я н.е l1р<:t€Шlbн1:яе u.мя. 110лЬJо€<:t'Yl!еля

Паро

...:

имени и пароля, все, что ему остается,

)

=:'====:~-

ILLI ;:;;;

.~

о ЗanoII,,"Т' napom.' ~ J1Щ>OJ18I1tta сер..ре

@"ме?) E~' j

u. l1<:tpOJJb, окн.о ЗUd.Лог<:t

<:tyYI\ен.'YI!u.фи.К<:tЩJ.u.

~e1Тj €bt€ез еНD

-

это только нажать кнопку .Отмена» ,

--............ 11 '--../.

аутентификацию, сервер отправит

браузеру страницу с сообщением

~ :~гiиатlарlнiы:iеWв;о;й~~ii._.&iifiiiiiii;а., " И3аИ1lJtтс. вы ДОllЖUЫ ввести прав. КJIЬвwe к"ж ПOJlЬЭОaaтeJ1l 1 Н парот.. чтобы получwrь доступ J: ЭТОЙ стрmнщс.

,

Если пользователь нажмет кнопку

.От.мена» для того, чтобы прекратить

об отклонении запроса на доступ, и ничего больше. Страница .Администрирование

рейтингов» послана не будет. Сообщение об отклонении запроса на доступ контролируется РНР-кодом в сценарии

admin . php,

который тесно связан

с НТТР-заголовками. Этот код выводит

сообщение и немедленно прекращает выполнение сценария :

т1 IDLl.Лож.ен.u.е о1Тjd.кж.е u.мee"ll\ еозмож.к.ос"ll\~ u..5!. ехit('<h2>Гитарные

войны </ h2 > Извините,

ОС1У\фw€u.'YI!Ь ~bu10лн.ен.u.е. cu,eMp U. €bt€ec"ll\u. СОдС"ll\€еt-tНDе соодщеl-W.е.

вы должны ввести правильные ' . ' имя пользователя и пароль , чтобы

о t'\рu.чu.~ О"ll\клон.е.н.u..5t

получить доступ к этой странице.');

3<:tllpoc<:t

о

.90C1Y\:/Ile.

к c1Y\p<:tн.u.u,e, е.сЛu. t)ОЛЬ30€<:I"II\е.ЛЬ IlреКр<:l'Yl!LI.Л а.1"'ен."II\u.~I(<:tu,що,

вы здесь ~

343


окончание кода аутентификации

Магниты РНР в сценарии «Администрирование рейтингов» приложения «Гитарные войны» отсутствуют

несколько важных фрагментов кода, которые обеспечивают HTTP-аутентиФикацию.

Используйте магниты, чтобы добавить недостающий код и с помощью НТТР-заголовков

защитить страницу «Администрирование рейтингов».

Совет: отдельные магниты могут быть использованы только один раз. <?php 11 имя пользователя и его ....... ..... ......... .. = ' rock' ; .................... .. . ='roll

Ф кации

пароль для аутенти и

';

if ( ! issetC .................................. .... ) 11 ! isset( ....................................... ............ . ) 11 ( $_ SERVER [ , РНР_AUTH_ USER ' ] ! = .................... J 1 1 ($_ SERVER [ , РНР _ AUTH_ PW'] ! = ................................. ) )

//

имя пользователя/пароль не действительны ДЛЯ ?тпр а в ки НТТР - заголовков ,

I/подтверждающих аутентиФикацию

................... (' НТТР/1

. 1

. , 401 Unauthorl.zed ) ;

( ' WWW-Authenticate : Basic realrn=........ ....... ... ...........' ) ,. ' ,). _ ( , <h2> Гитарные войны h2> Извините, вы ДОЛЖНЫ ввести правильные , .. ... ... ... .... ......'имя пользователя и п ароль , чтобы получить доступ к этои странице . ?> <htrnlxrnlns=''http : //www . w3 . org / 1999/xhtrnl" xrnl : lang=" ru" lang= "ru " > </htrnl>

'-

.~.r..

admin-Pt1>

"Гитарные войны"

$password password

з44

zлава6


защита вашего nриnожениR

о

Конечно можно ••• НПР-заrОIlОВКИ ИСПОIIЬЗУЮТСЯ

не ТОIIЬКО AIIЯ безопасности. ХОТЯ именно процесс аутентификации демонстрирует непосредственное

использование НТГР-зaroловков, они достаточно гибки и могут быть использованы для решения многих других интересных задач.

n header ( ) pu 1l 0лученuu «имя/значение~, как, например, показано ниже: Достаточно просто вызвать функцию

.711')02.0

JQг.ОЛО€КQ

dPQy~ep

~

header ( ..' LQ ......"_ Ф-...!;:з.....Q...n_'.............._ _ _,..___......._ _...................

t)ер еuэ е11') нct С11')

с соответствующей парой

pal1.uu,y

Qbout,p':p ( «О CQti11')e»),

?>

Эroт НТГР-зaroловок называетсЯ lосаtioп header (НТГР-зaroловок места расположения) и переадресовывает текущую страницу на страницу с именем

about, php на том же сайте «Гитарные воЙны~. А ниже показан

аналогичный НТГР-зaroловок, который переадресовывает текущую

страницу на страницу с именем аЬои t

БРQу~ер t)ер еuэ е11')

нct C"'iТ\

~

header ( . Refresh: 5,url....ht~,j(www.9uitа.rЩЦ'$ . !'!еfфй)Ьil~.р\:;р );

PQl-W.u,y

Qbou·t.~p

echo

через

5

секунэ·

. php через 5 секунд:

'Через

5

секунд

вы

перейдете

на

страницу

«О

сайте»';

?>

Этот НТГР-заголовок называется

refresh header (НТТР-заголовок

обновления), так как он обновляет страницу через указанное время. Вы часто сможете видеть, что такие НТТР-заголовки ссылаются

на текущую страницу, то есть страница обновляет себя сама.

НПР-заrОIlОВКИ

ДОIIЖНЫ быть

Один из последних НТТР-заголовков называется

content type

header (НТТР-заголовок формата содержания), потому что

на самом

он контролирует тип формата содержания, передаваемого сервером.

первом месте

В качестве примера вы можете объявить, что содержание выводится

в PHP-фаЙllе.

в формате простого текста вместо

Это необходимо, потому что НТТР-заголовок должен быть

<?Ph P

отправлен браузеру перед

echo

Исключительно важно

даже единственного пробела вне РНР-кода перед вызовом функции header(),

.

о.

00

{

'

~Og:J::;C~~~h~~~~~ry3epy

header ( 'tQntent.-~!>.tе)(tlрli1.in~ ) ;

любым содержанием страницы, не допускать в РНР-сценарии

HTML, используя следуюший header ( ) :

НТГР-заголовок при вызове функции

'ЭтОТ

<strong>TeKCT</strong>

не будет выделен

I

'

жирным шрифтом';

?>

в этом при мере текст, выводимый в браузере, будет показан как есть, без НТМL-форматирования. Иначе говоря, сервер говорит браузеру не интерпретировать текст как НТМL-код, поэтому все содержание,

включая НТМL-теги, будет воспроизведено буквально, как простой текст.

вы здесь ~

345


законченный код аутентификации

Магниты РНР. Решение в сценарии «Администрирование рейтингов» приложения «Гитарные войны» отсутствуют

несколько важных фрагментов кода, которые обеспечивают НТТР-аутентификацию.

Используйте магниты, чтобы добавить недостающий код и с помощью НТТР-заголовков

защитить страницу «Администрирование рейтингов».

Совет: отдельные магниты могут быть использованы только один раз.

СУ llе рг.лодcU1ЬНДЯ ll е ремеКНQЯ $_SERVIR IlреЭОС"УУ}CI€ляе"УУ}ЭОС"УУ}УI) 1< цмeн.u 1l0.!lb.зо€CI)Тtе.ля. u ег.о

.--_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ IlClР О Лю,

i

€€е.эеннht.м € О/(к.о .эUC\Лог.CI ~ек.)ТtЩPUI<Qu,u.u.

еля и его пароль для аутентификации - - - . . ' rock ' ;

= 'roll';·

~ имя 1l 0лЬJО€Q'YI']еля u. . . ег.о IlQPO.!lb ~. coxpClfieк.bt, € l)epeMeк.к.bt.x

Знд Чек.uя. цмeн.u u Il Q Р ОЛя., €€е.э еННbtе 1l 0$JО€Q)Тtелем, СРCI€н.u€QЮ'mСя.

€ C<tМoM НДЧcU1е си,енд uя..

.,

PHP_AUТH_USER~.

) 11

С J~Qн.нh!.мu 3нд чеНlJ..ЯМu..

ЛЬ'Yl1d.'YI1е

.7'Y111J.X

:i"JX €bt3o€o€

hl:i1r() q€d. tlПР-Jс1Z-0ЛО€Кd. t'\el.~dннbte

UJ'II,..... ""..-. .

q:>~НJ(u,u.u. ~ КdЧеС'Yl1€е с1рг.умеК-'YI1 0 , ~ЭY'Yl1

О'Yl1t1ра€ленbl. дра~зеrу,

//

имя пользователя/пароль не действительны для отправки НТТР-заголовков,

//

по тверждающих аутеНТИфикацию.

, header . ( 'НТТР/1.1 401 UnauthorlZed );

..

t'Guitarwa~8nt);

. rea1m-.uj ( 'WWW-Authenticate: ВаБlС JJ31 . . . . ( , <Ь2 > Гитарные

войны Ь2> Из вините, вы

_

должны ввести правильные

., ''''.~:..:.'' '''имя пользователя и пароль , чтобы получить доступ к этои странице.

,). ,

?>

<htm1 xmlns=''http://www.w3 .org/199

" xml: lang="ru" lang="ru">

</html>

ФУНJ<u,u.st ехiiЛ €btЙо.эu."УУ)

соодщек.u.е одо"УУ}клок.ек.u.ц J<:IllpoCCI

нд О"УУ}l<рbt"УУ}це

C'Yl']P-Clн.uu,bt ~ I)ре.эО~€fCIЩQе)Тt

€W:оэ л}Одоu. .9рУг.оu

wtфорМctu,цц ~ СЛУЧClе, Q,}'"YI1efi'YI']u.cpu.KQu,u.st

еслu.

.зQКОк.Чu."УУ}ся. к.еУЭQЧк.о.

346

zлаваб

Н'!'ТР/1.1 401 Unauthorized

WWW-АUt~"пtiсаtе: Basic

,

,

., Н\

rеаlnt='гитарныe ВОЙНЫ- . ~

..

..


защита вашего nриnожениR

-Тест-драйв Добавьте НПР-аутентификациlO в сценарий «Администрирование реЙТинrов». Внесите в сценарий

admin . php изменения,

обеспечивающие только вам доступ

к этой странице. Загрузите сценарий на ваш веб-сервер и откройте страницу в браузере. Вначале попробуйте ввести неправильное имя и/или пароль,

ru.1Т\dРrLbt.e. €oцн.bt 1Т\еll ерЬ

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

уде.:ж.эеl-tbt €1Т\Ом, ЧYr\о JlUJ",,,,"r,,",,'"

деJОI"\GI.СI-lO

хорошо JdLU,u.LU,ен.о.

(

JiG 8bJ~itG1h.

Z111tblX ~01tfOCO~ ~; Когда вызывается фУНКЦИЯ exit() в сценарии «Гитарные пользователь либо не введет свое имя и/или пароль, либо введет их неправильно.

войны»?

О; Несмотря на то что функция exi t () находится в РНР-коде

~; Имеет IIИ какое-нибудь практмческое значение выражение

случае, если пользователь отменяет аутентификацию, нажимая

НТТР-аутентмфикации?

сразу же за функциями

header ( ) , она вызывается только в том

кнопку «Отмена». В случае же неудавшейся аутентификации

:ервер прекращает интерпретацию кода после вызовов функций ~.~ader

()

и оmравления НПР-заголовков и ожидает повторного

basic realm (защищенная обllасть) в системе

О; Да. Оно определяет безопасную зону, защищенную определенным именем и паролем. После того как имя

ввода имени пользователя и его пароля. Только в том случае,

пользователя и его пароль были успешно введены для данной

если пользователь нажмет кнопку «Отмена», вызывается функция

зоны, браузер запоминает эти значения и больше не выводит

-o:.:i t (), сервер отправляет содержание сообщения, переданного

окно диалога аутентификации для всех последующих случаев

этой функции в качестве аргумента, и ничего больше.

получения от сервера НПР-заголовков аутентификации,

Если аутентификация проходит успешно, функция

касающихся этой зоны. Иначе говоря,

exi t ( )

basic realm позволяет

~ вызывается, потому что условное выражение управляющей

браузеру запомнить, что вы отвечаете требованиям

<онструкции

безопасности для данного набора страниц. Просто укажите одно

if

принимает значение

false, и

код. заключенный

3 ее фигурных скобках, выполняться не будет. Это условное зыражение принимает значение

true только В случаях,

когда

и то же значение

basic realm

НПР-заголовков аутентификации

для всех страниц этого набора.

вы здесь ~

347


другая проблема, связанная с безопасностью

Отлuчно! К счастью, я сохранuла

cmpaHUЦY «YVаленuе peumuHroB))

В 3дклаuках cBoero "рарера, а 3дтем, чуть-чуть nounpaBuB иату, состаВила

этот

0fj?OMHbIU

UКk

е ВОйны. Список рейтингов. о DODJIONn, ГвтарвwlВОивl Твоl JICIТaВr арегистрllpOВавв.ыii • это.. СОНСае? в биr peJlDpдo

. CIIВ ТЦ, IIpOcro .цoбu~ своl pelтквr • CDВCOI<.

Ой! ОIlЯ:ЩЬ

tAJ

Ilрцложен.ия

«Гu"tI1C\pн.bte €oйнbt::o removescore. php?id= 10&name=Jacob%20 Scorcherson& date=2008-05-0 1%20 20:3б:45&sсоге=389740&

uсЧеJЛU peu"Yl\uн.zu..

i

Кон.ечн.о, fщон.е~с:л~u~ :::о:м -"~!!!!~~~~~!!~~~~~~~~Ii IlPOC"YI\O, н.О с 1l0МОЩЬ)О

UR.\..

C"YI\PdНl.l.u,b1. re"Yl\ovescore,f*'r можн.О odOU"YI\U .3ащu"YI\У

C'II\Pdн.uu,bt ad"Yl\ill.i*'p.

Таи, может оыть, приnо_ение с<гитарны e войны») не Jащищено? Т10хоже, JЛоэ еu ,

I\Ol(jLllO.~uUся. н4 Н4ш.U

«1U1T\dpн.bt.e

€oйн.bt», Н4ш.ел ct)ocod ОдОU:ЩU .3dЩU'II\j Н4ш.ег.о I)рцло.:ж.ен.ия.

Подумайте о быстротечной славе. Злоумышленнику не понадобилось много времени , чтобы нанести удар вновь, выкинув рейтинги из приложения, и уж в который раз повергнуть в уныние толпы

соперничающих исполнителей. Похоже, защиты одной страницы <!Администрирование рейтингов. недостаточно, так как сценарий

<! Удаление рейтинга~ остается

пока еще доступным напрямую ...

,

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

348

глава 6


ЗQщитQ вQшего nриnожениR

о

Джо: В этом есть смысл. Я имею в виду то, что НТТР-аутентификация отлично защищает страницу .Лдминистрирование рейтингов •.

Фрэнк: Это точно. Поэтому все, что нам нужно сделать,

-

это поместить тот

же самый код, использующий НТТР-заголовки аутентификации, в сценарий

.Удаление рейтинга., и все будет в порядке, так? Джип: Да, это определенно будет работать. Но меня беспокоит то, что нам приходится повторять весь этот код аутентификации в двух местах. Что произойдет, если позднее

мы добавим еще одну страницу, которую тоже потребуется защитить? Повторять этот код опять?

Джо: Дублирование кода

-

это определенно проблема. Особенно потому, что у нас

есть имя пользователя и пароль

-

данные, которые защищаемые сценарии должны

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

$username и $password

в свой собственный включаемый (include) файл и затем включить имя этого файла в код каждого сценарня, которому требуется аутентификация? Мы даже можем включить эти переменные в добавляемый файл для переменных приложения

appvars . php.

Джо: Мне нравится направление твоих мыслей, но это решение касается только

небольшой части дублирующеrocя кода. Не забывай, что мы ведем речь о фрагменте кода приличного размера.

//

имя пользователя и его пароль для аутентификации

$username = 'rock ' ; $password = 'roll' ; i f (!isset($_SERVER[ 'PHP_AUTH_USER' ]) 11 ! isset ($_SERVER[' PHP_AUTH_PW']) 11 ($_SERVER [ , РНР_AUTH_ USER '] ! = $иБеrnarnе) 1 1 ($_SERVER [ , РНР _AUTH_PW'] ! = $password)) ( / / Имя пользователя/пароль не действительны для отправки НТТР-заголовков // подтверждающих аутентификацию

header( 'HTTP/l.1401 Unauthorized'); heade: ('WWW-Authenticate: Basic rеаlm="Гитарные войны"'); eX~,t ( <h2> Гитарные войны h2> Извините, вы должны ввести правильные ' . имя пользователя и пароль , чтобы получить доступ к этой странице. ' ) ; ?>

<html

Джип: Вы оба правы. Поэтому, я думаю, нам необходимо создать новый-добавляемый файл и поместить в

Hero весь код аутентификации, а

не только переменные

$username и $password.

Фрэнк: Точно, и мы сможем просто включить этот файл в любой сценарий, который захотим защитить с помощью НТТР-аутентификации.

Джо: Все правильноl Мы только должны следить за тем, чтобы включать

ero в самом начале, так как

он полагается на НТГР-заroловки в процессе аутентификации.

вы здесь.

349


соэдание сценария authorize.php

[оздание сценария «Аутентификация») у нас уже есть весь код, необходимый для создания нового сценария

Mbt lAзgлекаем Э1Т\О1Т\ КОЭ

lA3 c.u,eM?u5\. d.d1Т\ i ll.f*'р эля. ~ hP ) T 1Т\О г,о , "hY\odbt \')омеС1Т\u.·~ e,i'-" его из сценария a~ln .php в новыи фаил с~~енария (authorl z e ' P и заменить прежнии код выражением reqUlre_once. е ег,о содС1Т\gе.~Й ~о.л

«Аутентификация». ~ело заключае:,СЯ т~лько в том, чтобы пе~енести

cu,eMpu5\. d.u."i:horize·f*'f· 1/

Имя

пользователя

$username $password if

=

и

его пароль

для

аутентификации

' rock' i 'roll';

(!isset($_SERVER['PHP_AUTH_USER')) II !isset($_SERVER['PHP АИТН PW')) ($_SERVER['PHP_AUTH_USER') != $username) II ($_SERVER[' PHP_AUTH_PW') != $password)) (

//

имя пользователя/пароль не действительны для отправки НТТР-загаловков

II

подтверждающих аутентификацию

header('H'I"I'P/l.l 401 Unauthorized')j , he~der( 'WWW -Authenticate : Basic rеаlm=-Гитарные войны·'); eX1t( ' <h2> Гитарные войны h2> Извините, вы ДОЛЖНЫ ввести лравильные ' . , имя пользователя илароль , чтобы получить доступ к ЭТОЙ странице . ' ) ;

350

lлава6


защита вашего nриnожениR

тG\K

<?php / / имя пользователя и его пароль для $username = 'rock' ; $password = 'roll' ;

KG\K

cu,et-Щрu.Й «Аутен:~u.фu.кG\u,u.я»

аутентификации u.Сt) олЬзуеIТ\Ся.~.} соtS'ме.СlТ\н.о~tS'\JМЯ

сu,е~u.ямu., bL МожеlТ\е bLlТ\b ytS'epeнbL, Ч"rr\о ~ е CIТ\PG\н.u.u,(;1l. д~~yт Ilрu.н.с:9ле ЖG\IТ\Ь ~~~ 3G\Щu.ще.нкой. о MclТ\u.. Э)Тjо 03t-ЩЧG\еlТ\,

if (1 isset ($ SERVER [ 'РНР _AUTH_USER' ]) I I ! is'set ($_SЁRVER [ 'PHP_AUTH_PW' ]) I I «н.u. u.Сt] ОЛЬЗУ}O'Yr) оэн.у u. "YI'\Y ($_SERVER [ , РНР _AUTH_USER'] ! = $username) I I u.мя IlОлЬзоtS'G\lТ\еля/t]G\РОЛЬ». ($_SERVER [ , РНР _AUTH_PW'] ! = $pa:sword» { для отправки НТТР-заголовков, / / имя пользователя/пароль не деиствительны / / подтверждающих аутентИфика~ИD , header ( 'HTTP/l.1 401 unauthor~zed ); _ ",). header ( 'WWW-Authent icate: Basic realm=" Гитарные воины пр~вильные ' . h2 извините вы должны ввести exit ( '<h2> Гитарные воины > б лу' чить доступ К этой странице. ' ) ; 'имя пользователя и пароль , что ы по

же t]G\PY I

"

?>

_otS'MeC"Yl'\НD u.Сt]олЬзуе.мbLu. сu,еКдрu.u.

AjМеЩG\е."IТ\Ся. tS' cG\МoM КдЧd.Ле.

<?php require_once('authorize.php'); ?>

: J,еКдРu.я., "IТ\aK КаК он. €bt.Jb!Вael'l\

JJjн.кu,u.u. ~e.

derO.

<html>

<?php require_once('authorize.php'); ?> <html>

~ КЛЮЧЕВЫЕ МОМЕНТЫ

~Р-сценарий может использовать НПР-заголовки

пользователем, сохраняются в суперглобальном

для того, чтобы управлять процессом передачи информации от сервера браузеру.

массиве $_SERVER.

Встроенная РНР-функция header () используется для передачи браузеру НПР-заголовков, которые

Basic realm (защищенная область) НПР-аутентификации - это защищенная зона, ассоциируемая с определенным именем

могут использоваться для переадресации страницы,

пользователя и его паролем и позволяющая

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

защищать несколько страниц одновременно.

Если НПР-заголовок отправляется браузеру с помощью функции header ( ) , ее вызов должен производиться перед отправкой любого другого

Встроенная РНР-функция

exi t ( )

останавливает

действие сценария, предотвращая выполнение

любого кода, следующего за ней.

содержания.

Если страница защищается с использованием НПР-аутентификации, имя и пароль, введенные

вы здесь

351


в оБЛDсти 3Dщиты nриложениR глупых вопросов не бывает

IfС Бы~а.G11ъ

ZV11bJX ~011ГOCO~

СУ: я все еще не могу понять, как Зтел обошла эащиту ПРИЛОlКения «Гитарные войны». Что она сделала? О: Она использовала слабость, вытекающую из того, что в приложении была защищена только одна страница (<< Администрирование рейтингов»), в то время как функция удаления рейтинга фактически зависит от двух

страниц (<<Администрирование рейтингов» и .Удаление рейтинга»). На странице «Администрирование рейтингов»

представлен список гиперссылок, переадресовывающих на страницу «Удаление рейтинга» . Данные, определяющие,

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

URL, давая возможность сценарию «Удаление S_GET. Если у вас есть возможность составить

URL для открытия страницы «Удаление рейтинга»,

вы можете удалить рейтинг даже без открытия

страницы «Администрирование рейтингов». Именно это и сделала Этел.

СУ: НО как она уэнала, как составить действительный ДЛЯ ОТКРЫТИЯ URL

страницы «Удаление рейтинга»?

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

сохранила в закладках браузера страницу .Удаление рейтинга» в то время, когда сайт не был защищен . Но закладка

-

это не что иное, как

URL URL для

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

прямого доступа к странице .Удаление рейтинга» без необходимости переходить на нее по гиперссылке через страницу «Администрирование рейтингов».

СУ: Хорошо, но ведь рейтинг был введен заново после предыдущей атаки. Раэве это не оэначает, что старый

URL стал уже недействительным?

Данные-то ведь иэмениnись.

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

URL, что и

позволило ей без проблем удалить новый рейтинг. Очень важно никогда

не недооценивать способности людей в «творческом» подходе к вашим сценариям и использованию любых их слабых мест.

СУ: Хорошо. 3ащита страниц «Администрирование рейтингов» И «Удаление рейтинга. останавливает Этел, но раэве она не создает дополнительных препятствий ДЛЯ удаления рейтинга на эаконных основаниях?

О: Совсем нет. Без использования принципа защищенной области удаление

Huкorga

задачу, потому что вам пришлось бы вводить имя пользователя и его пароль

не нegоочeнuвatimе

рейтинга на законных основаниях действительно превратилось бы в непростую

отдельно и в странице «Администрирование рейтингов», и в странице «Удаление

рейтинга». Но не забывайте, что эта область определена для обеих страниц.

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

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

352

zлаваб

CnOC06НOCtnU мogen

nogxoge

1\

<<m1Юpческ.ом»

к

MUIUA\

u

UCnОJ\bЗOВд.НUЮ АЮБЬ1Х

ux С.лаБЬ1Х

cqeнapusм

мест.


защита вашего nриnожениR

.-Тест-драйв Создайте сценарий <<Аутентификаци.» и ВКnlOчите

ero

в сценарии «Администрирование рейтинrов»

и «Удаllение рейтинra», чтобы эащитит" их. Создайте новый текстовый файл с именем

authorize. php и введите в него adrnin . php код фактической аутентификации на код включения в него сценария ~Аутентификация •. Добавьте такое же выражение require_once в начало сценария removescore. php, чтобы код аутентификации. Затем замените в сценарии

защитить и его с помощью НТГР-аутентификации.

Загрузите все сценарии на ваш веб-сервер и IIопытайтесь напрямую открыть в браузере сценарий ~ Удаление рейтинга!>. Возможно, вам придется закрыть

все предыдущие сессии, открытые в вашем браузере с НТГР-аутентификациеЙ. Большинство браузеров запоминают параметры защищенной области, чтобы вам не приходилось многократно вводить имя пользователя и его пароль.

http://www.guitarwars.net/ removescore.php? id-l0& naшe-JасоЬ%20Sсоrсhеrson&

date-2008-0S-01%2020:36:4S& score-389740& screвnshot_jacobsscore.gif

г

I

I

Можете ли вы найти еще

какой-нибудь способ подвергнуть

PeJtn.п 314340 ' ... д-_у........ ~J.luaalcтмм'Rt~IG.~

риску приложение «Гитарные

войны»?

вь, здесь ~

353


опять фальшивый рейтинг

рейтииrовых

«гитарные войны»). 3ПИ30А 11:

атака' КJlОНОВ

к сожалению, счастье в мире <\Гитарных войн~ длилось недолго, потому что на месте законных рейтингов появляются поддельные, сея гнев и раздор во всем пространстве приложения. Очевидно, что изменить список рейтингов приложения <\Гитарные войны~ вполне возможно и без их удаления. Но как?

Гитарные войны. Список рейтинГОВ

по.в.повan Гиrаоиw1t ВОИИ! Твой реlтивг БЬСТJ)CIIWА. заре11lСТРВРОвaивыl ДВ обро эroМ \ШВС" реIWввroВ"1Вcnи т.... просто fu>бавь своlrре~~j~nВ~~~.ш ..._

.•

389740

1bIJI: д.е..ю CJI!oO'lClICOB Дan: 2008-05-01

1 20:36:45

глава б

belitasscore.gif

389740

jacobsscore.g if

23

2008-05-01 20:37:02

Невил Йохансон

98430

nevilsscore.gif

24

2008-05-01 20:37:23

Пако Джасториус

127650

pacosscore.gif

25

2008-05-01 20:37:40

Фиц Лайрстон

186580

phizsscore .gif

26

2008-05-01 20:38:00

Кенни Левиц

64930

kennysscore.gif

27

2008-05-01 20:38:23

Жан Поль Джонс

243260

Леди Ги

308710

28

354

282470


защита вашего nриnожениll

Вычитание сложением До сих пор мы работали исходя из предположения, что все рейтинги, загруженные вместе с изображениями, считаются подлинными. Но сейчас у нас есть все основания усомниться в этом. И нам совершенно ясно, кого

~южно В этом обвинить ...

Ну из, ЗmО я. .. l1I'U3НЗЮ с&<.>ю &ину. ~ce, чmо мне nl'UUJЛОСЬ сиелаmь, -- 3mO оmnl'з&umь nоmf'ЯСЗЮU'щU I'wmUHr&Mecme со слerкa

nОUnl'з&ленным U3QОl'зженuем. А-к, mЗК хочemсSl ObImb самым ЛУЧUJuм 11.Imзl'НЫМ &<'>ином! о

э-m ел t\ oН5LJlcl..

'-hr\ о

оНд с.мо.ж.е1l\ Ндн.еС1l\U

ог.рo.мн.Ь!.о. ~ще.f6

О.:ТU11\dPн./ItМ €oцн.a.м», t\POC1l\O

011\~d€~€

t\оээеЛЬн.btu. реu.11\Uн.г.

€.мec11\e со сЛег.l(d

01l\р еЭd К't'l\UР О€а.кн.bI.М U.3 0д ра.ж.ен.u.ем.

Напишите, как бы вы смогли решить проблему, связаиную С тем, что у людей имеется возможность оmравлять поддельные

рейтинги в приложение .Гитарные войны. :

вы здесь ~

355


«rumapHWM воинам» необходим арбитр

&еJопасность

Tpe6reT

прнсrтствня человека

Даже в компьютеризированном мире, в котором мы живем, иногда

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

Нagелeнue человека nолно.мОЧU9.мu

-

какую-то информацию и определить, подлинна она или нет. Мы ведем

аpБUтра

речь об арбитраже, когда на человека возлагается ответственность

om.лUЧНыt\

санкционировать прием информации, отправленной для веб-приложения, прежде чем выставлять ее на всеобщее обозрение.

gocmoвepнocmb

~

gaHHblX.

Рейтинг Действия 500000 389740 354190 322710

CnОСО6 n06Ыcиmь

nocmynaю1.UUX

Удалить / Сll1l!Циовировать

Удалить

om

nО.AbЗ06affie.лeii

Ну чrnо >Ке,

nOnl?ooyurne BrnucHyrnb каКОй­ HUOYVb поvvельныu VOKYMeнrn ... 3-3-3... reCirnUHr. я rа50rnаю rntЦarnельно UОUJuоаюсь reVKO.

, nрОС1Т\ое .90&з.€лен.u.е н.o€oг.o реU1Т\LU{GQ долЬше н.е О.3 Н4ЧQе1Т\,

'hI10 он.

cpQ.3Y Же дУ.9е1Т\ €btС1Т\Q€Лен. н4 oд0.3peн.u.e

шu.рокоU I)уdлu.ке.

Для приложения ~Гитарные войны~ полезно

использование арбитража, проводимого человеком.

Конечно, вполне возможно, что кто-нибудь подделает изображение рейтинга так тщательно,

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

фактора. Не забывайте, что защита информации в РНР-приложениях основывается прежде всего на предупредительных мерах .

356

глава 6

НQШ деСС1Т\РQш.н.btй

~рdu.1Т\Р «Гu.1Т\QРкbLx

6"oUIt:I> ... Не1Т\ 1Т\QКОг.о реU1Т\u.н.г,Q, КО1Т\оро му

дЬ!. он. 1)0Лн.ос1Т\Ь)О .90 €epM.


3QщuтQ вашего nрunожеНUR

План арОитража в приложении «Гитарные войны» Jобавление арбитража, проводимого человеком, в приложение «Гитарные войны>.> - задача непростая, потому что ее решение связано с несколькими частями приложения. Нужно внести изменения в базу

должен быть создан новый сценарий для санкционирования; в страницу «Администрирование рейтингов» необходимо добавить соответствующие гиперссылки для каждого рейтинга; наконец, на главную

.JallllbIX;

страницу теперь должны выводиться только санкционированные рейтинги. При таком большом количестве

необходимых изменений важно составить план и выполнять все действия поэтапно.

а.иС::ПСlльзуЙте SQL-запрос

вnения колонки

ALTER ДI1Я approved

(санкционировано) в таблицу. Давайте начнем с таблиuы базы данных, кaroрой необходима но вая колонка, чтобы отслеживать , санкционирована публ ичная демонстрация рейтинга или нет.

Создайтес ценарий«Санкционирование рейтинrа», который будет

санкционировать новый рейтинr

(заносить единицу в колонку approved). Кроме того, что ваша база данных получила возможность сохранять информацию

о санкционировании рейтинга, вам необходим

также сценарий для управления этим процессом.

Сценарий « Санкционирование рейтинга>.> должен

будет находить определенную

"',-----_._ _ ..._ рейтинга и изменять E;;.~,.,." запись с данными

для нее значение

колонки

approved. M._~ ~ C _ ~._.-.

Измените страницу «Администрирование

«---, ~--..~

рейтинrов», добавив в нее rиперссылки

«Санкционировать» ДI1я каждоrо еще

Измените SQL-запрос, в результате

не санкционированноrо реЙтинrа.

выполнения KOToporo из базы извnекаются данные, чтобы на rлавную страницу

Сценарий <!Санкционирование рейтинга » это внутренний сценарий , который не должен

быть доступен напрямую. Вместо этого доступ

выводились только санкционированные

реЙтинrи.

к н ему осуществляется через гиперссылки

На последнем этапе мы должны у бедиться в том, что

~ Санкционировать>,>, генерируемые сценарием ~ Администрирование рейтингов >.>; при этом на экран браузера выводятся гиперссылки только для еще

свя занного с санкционированием рейтингов ,

не санкциони ованных

В нем теперь должны быть только санкционированные

еЙтингов .

все де йствия, направленные на решение вопроса, отразил ись на списке демонстрируемых рейтингов .

рейтинги. И если

это не так , все и...

Ik_.ло .... )\Мut

""'.". MIiI ... a Чua .... 1'-- .1aIo_c

"...•.11_.'1'. п

~~

1Wu.:. йualk", ~ •• _......

изменения БЫЛИ бесполезными.

I

19740

WI)&·0's-412 1 : IН7

S4J90

'1OOI.Q$.Ш 20:)6:2'

::zoo3..m.o2 10:Jl ;' .c 1

МO& · OS-41 :!1:14.$6 1OOI-Оj ..щ 20;36:(17 1OOII-O'·011O:J1:1' 2OOI-OS~ 1 :!O:J7.40 aoot.oS.{)1 :юл :.t,

; ~-;::,"".:J~~=~~~~aм.~~.•_~.~ :

на ши пр едыду ши е · 8шi!i!i.

.\па

')I~"x-... ZOUf{.(IS-021 4 :Cn:,,, Д-"(-РWP<_~J...O II(\ :16:4 '

"tJJ6orll bi~..

;Гитарные аоЙКЫ . Список реЙТКИroа.

110 :\<40

эо

2111470

24J2Ю IW80 I~16j(1

1OOIi-М ..о I1О .3 'J :М 914) 0

:oQt·QS..OI ZO:JI:(J() И?Ю

j89740 :.~~~~

.~~

~

XiW~~ ~

~ ~ .n.

YA'!'~-~

h!,''''''

:.\54190 : ~ 'hIo(.,... ·l"~ i "',.:XIII~121 :)~1'1

вы здесь.

357


добавление колонки approved в таблицу guitarwars

Прqоставьте место АЛЯ санкций с помощью

SQL-Janpoca ALTER

для того чтобы добавить в таблицу gui tarwars новую колонку approved, необходимо сделать один SQL-запрос ALTER TABLE, который мы уже

использовали ранее.

ALTER TAВLE guitarwars ~ ADD COLUМN approved TINYINТ

имя. Yl\u.M эctк.к.btx

MySQ.L ~OOL я.€ля.еYl\Ся. Q}1bYl\epкaYl\u.€кbt.М u.Мeн..eM (lI се€эoн..u.МО М)

эля. Yl\u.t)ct.-9ctк.к.btx nN'1ltП, u. €b!. можеYl\е u.Сt)ОЛЬ'з0~ctYl\Ь Л)Q60е u3 rш.x.

Новая колонка имеет тип TINYINT, и данные, содержащиеся в ней,

могут иметь значения О (ноль) для несанкционированных рейтингов или

1 для санкционированных.

Поэтому все новые рейтинги

Испоnltзуйте

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

ALTER ДП. добавлени. коnонки approved (санкционировано) в табnицу.

Мuнуmочку, Я сомн~зюсь, чmо &bl можemе nrocmo uooa&umb колонку &mаалuцу ot:;J

uзмененuя сценаruя <<&оа&ленuе reiimuнfЗ)'.

f'аз&е SQI.--;.аf1rОС INS~~не uолжен иооа&ляmь uанНые u &ноВую колонку~

Это так: по.вnение новой КОIIОНКИ В табllице означает, что

в запросе INSERT сценари. «Добавnение рейтинrа» ДОII"'''' б...ть указан ... данные ДII_ нее. Очень важно не упустить из вида тот факт, что РНР-приложение

-

это большой ,

хорошо слаженный ансамбль, состоящий из многих разнородных частей: базы данных, включающей таблицы с колонками и записями, РНР-кода, НТМL-кода

и обычно СSS - кода. добавление новой колонки approv ed в таблицу gu i t arwars вызывает необходимость изменения SQL-запроса INSERT

в сценарии «добавление рейтинга~ : ~o €ce.x €к.o€b э оd4€ля.еМbtx .3ctt)u.ся.х

358

глава

6

INSERT

INТO gui tarwars

VALUES

(О, NOW(),

реCiYl\u.н..г.о€ jкачекu.е I(ОЛОККu. ctpproved УСYI\фw.€лu.€ctеYl\Ся. pct€кbtМ н..УЛ)Q... ~

Не Сctккu,u.окu.ро€ctк.о!

'$name', '$score','$screenshot',

~

1h1


защита вашего nриложения

Сценарий «Санкционирование рейтинга» по своей структуре очень похож

на сценарий «Удаление рейтинга» с той лишь разницей, что его функцией является не удаление, а санкционирование. Добавьте в сценарий «Санкционирование рейтинга» пропущенный код, обеспечивающий защиту страницы

и санкционирование рейтинга , данные которого были переданы в составе

<?php

URL.

?>

<?php require_once('appvars . php ' ) ; require_once('connectvars.php') ;

if (isset($_POST['submit'])) if ( ..... ...... ... ... .... ............ .. .. .... ..... ..... ... .... . . . . II

Соединение

II

Санкционирование

II

дЛЯ КОЛОНКИ

с

базой данных

рейтинга

approved

путем установки

таблицы

значения

1

guitarwars

$query = "UPDATE guitarwars SET ..... . .... .......... . ............................................ . ... "; mysqli_query($dbc, $query); mysqli_close($dbc) ;

II

Вывод на

экран пользователя

подтверждения

об успешном

санкционировании

echo

else echo

echo

'<р><а

href="

"><<

Назад к странице &quоt;Админ&quоt;</а></р>,

;

?>

вы здесь.

359


завершенный сценарий «Санкционирование рейтинга »)

Сценарий «Санкционирование рейтинга » по своей структуре очень похож

на сценарий «Удаление рейтинга» с той лишь разницей, что его функцией является

не удаление, а санкционирование. Добавьте в сценарий «Санкционирование рейтинга » пропущенный код, обеспечивающий защиту страницы и санкционирование рейтинга, данные которого были переданы в составе

<7 php

,

... .... .. . .. .

~~~~~~~7:"~~.~~~. ~~~~.~~~.~.i~P.?

.. ;

есе, 'hт\0 н.еоd~эu.мо, 'hт\0 bL 3dщu."1Т\u."1Т\~.I~ь)1)Р~~~

<l:СdНJ(u,u.оrшРО~drше реi1"1Т\u.к.г.d» с l')oMO""" )о \ЛJ'\

~ 1I0лЬзоеd)1)ел5t u. e~o I')dРОЛя., н.о .7)1)0.90Лж.н.о

7>

URL.

~К}l)OЧеrше сцемрLtЯ. «A~eH:mu.cf:)U·Kdu,ust» - .f'n\O

dbL)1)b

сэеЛdн.о

е cdJ/I.oM МЧQЛе, "ПIdK KdK cu,eMpu.i1 <l:itymен.)1)u.фu.Кr.1u,ust»

1I0мг.d.е)1)с5t м НТТР-3d~олоекu..

<7php

Создайте сценарий «Санкционирование

require_ once( 'appvars php'); require_ once( ' connectvars.php ' );

рейтинrа», который

будет санкционировать НОВый рейтинr (заносить

if (isset( $_ POST [' submit' ])) if ( ..........

7>

360

глава

6

{

~7:-~~~г~~~.f.i~~.'.J..~~..''!.~.~: ............ )

единицу в колонку

approved).

О


.ощuто lЮшеzо nрunо_ени"

Нс 8ы'iG11t,

Zi)f11blX ~011ГOCO~

'9; Почему при санкционировании рейтинга не передается

Нет ли других способов представления этих данных?

О; Есть. Тип MySQL-АаННblх ENUМ, сокращенное

также и имя файла изображения, подтверждающего рейтинг?

О; Потому что при санкционировании рейтинга нужны

от епumегаtеd (пронумерованный), позволяет вам создать колонку с ограниченным перечнем возможных значений .

данные только для того, чтобы найти в таблице запись

Поэтому вместо добавления колонки

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

1, можете

добавить колонку с типом данных ENUМ и сохранять в ней yes

approved.

(Да) или по (нет), как показано ниже:

'9;Использование в качестве значений ноля и единицы для колонки

approved с типом

данных TINYINТ, в которой вы сохраняли бы О или

ALTER TAВLE guitarwars ADD COLUМN approved ENlJМ('yes ',

approved выглядит не совсем понятным.

'по' )

Данные рейтинга, который необходимо санкционировать, передаются в сценарий « Санкционирование рейтинга» через гиперссылки « Санкционировать», создаваемые сценарием «Администрирование

рейтингов». Добавьте пропущенный код в сценарий « Администрирование рейтингов» для создания этих гиперссылок.

//

Из в лечение данных из

//

Форматирование

массива

данных

рейтингов

записей в

вид е

в

цикле .

код а HTМL

echo '<table>' ; echo

' <tr><th>Имя</th><th>Дата</th><th>Рейтинг</th><th>Действиe</th></tr> ' ;

whi l e ($row = mysqli_ fetch_ array($data)) //

Вы в од данных рейтин г а

echo '<tr class="scorerow "><td><strong>, echo ' <td>'

$row[ ' date']

echo ' <td>'

$row [ ' score']

.

screenshot='

.

'</strong></td> ';

,·</td> ' ; $row [ , id ' ] . ' &атр ; date= ' , $row [ , date ' ]

, &атр; пате = , . $row [ , пате' ] ' &атр ;

' пате']

. '</td> ' ;

echo ' <td><a href= "removescore .php?id= '

if

. $row[

'&aтp ; score='

. $row[ ' screenshot ' ] .

. $row[ ' score ']

' '' >Удалить<!а> ';

.. .... ..... .. .. . ... ..... ... .. .. .. ... . .... ............ ) { echo........ ............. ......................... ............. ............... ... .............. .. .................... ........ .....

echo ' </td></tr> '; echo '</table>' ;

Co€e"Y!\: г.u.t\ерссbl.лКQ

«(Q!1.КIJ,U.ОfШро€4"У!\ь» эоJDl(,н.6. 6bt"y!\b "у!\олЬко ~ к.еСQ!1.Кu,u.ОfШро€акн.btx реU"У!\u.к.г.о€. выздесь.

361


соэдание гиnерссылок «Санкционироваmь»

Данные рейтинга , который необходимо санкционировать, передаются в сценарий « Санкционирование рейтинга » через гиперссылки « Санкционировать », создаваемые сценарием « Администрирование

рейтингов». Добавьте пропущенный код в сценарий « Администрирование рейт ингов » для создания этих гиперссылок .

//

Извлечение

//

данных из

Форматирование

массива рейтингов

данных

записей

в

виде

в

цикле .

кода HTМL

echo '<table>'; echo

'<tr><th>Имя< / th >< th>Дата </th><th>Р ейтинг< / th><th>Действиe</th></tr>';

while ($row = mysqli_fetch_array( $data ) ) //

Вывод данных рейтинга

echo '<tr class="scorerow"><td><strong>, echo '<td>'

$row['date']

echo ' <td>'

$row['score']

$row['naтe']

. '< /td> '; .

'< /td> ';

echo ' <td><a href= "rernovescore.php?id=' , &атр; пате = ' . $row [ 'пате']

. $row[ ' id'] .

.

'</strong></td>';

Пр~е Чем созЭd€a.)Т)ь zullepccbtJlKY "С4нкu,u.oнu.рo€<\)Т)Ь», IIрОUJ€оqu:mся. IIpo€e Сс\ККu/.юнu.р6€a.нct JYr\<\ .3'\lIисЬ ц/k..\. кe'vn.

'&атр ;

.

score='

'&aтp;date='

. $row['date']

. $row [ , score ' ]

echo echo '< /table> ';

.....

""'"

:.h'1I8 х...,. 2008.,о,.мIА :02 :54 t.Wrwpc_ 2OOI..Q$..ol 20:36:4$

~

П.-}!Inn.,."с:

в,.

.. й........

.к... .....

2OOI-4i..о11О-З1,'О1"')о 2OOI.os.QJ 20:33:00 '-4930

. .. __ ___

. ~

",~

~,

.ш'

АНО

.

-

.

.

-

-

-

.

.

,

-

-

o

o

.

c

.

.

.

.

,

~

,

-

,

,

___

"

2008.(И..о120:18:23 243%60 2OOI-4J1..OJ '1О-Л;40 J ШIO 1OOI.(tS.(I11O".J7:23 12:16$0

~

. . . Uн• .lI8tac . . .ьt,м:!'IJ

~

~~1;'~/~-':~l> 1

2001,,0,-0121 :14:.56 3Ot1JO ~110:36:Cn 111410

Г

5u,.,.....

2001.,0,..0121 :1' : 17• 2OOI-М0421О:36:2 2001.05.0220"..32:5<4

л.......

I

..., д..

I

,....,...T~.. Jha ...

____'___

Измен те страницу

«~инистрирование реитинrов», добавив в нее rиперссыnки

«Санкционировать» дпя каЖДоrо еще

не!анкционированноrо реИТинrа.

362

глава 6


защита вашего nриnожениR

Несанкционированные рейтинги недостойны внимания Итак, вся инфраструктура для арбитража в приложении

• Гитарные

войны~ уже готова. Чего еще не хватает, так это заключительного

этапа, на котором должна быть обеспечена демонстрация на главной странице только санкционированных рейтингов. для этого необходимо

подправить SQL-запрос SELECT так, чтобы в результате его выполнения IIзвлекались только записи со значением колонки

1. то есть санкционированные.

approved,

равным

Это достигается включением в запрос

НCnОАЬЗytt~е_У~J\..05Ное

выражение WНEl\E gA9 того. чтОБЫ uзмечь gaHHMe.

COOtnБetnСП15ующue onpegеленно.му

~"C.l0BHOГO выражения WНERE.

SELECT • FROM guitarwars ~' 4:gp:t'"Qy.ed ';'- 1~ 40:4!::----_ _ _ ---. ORDER ВУ score DESC, date ASC

значению какоtt-лuso колонкu

-----------------

Вк.lючение в этот запрос условного выражения WНERE изымает

ilЗ результата запроса любые несанкционированные рейтинги, 5 состав которых входят также все новые рейтинги. Это дает арбитру

tсЛtA КОЛОtu(а approved u.Мee.:n л-,одое 3н.D.чеl-ttAе. I-tО н.е 1. реU"Vl\Щ-lZ

н.е дуэе"У!\ €кл-,оЧеl-t в €tAЭi.J.МbtU шtлРО КОй !,\~дЛtAКОU f'\еречекЬ.

зоз~южность просмотреть их и решить, удалить их из базы данных ;L111 сделать видимыми для широкой публики (санкционировать).

поте

28

screenshot

2008-05-01 21 : 14:56 leddysscore.gif

-.

32

2008-05-0220:36:38

Измените SQL-за"рос, ~.

- ~-epb "у!\олы(o :.

::~J{ u,uoн.u.po€aн.н.bt.e

; ~ iJ."y!\tA!1.ZtA

~:"gоэя."VI\Ся. -~ г.Лct€н.оU : ~ )4н.u.u,e.

• р8зу"ltтате • ..."Оllнени. KOToporo из 6аз... И3811ека1OТС. Данн ...е, чт06... на rlla.HYIO страницу .....Одиllисlt TOIlItKO санкциониро.анные

рейт нrи.


проведите тест-драйв сценария approvescore.php

ест-драйв Создайте сценарий «Санкционирование рейтинrа» и откорректируйте

остаnьные части ПРИnО)l(ени. «rитарные войны», чтобы ИСПОnЬЗ0Вать :пот сценарий. Используя инструментальную программу

MySQL, выполните SQL-запрос ALTER, чтобы добавить

к таблице gui tarwars новую колонку approved. Затем измените запрос INSERT в сценарии

addscore . php так, чтобы при добавлении новых записей колонке approved присваивалось бы значение «ноль~. Потом создайте новый текстовый файл с именем

approvedscore. php и введите в него код

сценария «Санкционирование реЙтинга~. Добавьте в сценарий admin. php код, создающий гиперссылку «Санкционировать~ для тех рейтингов, которые еще не санкционированы. И, наконси

измените SQL-запрос SELECT в сценарии index. php так, чтобы на главной странице были видны только санкционированные рейтинги.

Загрузите все сценарии на ваш веб-сервер и откройте главную страницу приложения

«Гитарные войны~ в браузере. Обратите внимание на то, какие именно рейтинги видны в списке. Затем откройте страницу «Администрирование рейтингов~, щелкните кнопкой мыши

на одной из гиперссылок .Санкционировать~ и выполните остальные действия, необходимые для санкционирования рейтинга. Откройте главную страницу опять и проверьте, появился ли в списке рейтингов тот, который вы только что санкционировали.

Гитарные воЙнw. Администрирование реЙТИНГОВ. :-вр_ев CII8COК peIIпoaoo.

_ _ «Г1InPВre"""'"

.....~~."'!~:..~.~H~~~~~.~":".~•. Им.

Эrел Хекел

~

322710 314340

~ "

Пе. ло

,

'ООООО

389740 3S419O

T~• .IIOP

Б•• д-. Г.

.

l'elТ8.r Де• .,..•••

Tdoya

JlI'AII

j

Дат.

2008-05-0214:02:S4

д.екоll C....vpco. 2008-0S-01 20:36:4'

Белат. Че.. ж.. Поль .ц.о.с Ф•• д••рсто. п.ход..стор.,., Не••л А_со.

Ке••• де...

2008-OS-0121:IS:17 2008-0S-0220:36:28 2oo8-0S-0220:32:S4 2008-0S-0121:14:S6 2008-0S-0120:36:07 2008-OS-01 20:38:23 2OO8-OS-01 20:37:40

308710

282470 243260

186S8O 2008-OS-0120:37:23 1276SO 2oo8-0S-01 20:37:02 98430

2008-05-01 20:38:00 64930

Vд8JUПЪ I СIIII!IUIОRИpOвать

~ rr~;~;;;;;~.

Vщ~ ~ ~ ущ.....

~

~=

___-,:!",,"---новQSl i'-tAt)ерссbtЛКd

«(Анхu,u.оrш.роеdYr\Ь » к.с:\ GYr\ ро.t·шu,е

«Аэ~tArш.с~tAро€о.~tAе peu.Yr\tA~O~

1"1 р еЭ ОСYr\о.еЛ51е1Т\

ЭОСYr\~t) К С1Т\мrш.u,е

«Со.нхu,u.оrш.роgо.rш.е ре UYr\UI-\.24» , ~Эе .3оэаннЬШ. peuYr\tA~ }l\oJl<,eYr\ ~btYr\b co.t-tJ< u,u.оrш.ро€о.t-L

364

глава 6


защита вашего nриnожениlf

Гитарные войВЫ. СаИlщионировав ие n, ~lIтиltТа.• Btotyмpct'101. '1'10 .~1ICI ~wrc ,*,~un. 'JТOТ 'J'd1Or1 и ...: ПсцJ10

д.n' 21108-OS-02 20:36:28 ~..... r:322710

:; « 'law к crpмuoп. """"nactpJIpOI8IПtе pe.Iпnp:pt.!

ФорМQ заl1раш.u.€ае'Yl\ I1ОЭ'Yl\€ержэек.u.е. l1ереэ 'YI\eM каК дуэе'Yl\ €btt)олн.ек.о Нoe.t)oc реЭС'Yl\€ен.н.о

ca~~Oк.u.po€aк.u.e

reu.'YI\u.t-IZd.·

вы здесь ~

365


3тen опять наносит удар

Хакерекая атака в миллион очков Введение арбитража в приложение .Гитарные войны. значительно повысило его защиту, но ему еще далеко до того, чтобы стать пуленепробиваемым. Похоже, нашему коварному лазутчику удалось найти новое слабое место в приложении и как-то втиснуть свой рейтинг, минуя

арбитра. Этел нужно остановить навсегда, чтобы восстановить доверие на всем пространстве .Гитарных войн • .

.Гитарные войны. Список рейтингов.

~~~rи~~':~i~~~:~~ ~~n::;o~~~~~~~~ в C~~~ .. ....... ...... _ ........ .......-

__

_

r

Apdu:mp дед coмк.eкust

ОС'Vl)С1н.о€цл дЬ!. Э'VI) O'YI\ € €btcweu c'Vl)el"jeн.u.

J<ОЕоле€СJ<u.Й peu'Vl)u.н.z ... ТеМ н.е Мен.ее

389740

он. .3эесЬ!

Эmел н.е мож.е"tl\

сэерЖd."tI\ЬСя., Ч"tI\Одbt

н.е I"jОJЛОРd9С"tl\€О~"tI\Ь

1'10 г\о€оэу "tI\О,щ Ч"tI\о ей ol'15t"tl\b У,9'VЮсЬ

€JЛОМ"tI\Ь cu.c'YI\eMy.

366

глава 6


эащumа вашего nрunожеНUII

Все Jависит от МОАеририроваиия? Хотя у арбитра нет ни тени сомнения в том, что он никогда не

санкционировал рейтинг Этел, этот злополучный рейтинг, тем не менее, здесь, выставлен на обозрение широкой публике, со значением колонки approved, равным единице. Мы знаем, что при выполнении сценария .Добавление рейтинга. значение колонки approved для каждого нового .JOбавляемого рейтинга устанавливается равным нулю, потому что !>lbI только что внесли соответствующие изменения в SQL-запрос этого

А?д\А"IY\? «\\A"IY\d?кbu< goo.l-\..» I-\..e мо.ж,е"lY\ 110t-tЯ."IY\b. Ч'vт\ о с.л~чu.лос.Ь.

)

сценария. Происходит что-то совершенно непонятное!

282470

belitasscore.gif

22

2008-05-01 20:36:45

Джекоб Скорчерсон

389740

jacobsscore.gif

23

2008-05-01 20:37:02

Невил Йохансон

98430

nevilsscore.gif

24

2008-05-01 20:37:23

Пако Джасториус

127650

25

2008-05-01 20:37:40

26

2008-05-01 20:38:00

Кенни Левиц

64930

kennysscore.gif

27

2008-05-01 20:38:23

Жан Поль Джонс

243260

jeanpaulsscore.gif

28

2008-05-01 21 :14:56

Леди Ги

308710

leddysscore.gif

29

2008-05-0121 :15:17

Тибоун Тэйлор

354190

tbonesscore.gif

31

2008-05-0220:32:54

БифДжек

314340

biffsscore.gif

Фиц

186580

ПецЛо

9

Этеп Хекеп

7mo'Yl\ ?eo.'YI\\A1-lZ- I-\..e

дbtЛ С.d~u,u.Он.u.?О~dl-\.. d?d\A'YI\?OM 'YI\eM I-\..e Mel-lee. КОЛОl-ll{d dprroved ег.о jd\l\АФ

uJ.л.'ее."IY\ 3Н.dче.I-\..\Ае. 1,

Как, по вашему мнению, фальшивый рейтинг Этел

~ рез~лЬ'Yl\d'Yl\е. Чег.о

миновал арбитра?

01-\..

~\A.9e.1-\.. uщ?ок 00.

\l~dЛ\Аке. вы эдесь ~

367


попробуйте атаку 3теn

Как оказалось, атака Этел в миллион очков не имеет ничего общего с формой «Санкционирование рейтинга». Ее злой умысел направлен исключительно на форму «Добавление рейтинга». Ниже приведен фрагмент данных, которые Этел ввела в форму «Добавление рейтинга» для достижения своей цели . Введите такие же данные

в свою форму и добавьте рейтинг. Что произойдет, как вы думаете?

Не .3ddУЭЬYl\е "'е о ",РОдел 1'10сле Сu.М€оло€ <!_-»

этеп

1000000',

Хекеп

~

воины

....

.

е реитинга. Имя: РейТиНг: Г--:------:;i---"

Изображение: (Выберите файл)

.7tno Може'lТ\ dbl,:Yf\b л}Одоu. <f>d:ЙЛ UJодРdжен.u.я. € фОР'м'fI\е GIF цлu. JPE6 рС\3мером н-е долее 3 2 KddU"II'j.

368

гnаваб

зэ есЬ .

'\

'ethelsscore2.gif', 1) -_

etheIsscore2.gif


защита вашего nриnожениR

Как именно она САелаJlа это? Для

,,

Toro чтобы понять, что происходит во время этой изощренной

атаки , давайте проследим весь путь, проходимый данными через

;;'"

сценарий .Добавление реЙтинга •.

I

: Гитарные ВОЙНЫ.

i~

Эmел €€eM c€oй peU'll'\t..tНZ...

.; 41 .Ф

I Добавление рейтинга.

u еще I<dI<Otl -'II'\О

C'II'\~н.н.btu МдОр

си.М€оло€!

$score

= $_POST['score'];

$_POST['screenshot')

н е.одЬ!.Чн.ое 3МЧе..ше t)oмt ф<>рж Score СОХРdк.stеl'l\Ся.

€ ,",еременн.оЙ $score u

t)e.pel-tосu'll'\Ся.

INSВRT INТO

VALUВS

(О,

guitarwars , '$name',

НОИ()

'liliiii',

'$screenshot' , О)

Поле данных .РеЙтинг. формы .Добавление реЙТинга. ожидает единственное целочисленное значение

как

-

такое, например,

1 000 000, но вместо этого получает несколько значений ,

I-tet)oc ре.9с"'II\€еl-tl-tо

заключенных в одинарные кавычки, отделенные друг от друга

€ jdt)poc INSIRT

запятыми , со странным двойным дефисом в конце. Очень странно. Эти данные сохраняются в переменной

вставляются в SQL-запрос

$ score, после чего INSERT. В результате мы получим

совершенно бессмысленный рейтинг, так? Или здесь происходит что-то, не предвещающее ничего хорошего?

Используя данные. представленные на предыдущей странице. напишите полностью SQL-запрос для атаки в миллион очков.

Убедитесь. что переменные в запросе заменены на данные формы . Прокомментируйте. к чему. по вашему мнению. все это приведет.

вь, здесь

369


что mQKOe QmQKQ «Внедрение SQL-КОаО»

~Ulенае задача Испольэуя данные, представленные на предыдущей странице, напишите полностью SQL-эапрос для атаки в миллион очков.

Убедитесь, что переменные в эапросе эаменены на данные формы. Про комментируйте, к чему, по вашему мнению, все это приведет.

;,;.W~.:.w.L........,,~~v.:::.:\t.::Q:.:.'r:~.w~Q~rs::..:..;.;... ':, :, :":, :, :",:, :,";,;,":. :. :"':, :, :",:, :,";,;,":. :.;"':, :, :":, :, :"",:, :,:..:.;'":":":":":":"';';' ';';' ':..:..:''.~.........~ .. .... ........... ... ....... .. ....... .... ..

Манипvляции сервером 6а) AaHHblX с помощыо комментариев Главным виновником атаки Этел в миллион очков является, как это ни странно,

SQL-комментариЙ. Текст от пробела, следующего за двойным дефисом, до конца

~ecb 'YI\eKc)ТJ t')осле сu.м€оЛcl.

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

комментария за двойным дефисом обязательно должен следовать пробел.

коммек.lI')"рUSl. (--)

А теперь давайте посмотрим на весь запрос Этел, включая этот изощренный

.90

прием, в корне меняющий содержание запроса. /

v" ..

INSERT INTO guitarwars VALUES

(О,

NOW() ,

'Этел Хекел'

,

'1000000',

'ethe1sscore2.gif', 1) --

K0н..Ll,<:t ClI')POKU,

U,гк.орU,руеll')Ся. u,KlI')epllpell')"lI')0poM

SQ.L.

'~

8ы,"ядит более осмысленно? Снм",щ комментария аккуратно удаляет ' \

остаток SQL-кода, не давая серверу повода генерировать сообщение

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

~ pe3~Jb"tY\""tY\e

в...... vu

,олк.е

н.u.Я.

_.

без задоринки. В результате новый запрос немедленно санкционируется, сервером 3~POC", ~0.9.9eмНiWc;.не оставляя арбитру ни малейшего шанса перехватить и проверить его 7tтiел, ее реu'Yl\u'к.г оbLЛ с"к.кu,u.ок.u.ровdl-L rd

зз

370

I

I

date 2008-05-05 14:58:59

zлово6

1

I

пате

J

$C~

J

screenshot;

... Этел Хекел

I 1000000 I

ethelsscore2.gif

I Qj)proved

J

1


защumа вашего nрunожеНUR

Форма (ДО6авление рейтинга») 6ы аa подвергнута атаке (Внедрение SQL-КОАа»)

ПоAS1 stЮgа gaHHblK qюp.мы1

Атака Этел известна под названием .Внедрение SQL-кода. и представляет

95.ЛS1Юt11CS CA85bI.м

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

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

С точкu Зpeнu9 защиты -место-м nРUAожею.щ

используются для вмешательства в работу SQL-запроса. В случае атаки

nomо-му что oнu

.8недрение SQL-кода. в приложении .Гитарные войны. Этел использует поле ввода рейтинга не только по его прямому назн~чению (как средство

~lЯ ввода рейтинга) , но и как способ ввода непосредственно в SQL-запрос

npegoctna5Л9Юm

.Iополнительных данных (имени файла изображения, подтверждающего

nо.льзователю

рейтинг, значения колонки

approval, санкционирующего фальшивый

рейтинг,

и символа комментария в конце для предотвращения генерации сообщения

юз-можнoct11b

об ошибке).

550QUtnЬ i

gaHHble.

Гитарные войны.

Добавление рейтинга.

1000000' ,

·ethelsscore2.gi •

INSERT INТO guitarwars VALUES (О, NOW(), '$name',

'1,1111',

'$screenshot', О)

IfG 8bl~itG"th,

gl}t11bJX ~011fOCO~

~.

-.р. Существуют пи в SQLдруrие симвопы комментариев

d).

-.р. Достиrнет пи успеха атака Этеп «Внедрение SQL-кода»,

IIpOме двойного дефиса (-)?

еcnи копонка

О: Да. Другой вариант однострочного комментария

табпицы?

тому, как это происходит при использовании символа двойного

Этот конкретный запрос INSERT располагает данные

предполагает использование символа «хэш» (#). днапогично

дефиса

(- -), весь текст после символа «хэш» (#) до конца строки игнорируется интерпретатором SQL. SQL также

approved не будет пocnедней в структуре

О: Нет, и это действительно очень важное замечание. в соответствии с порядком следования колонок в структуре

таблицы. Расположение единицы в конце запроса выполняет

поддерживает многострочные комментарии . Так же как и в РНр,

поставленную задачу просто потому, что колонка

интерпретатором игнорируются многострочные комментарии,

является последней и размещена непосредственно после

расположенные между символами

/ * и •/.

колонки

approved

screenshot. вы здесь.

371


nредоmвРQщенuе атаки «Внедрение 5QL-кодОI>

3ащитите свои данные от атаки «Внедрение SQL-КОАа») Слабым местом, которое используется в атаке ",Внедрение SQL-кодаi.>, является отсутствие проверки введенных в форму данных lIа lIаличие опасных символов. Опасными символами

являются любые символы, которые потеНI\Иально могут изменить содержание SQL-запроса.

К ним, в частности, относятся запятые, кавычки, двойные дефисы. даже символы пробелов в конце данных могут представлять опасность. Пробелы в начале и в конце строк могут быть очень легко удалены с помощью встроенной РНР-функции

trim (): достаточно просто

вызвать ее с потенциально опасной строкой, переданной ей в качестве аргумента, перед тем как

использовать эту строку в SQL-запросе.

ФУНJ<u,u.я

г ''''<1\' $пате = !SЫШ!( $_POST [ 'пате' ] ) ; $score =

уэctЛЯ-е"'tl')

IlрОdелbt g но.ЧctЛе U g KoKu,e

}

~~( $_POST [ , score ' ] ) ;

tr\"'tI')()

..7"'t1')W< эcJ.~ форМbt.

~

$screenshot = J~~~ ($_FILES[ 'screenshot'] ['пате']);

Arnaкa <<Внegpeнue ~fl~a» может 5ы1nb

Но пробелам и в начале и в конце строк не исчерпываются все

npegott15ращена

проблемы, связанные с опасными символами . Вы можете также

с nомоЦJЬЮ

столкнуться с запятыми, кавычками, символами комментариев

и еще, и еще ... Поэтому ДОllOлнительно к удалению лишних пробелов в начале и в конце строк вам необходим способ поиска и удаления

npa5UAbHoti

всех остальных проблемных символов. РНР приходит на помощь

05pasomкU

с другой встроенной функцией

фОрМЬL

- mysql i_real_escape_s tr ing ( ) ,

экранирующей потенциально опасные символы, которые могут

неблагоприятно повлиять на выполнение SQL-запроса. Эти символы могут быть использованы во вводимых данных: они просто не будут изменять содержание запросов .

Совместный вызов функций

trim()

и

mysqli_real_escape_string ()

устанавливает надежную линию обороны против атак

f-"

=

'${_

.,

_.

stГillЭ() ЭКРcJ.t-Шруе"УТ\ ot)ctCKbte

СUfi\€ОЛbt, "YI\0 e.c"YI\b "реодрct,3уеуг\ u.x g "ут\акоо. €UЭ, € KO"Yl\0'p oM oн.u аоЛЬше н.е рctССМd."УТ\рu.~ct)OYl\Ся.

сГ\еu,u.aлькbtе. сu.м€олbt.

.

!J!l1iLqli+:.,re~~escape_string: ( $дЬс, tf· . ' : "'.

Фун.кu,uя. "YТ\ys~~i_rM~_escctpe_

SQ\"-utt"YI\ер"ре"Yl\d."УТ\0ром KctK

",Внедрение SQL-кода».

$пате

gaHHblx

trim($_POST[

'пате']));

J

. . .

$score = ~sii:!.;i,..;'J'~<;il=escape_string: ($дЬс, tr im ($_POST [ , score' ] ) ) ; $screenshot

1'"

= 1щvsqli_rеаl_еsсаре_striпg ( $dЬс,

'.~ ~.

trim($_FILES['screenshot']

~ ФУКJ<u,uя "'~$q~,_red~_

Обработка данных этих трех полей ввода формы ",Гитарные воЙныi.> с помощью функций trim ( ) и mysqli_real_escape_string () значительно снижает щансы на успех атак ",Внедрение SQL-кода». Но этих двух

функций недостаточно. Возможно, существует способ сделать сам запрос менее уязвимым . . .

372

zлава6

['пате']));

еsсctре_stГ\ I1 Э () 5l€ля.е"УТ\ся.

фук.кu,u.еU дct,3bt эctkНbtx U "ОЭ"ут\ОМ\J ожuаctе"ут\ J

.;;

€ Кctчес"ут\€е

"ep€020 ctp2\JMett"yт\ct с~.l;1t.Лку " I .) д _ нд сое.эu.к-ен.uе G ct,30U Э ct н.н1""'U< ctНдЛог.u.Чн.о "yт\oM\I, () J ()KctK Э"ут\О "роu.СХОЭU"YI\ "РLЛ ~bt.30~e фун.кu,uu. €bt"олк-еiw.Я. 3ctl"\POGct,


зощито вашего nриnожениR

&олее 6езопа(ный запро(

INSERT

«( И(ПОЛЬЗ0ванием имен колонок)

Запрос

Кроме использования слабой защиты данных формы атака Этел

может БЫть

• Внедрение

SQL-кода» также полагается на тот факт, что колонка

,;;;p roved следует в структуре таблицы непосредственно после колонки ,,:::reenshot . Это как раз то, что дало ей возможность сделать свое дело п ростым добавлением в конец запроса INSERT единицы , отправленной 5dTt:'M в колонку

approved. Проблема этого запроса заключается в том,

--по он требует данных для всех колонок, а это повышает риск.

i

КОЛОI-I.ОК id ~ OI-l.U.

Mozyvn IIpoC'II\O

'$score' , '$screenshot',

66apиaнme.

npu

кomаром

указЫ5аеmС9. Kaкue ЗН8.чeнuэ

СОХрд.1ВЮtnС9

1l0ЛУЧct'll\Ь змЧеrш.Я. 110 у.мОЛЧctl-l.U.)О.

INSERT INTO guitarwars VALUES (О, NOW(), '$пате',

СОСП1а5Лен

совершенно точно

~ u.эеа.ле м.м l-I.е"lТ\ l-I.еоdхоэu..мос"IТ\U

3a.9 ctgct'll\b змЧеrш.Я. u. ctpproved, 'YТ',ctK KctK

INSEI\Т

О)

6

KaкUX колонках.

r\or,la данные добавляются в таблицу с использованием такого варианта запроса INSERT, они должны :'t:речисляться в том порядке, в каком перечислены соответствующие колонки в структуре таблицы. Поэтому пятое значение в выражении VALUE будет отправлено в колонку screenshot : эта колонка находится ,,3 пятом месте в структуре таблицы. Но нет никакой нужды вводить значения колонок

id и approved,

:i 'ХКОЛЬКУ колонка id создана как автоинкрементная, а значение колонки approved при добавлении :;ивой записи всегда должно быть равно нулю. Правильнее было бы сосредоточиться на добавлении только

~ex данных, значение которых не может быть определено самим приложением. Значения же колонок id ;~

,;pproved должны устанавливаться

\Ibl

по умолчанию как

AUTO_INCREMENT

и НОЛЬ

соответственно.

должны переписать запрос INSERT, перечислив имена колонок перед списком их значений. При этом

i начения во втором списке должны быть расположены в том же порядке, в котором перечислены колонки ~ первом списке. Это снижает риск установки пользователем значения колонки

approved, так

как этой

:~().lОнки просто нет в запросе. Если такой вариант запроса INSERT показался вам знакомым, то это потому, .,то "ы уже использовали его ранее в других примерах.

[td;e; , B~eJC,.,~M~~~:~hQt; YI

INSERT INTO guitarwars VALUES (NOW(), '$пате',

'$score',

id .мо.ж.е"lТ\ dbt'll\b u.скл)ОЧем UJ CIlU.CKct, tjO'll\OMy

'$screenshot')

КОЛОКJ<ct

Ч'YI'\О

~ КОЛОКJ<j ctpproved I-I.e дуэе'll\ .3ctl!ucctl-l.О I-I.U.Чег.о, 'll\ctK КаК ее g CIlU.CKctX 3d.llpocct.

к.е'УТ)

ом ctg'll\OUKJ<pe.mel-l.'II\Мя.. Эта версия составлена в варианте, при котором

: , )вершснно точно указывается, какие значения :' ,храняются в каких колонках, позволяя вам добавлять .::t HHbIe

в таблицу, не беспокоясь о том, в каком порядке

: :с' речислены соответствующие им колонки в се

: -:- руктуре. Фактически использование такого варианта '-dпроса INSERT считается более предпочтительным . -:- H.1CM

программирования, потому что вы явно

,: "азываете, куда именно дол.жны быть записаны данные, ~ не полагаетесь в этом на структуру таблины .

выздесь ~

·'373 '


ключе80е СЛО80

DEFAULT

11000ЖQumе секунQочку.

Я ~er&ble слыwу о mOM, чmо & mаОлuцах MySQI.-можно nruменяmь знэченuя по УМОЛЧанщо.

l\eUсm&umельно лu CYLUeCm&yem mакая &О3МQжносmь:?

Это не тоn"ко возможно, но и очен" рекомендуете. присваиват

rAe

..

-

коnонкам значени. по умоnчаниlO,

это тоn"ко возможно.

Выражение с ключевым словом

DEFAULT позволяет вам указать для

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

INSERT,

будучи уверенным, что при добавлении новой записи колонка получит

это значение автоматически. Такой подход исключительно удобен применительно к колонке approved таблицы gu i tarwars. Теперь все, что нам необходимо, - это модифицировать таблицу gui tarwars еще один раз, а именно установить для колонки

approved значение, равное

нулю

(несанкционированно), в качестве значения по умолчанию.

TctK KctK КОЛОКJ<ct ~pprovecl уже сущес"Щ€уе"Щ, € Э"ЩОМ Jctllpoce ALTER TA~'E ~ .90л.ж.кЬ!. u.СIlОЛЬJО€ct"ЩЬ

€btрctжеfW.е MODIFY COLUi\\N €мес"Що ADD COLUft\N.

~ALTER TAВLE

guitarwars MODIFY COLUМN approved DEFAULT О

~

TINYINТ

~

~ .9 0ЛЖкЬ!. УКctJct"ЩЬ "Щu.t)

.9 ct кн.bt.x ЭЛЯ i<ОЛОКJ<u., 'ffl\Odbt .9 ct"щЬ I)OI-lSt"ЩЬ, 'ffl\o Э"Що u.мeн.н.o "щct КОЛОКJ<ct, ко"щoРУ)О €b!.

l)ер€оКctЧ<v1bКО СОJ.9ct€ctЛu..

Так как колонка

approved изменена таким образом, что для нее

установлено значение по умолчанию, в результате выполнения

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

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

374

гла8аб

approved становится

недоступной


защита вашего nриложениR

Проверка яанны x формы на яостоверность

никогяа не может 6Ыть чрезмерной Последняя ступень в минимизации риска атаки ~Внедрение SQL-кода~ включает

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

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

i f (! empty

($пате)

t;:z ($score)

&&!

""",,,,~*<ffii

&&

! empty ($screenshot})

{

7rnC\ Уt)Рd€JJ5t~С\Я

Этот код выглядит достаточно неплохо, но, когда речь идет о вопросах защиты

J{он.С)У)РУI<u,ця

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

if

t)ро€еряе)У), €ce

Раз поле ввода рейтинга ожидает целочисленной величины, имеет смысл

убедиться в том, что значение этого поля не только не пустое, но и является

Ли t)оля ФорМbt

целым числом. РНР-функция

Jdt)олн.енbt.

возвращая

true,

is_numeric ()

производит такую проверку,

если переменная, переданная ей в качестве аргумента,

Тrие u.лu. fd~se

является целым числом, и false, если это переменная любого другого типа.

.1c\€цcц"'Iт\ o"'lТ\ "'IТ\0г-o,

Последовательное выполнение таких простых действий, как проверка, введено

ли в поле формы целое число, когда вы ожидаете ввода данных именно такого

f:€е.л \lОЛЬ3 0€С\"'IТ\е.лЬ

типа, делает ваше приложение максимально защищенным от хакерских атак

u,елое число u.лu.

н.e"'lТ\

is_numеriс(4БS730)

\.

is_numeric('one million!')

True!~

l fd~se.

€ \lоле €€0.9d

реU",OIШI. )

is_numeric($score)

is_numeric(O)

Вeзgе. гуе можно. нacmauвaитe. чтОБЫ уанные БЫЛU в том срор.мате. в котором вы1

ux.

заnраwuвaemе.

Перепишите форму в сценарии «Добавление рейтинга», добавив управляющую

конструкцию

if с использованием функции is_numeric () так, чтобы разрешалось

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

вь, эдесь.

375


тест-драЙ8 H08WO сценария

addscore.php

Перепишите форму в сценарии «Добавление рейтинга», добавив управляющую конструкцию

if

с использованием функции

is_numeric ()

так, чтобы разрешалось

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

.1.. .................................. .. ........................... .. ...............................

-Тест-драйв Ужесточите обработку данных формы

сценарии «ДО6авnение реЙТинrа».

Организуйте процесс присвоения значений переменным сценария ~Добавление рейтинга~ так, чтобы, испольауя функции

trim () и mysqli_real_escape_string (), ~подчистить~ данные

формы. Затем измените запрос INSERT так, чтобы в нем перечислялись и наименования колонок, и их значения, исключив при этом колонки

id

и

approved.

Внесите изменения в управляющую

конструкцию i f, проверяющую данные формы на достоверность, чтобы проверялось также и то, введен ли рейтинг в формате целого числа. Наконец, используя инструментальную программу

чтобы установить для колонки

MySQL, выполните запрос ALTER TABLE так, approved значение по умолчанию, равное нулю.

Загрузите новый сценарий ~Добавление рейтинга~ на свой веб-сервер, перейдите к нему

в браузере и попробуйте опять провести атаку ~Внедрение SQL-кода~ .

Тlро€ерЦQ .9QнrФtx форМbi. н4 .90c"tl)o~epн.oc"tl)b

н.е О~РQн.uЧU€Qе"tl)Ся. ~CtМU dQ,3bt .9 Q н.н.bI.x.

rM€Q 10

PQCcМQ"tI)pu~e"tl)

Э"tl)о ,зН4ЧU"tl)еЛЬн.о

376

глава 6

110.9podKee...


защита вашего nриложениR

Пожар пот.,wеиl Похоже, желание Этел вредить рейтингам «Гитарных войн» было в конце

концов сломлено благодаря улучшениям, внесенным в ПРиложение 11

сделавшим его невосприимчивым к атакам <lВнедрение SQL-кода,).

Непобедимый чемпион «Гитарных войн» ответил на это регистрацией

нового, еще более высокого рейтинга.

W==~~~~~ Наивысший рейтинг:

~ YC~OKoe~й "YrIe~, Ч'tr10 "YrIer,epb peu'l!1u.нzu. 3С\ЩUЩеНbt 0'l!1 r,оgr.еЖэеНW!. uз gк.е,:джекод r, РUСlk:\Л rtogbt.u

46573

Боже мои! Опять нuчего Не получuлось. Может, ПРUtUло

Время, Korva мне просто нужно научuться UfJ?amb на Вuртузльнои rumape~..

рейm,u.нz, КО'l!10рbt.й дуэ е'l!1 к.еЛег.ко ~реgзой'l!1U,

СМUрU€;\ЦU.СЬ с мbt.слЬ)О, 'ffl\O ей лучше Гlр,uсоеэu.к.u'lТ)ЬСя.

К СООdщес'IТ)€У, Чем ГlРОЭОЛЖ4'1Т)Ь к.ec'lТ)и. Гlорct.жек.uе о,Эк.о

JQ эруг.u.м, ~ел реш~е"Yrl, Ч'IТ)~

К4С'IТ)УIIUЛО €peмsi. u. еи C'IТ)Q'IТ)D ,Щ'lТ)Q РНbtМ €OU.rtOM,

вы здесь ~

377


инструментарии РНР & MYSQL

Ваш инструментарий РНР и

MySQL

в дополнение к повышению уровня приложения «rитарные войны» вы

приобрели некоторое количество новых инструментов и технолоrиЙ.

Давайте вспомним наиболее важные из них.

~c1Т1 роеННt1S1.

PtI Р-ф)'КJ<up.st,

U; Сt'1 0лЬ8'уеМd51. эля. t'1po€efl<u, Я€ЛSl.е1Т\Ся. лu. t'1epemel-O-l.QЯ, t)ере.94ННdЯ ~й' ~,Kd~ec1Y\€e dрг.'уме н.1Т1d, u,~ЧUСЛОА

ЭYnо. ф)'НКu,u.Sl. 110JJеЗНdэЛя. Ilpo€epl<u, эеi1с1Т1€U1Т}еЛЬн.о

лu. € u,елочu.слеЖbte t')оля. форМbL €€еэен.bL u,eлbt.е ЧUСЛd.

378

глава

6

exitO


защита вашего nриложениR

вы здесь}

379


7

cO~r1HU,G 11GfСОНr1J\u,дu,fО~r1нноgо

.ffiGБ-11fu,J\О~GJfI4fl

-*

*-

,,,, MeHII nомниrе?~

-.-

~

~

HanOMHume, пожалуйста, ~aUJe UМ5I.l1rа~uльно, Аконсон. Что-то Я не нахожу ~aUJeU reflJCmrauuu, MUCmer

Акексон. -Вы ~ereнbI, что й<fоrмлялu fЭrантщо на зту холоuuльнуlO кaMerY:? О, я nOHUмalO: ~ы 3~OHume nrямо

u3 кaMerbI. и HanOMHume, пожалуйста, ~aUJe uмя.

Никому не нравится,

KorAa

о нем забывают, особенно это не любят

пользователи веб-приложениЙ. Если приложение ориентировано на работу с пользователями как с членами своего рода сообщества и пользователи обмениваются с ним информацией в определенной степени личного характера, такое приложение должно помнить своих пользователей . Вам определенно не понравилось бы представляться своей семье каждый раз, появляясь на пороге

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

MySQL?), -

соэдавать

персонаnиэированные веб-приnожения, способные эапоминать поnьэоватеnеЙ.

ЭТО новая глава

381


хорошее несоответствие найти нелегко

Говорят, ПРОТИВОПОЛОЖНОСТИ СХОДЯТСЯ История вековой давности: парень встречает девушку. Девушка считает

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

они проживают вместе счастливую жизнь. Эта история явилась поводом для открытия современного сайта знакомств ~Несоответствия.

mis-match. net.

-

Сайт ~Несоответствия. очень серьезно относится к теории

«противоположности сходятся», сопоставляя людей на основе различий их характеров .

Проблема в том, что сайту ~Несоответствия. пора уже подняться с колен. Ему крайне необходим веб-разработчик, чтобы закончить систему. Вот почему вы здесь. Миллионы одиноких сердец с волнением ожидают, когда вы завершите

приложение ... Не обманите их ожидания!

Сuэн.u. Л)ОдUYl\

Г;:'---'--'-

YI\ еле€uзuо н.н.bt.е

I Иоганн Нетлз

I Парень

еeQЛUYl\U -шоу,

u.oGy.

I 1981-11-03

сушu

U очек.Ь н.аэееYl\Ся.

I Афины, Джорджия

н.а СЧdСYl\лu€ое к.еСООYl\€еYl\сYI\€uе.

~

.... ....

....

00 в персонаllизированном

be6-ПРИllожении содержите.

6ollbwoe КОIIИ"ество IIИ"НОЙ информации, позтому ПОllЬЗ0ватеllИ ДОIIЖНЫ иметь доступ к нему

на

nepCOHallbHOM уровне.

~._---

---

I Сидни Келсоу I Девушка i 1984-07-19

I

Темпе, Аризона

Иог.dн.н. л)Оdu.YI\ 1'1 росеесcu.он.алЬк.У)О

дОрЬду, Yl\5lЖeЛУ)О dYl\леYl\Щ(У, cl'1dМ

u С €олн.ен.u.е'м Ж:9еYl\, 1( ог.Эd l<YI\o-н.u.dуэ Ь OYI\€'eYl\uYl\ ему. Пользователям сайта ~Несоответствия. необходима возможность обмениваться информацией с сайтом на персональном уровне. Прежде всего это означает, что им нужны персональные профили, в которые они могли

бы заносить данные о себе (дату рождения, пол и место жительства), чтобы

обмениваться ими с другими пользователями сайта ~Несоответствия • .

382

глава

7


соэдание персоналuэuрованноzо ве6-приложениR

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

сообщества пользователей, каждый из которых может обмениваться 7mo дd.,3d .9o.Кttbtx информацией с сайтом и управлять своими персональными данными. "'II\iS"'II\o.t.ch. Таблица mismatch_user базы данных mismatch используется для х~анения

персональных данных пользователей сайта .Несоответствия. .

В 1Т\о.длuu,е

"'II\iS"'II\d-t~_usеr

dcIJbt .9dнrtbtx

1Т\is"'ll\о.t.~ хро.Н5t1У\ся.

t)еРСОнд.ЛЬНbtе

эо. Ннbtе

l)олЬjо€о.1У\елей.

I...,t--~

11

в 1(0.>1<:90(1

зо.t\uсu "'II\о.длuu,bt "'II\is"'II\o.t.ch_user хро.НЯ"'ll\ся.

t\е.рсоКдЛЬн.bt.е. эо.f.u{btе. оэн.ог-о

l) олЬ 30€ct"'ll\е.ля.. llecwraетtт•••. ВРОС.'

... ----, -=

с....

-:

КUCOY

,_."

.... -..erм'T....... A _

....

пepcoll&8lo_. IIRфоp>WV<I---------,

---,

:~.

........: ;к-оу

п...:~

....г...:~·~·4 штar. ,

...... .

С~o.н.uu,o.м «П pOCMO"'ll\ р 1) РОСРUJ1я. » ' и. Р е.эо.К1Т\uро€о.н.uе t) рофU.ля. » н.e.OдXO~u.мo 31-lo.1У\Ь, 1( t)pocpw1)O 1(0.1(0&0 , l)оJ1bзо~о.'Yr\еля. t)ОЛУЧct1У\Ь .90C1Y\)lI1. ..-

..........., @y-. .)(:101dnoW*и

Сидни Келсоу Девушка

~,

1984-07-19 Темпе, Аризона

в .10полнение к просмотру профиля пользователь сайта

• Несоответствия. должен также иметь возможность ;>е.1актировать свой собственный профиль. Но проблема

Как сделать, чтобbl страница

3 том, что приложение должно знать , профиль какого

«Редактирование профиля»

:lользователя может редактироваться. Страница

• Редактирование профиля. должна как-то определять,

ОТl<Рblвалась только ДЛЯ

какой

:lо.lьзователь запрашивает доступ к ней для редактирования

своего пользователя?

::рофиля.

вы здесь

383


добавленuе процедуры входа в nрuложенuе «Несоответствия»

ПОЛЬJователям приложения «Несоответствия» неО6ХОДИМО войти в приложение, прежде чем они получат доступ к прОфилям Решение проблемы доступа к персональным данным заключается во входе пользователей в приложение после его открытия. При этом вопрос

Прuнuun вкogа

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

n0350AgeIn

Зная , кто есть кто, IIРИЛОЖСНИС "Несоответствия» получает возможность предоставлять полный достун (редактироваllие) к персоналыюй Иllформации только ее владельцу и ограниченный доступ (просмотр) всем остальным

пользователям , также вошедшим в приложение. Итак, пользователь, вошедший

в приложение, будет иметь полную возможность редактировать свой профиль, но при этом только просматривать профили всех остальных . Принцип входа rюльзоватслей в приложение

-

это ключевой момент на пути создания

lIерсонализированного приложения "Несоответствия».

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

Имя ПОЛЬJователя

вes-nрuложeнuю

взаuмogettcmвoвamь с nOJ\Ь305ameJ\9МU

на nepcoнaAbHOM

уровне.

Пароль

Задача имени заключается в предоставлении

Пароль несет ответственность за предоставление

пользователю уникального идентификатора,

определенного уровня секретности при входе пользователя

используя который система сможет найти

в приложение, что позволяет приложению быть уверенным.

информацию, связанную именно с этим

что оно имеет дело именно с тем пользователем, за которого

пользователем. Пользователи смогут также обмениваться информацией друг с лругом, используя эти имена .

тот себя выдает, и защитить его персональные данные. Поэтому при входе в приложение пользователь должен ввести не только свое имя (представиться), но также и CBoii пароль (подтвердить свою личность).

сидних

инетлз

~

******

~

\ ********, "'-Но. C"YI\pdн.u.u,e ТldРОЛЬ О"Yl\к.ОС\ХYl\Ся. Име.н.а 1l0льзоеd"fl\еле.u. одbtЧгl..O <сРе.Эd.I("YI\LtРО€dн.u.е "-., 1( LtСКЛ)ОЧLt"Yl\елЬк.о СОС"Yl\оя."YI\ lЛ3 dJKe Lt u,Ltф? IlРОФLtЛя.~ "YI\ellepb Ч~С"Yl\€Lt"Yl\ельн.о'мУ КЛdССУ эd.к.н.bt.x Lt еbtдLtр"d)О'УI\Ся. СdМLtМlЛ tlоя.€LtЛОСЬ Lt н.е эолж-ек. дbt"Yl\Ь €lЛ~LlМ.bI.М !')олЬ30~d."fI\еля.МLt.

IIреЭУllреэLt"Yl\ельн.ое

Имя и пароль позuоляют пользователю соодщен.u.е о "fI\OM, ЧYl\о войти В приложение «Несоответствия» 1l0.J'bзЩeJb €ou.te.л и получить досту" К своим

е tlрLtлож-ек.u е .

персональным данным , например

внести изменения в свой нрофиль. СИДНИК

€o есем t)рLtЛож-ен.u.Lt, кл)ОЧd.я.

~d.Jj Эdк.н.bt.x;

Вы вОшли в nриложение как CUj')Нl.~

~ Несоответствии. Ред

******

ПерсоналЬН8JI информация Имя t)ОЛЬJоеd."iТ}еля. Lt e~o МрОЛЬ - . Э"/Т'jО

€ce, Ч'fI\о н.еодхоэLtМо

IlrLtложенu}О, ЧYl\одbt t')он.я."fТ)Ь , с кем ок.о LtМee"iТ} эело .

384

глава 7

Им.:


создание nерсоналuзuрованного ве6-nриложениR

Более детальная разра60тка плана ДЛЯ входа ПОЛЬЗ0вателей в приложение Добавить в приложение ~ Несоответствия» по,ZЩержку процедуры входа в него пользователей

-

ЭТО не просто трюк, ПОЭТОМУ, перед тем как писать конкретный код

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

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

Нам также необходимо предоставить пользователям способ для ввода своих входных данных. Они должны быть как-то интегрированы с другими частями приложения

«Несоответствия», чтобы персональные страницы, как , например, ~ Редактирование

профиля», были доступны только после успешного входа в приложение. Ниже приведены этапы разработки кода, обеспечивающего вход пользователей в приложение.

~. Используйте SQL-запрос ALTER TABLE, . , чтобы добавить в таблицу колонки username (имя пользователя) и password (пароль).

Созд

пароля.

Форма входа в ПРИЛожение _

Таблице необходимы новые колонки, чтобы

ПОЛНОСТЬЮ защити

username

и

Имени ПОЛьзователя роса деИСТВУЮщего После правильно и его пароля. Только

.~ _Cj!k

password.

го Ввода ЭТОЙ

ПРИложениесможет

к персональным

-

Ф

ин Ормации

предоставить доступ

Таким образом данным пользователей.

L

ЭТо то, что

ИНформацией путе: ~:~аницы сvперсональной

сохранять в них входные данные для каждого

пользователя. Это колонки

-

аите НОВЫЙ сценарий

заПроса имени дпя и ero ПОЛЬЗователя

, ЭТОт сценари v

Ограничить досту

и ДОлжен

п к страницам

с персональноиv инф чтобы они б

пред

Ормаци

v

еи,

не ыли видны без

ваРительной процедуры

... -_.._ . _ . --. __ --....- . -... ::.., ~

p~_. _ _. "';'

Входа в ПРИЛожение.

L~") ~

Соrласуйте сценарий «Вход в приложение»

с остальнымИ частями приложения. Страницы ~ Просмотр профиля» и ~Редактирование

,!!..~~:'I;'::::=;:=...............

К_,и=uLл , г. .-,;::;=-.- -:: . : - .-., ==- : : : ... ' ':::: I L . _ . . .__ :. . .1I ......

профиля» должны быть доступны только пользователям , ~ ::=~~ едшим процедуру входа в приложение. Поэтому, :.:_, , ' :.7.:, \ ~...::::;:;..прош wr....-...c.w ........... .:....- .......,.,....,~~ rt! ~.. прежде чем предоставить доступ к этим страницам, -_'. . нам необходимо убедиться , что пользователь,

запрашивающий их, вошел в приложение.

~"";:""" '-'

- _._ .•~,

о

••

,

о.г

"

вы здесь ~

385


настройка прuложенuя «Несоот_етст_ия»

Прежде чем двиl'CIТItCtl даllьше, найдите врем. познакомитьCtl

с ПРИllожением «Несоответстви.» побllиже, чтобы ПОIlУЧИТЬ

представnение о том, как оно работает. Загрузите код для приложения ~Несоответствия. с сайта по адресу

www.headfirstlabs.com/books/hfphp. Отправьте весь код, кроме файлов с суффиксом . sql, на ваш веб-сервер. В файлах с суффиксом . sql содержатся SQL-запросы для создания всех таблиц, необходимых приложению .Несоответствия •. Убедитесь в том, что вы сделали все запросы, используя вашу инструментальную MySQL-программу, и создали таким образом все таблицы, необходимые для начала работы. После того как все это сделано, перейдите в своем браузере к странице

index. php и посмотрите,

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

Несоответетв...

rм€н.:tя. С1Т\рс'н.uup I)РЦЛОЖеI-ШЯ.

,

«Н ecoo1Т\€e1Т\С1Т\€uя.» эС\е1Т\ €aм €озмо.ж.н.ос1Т\Ь €uэ е1Т\Ь uмeн.:t u ф'?1Т\огрС\фu.u 1l0слеэн.ux Член.о€ соо3щес1Т\€С\, н.о н.е 30лее 1Т\o~o 3ед IlрОХОЖ:9еl-ШЯ. Ilp0u,e.9ypbL €xo,9C\ g Ilрцл о .ж.ен.uе.

..., це Ир9Т880DOJI08IIQCт. aOAIIТC:8.

т

• ПРОС"cm> upoФau .~ ........ upoФ'"

. ...

)

....

Весь код для приложения .Несоответствия.

доступен для загрузки на сайте .Лаборатория

7щuэ€е

~ul)epccbull(u €еэ'JYfl

.ii. ._••••• -.-.'I!J!"~ '. .

€ ll е рсоКt::lЛAJuрo€aж)'}О 03МС1Т\Ь

386

'Очертя голову". по адресу:

. ~UП

гла_а

7

I)РЦЛО,Ж.еI-ШЯ..

www .headfirstlabs.com/books/hfphp

........... .......................................................... . ~


создание nерсоналuзuрованного ве6-nриnожениR

Подготовка

6aJbI

данных к процедуре входа в ПРНЛОJКенне ТС\~Лu'u,е Yr\iSYr\d:t.ci) u,ser

Итак, продолжим работу. Таблица mismatch_user уже выполняет полезную

н.eo~xooимbt. I<ОЛО';U,

функцию, сохраняя данные профиля для каждого пользователя, но этого

.J

.9 ля. СОХDС\Н,ен.u.я. I

недостаточно для того, чтобы пользователь смог войти в приложение.

Если выражаться точнее, в таблице не хватает колонок для сохранения имени

tAМeн.u. t)ОлЬJО6'С\Yr\~Ля.

u,~ e~o IlС\DОЛя., \.f'vrjoobt I ооеСt)ечU,"tТ\Ь I1pou,e.9-YD-Y 6'ХО.9С\ 6' t)рu.ложен.u.е~ ·

пользователя и его пароля .

/

~

mismatch_user

tfG 8bJ~ClG'th,

[ ==-L__J.---i---.L--L ---1-.-J'----'-----

~011ГOCO~ '9; ПочемуgV11bJX бы нам не ИСПОnЬЗ0вать

И имя пользователя, и его пароль записываются в формате

идентификации ПОnЬЗ0ватеnя?

простого текста, поэтому для новых колонок

11

password,

username

предназначенных для сохранения имени

userjd вместо username дnя уникаnьной

О; При жеnании это можно сделать.

пользователя и его пароля в таблице mismatch_user, можно

Фактически назначение

предусмотреть уже знакомый нам тип данных MySQL VARCHAR.

в том, чтобы предоставить уникальный

user _id заключается

НО в отличие от других данных профиля пользователя эти

и эффективный способ идентифицировать

колонки не должны содержать пустые значения (NULL).

запись конкретного пользователя. Но числовые

идентификаторы не так легко запомнить, а, кроме того, пользователям просто нравится

создавать свои собственные имена дnя доступа к персонализированным веб-приnожениям .

Поэтому это, скорее, вопрос простоты и удобства

di.rdre

-

использования

-

дать возможность Иоганну

войти в приложение как «инетлз», а не

«11 ».

Мало кто захочет быть низведенным до уровня простого числа! Закончите SQL-запрос для добавления колонок

username password, расположив их так, как показано ниже. При этом Мd.ЛО KYr\0 Jcl.XочеYr\ колонка username должна содержать до 32 символов, 1'10t)btYr\С\"II'\ЬСя. JC\t)oмн.u."II'\b ~ а колонка password - до 1б символов, и ни одна из них и

I'1С\РОЛЬ.СО.9ер~~u'U долее 16 сu. мJ50ЛО€'

не должна быть пустой.

вы здесь

387


ЭDmочumе KDPDHiJDW решение

~Ш8НU8 ,адачu Закончите SQL-запрос для добавления колонок

usernarne password, расположив их так, как показано ниже. При этом колонка usernarne должна содержать до З2 символов, а колонка password - до 16 символов, и ни одна из них би

SD.L-.3dt1poc ALTER ТА ~LE

UСl)олЬ.3уе'У!\СЯ я ЛЯ

аООd€леКuЯ к.о~Ъtх колок.ок

~ суш,еС'У!\€у)О!.Цеu. 'У!\ddлuu,е.

не должна

ыть пустои.

.A\"TERJA ~\..E :Щ\SJJ\с!.t~_usе.r.АDD. us.e.rnc!.lII~. УАRCtМК(З 2). tют. NU \"k AfГ.'ER. use.r.jd•........

q

.ADD..OdSS.WQI'l:f. ~ARCHAR(1.6), NOT NULL AF.Г.tR. use.rl1d"tl\e ..~ Ko~o~a.

..:J

I .

~}Оче€ое сло€о AFГER Оt')ре.9 еляе'У!\ .мес'У!\О С'У!\РУК'У!\уре 'У!\ddЛULфt, н..а. КО'У!\ОРое д,У.ае'У!\

t)ом.еЩен..а. н.О€dЯ КОЛОН,l{d

(

.

I

usert')d'Y!\e

,уже

ЭООdмен..а.. t')ОЭ"rt\ом,у

ссbtлКd н.а. н.ее .3эесЬ €t')олн.е .9 0 t')yc'Y!\u.м.ct.

'.J

~ MecYn,o € C'Y!\pYKYn,ype Yn,ddлuu,е. н.а. I(О'У!\ОроМ 1,....----~LfН~.."'И:_I'. ._:_--l н.о.хО.9 U'У!\Ся. КОЛОн'кd. осодог.о зн.а.Чен.uя. н.е UМee'Y!\, Испоnь:;з~"'~М.~IМr,# н.о С OpZdttu.jdu,u.Oн.н.oU. Yn,ОЧКU дрен.uя. лучше ALTER TABLE, чтобы

t)о.меЩd'У!\Ь €t')ереэ u н.а.uдолее €dЖн.bl.е (А.3 .9d н.нbtx.

добавить в табnицу коnонки

usemame (ИМА ПОnЬЗ0ватеnА) и password (пароnь). я у6ерена, Чmо нелЬ3Я со)(rаняmь narоль &да3€- ()анны)( &&u()e nrocmoro т~cтa...

fаз&е. мы не ()оt\Жны nrw&аrumельно )аUJUФrо&аmь его:?

Совершенно правиnьное замечание •••

Пароnь необходимо заwифровать. Шифрование в приложении ~НесоответСТВИЯj) при сохранении

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

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

Поэтому нам необходим способ шифрования пароля перед тем, как он будет помещен в таблицу mismatch_user. Но проблема в том, что шифроВание не поможет нам до тех пор, пока у пользователя отсутствует возможность ввести свое имя

388

и пароль для входа в ПРИJlожение

...


созданuе nерсоналuзuрованноzо ве6-nрunожеНUR

СО3Аание интерфейса АnЯ ВХОАа ПОnЬЗ0ватеnя В ПРИnОJКение После того как база данных получила возможность сохранять входные данные пользователя, нам необходимо предоставить возможность пользователю вводить эти данные и входить в приложение .

Uнmepcpettc g.лsa

Поле ЭЛЯ €€оэа t'lароЛЯ

1 Jd.щuщеко, 1l0Э"I'I\ОМУ t'lрочu."I'I\d."I'I\Ь (

&Юga~eнu

г-----__4..:e~~o~c экраНd н.е€оJМОЖКО. ПQРОЛЬ

~ •••••••

nРUAожeнue

нeooкoguм

имени пользователя и пароля , а также кнопку для выполнения

самой процедуры входа в приложение .

l uн.e"l'l\m

Moga

nо~me.лsa

5

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

имя

Длg

u

naро.лsa.

1 1

[l3oU"fr!IA.

--Еслu. U.М5t u. мроЛЬ cOO"ll\€e"l'l\c"I'I\€Y)O"tТ\ JНdчеrw.Я.М. u.Ме)OUJ,UМСЯ в dd.Je qaнttbu<. t'lОЛЬJо€a"l'l\е.лЬ €ойэе."I'I\

-g t'lрuложен.u.е.

. . . . . . . . . . . . . . . . . . 1, о

lfG 8bl~.G'}}.,

ZV'\1blX ~o'\1foco~

'Р; Но ведь в баэе данных сохраняются не симвоnы

Если вас волцуетвопрос

.~1\Cb

~~Т"

о том, как пользователь

сможет войти

в приложеиие, если мы

эае3Дочек, так?

еще не назначили ему

О; ЭТО верно. СИМВОЛЫ звездочек выводятся в поле формы

имя и пароль

только ЛИШЬ ДЛЯ обеспечения ВИДИМОЙ его защиты, не давая возможности кому-нибудь прочитать пароnь, заглядывая пользователю через плечо. При передаче формы на сервер вместе с ней передается сам пароль, а не символы звездочек.

Вот почему важно шифровать пароль перед сохранением его в базе данных.

...

не волнуЙТесь. Мы перейдем к вопросу создания для пользователя имени и пароля чуть

позднее . Пока важно заложить основу самого процесса входа в приложение, хотя у нас есть еще задачи, которые предстоит решить, прежде чем все это выстроится в единую систему.

вы здесь ~

389


функqUII SHA()

WИфрование пароля с ПОМОЩЬЮ фУНКЦИИ

SHA()

Интерфейс входа пользователей в приложение достаточно прост и понятен,

но он не предусматривает шифрования паролей. MySQL предлагает функцию

1'1Y~UU9

SHA ( ) , которая зашифровывает строку текста, используя алroритuм шифрования SНA() UI\1l1JhVetn SHA. Функция, получив в качестве аргумента строку текста любои длины, ·т,..J возвращает строку текста длиной в 40 цифр, выраженных в шестнадцатеричной ctnpoкy tneК.crna. системе счисления. Эта строка называется хеш-функцией, или дайджестом

n~~

исходной строки. В данном случае, если функции SНA () передать в качестве"'---"'-J -

......'\

аргумента пароль пользователя, она сгенерирует

ее

6 yнuкa.льtlD1ц

40-символьный код, уникально представляющий этот пароль.

4O-cuмюльныt1

ttog.

Так как функция SHA () является функцией MySQL, а не РНР, вам необходимо вызывать ее в составе SQL-запроса, который используется при добавлении пароля в таблицу или его изменении. Например, этот код добавляет запись для нового пользователя в таблицу misma tch_user, зашифровывая при этом пароль с использованием функции SHA ( ) : .

INSERT INTO rnisrnatch_user (username, password, join_date) VALUES

('инетлз ', §~('tatlo~r'),

nytтleM Ilрuмен.екuЯ. ctЛг.Ор'tA"'IТ\Jv\d ШШ:РРО€dнu5t~ \ SHA cpyн.кUМ5l SHA() Ilpeodpct.3ye"'lТ\ IldРОлЬ € C"'IТ\POKY. COC"'IТ\o5t~)O UJ сорока

'-

ше.С"'IТ\н.d:9Щ\"'IТ\ерtAЧн.btx u,u.фр.

Эта же самая функция SHAO используется на другом конце

NOW())

~o эеu.С"'IТ\€tA"'IТ\еЛЬкbt.u. t]dPOJ1b. "'IТ\0 eC"tI'\b "'IТ\0"tl'\. /(O"tl'\0pbtu. дlM €€еэен.

~ t]оле €€ОЭd t]dРОЛЯ

процесса входа в приложение - при проверке соответствия пароля,

форме.

введенного пользователем, паролю, находящемуся в базе данных.

Фун.кu,u.st SHA() '"'peodPct.3ye"Y" 8-сtAМ€олЬн.btu. t"ldpo.тib € 3dWtAФРО€dt-U-lУ)О

.. "... "

C"'IТ\POKy, COC"'lТ\o5tIЦy)O

tA3

40 wеС"'IТ\н.d.9Щ\"'IТ\ерtAЧW

u,u.фр.

( __JCI

~

~

9

диордре

08447Ь ...

10

болдnол

2ЗОdсЬ ...

11

-

]

"нотлз ... G11dD~ Вы вошли в nрuложение как UHemJ13

390

zлава7


соэдание nерсоналuзuрованноzо ве6-nриложениR

Сравнение

.QеWИФlllllаИИI паролей Как только вы зашифровали какую-то информацию, у вас совершенно

Ч'ункчU9 SНAO

инстинктивно возникает мысль о том, как вы сможете ее дешифровать,

когда в этом возникнет необходимость. Но функция SHA () выполняет - без возможности восстановления

ucnоАЬЗУetn

одно направленное шифрование

алгорuтм

информации в первоначальном, незашифрованном виде . Это повышает

уровень защиты, так как если даже кому-то удалось взломать вашу базу данных ogнона.npasленнorо и получить доступ к паролям, он не сможет дешифровать их . Но как тогда UlUqJpOВa.НU9. пользователю войти в приложение, если мы не можем дешифровать его пароль? R.

Вам нет необходимости знать пароль пользователя в его исходном , незашифрованном виде; важно только, чтобы пользователь ввел его правильно, потому что функция SНA () всегда возвращает один и тот же 40-символьный код при условии , что вы всегда передаете ей в качестве аргумента одну и ту же

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

uы1 не можem.e

geшuqJpOВa.ffib

3аUlU<PJЮ58.нные

gaHHbJe.

пользователем в форму, и сравнить полученный 40-символьный код с тем, что имеется у вас в колонке password таблицы mismatch_user для записи этого пользователя . Это может быть достигнуто выполнением единственного SQL-запроса, который пытается выбрать запись пользователя, основываясь на его пароле.

r

* FROM misma~,p,...user WНERE password = Ib~( 'tatlover')

SELECT

~o llС\е олЬ , KO'tТ\ODbtu €€ел

1l0ЛЬ'з0~С\'tТ\еЛЬ .ж~ЛcI

-

€Oй'tТ\и € Ilрu.л;.жен.u.е~u.u

s1

1ft

ubJ~a.t""

ZJ\v l1blX ~Ol1POCO~

d} V 1 ~ дР: Откуда происходит название функции ф~Ю{lJ.,I.lЯ SHA() €btзbt€6е1Т\с5t эля. -moгo0'g'1'0 bt eк.u.e ..",HfRE SHA()? j6I..1AJ.ФЕО€61Т\Ь 1\6р' ОлЬ u. l\ере.9d1Т\Ь ег.о btfdЖ О I

~ €u.qe ~О-Сu..МgольfWг.о КО.96 .

выбираются все записи , для которых значение колонки password

: SHA - зто сокращение от Secure Hash Algorithm (алгоритм криптографического хеширования) . «Хеш» - это термин,

соответствует паролю, введенному пользователем в зашифрованном

используемый в программировании

В результате-'выполнения этого запроса из таблицы mismatch_user

виде, хеш-функции строки tat lover в данном случае. Так как мы

сравниваем зашифрованные версии пароля, совершенно необязательно

знать его оригинальное незашифрованное значение. Запрос,

и означающий (в узком смысле) строку

фиксированной длины, однозначно представляющую строку текста

произвольной длины. В случае функции

в результате выполнения которого мы находим запись пользователя,

SHA ( ) , использующей

пытающегося войти в приложение, использует функцию SНA ( ) , но нам

хеш

-

алгоритм

SHA,

это строка, состоящая из 40 цифр,

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

выраженных в шестнадцатеричной системе

идентификатора пользователя, что мы скоро увидим .

счисления, и однозначно определяющая

До6аВJlенне места АЛЯ JаWНфрованного паРОJlЯ

(пароль).

Шифрование паролей с помощью функции SНA влечет за собой

() пр06лему для приложения «Несоответствия», связанную с тем, что ~lина зашифрованного пароля в 40 символов превышает максимальную

~ lИну строк, сохраняемых в колонке password (16 символов). для того

строку, переданную ей в качестве аргумента

1?: Существуют ли другие способы шифрования паролей? О

:

Да. MySQL предлагает другую,

чтобы расширить колонку в пределах, позволяющих сохранять пароль подобную SHA ( ) функцию, называемую в зашифрованном виде, мы можем использовать SQL-запрос ALTER TAВLE. MD5 ( ), которая использует похожий способ шифрования. Но алгоритм SHA считается

NOT NULL

:>OJMep колон.кu.

pC\ssword

UJMeKeK

::0 40, Ч'lт\о 1l0,3€ОЛu.'tТ\ сохрС\н.я.'tТ\Ь ~ароЛЬ € .3С\шu.cf:>РО€С\к.t-tоМ €u.э е .

немного более защищенным, поэтому лучше использовать функцию SHA ( ) . РНР также предлагает эквивалентные функции (shal () и md5 ( )) на тот случай, если вам понадобится выполнять операции шифрования в РНР-коде, а не в SQL-запросе.

выздесь ~

391


модuфuкаЦUR таблицы

mismatch .user

ест-драй в Добавьте коnонки

username

и

password

в табnицу

mismatch_user

и проведите испытаНИА.

Используя инструментальную программу

MySQL, сделайте запрос,

в результате выполнения

которого в таблице mismatch_user появятся новые колuнки username и password.

ALTER TABLE mismatch_user АОО username VARCHAR(32) NOT NULL AFTER user_id, АОО password VARCHAR(16) NOT NULL AFTER username Но наша колонка

password

в действительности должна допускать сохранение в ней

зашифрованных строк длиной

40 символов,

поэтому выпuлните запрос

ALTER TABLE еще раз,

чтобы добавить места для сохранения зашифрованных паролей .

ALTER TABLE mismatch_user CНANGE password password VARCHAR (40) NOT NULL Теперь, для того чтобы прuверить новые колuнки, давайте ВЫIIОЛНИI\I аапрос INSERT для нового пользоватсля .

INSERT INTO mismatch_user (username, password, join_date ) VALlIES

('джими',

SHA ( 'heyjoe'), NOW())

Для более тщательной проверки, действительно ли пароль сохранен в базе данных в зашифрованнuм виде, ВЫIIолните запрос

SELECT для

нового пользователя .

SELECT password FROM mismatch_user WHERE username =

'джими'

И, наконец, вы можсте сымитировать проверку входа пользователя в приложение путем выпuлнения запроса

SELECT для имени пользователя и использования функции SHA ( ) WHERE.

с паролем в качестве аргумента в условном выражении

SELECT username FROM mismatch_user WHERE pass\'iord

ЗЕА (

'heyjoe')

Дл51 YCt)eLUJ-WZО

gхоэd. \')олЬзo€a"Yr\е.~

€ t1рLlЛожен.u.е ~')'<

-

эолж.ен. дbt"Yr\Ь "l'К'" же мроЛЬ. KO"Yr\0pt'-

ЦСI\ ОлЬ3o€ался. r;~

эод<i€ле.н.u.u. Эdк..-t,: .

3d t\U.Cu.. 392

lлава7


соэдание nерсоналuзuрованноzо _е6-nриnожениll

Иmак, mwert' na!'оль 33UJшр!'о&ан, 1'10 t1зм t1WOXoQUMO еще co3<)amb cro!'му &хоиа & "ruложеtlUе. Можем ЛU мы "!'ocmo UС"ОЛЬ3Q&аmь Н'llР'ауmettmшрuкацuю, &Wb OtIа mэК>Ке mreOyem &&оиа UMettU "ользо&аmеля Uего "аrоля иля uocmyna к ззmUUШitlЫМ cmraнuцaм~

Конечно.

()

HnP-аутентификаци. опредеnенно

сможет cwrpaТlt роnь простой системы входа поnьэоватеn. в приnожение.

Если вы помните, в приложении ~Гитарные войны~ ,

описанном в предыдущих главах, НТТР-аутентификация использовалась для ограничения доступа к определенным страницам приложения путем запроса имени пользователя

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

~имя пользователя/его пароль~, в то время как для всего

приложения ~Гитарные войны~ была только одна такая пара . Пользователи приложения ~Несоответствия» могут использовать то же самое окно НТТР-аутентификации,

только каждый из них должен будет вводить свои

собственные имя и пароль.

ДI!. I1pOQюrра 0Т0ii """"'_ .... НеобхОДИмо 8O~rм ~нмe c~88Т'Ct8МR• ..8 WWW.тj.-.таtch~ne:t.

вaw I\8paI1b будer

n_ .

"":'UНOфpoмином а_.

~:b: ~r~:::~~~==:~::~ i

О Эarюмшrrь 118P<1/1b а -~epe пaponail на сервере

С'lf\dК.9 ct р1Т\КОе. окн.о нп р -ctf"\еК1Т\u.cpu.Кctu,tщ €кешкееофюуМЛе.кце.

K01Т\OPOZO jctg'u.сu-1Т\ 01Т\

dpctyjepct, .мо,ж,е1Т\ dbt.1I\b u. С I1 0ЛЬjО€ctн.о € КctчеС1l\€е I1POC1l\OZO U-К1I\ерфеuсct €хоэа 11 0ЛЬjо€ct1l\е.леU

€ I1Рu.ло,ж,е.кце..

вь, эдесь

393


HTTP-QуmенmuфUКQЦUR в nрuложенuu <,Несооmвеmсmвuя»

АvтеИТИфикация ПОЛЬJователей

(

помощью НТТР

Как было показано в приложении .Гитарные войны., чтобы ограничить доступ к странице с использованием окна диалога НТТР-аутентификации, необходимо отправить два заголовка. В результате их обработки браузер запрашивал имя пользователя и его пароль, чтобы решить вопрос о предоставлении доступа к странице .Администрирование рейтингов. приложения

.Гитарные войны •.

rеаlш-·ГИтаркwе 80ЙКU·

Эmu. э€а. Jd.~оло€ка. эол.жн.bt. dbt"'fl'\b t)OCJ1d.н.bt. эля "'fI'\Oгoo, Ч'l!\о~bt ог.ра.t-Шчu."'fI'\Ь ЭОС"'fI'\~t) к C"'fI'\pa.t-Шu,е

С u.Сt)ОJbзо€а.t-Шем НТТР -d~еfol"'fI'\u.q:>uКdu,u.u.. Отправка заголовков для НТТР-аутентификации требует двух строк кода вызовов функции

header ( )

для каждого из отправляемых заголовков.

header('HTTP/1.1 401 Unauthorized'); header('WWW-Аuthепtiсаtе: Basic

394

гЛQВQ7

-


соэдание nерсонализuроваННОlО ве6-nриnожениlf

Определите части приложения «Несоответствия», на которые оказывает влияние сценарий «Вход В приложение»

(login. php), и

как они должны ИСПОЛЬЗ0вать

НПР-аутентификацию для контроля доступа. Прокомментируйте это.

э-mо

cu,eMpuu o:~xo.9

€ t)рuложен.u.е».

--

---8.A.~

.&-

.8.А-

- ....----

..........

IКWТМL.........,.....

........

I~t:~-=-\ . 1 !~

Ь,.."Г"

....: -

ш._.:. ...~

lIIi_tch_u•• r

r11

rrTIE'" вы здесь ~

395


упражнение решение

Определите части приложения «Несоответствия», на которые оказывает влияние

сценарий «Вход В приложение»

(login. php),

и как они должны использовать

НПР-аутентификацию для контроля доступа. Прокомментируйте это .

....

-... .-......-_-

login-Pt1> Ко~Эct t\ оЛЬ3o€ct"Yl\еJ1b €оuэе"Yl\

€ t\~о.женu.е, e~o u.мst u t\ctp'0J1b t\рci€еря)O"l\'\СЯ н.ct cOO"Yl\€e"Yl\c"YI\€ue 3Н.ctЧе~

1(0"Yl\0pbte coxpctн.eкbl.

€дoJe~.

1l: п......, ,...... ""'.."' ... о

IfG БЫ~iG't1I,

.."""'"

.~~~.:ц ~~~I~~~~

с ограниченным доступом, требующих входа пользователя

в приложение?

О ; Потому что главная страница -

"',, ''',",

остальных его членов.

'ПО6ы 'р."." .рОФО.." "" '",'••

t:f} это самое первое место,

-р ; Как шифрование паропей скаэывается на НПР-аутентификации?

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

О

в приложение. Поэтому главная страница выступает одновременно

передача пароля и его хранение. Функция

- для тех, кто - для членов сообщества,

; Здесь имеются две отличные друг от друга проблемы: MySQL SНA ( ) решает

и как зазывала, и как отравная точка: зазывала

проблему безопасного сохранения пароля в базе данных

впервые попал на сайт, отправная точка

в зашифрованном виде. База данных не имеет ни малейшего

'9

0 о.рые должны войти в приложение, чтобы следовать далее.

понятия о том, как вы перед этим передавали пароль, поэтому данная форма шифрования не оказывает никакого влияния

Может ли попьэователь, вошедший в приложение,

на НПР-аутентификацию.

просматривать чужой профиnь?

Тем не менее очень важно обеспечить шифрование пароля

О; Да. Основная идея здесь в том, что профили доступны

данными окна НПР·аутентификации . Этот вид шифрования

для просмотра всем пользователям, вошедшим в приложение,

и при передаче его от браузера к серверу вместе с остальными

не рассматривается в данной главе и, вообще говоря, необходим

но остаются недоступными гостям саЙта. Иначе говоря, вы, будучи

только в приложениях, имеющих дело с весьма чувствительными

членом сообщества «Несоответствия» (имея в нем учетную

данными .

396

глава

7


создQнuе nерсонйлuзuровйнного ве6-nрunожеНUR

ВХОД ПОЛЬЗ0вателей в приложение с ИСПОЛЬЗ0ванием HTTP-аутеНТИфикации Сценарий аутентификации

(log in. php) несет ответственность за запрос имени пользователя

и его пароля с использованием заголовков НТТР-аутентификации, извлечение имени и пароля

из суперглобального массива $_SERVER и проверку их соответствия данным, имеющимся в таблице

mismatch_user, перед тем как предоставить доступ к защищенной странице.

Еслu. u.мя

!l ОЛЬЗ О €С1't!)еля

<?php

~~u.лu. !lС\РОЛЬ

require_once ( , connect vars . php , ) ; if

t>t>e.g e нbt. iie!l pct€UJ1biiO

(!isset($_SERVER['PHP_AUTH_USER' ] ) I I !isset($_SERVER['PHP_AUTH_PW'])) // Имя пользователя и/или его пароль не были введены,

~.•. . .

_,

""4 f.·

{

ехit('<hЗ>Несоответствия</hЗ>Простите,

вы должны ввести

'

3ct г ло€цu.

. / ctytr\еН:Y!luсрu.j(~Щ.щ

~

•.'..'. '. . /1

."'-";~---'

О't!);rС\€ля~ся

ваше имя и

.9ля Ijo~mopiiozo ш< 3C\!lpocd.

пароль для того,

'чтобы войти в приложение и получить доступ к этой странице. ' ;

J

nолу'lек.uе Uft\eк.u

1l 0ЛЬ.3 0€d'У!\еля.

U

.

3C\llpocC\ .9ля

ег.о t)dРОЛя..

// Соединение с базой данных $дЬс mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAМE);

'

Вl'"l.t)олн.енuе

t)ОЛ)"-Iенuя

ЗС\Il UС Ц

t)ОЛЬЗО€d't!)еля.

с .9C\к.нl.1Lм lA..Мeн.eM

u.

t)C\ ро лем,

еслt.1 'У!\С\КО€dЯ lA..Мее'У!\СЯ.

if

(mysqli_num_rows($data)

1/

Процедура

//

идентификатора

входа

== 1)

прошла

{

нормально,

пользователя

и

его

присваиваем

переменным

значения

пароля

Iслu. .3б.t)u.сЬ rИU:9 е tv::l 'У!\О

! ,

g

хаз

i11w~ ~ r~~:p~~t~~~el~~euмo

_""".""·4"',' ._~......~,

Jtv::lчен.ц5!. t)~емеi-\J-tl-v.',

~u.ser _.id

else // //

Имя

пользователя

поэтому

и/или

о'Гправляются

его

паропь

заголовки

введены

u.

~u.sert)C\'t!)e.

неверно,

аутен'Гификации.

ехit('<hЗ>Несоответствия <i hЗ ~ простит е , вы должны ввесI'И ваше имя и пароль для того, 'чтобы

//

войти

в

приложение

Подтверждение успешного

входа

в

и

получить доступ

к

этой

с транице.

'

.

';

приложение

R~~'.~1I:m~~~:mifi}[ВЫ 7врпtди. l[! " rtp.WiОJii~~ие.,: K~aг ?>

К }'Yf)OMy моме.к.'Yf)У €ce

/

€ 1'10ряэке, t)o}'Yf)OMy glJl'йОЭ lA'Yf)С51 1'1 0Э'Yf)ее:РЖ:9е.I-UJ.е УСt')еwк.ог,о ехоэ~ ь' I'1рuло.ж.ек.u.е.

·11"".~'сценариЙ ДnЯ запроса имени ПОnltзоватеnя и

ero

пароnя.

вы здесь

397


тест-арайв nрuложенuя «Несооmвеmсmвuя»

-Тест-драйв Создайте новый сценарий «ВХОД В при"ожение» и ВlUllOчите. ero в сценарии «Просмотр про.и".» и «Редактирование профи".». Создайте новый текстовый файл с именем

login. php

и введите в него

код процедуры входа в приложение (или загрузите его с сайта по адресу

www.headfirstlabs.com/books/hfphp). Затем добавьте в начало сценариев viewprofile .php и editprofile .php РНР-код, включающий новый сценарий

входа

в приложение.

Загрузите все сценарии на ваш веб-сервер и откройте главную страницу приложения .Несоответствия. в браузере. Щелкните кнопкой мыши по гиперссылке .Просмотр

профиля. или .Редактирование профиля., чтобы войти в приложение и получить доступ к персонализированным страницам. Конечно, это будет работать только при условии, что вы уже добавили запись с соответствующим именем и паролем в таблицу базы данных.

:1mU э€е ~Ullерссbt.л1(U €еэY!l нд ,34щuщекн.l:я.e

C"lY\pC\н.u.up.., l(o"lY\0pbte €btJ&t.€C\}O"IY\ сu,ендрuй

<.<~хоэ € llJ>uло.ж.ен.u.е:о, еслu 1l0ль"О€С\"IТ\еЛЬ еще н.е ~ошел € н.его.

(j

• _О.

YтOlТ\ f'\С\РОЛЬ "С\шu<:рро€~еlТ\Ся. с f'\ОМОЩЬ)О <:p~I'U<up.u SHA() €

U сра€I'Ш€С\еlТ\Ся. с ,34шu<:рро C\~ Весоответст.... ,1lС\ооле'м € ~C\,3e Эct~' Чmодbt • ~M:c~e противополоа:ВОСТII схо ятся. eluu"I!\b, рС\,3решен. ~ ЭОf'\~СК . • .Ре

398

arrи

глава

7


соэданuе nерсоналuзuрованного ве6-nрuложеНUR

<t~tlе:>НеСООТ.8етс'r8ИЯ. ПРС>СнО1'р "РОФИЛЯ.</titlе>

</h:~~~k

.....,

Иonп

....

lInи

~,

tуре:z"tе.хt/С8З· hrеf=·stуlе.сsз.

1>

~

:

ДIOn

rel"' · stylesheet "

. . . . . . .:

19I1-ll~

-"'_:~.д.Jppu

r"""'re_"nce' ' login. <html>

<Ь:~~:lе>несоответствИJi. Редаlt'l"1фOвание npoфиля</titlе> tуре"' " tех.t/сsз ·

href=. "style , css· />

Iслu. €€еэен.bt 11jk\€uлbн.btе цмя u I1~РОЛЬ, 110ЛЬ30€~1У\еЛЬ €хоз u1У\ € I1рu.ло.ж.ен.u.е u ~~р,'j~е1У\Ся. ос1У\cthbН4Я ~C1Y\b С1У\jk\н.u.Lфt.

К<tЖ:9ь!.Й t)ОЛЬ30€~1У\ель

t)ОЛ,'jЧctе1У\ ЗОС1У\,'jt) к C€OЦМ

лu. ЧН.bI.М «н.еСОО1У\€е1У\С"!ТI€'уЩЦМ» з~ННbt.м. KO"!ТIopb!.e Он. мо.ж.е"!ТI рез~к"!ТIЦРО€~"!ТIЬ.

Соrnасуйте сцAJiiа&II'II."'.I~W в припожение» с остаnьными чаcтwми припожени

••

8Ь' эдесь ~

399


nрunоженuю «НесоответствиII» необходима форма для создания учетной записи

я Оы с уu<'>&<'>льсm&ueм &<.>UJЛЭ

&nj?uл<.>~uе u начала сосmа&ЛS1mь c&<.>u nj?<.>фUЛЬ, но никак не M<.>f'j n<.>НS1mь, как мне CQ3Uamb учemную 3зnuсь & 3!1t<.>M nj?UЛ<'>Женuu! о

Новые ПОnЬЗ0Ватe.nи доnжны иметь возмо]Кность со3Давать в приnо]Кении

учетные записи ДnA се6А. Новый сценарий .Вход в приложение~ приложения .Несоответствия., используя НТТР-аутентификацию, выполняет полезную функцию по входу пользователей

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

записи. Если у вас еще нет имени и пароля в базе данных, войти в приложение - неразрешимая проблема. Приложению .Несоответствия. необходима форма .Создание учетной записи., которая позволяла бы присоединяться к сообществу, добавляя в базу данных новое имя и пароль.

Имя ПОЛЫОВIТeJlЯ?

400

глава 7

Пароль?


создание nеРСОНQлизированного ве6-nриложениR

Форма ДЛЯ СОJдания учетных записей ДЛЯ иовых ПОЛЬJователей Как должна выглядеть форма ~Создание учетной записи~ 7 Мы знаем, что она должна

позволить пользователю ввести выбранное им имя и пароль ... Что-нибудь еще? Так как пользователь заносит свой пароль в форму, а символы, из которых составлены пароли,

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

(маловероятно, что пользователь допустит одну и ту же опечатку два раза подряд). Итак, в задачу страницы ~Создание учетной записи~ входят получение от пользователя его имени и пароля, проверка, не используется ли уже другим пользователем введенное имя,

и добавление новой записи в таблицу mismatch_user.

После t-tcl.Ж4i'!\ust кк.оГ\ки «Co.3~i'!\b» u..мя.

t)о.лЬ.30€~i'!\еля. u ег.о

t)~ОлЬ дУЭJffl ЭОд~€лекbt

€ 3а.3у э~кнbu< t) рuложен.u.я..

болдnол

d8aO 1 1...

инетлэ

eSlld7 ...

ру6ир

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

уже существующего пользователя. Сценарий должен быть достаточно

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

T~K K~K Il~роль .3~w.ucppo€~tt, Мь!. € aeJoIi<:3,cк.oci'!\u, э~же еслu ЮТ10-НUдУЭ Ь ,у€uэu.i'!\ ЭФI-н.bt.е

€ d<:IJe.

страницей .Создание учетной записи~, сводятся к тому, чтобы

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

пользователя в таблицу

mismatch_user. вы здесь ~

401


Зll8ершение сцеНllриR signup.php

Магниты РНР u

MySUL

в сценарии «Соэдание учетной эаписи» приложения «Несоответствия» испольэуется своя собственная форма для предоставления польэователю воэможности ввести выбранное им имя и пароль. Проблема в том, что код сценария неполон . Испольэуя магниты, расположенные ниже, эавершите код сценария

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

<?php require_once('appvars.php') ; require_once('connectvars.php'); //

Соединение с базой данных

$dbc = mysqli_connect (DB_HOST, DB_USER, DB_ PASSWORD ,

DB_NAМE)

;

i f (isset ($_POST [' submit'])) {

//

Извлечение данных профиля из суперглобального массива

$_POST

...................... = mysqli_real_escape_string ($dbc, trim ($_POST [ '..................... .' ] ) ) ; ....................... 7' mysqli_real_escape_string($dbc, trim($_POST[ '.................... . :])); ....................... 7' mysqli_real_ escape_string ($dbc, trim( $_POST [ ' .... .. ........ .. .. ... :] ) ) ;

i f (! empty ($username)

&& ! empty

($passwordl)

&& ! empty

($password2)

&&

(..... ..... ........... == ... . ................ .J) { //

Проверка того , что никто из уже записанных пользователей не пользуется таким же именем,

//

как то, которое ввел новый пользователь

$query = "SELECT * FROM mismatch_user WНERE username = '$username' " ; $data = mysqli_query ($dbc , $query) ; if (mysqli_ num_rows ($data) == //

О)

{

Имя, введенное пользователем, не используется, поэтому добавляем данные в базу

$query = "INSERT INTOmismatch_ user (username , password, join_date) VALUES ' • ( : ..................... ' , SНA ( .' ..................... :) , NOW () ) " ; mysqli_query ($dbc, $query) ; //

Вывод подтверждения пользователю

echo

'<р>Ваша новая учетная запись успешно создана . Вы можете войти в приложение и

' <а

href="editprofile . php" >отредактировать

l' mysqli_close ($dbc) ; exit () ;

"

свой профиль </а> . </р>'

Не Jctdb!.€ctuYf\e, \flт)o еслu. € €ctшеu cYf\p0l(e

ог.рctнuченн.оu. o,9u.нc.tpн.b!.мu. Кct€btЧКQМu. ' Il Оя.€u.Yf\Ся. qt)OCYf\poep, €b!. .9 0JlЖн.bt ' JQМQCKU.p?€ctYf\b ег.о с t)ОМОЩЬ}О Н.QЦЛОННDu.

чеРYf\bt (\ ).

402

ZЛll8а7

'

;


соэданuе nерсоналuэuрованноzо be6-nрuложеНUR else { //

Учетная запись с таким именем уже сущест вует в базе данных, поэтому выводится сообщение об

ошибке

echo ' <р class=" error" > Учетная ;

запись с таким именем уже существует . Введите , пожалуйста, другое

имя . </ Р>,

••••••••••• 1 • • ••• • • • ••

= " .. ;

else { echo

'<р

дважды. </р>'

class="error">Bbl должны ;

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

-

} }

mysqli_ close($dbc); ?> <р>В в едите, пожалуйста, ваше имя и пар оль для создания учетной записи в приложении &quоt ; Несоответствия&quоt;\.< / р >

<form method="post" action="<?php echo $_ SERVER [ 'PHP_ SELF ' ] ; ?>" > <fieldset>

<lеgепd>Входные данные

</ legend>

<l abel for= "username" >иМЯПО·ЛЬЗОiiателя : </ label > <input type="text" id=" .... . . . . . .. .. . ." .. .. .......... ;.:?>" /><br />

naтe=" . . .. . ... . ....... ~

value="<?php if

(!

empty с

............... ) ) echo

<label for= " ........... . .... ." >Пароль : </ label > <input type=" .. . .. .. ...... . . . " id=" ............ . ..." <label

пате=" ..... . ..

. ... ... . " /><br />

fоr=" ... . . .... ... .. . . .">Повторите пароль:</lаЬеl>

<input type=" . .. ....... . ... .. " id=" .. . ......... . ..."

пате="

. . .. ........... ." /><br />

</ fieldset> <iпрuttуре="suЬmit"vаluе="Создать" пате="

submit " />

</ form>

вы здесь ~

403


ЭQ8ершенн",й (цеНQРUЙ signup.php

Marнutnbl РНР u

-

MvsnL z.

В сценарии «Создание учетной записи» приложения «Несоответствия»

~o СРОDМс\ «Со.3.9 d н1.е

r

используется своя собственная форма для предоставления ПОЛЬЗ0вателю уЧе"ll'lНDЙ возможности ввести выбранное им имя и пароль. Проблема в том, что Jdt)u.cu.~. код сценария неполон. Используя магниты, ~~~• • •·i1·:Ii··""I·i• • • • •• • • • • расположенные ниже, заверwите код сценария • так, чтобы новый ПОЛЬЗ0ватель мог создать Веемт..,с ••••. c.w.••• )"IeI'8•• _са.

'f'

=41

B _ o......Ykтa.

~~:::~в:~~~~:яи».присоединитЬСя к сообществу

~=-:..7..'_::..._~_:a_.O_~_~._._.H_ccooncтcr.....

..------------------------10L--i п.::~[~~.: ... . . ·~. : : J 1I <?php

~--_._----_

require_once('appvars.php'); require_once('connectvars . php'); //

Соединение с базой дaнных

$dbc = mysql i_connect (DB_HOST. DB_USER. DB_PASSWORD,

i f (isset($_POST['submit'])

DB_NAМE)

;

{

.,нных профиля из суперглобального массива

$_POST

$useru&lll8_ mysqli_real_escape_string ($dbc. trim($_POSTI\-..;;.;;===::...... · ] ) ; $paBBwordl

mysqli_real_escape_string($dbc. trim($_POST[

:]));

$paBBword2

i:mysqli_real_escape_string($dbc. trim($_POST[

]»);

if

$;..

(i;~;i~;,;~~e';.!)~&~&",,':iIIIIoo~"'""'ti!.~swordl)

/1/..

:fl.}=ч.

8jWo.

$password2

•. {

ро .el(c:t, €ce лu.

с:::::::::

&& ! empty ($password2) &&

*

FROM

mismatch_us~r WНERE username i $uвеrnaшe

$data - mysqll._query ($dbc. $query) .

i f (mysqli_num_rows($data) == //

,j

~..:€~~

О) {

~

Имя, введенное пользователем. не используется. поэтому добавляем данные в базу

• • • • •11

join_date) VALUES ••

• NOW ( ) ) " ;

' - Еслu.

'YI\c:lI<Ог.о t)ОЛЬjО€d.Yrjеля.

н.eYrj, м/:я Mo)f(.e,М ЭО&€ЦYrjЬ

r;SER~: u.Сr)ОЛЬJУЯ J<:\I1POC

Вывод подтверждения пользователю

echo

'<р>Ваша новая учетная запись успеmн

'<а

href="editprofile . рhр">отредакт

создана. Вы можете войти в приложение и

овать свой профиль

• .

< / а> . < /р> ' ;

mySqli_ClOSe($dbC);~

~eCb МОЖе'Yl\ UСr)ОЛЬ,30€CI'YI\ЬСя. людой UJ Э€УХ

exit () ;

t)p01{ep/(y

}

I3bt.€oq r)ОЛЬ.30€dYrjеЛ)О

~ t)~Yrj~еРЖ:9еfЩ5( Од УСt)еШн.Ом

1II .........~~~...~ СО'з,9<ООШ .эля н.ег.о • УЧеYrjli.Oй J<:\t)ucu. u

404

. Бbulo~1rГ ,

. .. . ~ t)оJb~e.лst С 'YI\dI<uМ

Lf""i~~i.li:.l.шш.s;,чаsswоrd,

//

6'€еэекbt U 0&

лu. t1c:tроля oЭUМl<о€bte.

':::lписанных пользователей не пользуется таким же именем.

/ / как то, которое ввел новый пользователь $query_ = "SELECT

ЭC:I

гЛQ8Q

7

J<:\€epwetШe

сu,eн.c:tрuя..

eqeн.кb\.x t)<:\ролей, Yrjc:tl< 1<<:\1< они УЖе I1рОщлu. н.c:t YrjОЖ:9еСYrj€ен.н.осYrjЬ.

....J


соэданuе nерсоналuэuрованного be6-nрuложеНUR

else {

/ / Учетная запись с таким именем уже существует в базе данных, поэтому выводится сообщение _ echo '<р class=" error" > Учетная запись с таким именем уже существует. Введите, пожалуиста ,

об ошибке

друго

Оdк.улекuе t)epeMeнн.ou

$username

• • • • • "~ $usert)Q"'fТ\e, ЭЛЯ "'fТ\oг.o чу!)оdbt. } t)оле. «Имя. t)ОJ1bJО€Q"'fТ\еля.»

имя. t)олЬ.30€о:mеля.

\

u.Сt)оЛЬзуе"'fТ\Ся., t)ОЭ"'fТ\ОМУ €bt.€оэu."'fТ\Ся. СООдщекuе од ошцдке.

dblJio t1yC"'fТ\btм.

}

else { . ния учетной echo '<р class=" error" >Вы должны ввести все данные для созда

дважды. </р>' ;

~

записи

Оэк.о u.лu. к.еСJ(ОЛЬJ(О t)олей

'

в том числе пароль

-

'--.I1УС"'fТ\bt., t)ОЭ"'fТ\ОМУ €bt€оэu."fТ\Ся.

}

СООдщекuе од ОШцдК е.

} mysqli_cl ose($dbc) ; ?>

<р>Введите, пожалуйста, ваше имя и пароль для создания учетной записи в приложении &quоt ;не соответствия&quоt; \ .</р>

<forrnmethod="post tt action=11 <?php echo $_SERVER[ I PHP_SELF 1] ; ?>">

<fieldset>

<lеgепd>входные данные </ legend>

L </label> J:~~ :~ ~~;;зова::.еля: us ername

<label for="username" .... .. us ername ,_ . е= "text" id $username >< > . ~ У .. 2t1А.

е=

' lue="<?php if (!empty

• • • • • •t;.

...

~_

$username

cho

<br />

</fieldset> <input type='submit" vаluе="Создать" name=" submit, / > < / form>

'9: Почему мы просто не можем мспOJlЬЭОвать

КТТР·аутеtmlфм'UIЦИIO ДАЯ создания учетных записей?

О: Потому что эадачей сценария .Соэдание учетной записи»

является не ограничение доступа к веб-страницам, а предоставление

ГOCO~ •

Значит, сценарий .Создание учетной записи> осуществляет вход

пользователей в прмnожение после создан"" учетных записей?

О: Нет. Это нерезонно, в частности, и потому, что эадачу входа

пользователя в приложение уже решает сценарий .Вход в приложение»

гюльзователlO возможности ввести уникальное имя и пароль и затем

и нет никакой необходимости повторять тот же код в сценарии .Соэдание

добаВИТЬ эти данные в базу. Конечно, можно использовать окно диалога НТТР-аутентификации как интерфейс ввода имени пользователя и его naроля, но использовать для этих целей саму функцию аутентификации

учетной записи.. Вместо этого сценарий .Соэдание учетной записи»

только лишь для создания учетной записи

сразу же после создания учетной записи. Д ТёlK как он еще не успел войти

-

это явный перегиб.

предоставляет пользователю гиперссылку на страницу .Редактирование профмnя., на которую пользователь, предположительно, захочет зайти

Дnя такой цели лучше создать свою собственную форму, при этом

в прмnожение, ему будет выведено окно диалога .Вход в приnожение» как

вы получаете преимущество в том, что подстраховываете пользователя

часть попытки получить доступ к защищенной странице .Редактирование

зт опечаток при вводе пароля вслепую, предоставляя возможность

профиля •. Таким образом, сценарий «Создание учетной записи» все

вводить его два раза.

равно приводит пользователя к окну диалога .Вход в приложение» через страницу .Редактирование профипя», а не напрямую.

ВЫ здесь ~

405


дotЮеленuе гunерссылки ({Соэданuе учетной заnисu»

Дайте ПОЛЬJователю BOJMOJКHOCTb

COJAaTb

учетную Jапись

у нас есть сценарий ~Создание учетной записи., но как пользователь откроет соответствующую страницу? Мы должны дать пользователю понять, как он может создать учетную запись. По одному из вариантов можно поместить гиперссылку ~Создание учетной записи. на главную страницу

приложения ~Несоответствия •. Неплохая идея, но тогда нам нужно включать или выключать ее в зависимости от того, вошел пользователь в приложение или нет. Другой вариант просто предусматривает размещение гиперссылки ~Создание учетной записи. на странице ~Bxoд в приложение •. Когда новый пользователь, например, щелкает кнопкой мыши на гиперссылках ~Просмотр профиля.

или ~Редактирование профиля. на главной странице, сценарий ~Bxoд в приложение. предлагает ему ввести свое имя и пароль. Так как у него еще нет учетной записи , а следовательно, имени

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

~Создание учетной записи •. Сделать это можно, слегка изменив сообщение об ошибке, выводимое сценарием ~Bxoд в приложение. , чтобы оно включало гиперссылку на сценарий

signup . php.

Ниже приведен оригинальный код сообщения об ошибке сценария ~Bxoд в приложение. :

ехit(' < hЗ > Несоответствия< / hЗ > Извините,

вы должны ввести ваше имя и пароль,

' чтобы войти в приложение и получить доступ к этой странице.' ;

'

.

7nl01'l\ 1(0.9 Щ>ОС1'l\0 coo&.upe1'l\

~ o~ olt!A.~l(e де,3 1(~l(огоо-./1I..Jо ' - 1'0мuка.н.uя. о 1'1\0).\ K~I(

Такой код практически появляется в двух различных частях сценария ~Bxoд в приложение.: когда не введено имя пользователя и/или его пароль и когда они введены неправильно. Идея поместить гиперссылку

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

406

глава 7

.мож.ко СО'з.9~1'I\Ь jче1'l\t-t:ро

~t)\J.cb € t)рIJJlОЖоеt-t\J.\J. «НеСО01'l\€е1'l\C1'I\€\J.Я.» •


соэданuе nерсоналuзuрованного ве6-nрuложеНUR

ест-драй в Добавьте функциlO «Создание учетной записи» в приnо.ение «Несоответствия». Создайте новый текстовый файл с именем

signup. php и

введите в него код добавления учетной

записи (или загрузитесценарий с сайта поадресуwww.hеаdfirstlаЬs.соm/Ьооks / hfрhр).

Затем для тех пользователей, которые не могут войти в приложение, добавьте в сценарий

login. php

гиперссылки на сценарий .Создание учетной записи •.

Загрузите все сценарии на ваш веб-сервер и откройте страницу .Создание учетной записи~ в браузере. Создайте новую учетную запись и войдите в приложение. Отредактируйте и просмотрите свой

профиль, чтобы убедиться, что сценарии .Создание учетной записи. и «Вход в приложение~ работают правильно. Теперь приложение обрело тот персонализированный оттенок, которого ему не хватало. Щелкните кнопкой мыши по гиперссылке .Просмотр профиля. или «Редактирование профиля~,

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

k::'---... Для 'YI)ozo Y'YrjOdbt Руди.

....... ..........

.....

.

......~~. . . ~ ..JfIIWМ. .

,

..,.,~

..,.-~

.,.~.--.,.......,...,..

~

-Г~

-Е......

.....

~.. _.-.-,~":~

I

"

MOгJk:\ €ОЙ'Yl)u.

€ Ilрило .жекuе.

u.СllоJJb,зуе-тся

нттр~еfi.-тu.ФUКQu,ця, dQJu.РУI<)щфtся Н.Q u.к.ФОр#(:tu,цu

ее уЧе-тfi.ОЙ 3Qtщсu..

J1w8C8h'.~-""" HeeoonteYC1'8ll8. I'tA8I<Т8POU··· ...........

r --,-

\~=f.J_.~ b~")"

~елuколenно! Я мory ~oumu ~ nruлoЖaiuе «Несооm~emсm~uя» u не mолько nrocмaml"u~aml nrоcfuлu ~Щ( nоль;,о&аmеле но u r,waкmUrO~amb мой

coOcm~aiHbIU.

о о

407


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.