КулЛиб - Классная библиотека! Скачать книги бесплатно 

Создаем динамические веб-сайты с помощью PHP, MySQL, JavaScript, CSS и HTML5 [Робин Никсон] (pdf) читать онлайн

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]
ББК 32.988-02-018
УДК 004.738.5
Н64

Никсон Р.
Н64

Создаем динамические веб-сайты с помощью PHP, MySQL, JavaScript, CSS
и HTML5. 4-е изд. — СПб.: Питер, 2016. — 768 с.: ил. — (Серия «Бестселлеры
O’Reilly»).
ISBN 978-5-496-02146-3

Научитесь создавать интерактивные сайты, активно работающие с данными, воплощая в них мощные комбинации свободно распространяемых технологий и веб-стандартов. Для этого достаточно обладать базовыми
знаниями языка HTML. Это популярное и доступное пособие поможет вам уверенно освоить динамическое
веб-программирование с применением самых современных языков и технологий: PHP, MySQL, JavaScript,
CSS и HTML5.
С каждой из упомянутых технологий вы познакомитесь отдельно, научитесь применять их в комбинации
друг с другом, а по ходу изложения освоите ценные практические приемы веб-программирования. В конце
книги весь изученный материал будет обобщен: вы создадите полнофункциональный сайт, работающий по
принципу социальной сети.
• Изучите важнейшие аспекты языка PHP и основы объектно-ориентированного программирования.
• Откройте для себя базу данных MySQL
• Управляйте cookie-файлами и сеансами, обеспечивайте высокий уровень безопасности.
• Пользуйтесь фундаментальными возможностями языка JavaScript
• Применяйте вызовы AJAX, чтобы значительно повысить динамику вашего сайта.
• Изучите основы CSS для форматирования и оформления ваших страниц.
• Познакомьтесь с возможностями HTML5: геолокацией, работой с аудио и видео, холстом.

12+ (В соответствии с Федеральным законом от 29 декабря 2010 г. № 436-ФЗ.)
ББК 32.988-02-018
УДК 004.738.5
Права на издание получены по соглашению с O’Reilly. Все права защищены. Никакая часть данной книги не
может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских
прав.
Информация, содержащаяся в данной книге, получена из источников, рассматриваемых издательством как надежные. Тем не менее, имея в виду возможные человеческие или технические ошибки, издательство не может
гарантировать абсолютную точность и полноту приводимых сведений и не несет ответственности за возможные
ошибки, связанные с использованием книги.
ISBN 978-1491918661 англ.
ISBN 978-5-496-02146-3

© Copyright c 2015 Robin Nixon. All rights reserved
© Перевод на русский язык ООО Издательство «Питер», 2016
© Издание на русском языке, оформление ООО Издательство «Питер», 2016
© Серия «Бестселлеры O’Reilly», 2016

Краткое содержание
Предисловие. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
От издательства. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Глава 1. Введение в динамическое содержимое веб-страницы. . . 34
Глава 2. Установка сервера, предназначенного для разработки . . . 49
Глава 3. Введение в PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Глава 4. Выражения и управление процессом выполнения
программы в PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Глава 5. Функции и объекты PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Глава 6. Массивы в PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Глава 7. Практикум по программированию на PHP . . . . . . . . . . . . . 167
Глава 8. Введение в MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Глава 9. Освоение MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Глава 10. Доступ к MySQL с использованием PHP . . . . . . . . . . . . . . . 258
Глава 11. Обработка форм . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Глава 12. Cookie, сессии и аутентификация . . . . . . . . . . . . . . . . . . . 310
Глава 13. Изучение JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Глава 14. Выражения и управление процессом выполнения
сценариев в JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Глава 15. Функции, объекты и массивы JavaScript. . . . . . . . . . . . . . 371
Глава 16. Проверка данных и обработка ошибок в JavaScript
и PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
Глава 17. Использование технологии AJAX . . . . . . . . . . . . . . . . . . . . 414
Глава 18. Введение в CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430

6

Краткое содержание

Глава 19. Расширение CSS с помощью CSS3. . . . . . . . . . . . . . . . . . . 469
Глава 20. Доступ к CSS из JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . 496
Глава 21. Введение в jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
Глава 22. Введение в HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576
Глава 23. Холсты в HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
Глава 24. Аудио и видео в HTML5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
Глава 25. Другие свойства HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . 646
Глава 26. Объединение технологий . . . . . . . . . . . . . . . . . . . . . . . . . . 668
Приложение А. Ответы на контрольные вопросы. . . . . . . . . . . . . . 703
Приложение Б. Интернет-ресурсы. . . . . . . . . . . . . . . . . . . . . . . . . . . 730
Приложение В. MySQL's FULLTEXT Stopwords . . . . . . . . . . . . . . . . . 733
Приложение Г. Функции MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736
Приложение Д. Селекторы, объекты и методы jQuery. . . . . . . . . 747

Оглавление
Предисловие. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Для кого предназначена эта книга. . . . .
Предположения, допущенные в данной
Как устроена книга . . . . . . . . . . . . . . . .
Дополнительная литература . . . . . . . . .
Условные обозначения. . . . . . . . . . . . .
Использование примеров кода. . . . . . . .
Благодарности. . . . . . . . . . . . . . . . . . . .

. . . . .
книге .
. . . . .
. . . . .
.....
. . . . .
. . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
...................
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .

29
29
30
30
31
32
32

От издательства. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Глава 1. Введение в динамическое содержимое веб-страницы. . . 34
HTTP и HTML: основы, заложенные Бернерсом-Ли . . . . . . . .
Процедура «запрос — ответ». . . . . . . . . . . . . . . . . . . . . . . .
Преимущества использования PHP, MySQL, JavaScript и CSS .
PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CSS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
А теперь HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Веб-сервер Apache. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Несколько слов о программах с открытым исходным кодом .
А теперь все это, вместе взятое. . . . . . . . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

35
35
38
39
40
41
42
43
44
45
45
47

Глава 2. Установка сервера, предназначенного для разработки . . . 49
Что такое WAMP, MAMP и LAMP . . . . . . . . . . . . . . . . .
Установка XAMPP в систему Windows. . . . . . . . . . . . .
Тестирование установки . . . . . . . . . . . . . . . . . . .
Обращение к исходному источнику документов. .
Другие системы WAMP. . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

50
50
57
58
59

8

Оглавление

Установка XAMPP в систему Mac OS X. . . . . . . . . . . . .
Обращение к исходному источнику документов. .
Установка LAMP в Linux . . . . . . . . . . . . . . . . . . . . . . .
Работа в удаленном режиме . . . . . . . . . . . . . . . . . . .
Вход в систему . . . . . . . . . . . . . . . . . . . . . . . . . .
Использование FTP. . . . . . . . . . . . . . . . . . . . . . .
Использование редактора программ. . . . . . . . . . . . . .
Использование IDE . . . . . . . . . . . . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

59
60
60
61
61
61
63
64
65

Глава 3. Введение в PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Включение PHP в HTML . . . . . . . . . . . . . . . . .
Примеры в этой книге . . . . . . . . . . . . . . . . . .
Структура PHP. . . . . . . . . . . . . . . . . . . . . . . .
Комментарии. . . . . . . . . . . . . . . . . . . . . .
Основной синтаксис . . . . . . . . . . . . . . . .
Переменные . . . . . . . . . . . . . . . . . . . . . .
Операторы . . . . . . . . . . . . . . . . . . . . . . .
Присваивание значений переменным. . .
Многострочные команды. . . . . . . . . . . . .
Типы переменных. . . . . . . . . . . . . . . . . .
Константы. . . . . . . . . . . . . . . . . . . . . . . .
Предопределенные константы. . . . . . . . .
Различие между командами echo и print .
Функции . . . . . . . . . . . . . . . . . . . . . . . . .
Область видимости переменной . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
................
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .

66
68
69
69
70
70
75
78
81
83
84
84
85
86
87
93

Глава 4. Выражения и управление процессом выполнения
программы в PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Выражения . . . . . . . . . . . . . . . . . . . .
TRUE или FALSE?. . . . . . . . . . . . .
Литералы и переменные. . . . . . .
Операторы . . . . . . . . . . . . . . . . . . . .
Приоритетность операторов . . . .
Взаимосвязанность операторов. .
Операторы отношения. . . . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

. . . . . . . . . . . . . . . . . . . . . . . . 95
. . . . . . . . . . . . . . . . . . . . . . . . 95
. . . . . . . . . . . . . . . . . . . . . . . . 97
. . . . . . . . . . . . . . . . . . . . . . . . 98
. . . . . . . . . . . . . . . . . . . . . . . . 99
. . . . . . . . . . . . . . . . . . . . . . . 100
. . . . . . . . . . . . . . . . . . . . . . . 102

9

Оглавление

Условия. . . . . . . . . . . . . . . . . . . . . . . . . .
Инструкция if . . . . . . . . . . . . . . . . . .
Инструкция else. . . . . . . . . . . . . . . . .
Инструкция elseif. . . . . . . . . . . . . . . .
Инструкция switch. . . . . . . . . . . . . . .
Оператор ? . . . . . . . . . . . . . . . . . . . .
Организация циклов . . . . . . . . . . . . . . . .
Циклы while. . . . . . . . . . . . . . . . . . . .
Циклы do...while . . . . . . . . . . . . . . . .
Циклы for . . . . . . . . . . . . . . . . . . . . .
Прекращение работы цикла. . . . . . . .
Инструкция continue . . . . . . . . . . . . .
Неявное и явное преобразование типов. .
Динамическое связывание в PHP. . . . . . .
Динамическое связывание в действии . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

106
106
107
109
110
113
114
115
116
117
119
120
120
121
122
123

Глава 5. Функции и объекты PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Функции PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Определение функции. . . . . . . . . . . . . . . . . . .
Возвращение значения . . . . . . . . . . . . . . . . . .
Возвращение массива . . . . . . . . . . . . . . . . . . .
Не передавайте аргументы по ссылке . . . . . . .
Возвращение глобальных переменных. . . . . . .
И еще раз об области видимости переменных .
Включение и запрос файлов . . . . . . . . . . . . . . . . .
Инструкция include . . . . . . . . . . . . . . . . . . . . .
Инструкция include_once. . . . . . . . . . . . . . . . .
Инструкции require и require_once. . . . . . . . . .
Совместимость версий PHP . . . . . . . . . . . . . . . . . .
Объекты PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Терминология. . . . . . . . . . . . . . . . . . . . . . . . .
Объявление класса. . . . . . . . . . . . . . . . . . . . .
Создание объекта. . . . . . . . . . . . . . . . . . . . . .
Доступ к объектам. . . . . . . . . . . . . . . . . . . . . .
Клонирование объектов . . . . . . . . . . . . . . . . .
Конструкторы . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

126
127
128
130
130
132
133
133
133
134
134
135
135
136
138
138
139
140
141

10

Оглавление

Деструкторы в PHP 5. . . . . . .
Написание методов. . . . . . . .
Статические методы в PHP 5.
Объявление свойств . . . . . . .
Объявление констант . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

142
142
143
144
145

Область видимости свойств и методов в PHP 5. . . . . . . . . . . . . . . . . 145
Статические свойства и методы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Наследование. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151

Глава 6. Массивы в PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Основные подходы к массивам. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Массивы с числовой индексацией . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Ассоциативные массивы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Присваивание с использованием ключевого слова array. . . . . . . . . . . 155
Цикл foreach...as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Многомерные массивы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Использование функций для работы с массивами. . . . . . . . . . . . . . . . . . . 161
is_array. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
count. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
sort. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
shuffle. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
explode. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
extract. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
compact. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
reset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
end. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

Глава 7. Практикум по программированию на PHP . . . . . . . . . . . . . 167
Функция printf. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Настройка представления данных. . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Дополнение строк. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Функция sprintf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Функции даты и времени. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Константы, связанные с датами. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
Функция checkdate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

11

Оглавление

Работа с файлами . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Проверка существования файла . . . . . . . . . . . . . .
Создание файла . . . . . . . . . . . . . . . . . . . . . . . . . .
Чтение из файлов. . . . . . . . . . . . . . . . . . . . . . . . .
Копирование файлов. . . . . . . . . . . . . . . . . . . . . . .
Перемещение файла. . . . . . . . . . . . . . . . . . . . . . .
Удаление файла . . . . . . . . . . . . . . . . . . . . . . . . . .
Обновление файлов . . . . . . . . . . . . . . . . . . . . . . .
Блокирование файлов при коллективном доступе .
Чтение всего файла целиком. . . . . . . . . . . . . . . . .
Загрузка файлов на веб-сервер. . . . . . . . . . . . . . .
Системные вызовы. . . . . . . . . . . . . . . . . . . . . . . . . . . .
XHTML или HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

175
176
176
178
178
179
179
180
181
182
183
188
190
191

Глава 8. Введение в MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Основные характеристики MySQL. . . . . . . . . . . . . . . . .
Сводка понятий, используемых в базах данных . . . . . .
Доступ к MySQL из командной строки. . . . . . . . . . . . . .
Начало работы с интерфейсом командной строки .
Использование интерфейса командной строки. . . .
Команды MySQL . . . . . . . . . . . . . . . . . . . . . . . . . .
Типы данных. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Индексы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Создание индекса. . . . . . . . . . . . . . . . . . . . . . . . .
Создание запросов к базе данных MySQL. . . . . . . .
Объединение таблиц. . . . . . . . . . . . . . . . . . . . . . .
Использование логических операторов . . . . . . . . .
Функции MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Работа с MySQL через phpMyAdmin . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

192
193
193
194
197
199
203
212
213
218
227
229
229
230
231

Глава 9. Освоение MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Проектирование базы данных . . . . . . . . . . . . . . . . . . . . .
Первичные ключи: ключи к реляционным базам данных .
Нормализация. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Первая нормальная форма . . . . . . . . . . . . . . . . . . . .
Вторая нормальная форма. . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

233
234
235
236
238

12

Оглавление

Третья нормальная форма. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Когда не следует проводить нормализацию. . . . . . . . . . . . . . . . . . . . 243
Отношения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
«Один к одному». . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
«Один ко многим». . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
«Многие ко многим». . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Базы данных и анонимность . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Транзакции. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Ядра (механизмы хранения) транзакций . . . . . . . . . . . . . . . . . . . . . . 248
Команда BEGIN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Команда COMMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Команда ROLLBACK. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Команда EXPLAIN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Резервное копирование и восстановление данных. . . . . . . . . . . . . . . . . . 252
Команда mysqldump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Создание файла резервной копии. . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Восстановление данных из файла резервной копии. . . . . . . . . . . . . . 255
Выгрузка данных в файлы формата CSV . . . . . . . . . . . . . . . . . . . . . . 255
Планирование резервного копирования. . . . . . . . . . . . . . . . . . . . . . . 256
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256

Глава 10. Доступ к MySQL с использованием PHP . . . . . . . . . . . . . . . 258
Запросы к базе данных MySQL с помощью PHP. . . . . . . . . . . . . . . . . . . . . 258
Процесс . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Создание файла регистрации . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Подключение к базе данных MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . 260
Практический пример . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Массив $_POST. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Удаление записи. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Отображение формы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Запросы к базе данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Запуск программы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
Практическая работа с MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
Создание таблицы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
Описание таблицы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Удаление таблицы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Добавление данных. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274

Оглавление

13

Извлечение данных. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Обновление данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Удаление данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Свойство AUTO_INCREMENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Выполнение дополнительных запросов . . . . . . . . . . . . . . . . . . . . . . . 278
Предотвращение попыток взлома . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Возможные меры противодействия . . . . . . . . . . . . . . . . . . . . . . . . . . 280
Указатели мест заполнения. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Предотвращение внедрения HTML-кода. . . . . . . . . . . . . . . . . . . . . . . 284
Процедурный метод использования mysqli. . . . . . . . . . . . . . . . . . . . . 285
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287

Глава 11. Обработка форм . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Создание форм . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Извлечение отправленных данных. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
register_globals: склонность к использованию устаревших
решений. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Значения по умолчанию . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
Типы элементов ввода данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Обезвреживание введенных данных . . . . . . . . . . . . . . . . . . . . . . . . . 300
Пример программы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
А что нового в HTML5?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Атрибут autocomplete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Атрибут autofocus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Атрибут placeholder. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Атрибут required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Атрибуты подмены . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Атрибуты width и height. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Свойства, ожидающие повсеместной реализации. . . . . . . . . . . . . . . . . . . 306
Атрибут form. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Атрибут list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Атрибуты min и max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Атрибут step. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Тип ввода color. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Типы ввода number и range. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Окно выбора даты и времени . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309

14

Оглавление

Глава 12. Cookie, сессии и аутентификация . . . . . . . . . . . . . . . . . . . 310
Использование cookie в PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
Установка cookie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
Доступ к cookie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Удаление cookie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
HTTP-аутентификация. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Сохранение имен пользователей и паролей. . . . . . . . . . . . . . . . . . . . 316
Добавление произвольных данных . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Использование сессий. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Начало сессии. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Завершение сессии. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
Безопасность сессии . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330

Глава 13. Изучение JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
JavaScript и текст HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Использование сценариев в заголовке документа . . . . . . . . . . . . . . . 333
Устаревшие и нестандартные браузеры. . . . . . . . . . . . . . . . . . . . . . . 333
Включение файлов JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Отладка кода JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
Использование комментариев . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Точка с запятой. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Переменные . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Строковые переменные. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Числовые переменные. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Массивы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
Операторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Арифметические операторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Операторы присваивания . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Операторы сравнения. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Логические операторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Инкремент и декремент переменной . . . . . . . . . . . . . . . . . . . . . . . . . 342
Объединение строк. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
Управляющие символы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
Типизация переменных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Функции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344

15

Оглавление

Глобальные переменные . . . . . . . . . . .
Локальные переменные. . . . . . . . . . . .
Объектная модель документа. . . . . . . .
Но не все так просто. . . . . . . . . . .
Еще одно использование знака $. .
Использование DOM . . . . . . . . . . .
О функции document.write. . . . . . . . . .
Использование console.log. . . . . . .
Использование alert. . . . . . . . . . .
Запись в элементы . . . . . . . . . . . .
Использование document.write. . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
.........................
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .

344
344
346
348
348
349
350
350
350
350
350
351

Глава 14. Выражения и управление процессом выполнения
сценариев в JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Выражения . . . . . . . . . . . . . . . . .
Литералы и переменные . . . . . . .
Операторы . . . . . . . . . . . . . . . . .
Приоритетность операторов .
Взаимосвязанность . . . . . . . .
Операторы отношения. . . . .
Инструкция with. . . . . . . . . . . . . .
Использование события onerror. .
Конструкция try...catch. . . . . . . . .
Условия. . . . . . . . . . . . . . . . . . . .
Инструкция if . . . . . . . . . . . .
Инструкция else. . . . . . . . . . .
Инструкция switch. . . . . . . . .
Оператор ? . . . . . . . . . . . . . .
Циклы. . . . . . . . . . . . . . . . . . . . .
Циклы while. . . . . . . . . . . . . .
Циклы do...while . . . . . . . . . .
Циклы for . . . . . . . . . . . . . . .
Прекращение работы цикла. .
Инструкция continue . . . . . . .
Явное преобразование типов. . . .
Вопросы . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
.......................
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .

353
354
355
356
356
357
360
360
362
362
363
363
364
365
366
366
366
367
368
368
369
370

16

Оглавление

Глава 15. Функции, объекты и массивы JavaScript. . . . . . . . . . . . . . 371
Функции JavaScript. . . . . . . . . . .
Определение функции. . . . .
Массив аргументов . . . . . . .
Возвращение значения . . . .
Возвращение массива . . . . .
Объекты JavaScript. . . . . . . . . . .
Объявление класса. . . . . . .
Создание объекта. . . . . . . .
Доступ к объектам. . . . . . . .
Ключевое слово prototype. .
Массивы в JavaScript . . . . . . . . .
Числовые массивы . . . . . . .
Ассоциативные массивы . . .
Многомерные массивы. . . .
Методы массивов . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
.......................
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .

371
371
372
373
375
376
376
377
378
378
381
381
382
383
384
389

Глава 16. Проверка данных и обработка ошибок в JavaScript
и PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
Проверка данных, введенных пользователем, средствами JavaScript.
Документ validate.html (часть первая) . . . . . . . . . . . . . . . . . . . . .
Документ validate.html (часть вторая) . . . . . . . . . . . . . . . . . . . . .
Регулярные выражения. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Соответствие, закладываемое в метасимволы . . . . . . . . . . . . . . .
Нестрогое символьное соответствие . . . . . . . . . . . . . . . . . . . . . .
Группировка с помощью скобок. . . . . . . . . . . . . . . . . . . . . . . . . .
Символьный класс. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Указание диапазона . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Инвертирование . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Более сложные примеры. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Сводная таблица метасимволов. . . . . . . . . . . . . . . . . . . . . . . . . .
Общие модификаторы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Использование регулярных выражений в JavaScript. . . . . . . . . . .
Использование регулярных выражений в PHP . . . . . . . . . . . . . . .
Повторное отображение формы после проверки
данных PHP-программой. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

390
391
393
396
397
397
399
399
400
400
400
403
405
405
406

. . . 407
. . . 413

17

Оглавление

Глава 17. Использование технологии AJAX . . . . . . . . . . . . . . . . . . . . 414
Что такое AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . .
XMLHttpRequest. . . . . . . . . . . . . . . . . . . . . . . . . . .
Ваша первая программа, использующая AJAX .
Использование GET вместо POST. . . . . . . . . . .
Отправка XML-запросов. . . . . . . . . . . . . . . . . .
Использование для AJAX специальной среды. . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

415
415
417
422
424
428
429

Глава 18. Введение в CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Импортирование таблицы стилей. . . . . . . . . . . . . . .
Импортирование CSS из HTML-кода. . . . . . . . . .
Встроенные настройки стиля. . . . . . . . . . . . . . .
Идентификаторы (ID) . . . . . . . . . . . . . . . . . . . . . . .
Классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Точки с запятой. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Правила CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Множественные задания стиля . . . . . . . . . . . . .
Использование комментариев. . . . . . . . . . . . . .
Типы стилей . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Исходные стили. . . . . . . . . . . . . . . . . . . . . . . . .
Пользовательские стили . . . . . . . . . . . . . . . . . .
Внешние таблицы стилей . . . . . . . . . . . . . . . . .
Внутренние стили. . . . . . . . . . . . . . . . . . . . . . .
Внедренные стили. . . . . . . . . . . . . . . . . . . . . . .
Селекторы CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Селектортипа. . . . . . . . . . . . . . . . . . . . . . . . . .
Селектор потомков . . . . . . . . . . . . . . . . . . . . . .
Селектор дочерних элементов. . . . . . . . . . . . . .
Селектор элементов, имеющих идентификатор .
Селектор класса . . . . . . . . . . . . . . . . . . . . . . . .
Селектор атрибутов. . . . . . . . . . . . . . . . . . . . . .
Универсальный селектор. . . . . . . . . . . . . . . . . .
Групповая селекция . . . . . . . . . . . . . . . . . . . . .
Каскадность CSS . . . . . . . . . . . . . . . . . . . . . . . . . . .
Создатель таблиц стилей. . . . . . . . . . . . . . . . . .
Методы создания таблиц стилей . . . . . . . . . . . .
Селекторы таблиц стилей . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

431
432
432
432
433
433
433
434
435
435
435
436
436
437
437
437
437
438
439
440
441
441
442
442
443
443
444
444

18

Оглавление

Вычисление специфики. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
Разница между элементами Div и Span. . . . . . . . . . . . . . . . . . . . . . . 447
Измерения. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
Шрифты и оформление. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
font-family. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
font-style. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
font-size. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
font-weight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Управление стилями текста. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Оформление. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Разрядка. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Выравнивание. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
Преобразование . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
Отступы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
Цвета CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
Сокращенные цветовые строки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
Градиенты. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
Позиционирование элементов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Абсолютное позиционирование. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Относительное позиционирование. . . . . . . . . . . . . . . . . . . . . . . . . . . 458
Фиксированное позиционирование . . . . . . . . . . . . . . . . . . . . . . . . . . 458
Псевдоклассы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
Сокращенная запись правил . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Модель блока и макет страницы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Установка полей. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
Применение границ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
Настройка отступов. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
Содержимое объекта. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468

Глава 19. Расширение CSS с помощью CSS3. . . . . . . . . . . . . . . . . . . 469
Селекторы атрибутов. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
Соответствие частям строк . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
Оператор ^. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
Оператор $. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
Оператор *. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
Свойство box-sizing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471

19

Оглавление

Создание фона в CSS3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство background-clip. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство background-origin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство background-size. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Использование нескольких фонов. . . . . . . . . . . . . . . . . . . . . . . . . . .
Границы CSS3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство border-color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство border-radius. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Прямоугольные тени . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Выход элемента за пределы размеров . . . . . . . . . . . . . . . . . . . . . . . . . . .
Разметка с использованием нескольких колонок . . . . . . . . . . . . . . . . . . .
Цвета и непрозрачность. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Цвета HSL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Цвета HSLA. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Цвета RGB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Цвета RGBA. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство opacity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Эффекты, применяемые к тексту. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство text-shadow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство text-overflow. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойство word-wrap. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Веб-шрифты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Трансформации. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Трехмерная трансформация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Переходы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Свойства, применяемые к переходам. . . . . . . . . . . . . . . . . . . . . . . . .
Продолжительность перехода. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Задержка перехода. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Задание скорости перехода. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Сокращенный синтаксис . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

472
472
473
474
475
477
477
477
480
481
481
483
483
484
484
485
485
486
486
486
487
487
489
490
491
492
492
492
492
493
495

Глава 20. Доступ к CSS из JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . 496
Еще одно обращение к функции getElementById. .
Функция O . . . . . . . . . . . . . . . . . . . . . . . . . .
Функция S. . . . . . . . . . . . . . . . . . . . . . . . . . .
Функция C. . . . . . . . . . . . . . . . . . . . . . . . . . .
Включение функций . . . . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

496
496
497
498
499

20

Оглавление

Обращение к свойствам CSS из JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . 500
Некоторые общие свойства. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
Другие свойства . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Встроенный JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
Ключевое слово this . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
Привязка событий к объектам в сценарии . . . . . . . . . . . . . . . . . . . . . 504
Прикрепление к другим событиям. . . . . . . . . . . . . . . . . . . . . . . . . . . 505
Добавление новых элементов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
Удаление элементов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Альтернативы добавлению и удалению элементов. . . . . . . . . . . . . . . 508
Использование прерываний. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Использование функции setTimeout. . . . . . . . . . . . . . . . . . . . . . . . . . 509
Отмена тайм-аута . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
Функция setInterval. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
Использование прерываний для анимации. . . . . . . . . . . . . . . . . . . . . 512
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513

Глава 21. Введение в jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
Почему же именно jQuery?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
Включение jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
Выбор подходящей версии . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
Загрузка . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Использование сети доставки контента. . . . . . . . . . . . . . . . . . . . . . . 518
Всегда используйте самую последнюю версию. . . . . . . . . . . . . . . . . 519
Заказная сборка jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Синтаксис jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Простой пример . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Как избежать конфликта библиотек. . . . . . . . . . . . . . . . . . . . . . . . . 521
Селекторы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
Метод css . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
Селектор элемента . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Селектор идентификатора. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Селектор класса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Сочетание селекторов. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Обработка событий . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Ожидание готовности документа. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Функции и свойства событий. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527

21

Оглавление

События blur и focus . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ключевое слово this . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
События click и dblclick . . . . . . . . . . . . . . . . . . . . . . . . . . .
Событие keypress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Деликатное программирование. . . . . . . . . . . . . . . . . . . . .
Событие mousemove. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Другие события, связанные с мышью. . . . . . . . . . . . . . . . .
Альтернативные методы работы с мышью. . . . . . . . . . . . .
Событие submit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Специальные эффекты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Исчезновение и появление . . . . . . . . . . . . . . . . . . . . . . . .
Метод toggle. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Проявление и растворение . . . . . . . . . . . . . . . . . . . . . . . .
Скольжение элементов вверх и вниз. . . . . . . . . . . . . . . . .
Анимация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Остановка анимации. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Работа с DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Разница между методами text и html. . . . . . . . . . . . . . . . .
Методы val и attr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Добавление и удаление элементов . . . . . . . . . . . . . . . . . .
Динамическое применение классов . . . . . . . . . . . . . . . . . . . . .
Работа с размерами. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Методы width и height. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Методы innerWidth и innerHeight . . . . . . . . . . . . . . . . . . . .
Методы outerWidth и outerHeight. . . . . . . . . . . . . . . . . . . .
Обход объектов DOM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Родительские элементы. . . . . . . . . . . . . . . . . . . . . . . . . . .
Дочерние элементы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Одноуровневые элементы. . . . . . . . . . . . . . . . . . . . . . . . .
Выбор следующих и предыдущих элементов . . . . . . . . . . .
Обход элементов, выбранных с помощью методов jQuery .
Метод is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Использование jQuery без селекторов . . . . . . . . . . . . . . . . . . .
Метод $.each. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Метод $.map. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Использование Ajax. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Использование метода Post. . . . . . . . . . . . . . . . . . . . . . . .
Использование метода Get . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

527
529
529
530
532
532
535
536
537
539
540
541
541
543
544
547
547
548
549
550
552
553
553
556
556
556
557
562
562
564
565
567
569
569
570
570
570
571

22

Оглавление

Дополнительные модули . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
Пользовательский интерфейс jQuery. . . . . . . . . . . . . . . . . . . . . . . . . 572
Другие дополнительные модули . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573
jQuery для мобильных устройств. . . . . . . . . . . . . . . . . . . . . . . . . . . . 573
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574

Глава 22. Введение в HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576
Холст. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577
Геолокация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 578
Аудио и видео. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
Формы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581
Локальное хранилище. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582
Рабочие веб-процессы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582
Веб-приложения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582
Микроданные . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583

Глава 23. Холсты в HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
Создание холста и доступ к нему. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
Функция toDataURL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
Указание типа изображения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
Метод fillRect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
Метод clearRect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
Метод strokeRect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
Сочетание всех этих команд . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
Метод createLinearGradient. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590
Метод addColorStop в подробностях. . . . . . . . . . . . . . . . . . . . . . . . . . 593
Метод createRadialGradient. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
Использование узоров для заливки. . . . . . . . . . . . . . . . . . . . . . . . . . 595
Запись текста на холсте. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
Метод strokeText . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597
Свойство textBaseLine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597
Свойство font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Свойство textAlign. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Метод fillText. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Метод measureText . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599

23

Оглавление

Рисование линий. . . . . . . . . . . . . . . . . .
Свойство lineWidth. . . . . . . . . . . . . .
Свойства lineCap и lineJoin. . . . . . . .
Свойство miterLimit. . . . . . . . . . . . .
Использование путей. . . . . . . . . . . . . . .
Методы moveTo и LineTo . . . . . . . . .
Метод stroke. . . . . . . . . . . . . . . . . .
Метод rect. . . . . . . . . . . . . . . . . . . .
Заливка областей . . . . . . . . . . . . . . . . .
Метод clip . . . . . . . . . . . . . . . . . . . . . . .
Метод isPointInPath . . . . . . . . . . . . . . . .
Работа с кривыми линиями . . . . . . . . . .
Метод arc . . . . . . . . . . . . . . . . . . . .
Метод arcTo. . . . . . . . . . . . . . . . . . .
Метод quadraticCurveTo . . . . . . . . . .
Метод bezierCurveTo . . . . . . . . . . . .
Обработка изображений . . . . . . . . . . . .
Метод drawImage . . . . . . . . . . . . . .
Изменение размеров изображения .
Выбор области изображения. . . . . .
Копирование с холста. . . . . . . . . . .
Добавление теней. . . . . . . . . . . . . .
Редактирование на уровне пикселов . . .
Метод getImageData . . . . . . . . . . . .
Массив data. . . . . . . . . . . . . . . . . . .
Метод putImageData . . . . . . . . . . . .
Метод createImageData . . . . . . . . . .
Более сложные графические эффекты. .
Свойство globalCompositeOperation .
Свойство globalAlpha. . . . . . . . . . . .
Преобразования . . . . . . . . . . . . . . . . . .
Метод scale. . . . . . . . . . . . . . . . . . .
Методы save и restore . . . . . . . . . . .
Метод rotate . . . . . . . . . . . . . . . . . .
Метод translate . . . . . . . . . . . . . . . .
Метод transform. . . . . . . . . . . . . . . .
Метод setTransform . . . . . . . . . . . . .
Резюме . . . . . . . . . . . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

600
600
600
602
603
603
603
604
604
606
609
609
610
612
613
615
615
616
616
616
618
618
620
620
621
623
623
624
624
626
627
627
628
628
629
631
632
632
633

24

Оглавление

Глава 24. Аудио и видео в HTML5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
О кодеках . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Элемент . . . . . . . . . . . . . . . . . . . . . . . . .
Поддержка браузеров, не работающих с HTML5. .
Элемент . . . . . . . . . . . . . . . . . . . . . . . . .
Видеокодеки. . . . . . . . . . . . . . . . . . . . . . . . .
Поддержка устаревших браузеров. . . . . . . . .
Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

635
636
638
639
640
643
644
644

Глава 25. Другие свойства HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . 646
Геолокация и служба GPS . . . . . . . . . . . . . . . .
Другие методы определения местоположения .
Геолокация и HTML5 . . . . . . . . . . . . . . . . . . . .
Локальное хранилище. . . . . . . . . . . . . . . . . . .
Использование локального хранилища . . .
Объект localStorage. . . . . . . . . . . . . . . . . .
Рабочие веб-процессы. . . . . . . . . . . . . . . . . . .
Автономные веб-приложения. . . . . . . . . . . . . .
Перетаскивание. . . . . . . . . . . . . . . . . . . . . . . .
Обмен сообщениями между документами. . . . .
Микроданные . . . . . . . . . . . . . . . . . . . . . . . . .
Другие теги HTML5 . . . . . . . . . . . . . . . . . . . . .
Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вопросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

646
647
647
651
652
652
654
656
658
660
663
666
666
666

Глава 26. Объединение технологий . . . . . . . . . . . . . . . . . . . . . . . . . . 668
Проектирование сайта социальной сети. . . . . . . . . . . . . . . . . . . . . . . . . .
Информация на сайте . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Файл functions.php. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Функции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Файл header.php. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Файл setup.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Файл index.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Файл signup.php. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Проверка возможности применения желаемого имени
пользователя . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Регистрация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

668
669
669
669
671
673
675
676
676
676

25

Оглавление

Файл checkuser.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679
Файл login.php. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 680
Файл profile.php. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682
Добавление текста в поле About Me (Обо мне). . . . . . . . . . . . . . . . . . 683
Добавление изображения профиля. . . . . . . . . . . . . . . . . . . . . . . . . . 683
Обработка изображения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683
Отображение текущего профиля. . . . . . . . . . . . . . . . . . . . . . . . . . . . 684
Файл members.php. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687
Просмотр профилей пользователей. . . . . . . . . . . . . . . . . . . . . . . . . . 687
Добавление и удаление друзей. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687
Вывод списка всех участников. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687
Файл friends.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 690
Файл messages.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694
Файл logout.php. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
Файл styles.css. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698
Файл javascript.js. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701

Приложение А. Ответы на контрольные вопросы. . . . . . . . . . . . . . 703
Ответы на вопросы главы 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703
Ответы на вопросы главы 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
Ответы на вопросы главы 3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
Ответы на вопросы главы 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706
Ответы на вопросы главы 5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707
Ответы на вопросы главы 6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
Ответы на вопросы главы 7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
Ответы на вопросы главы 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 710
Ответы на вопросы главы 9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 711
Ответы на вопросы главы 10. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
Ответы на вопросы главы 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
Ответы на вопросы главы 12. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714
Ответы на вопросы главы 13. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715
Ответы на вопросы главы 14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716
Ответы на вопросы главы 15. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
Ответы
Ответы
Ответы
Ответы

на
на
на
на

вопросы
вопросы
вопросы
вопросы

главы
главы
главы
главы

16.
17.
18.
19.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

718
719
720
721

26
Ответы
Ответы
Ответы
Ответы
Ответы
Ответы

Оглавление

на
на
на
на
на
на

вопросы
вопросы
вопросы
вопросы
вопросы
вопросы

главы
главы
главы
главы
главы
главы

20.
21.
22.
23.
24.
25.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

723
724
725
726
727
728

Приложение Б. Интернет-ресурсы. . . . . . . . . . . . . . . . . . . . . . . . . . . 730
Сайты, относящиеся к PHP. . . . . . . . . . . .
Сайты, относящиеся к MySQL. . . . . . . . . .
Сайты, относящиеся к JavaScript . . . . . . .
Сайты, относящиеся к CSS. . . . . . . . . . . .
Сайты, относящиеся к HTML5. . . . . . . . . .
Сайты, относящиеся к AJAX . . . . . . . . . . .
Сайты с разнообразными ресурсами. . . . .
Сайты с ресурсами издательства O'Reilly .

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

730
730
731
731
731
731
732
732

Приложение В. MySQL's FULLTEXT Stopwords . . . . . . . . . . . . . . . . . 733
Приложение Г. Функции MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736
Строковые функции. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736
Функции для работы с датами . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739
Функции для работы с временем . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744

Приложение Д. Селекторы, объекты и методы jQuery. . . . . . . . . 747
Селекторы jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747
Объекты jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 751
Методы jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 752

Юлии

Предисловие
Сочетание PHP и MySQL — один из самых удобных подходов к динамическому
веб-конструированию, основанному на использовании баз данных. Этот подход
удерживает свои позиции, несмотря на вызовы, брошенные интегрированными
средами разработки, такими как Ruby on Rails, освоение работы с которыми дается
значительно труднее. Благодаря открытости исходных кодов (в отличие от конкурирующей технологии Microsoft .NET Framework) это технологическое сочетание
можно использовать совершенно бесплатно, поэтому оно очень популярно у вебразработчиков.
Любой нацеленный на результативность разработчик, использующий платформу UNIX/Linux или даже Windows/Apache, нуждается в серьезном освоении этих
технологий. В сочетании с партнерскими технологиями JavaScript, jQuery, CSS
и HTML5 можно создавать сайты калибра таких промышленных стандартов, как
Facebook, Twitter и Gmail.

Для кого предназначена эта книга
Эта книга предназначена для тех, кто хочет изучить способы создания эффективных и динамичных сайтов. Сюда можно отнести веб-мастеров или специалистов
по графическому дизайну, которым уже приходилось создавать статические сайты
и у которых есть желание вывести свое мастерство на следующий уровень, а также
студентов вузов и колледжей, недавних выпускников этих учебных заведений
и просто самоучек.
Фактически любой человек, стремящийся изучить основные принципы, заложенные в основу технологии Web 2.0, известной как ���������������������������
AJAX�����������������������
, сможет получить весьма обстоятельные сведения об основных технологиях: PHP, MySQL, JavaScript,
CSS и HTML5, а также изучить основы библиотеки jQuery.

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

30

Предисловие

сайт. Но при этом не обязательно наличие у читателя каких-либо знаний в области
PHP�������������������������������������������������������������������������
, �����������������������������������������������������������������������
MySQL������������������������������������������������������������������
, ����������������������������������������������������������������
JavaScript������������������������������������������������������
, ����������������������������������������������������
CSS�������������������������������������������������
����������������������������������������������
HTML������������������������������������������
5, хотя, если такие знания имеются, изучение материала будет происходить значительно быстрее.

Как устроена книга
Главы книги расположены в определенном порядке. Сначала идет представление
всех основных технологий, рассматриваемых в книге, а затем описывается процесс
их установки на сервер, предназначенный для разработки веб-приложений, для
того чтобы подготовить читателя к практической работе с примерами.
В первой части книги преподносятся основы языка программирования PHP,
включая основы синтаксиса, массивов, функций и объектно-ориентированного
программирования.
Затем, после усвоения основ �������������������������������������������������
PHP����������������������������������������������
, можно переходить к введению в систему управления базами данных MySQL���������������������������������������������������
��������������������������������������������������������
, рассмотрение которой начинается с изучения структуры базы данных MySQL и заканчивается составлением сложных запросов.
После этого рассказывается о том, как воспользоваться сочетанием PHP
и MySQL, чтобы приступить к созданию собственных динамических веб-страниц
путем интегрирования в это сочетание форм и других функциональных возможностей HTML. Затем будут рассмотрены подробности практических аспектов
разработки на PHP и MySQL, включая описание различных полезных функций
и способов работы с cookies и сессиями, а также способов поддержания высокого
уровня безопасности.
В следующих нескольких главах излагаются основы ��������������������������
JavaScript����������������
, начиная с простых функций и обработки событий и заканчивая доступом к объектной модели
документа (DOM), проверкой введенных данных и обработкой ошибок в браузере.
Это обстоятельный учебник для тех, кто приступает к использованию популярной
библиотеки jQuery для JavaScript.
После рассмотрения основных технологий описываются способы создания
фоновых AJAX-вызовов и превращения сайтов в высокодинамичную среду.
После этого вам предстоит освоить еще две главы, в которых рассматривается,
как использовать CSS для стилевого оформления и подбора формата ваших вебстраниц, и описываются новые свойства, встроенные в ����������������������
HTML������������������
5, включающие геолокацию, аудио, видео и холст.
Получив все эти сведения, вы сможете создать полноценный набор программ,
в совокупности представляющий собой работоспособный сайт социальной сети.
По мере изложения материала дается большое количество указаний и советов
по выработке хорошего стиля программирования, а также подсказок, которые помогут читателям обнаружить и устранить скрытые ошибки программирования.
Кроме того, делается много ссылок на сайты с дополнительными материалами,
относящимися к рассматриваемым темам.

Дополнительная литература
Приступив к изучению разработки программных продуктов с помощью PHP,
MySQL, JavaScript, CSS и HTML5, вы наверняка будете готовы к переводу своего

Условные обозначения

31

мастерства на новый уровень, если воспользуетесь следующими книгами, которые
можно найти на сайте издательства O'Reilly или на других сайтах, где продаются
книги:
 Dynamic HTML: The Definitive Reference (http://oreil.ly/dynamic_html) Денни�����
����������
Гуд����
мана (Danny Goodman);
 PHP in a Nutshell (http://oreil.ly/PHP_nutshell) Пола Хадсона (Paul Hudson);
 MySQL in a Nutshell (http://oreil.ly/MySQL_nutshell) Рассела Дайера (Russell Dyer);
 JavaScript: The Definitive Guide (http://oreil.ly/JS_Definitive) Дэвида Фланагана
(David Flanagan);
 CSS: The Definitive Guide (http://oreil.ly/CSS_Definitive) Эрика А. Майера (Eric A. Myer);
 HTML5: The Missing Manual Мэтью Макдональда (Matthew MacDonald).

Условные обозначения
В книге применяются следующие условные обозначения.
Шрифт для названий

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

Используется для имен файлов, названий путей, именпеременных и команд.
К примеру, путь будет выглядеть так: /Developer/Applications.
Шрифт для листингов

Применяется для отображения примеров исходного кода и содержимого файлов.
Шрифт для листингов полужирный

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

Обозначает код, который должен быть заменен подходящим значением (например, имя_пользователя).
Вам следует обращать особое внимание на специальные врезки, выделенные
с помощью следующих рисунков.
Это подсказка, пожелание, заметка общего типа. Содержит полезную прикладную информацию по рассматриваемой теме.

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

32

Предисловие

Использование примеров кода
Эта книга предназначена для оказания помощи в выполнении стоящих перед вами
задач. Вы можете использовать код, приведенный в ней, в своих программах и документации. Вам не нужно обращаться к нам за разрешением, до тех пор пока
вы не станете копировать значительную часть кода. Например, использование
при написании программы нескольких фрагментов кода, взятых из данной книги,
не требует специального разрешения. Но продажа и распространение компакт-диска с примерами из книг издательства ��������������������������������������������
O�������������������������������������������
'������������������������������������������
Reilly������������������������������������
— требует. Ответы на вопросы, в которых упоминаются материалы этой книги, и цитирование приведенных в ней
примеров не требуют разрешения. Но включение существенного объема примеров
кода, приводимых в данной книге, в документацию по вашему собственному продукту требует получения разрешения. У этой книги имеется сопутствующий сайт,
доступный по адресу http://lpmj.net, откуда вы можете скачать все приведенные
в ней примеры одним ZIP-файлом.
Ссылки на источник приветствуются, но не обязательны. В такие ссылки обычно включаются название книги, имя ее автора, название издательства и номер ISBN.
Например: Learning PHP, MySQL, JavaScript, CSS and HTML5, третье издание, автор
Робин Никсон (Robin Nixon). Copyright 2012 Robin Nixon, 978-1-4919-4946-7.
При любых сомнениях относительно превышения разрешенного объема использования примеров кода, приведенных в данной книге, можете свободно обращаться к нам по адресу permissions@oreilly.com.

Благодарности
Хочу еще раз поблагодарить своего редактора Энди Орама и всех, кто приложил
немало усилий для выхода этой книги, в том числе Альберта Виаша — за его всеобъемлющую техническую рецензию, Николь Шелби за общее руководство выпуском книги, Рэйчел Монаган — за редактуру, Жасмин Квитин — за корректуру,
Роберту Романо — за исходные иллюстрации, Ребекку Демарест — за новые иллюстрации, Дэвида Футато — за внутренний дизайн книги, Люси Хаскинс — за создание индекса, Карен Монтгомери — за великолепную сахарную сумчатую летягу
на обложке книги, Рэнди Камера — за последний вариант обложки книги, а также
многочисленных помощников, отправивших сведения о замеченных ошибках и высказавших свои предложения относительно этого нового издания.

От издательства
Ваши замечания, предложения и вопросы отправляйте по адресу электронной почты July@piter.com (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На сайте издательства http://www.piter.com вы найдете подробную информацию
о наших книгах.

1

Введение
в динамическое
содержимое
веб-страницы

Всемирная паутина — это непрерывно развивающаяся сеть, ушедшая далеко вперед
от своей концепции ранних 1990-х, когда ее создание было обусловлено решением
конкретных задач. Высокотехнологичные эксперименты в ЦЕРНе (Европейском
центре физики высоких энергий, известном в наши дни в качестве обладателя Большого адронного коллайдера) выдавали невероятно большой объем данных, который был слишком велик для распространения среди участвующих в экспериментах
ученых, разбросанных по всему миру.
К тому времени Интернет уже существовал и к нему было подключено несколько сотен тысяч компьютеров, поэтому Тим Бернерс-Ли (специалист ЦЕРНа) придумал способ навигации между ними с использованием среды гиперссылок — так
называемого протокола передачи гиперссылок (Hyper Text Transfer Protocol (HTTP)).
Он также создал специальный язык разметки, названный языком гипертекстовой
разметки (Hyper Text Markup Language (HTML)). Для того чтобы собрать все это
воедино, он создал первые браузер и веб-сервер, которые теперь воспринимаются
нами как должное.
Но в то время эта концепция носила революционный характер. До этого основной объем соединений приходился на пользователей домашних модемов, дозванивавшихся и подключавшихся к электронным доскам объявлений, которые базировались на отдельном компьютере и позволяли общаться и обмениваться данными
только с другими пользователями данной службы. Следовательно, для эффективного электронного общения с коллегами и друзьями нужно было становиться
участником многих электронных досок объявлений.
Но Бернерс-Ли изменил все это одним махом, и к середине 1990-х годов уже
существовали три основных конкурирующих друг с другом графических браузера,
пользовавшихся вниманием 5 млн посетителей. Однако вскоре стало очевидно, что
кое-что было упущено. Конечно, текстовые и графические страницы, имеющие
гиперссылки для перехода на другие страницы, были блестящей концепцией, но
результаты не отражали текущий потенциал компьютеров и Интернета по удовлетворению насущных потребностей пользователей в динамическом изменении
контекста. Всемирная паутина оставляла весьма невыразительное впечатление,
даже при наличии прокрутки текста и анимированных GIF-картинок.

Процедура «запрос — ответ»

35

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

HTTP и HTML: основы,
заложенные Бернерсом-Ли
HTTP�������������������������������������������������������������������������
представляет собой стандарт взаимодействия, регулирующий порядок направления запросов и получения ответов — процесса, происходящего между браузером,
запущенным на компьютере конечного пользователя, и веб-сервером. Задача сервера состоит в том, чтобы принять запрос от клиента и попытаться дать на него
содержательный ответ, обычно передавая ему запрошенную веб-страницу. Именно
поэтому и используется термин «сервер» («обслуживающий»). Партнером, взаимодействующим с сервером, является клиент, поэтому данное понятие применяется
как к браузеру, так и к компьютеру, на котором он работает.
Между клиентом и сервером может располагаться ряд других устройств, например маршрутизаторы, модули доступа, шлюзы и т. д. Они выполняют различные
задачи по обеспечению безошибочного перемещения запросов и ответов между
клиентом и сервером. Как правило, для отправки этой информации используется
Интернет.
Обычно веб-сервер может обрабатывать сразу несколько подключений, а при
отсутствии связи с клиентом он находится в режиме ожидания входящего подключения. При поступлении запроса на подключение сервер подтверждает его
получение отправкой ответа.

Процедура «запрос — ответ»
В наиболее общем виде процесс «запрос — ответ» состоит из просьбы браузера
к веб-серверу отправить ему веб-страницу и выполнения браузером данной просьбы.
После этого браузер занимается отображением страницы (рис. 1.1).
При этом соблюдается такая последовательность действий.
1. Вы вводите в адресную строку браузера http://server.com.
2. Ваш браузер ищет IP-адрес, соответствующий доменному имени server.com.
3. Браузер посылает запрос на главную страницу server.com.
4. Запрос проходит по Интернету и поступает на веб-сервер server.com.
5. Веб-сервер, получивший запрос, ищет веб-страницу на своем жестком диске.

36

Глава 1. Введение в динамическое содержимое веб-страницы

6. Сервер извлекает веб-страницу и отправляет ее по обратному маршруту в адрес
браузера.
7. Браузер отображает веб-страницу.

Рис. 1.1. Основная последовательность процесса «запрос — ответ» между клиентом и сервером

При передаче типовой веб-страницы этот процесс осуществляется для каждого
имеющегося на ней объекта: элемента графики, встроенного видео- или Flash-ролика
и даже шаблона CSS.
Обратите внимание на то, что на шаге 2 браузер ищет IP-адрес, принадлежащий
доменному имени server.com. У каждой машины, подключенной к Интернету, включая и ваш компьютер, есть свой IP-адрес. Но, как правило, доступ к веб-серверам
осуществляется по именам, таким как google.com. Вам, должно быть, известно, что
браузер обращается к вспомогательной интернет-службе, так называемой службе
доменных имен (Domain Name Service (DNS)), для того чтобы найти связанный
с сервером IP-адрес, а затем воспользоваться им для связи с компьютером.
При передаче динамических веб-страниц процедура состоит из большего количества действий, поскольку к ней могут привлекаться как PHP, так и MySQL (рис. 1.2).
1. Вы вводите в адресную строку браузера http://server.com.
2. Ваш браузер ищет IP-адрес, соответствующий доменному имени server.com.
3. Браузер посылает запрос на главную страницу server.com.

Процедура «запрос — ответ»

37

4. Запрос проходит по Сети и поступает на веб-сервер server.com.
5. Веб-сервер, получивший запрос, ищет веб-страницу на своем жестком диске.
6. Теперь, когда главная страница размещена в его памяти, веб-сервер замечает,
что она представлена файлом, включающим в себя PHP-сценарии, и передает
страницу интерпретатору PHP.
7. Интерпретатор PHP выполняет PHP-код.
8. Кое-какие фрагменты кода PHP содержат MySQL-инструкции, которые интерпретатор PHP, в свою очередь, передает процессору базы данных MySQL.
9. База данных MySQL возвращает результаты выполнения инструкции интерпретатору PHP.
10. Интерпретатор PHP возвращает веб-серверу результаты выполнения кода PHP,
а также результаты, полученные от базы данных MySQL.
11. Веб-сервер возвращает страницу выдавшему запрос клиенту, который отображает эту страницу на экране.

Рис. 1.2. Динамическая последовательность процесса «запрос — ответ», выполняемого
клиентом и сервером

38

Глава 1. Введение в динамическое содержимое веб-страницы

Конечно, ознакомиться с этим процессом и узнать о совместной работе трех
элементов не помешает, но на практике эти подробности не понадобятся, поскольку все происходит в автоматическом режиме.
В каждом из примеров возвращенные браузеру HTML����������������������
��������������������������
-страницы могут содержать также код JavaScript, интерпретируемый локально на машине клиента. Этот
код может инициировать еще один запрос, точно так же запрос может быть инициирован встроенными объектами, например изображениями.

Преимущества использования PHP,
MySQL, JavaScript и CSS
В начале этой главы был представлен мир технологии ��������������������������
Web�����������������������
1.0, но рывок к созданию технологии Web 1.1, вместе с которой были разработаны такие браузерные
расширения, как Java, JavaScript, JScript (несколько иной вариант JavaScript от
корпорации ���������������������������������������������������������������������
Microsoft������������������������������������������������������������
) ��������������������������������������������������������
ActiveX�������������������������������������������������
, не заставил себя долго ждать. На серверной стороне прогресс был обеспечен за счет общего шлюзового интерфейса (Common
Gateway��������������������������������������������������������������������������
�������������������������������������������������������������������������
Interface����������������������������������������������������������������
(��������������������������������������������������������������
CGI�����������������������������������������������������������
)), использования таких языков сценариев, как �������������
Perl���������
(альтернатива языку PHP), и выполнения сценариев на стороне сервера —динамической
вставки содержимого одного файла (или выходных данных системного вызова)
в другой файл.
Когда ситуация окончательно прояснилась, на передовых позициях остались
три основные технологии. Несмотря на то что язык сценариев Perl силами своих
стойких приверженцев сохранил популярность, простота PHP и допустимость
использования в нем встроенных ссылок на программу базы данных ����������
MySQL�����
обеспечили этому языку более чем двойное превосходство по количеству пользователей. А ����������������������������������������������������������������������
JavaScript������������������������������������������������������������
, ставший важнейшей составной частью уравнения, используемого для динамического манипулирования каскадными таблицами стилей (Cascading
Style Sheets (CSS)) и HTML, в настоящее время берет на себя наиболее трудоемкие
задачи осуществления AJAX-процесса на стороне клиента. Благодаря технологии
AJAX веб-страницы обрабатывают данные и отправляют запросы веб-серверу
в фоновом режиме, не оповещая пользователя о происходящем.
Несомненно, своеобразный симбиоз PHP����������������������������������
�������������������������������������
�������������������������������
MySQL��������������������������
способствует их продвижению, но что привлекает к ним разработчиков в первую очередь? На это следует дать
простой ответ: та легкость, с которой эти технологии можно использовать для
быстрого создания на сайтах динамических элементов. MySQL�����������������
����������������������
является быстродействующей и мощной, но при этом простой в использовании системой базы
данных, предлагающей сайту практически все необходимое для поиска и обработки данных, которые предназначены для браузеров. Когда PHP для хранения
и извлечения этих данных выступает в союзе с MySQL, вы получаете основные
составляющие, необходимые для разработки сайтов социальных сетей и для перехода к технологии Web 2.0.
И когда вы также соедините вместе JavaScript и CSS, у вас появится рецепт для
создания высокодинамичных и интерактивных сайтов.

Преимущества использования PHP, MySQL, JavaScript и CSS

39

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

Here's the latest news.

Открывающий тег . Все, что находится за пределами этой конструкции, отправляется клиенту в виде простого HTML. Поэтому текст Here's the
latest news просто выводится в браузер. А внутри PHP-тегов встроенная функция
date отображает текущий день недели, соответствующий системному времени
сервера.
В итоге на выходе из этих двух частей получается примерно следующее:
Today is Wednesday. Here's the latest news.

PHP������������������������������������������������������������������
— довольно гибкий язык, и некоторые разработчики предпочитают помещать PHP���������������������������������������������������������������
������������������������������������������������������������������
-конструкцию непосредственно рядом с кодом ��������������������
PHP�����������������
, как в этом примере:
Today is . Here's the latest news.

Существуют также другие способы форматирования и вывода информации,
которые будут рассмотрены в главах, посвященных PHP. Важно усвоить то, что,
используя PHP, веб-разработчики получают язык сценариев, который хотя и не
обладает быстротой кода, скомпилированного на C или ему подобных языках, но
все же работает невероятно быстро и к тому же очень хорошо вписывается в разметку HTML.
Если вы собираетесь набирать встречающиеся в этой книге примеры на PHP, чтобы работать параллельно с моим повествованием, не забывайте предварять их тегом , для того чтобы обеспечить их обработку интерпретатором PHP.
Для упрощения этой задачи можно заранее подготовить файл example.php, содержащий
эти теги.

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

40

Глава 1. Введение в динамическое содержимое веб-страницы

MySQL
Разумеется, без средств отслеживания тех изменений, которые пользователь вносит во время работы с вашим сайтом, нельзя в полной мере говорить о возможностях динамического изменения выходного кода HTML��������������������������
������������������������������
. На заре создания Всемирной паутины многие сайты использовали неструктурированные текстовые файлы
для хранения таких данных, как имена пользователей и пароли. Но такой подход
мог вызвать ряд проблем, если файл не был надежно заблокирован от повреждений, возникающих при одновременном доступе к нему множества пользователей.
К тому же неструктурированный файл мог разрастаться до таких размеров, что
с ним непросто было работать, не говоря уже о трудностях, связанных с попытками
объединения файлов и осуществления в них сложных поисковых операций за какое-нибудь мало-мальски приемлемое время.
Именно в таких случаях большое значение приобретает использование реляционных баз данных со структурированной системой запросов. И MySQL, будучи
совершенно бесплатной и установленной на огромном количестве веб-серверов
системой, оказывается как нельзя кстати. Она представляет собой надежную и исключительно быстродействующую систему управления базами данных, использующую команды, похожие на простые английские слова.
Высшим уровнем структуры MySQL является база данных, внутри которой
можно иметь одну или несколько таблиц, содержащих ваши данные. Предположим,
вы работаете над таблицей под названием users (пользователи), внутри которой
были созданы графы для фамилий — surname, имен — firstname и адресов электронной почты — email, и теперь нужно добавить еще одного пользователя. Одна из
команд, которую можно применить для этого, выглядит следующим образом:
INSERT INTO users VALUES('Smith', 'John', 'jsmith@mysite.com');

Разумеется, как упоминалось ранее, для создания базы данных и таблицы,
а также настройки всех нужных полей понадобится выдать и другие команды, но
используемая здесь команда INSERT демонстрирует простоту добавления в базу
данных новой информации. Команда INSERT является примером структурированного языка запросов (������������������������������������������������������
Structured��������������������������������������������
Query��������������������������������������
�������������������������������������������
�������������������������������������
Language�����������������������������
(���������������������������
SQL������������������������
)), разработанного в начале 1970-х годов и напоминающего один из старейших языков программирования — COBOL. Тем не менее он хорошо подходит для запросов к базе данных, что
и предопределило его использование в течение столь длительного времени.
Так же просто выполняется и поиск данных. Предположим, что имеется адрес
электронной почты пользователя и нужно найти имя его владельца. Для этого
можно ввести следующий запрос MySQL:
SELECT surname,firstname FROM users WHERE email='jsmith@mysite.com';

После этого MySQL вернет Smith, John и любые другие пары имен, которые
могут быть связаны в базе данных с адресом электронной почты.
Нетрудно предположить, что возможности MySQL простираются значительно
дальше выполнения простых команд вставки и выбора — INSERT и SELECT. Например,
можно объединить несколько таблиц в соответствии с множеством различных

Преимущества использования PHP, MySQL, JavaScript и CSS

41

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

JavaScript
Самая старая из трех основных технологий, рассматриваемых в данной книге, —
JavaScript — была создана для получения доступа из сценариев ко всем элементам
HTML����������������������������������������������������������������������
-документа. Иными словами, она предоставляет средства для динамического взаимодействия с пользователем, например для проверки приемлемости адресов
электронной почты в формах ввода данных, отображения подсказок наподобие
«Вы действительно подразумевали именно это?» и т. д. (хотя с точки зрения безопасности, которая всегда должна реализовываться на веб-сервере, на эту технологию положиться нельзя).
В сочетании с CSS JavaScript закладывает основу мощности динамических вебстраниц, которые изменяются буквально на глазах, в отличие от новой страницы,
возвращаемой сервером.
Тем не менее с использованием JavaScript����������������������������������
��������������������������������������������
могут возникнуть осложнения, обусловленные некоторыми существенными различиями в способах реализации этого языка, выбранных разными разработчиками браузеров. В основном эти различия
возникают, когда некоторые производители пытаются придать своим браузерам
дополнительные функциональные возможности, не обращая внимания на совместимость с продуктами своих конкурентов.
К счастью, разработчики в большинстве своем уже взялись за ум и осознали
необходимость полной совместимости своих продуктов, чтобы не приходилось
создавать код с множеством исключений. Но остаются миллионы экземпляров
устаревших браузеров, которыми будут пользоваться на протяжении еще многих
лет. Тем не менее и для них существуют решения проблем несовместимости, и позже в этой книге будут рассмотрены библиотеки и технологии, позволяющие без
каких-либо опасений игнорировать существующие различия.
А сейчас взглянем на то, как можно воспользоваться обычным JavaScript-кодом,
воспринимаемым всеми браузерами:

document.write("Today is " + Date() );


42

Глава 1. Введение в динамическое содержимое веб-страницы

Этот фрагмент кода предписывает браузеру интерпретировать все, что находится внутри тегов script, в качестве кода JavaScript����������������������������������
��������������������������������������������
, что затем браузер и сделает, записав в текущий документ текст «������������������������������������������������
Today�������������������������������������������
������������������������������������������
is����������������������������������������
», а также дату, полученную за счет использования принадлежащей JavaScript функции Date. В результате получится
нечто подобное следующему:
Today is Sun Jan 01 2017 01:23:45
Если не требуется указывать конкретную версию JavaScript, то, как правило, можно опустить
type="text/javascript" и использовать для начала интерпретации JavaScript тег .

Ранее было упомянуто, что изначально JavaScript разрабатывался для того,
чтобы получить возможность динамического управления различными элементами,
находящимися внутри HTML-документа, и это его предназначение по-прежнему
является основным. Но все чаще JavaScript������������������������������������
����������������������������������������������
применяется для реализации технологии AJAX. Это понятие используется для обозначения процессов доступа к вебсерверу в фоновом режиме. (Сначала оно означало «асинхронный JavaScript
��������������������������������������������������������������������������
XML�����������������������������������������������������������������������
»����������������������������������������������������������������������
 ���������������������������������������������������������������������
— �������������������������������������������������������������������
Asynchronous�������������������������������������������������������
������������������������������������������������������
JavaScript��������������������������������������������
�������������������������������������������
and����������������������������������������
���������������������������������������
XML������������������������������������
, но сейчас это определение несколько устарело.)
AJAX������������������������������������������������������������������
— процесс, лежащий в основе технологии Web�����������������������
��������������������������
2.0 (этот термин популяризирован Тимом О'Рейли, основателем и исполнительным директором издательства, в котором эта книга вышла на английском языке), при использовании
которой веб-страницы стали напоминать автономные программы, поскольку их
уже не нужно загружать целиком. Вместо этого в быстром вызове AJAX может
быть задействован отдельный элемент веб-страницы, например, может быть изменена ваша фотография на сайте социальной сети или заменена кнопка, на которой нужно щелкнуть, отвечая на вопрос. Полностью эта тема будет рассмотрена в главе 17.
Затем в главе 21 мы присмотримся к среде jQuery, которую можно использовать,
чтобы не изобретать колесо в случае возникновения потребностей в быстродействующем, кросс-браузерном коде для управления веб-страницами. Конечно, доступны и другие подобные среды, но jQuery����������������������������������
����������������������������������������
является самой популярной библиотекой и, исходя из показателей, накопленных за весьма длительный срок ее
использования, обладает исключительной надежностью и является основным
средством в арсенале многих опытных разработчиков.

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

А теперь HTML5

43

Применение CSS может просто заключаться во вставке правил между тегами
и , расположенными в заголовке веб-страницы:

p
{
text-align:justify;
font-family:Helvetica;
}


Эти правила будут изменять исходное выравнивание текста тега , чтобы содержащиеся в нем абзацы были полностью выровнены и для них использовался
шрифт Helvetica.
В главе 18 вы увидите, что существует множество различных способов задания
правил CSS и их также можно включать непосредственно в теги или сохранять во
внешнем файле, предназначенном для отдельной загрузки. Такая гибкость позволяет проводить точную настройку стиля HTML. Вы также увидите, как с помощью
CSS можно, например, создать встроенную функцию hover для анимирования объектов при проходе над ними указателя мыши. Кроме того, вы научитесь получать
доступ ко всем свойствам CSS-элемента из JavaScript и из HTML.

А теперь HTML5
Какими бы ни были полезными все эти дополнения к веб-стандартам, самым амбициозным разработчикам и их было мало. К примеру, так и не был придуман простой способ работы с графикой в браузере, не требующий обращения к таким
дополнительным модулям, как Flash. То же самое происходило и в отношении
аудио- и видеовставок в веб-страницы. Кроме того, можно отметить множество
досадных несоответствий, вкравшихся в HTML в процессе его развития.
Итак, чтобы подчистить все эти шероховатости, перенести Интернет за пределы
технологии Web 2.0 в его следующую фазу развития, был создан новый стандарт
HTML, устраняющий перечисленные недостатки. Он был назван HTML5 и начал
разрабатываться в далеком 2004 году, когда Mozilla Foundation и Opera Software
(разработчики двух популярных браузеров) составили его первый проект. Но его
окончательный проект был представлен World Wide Web Consortium (W3C),
международной организацией, руководящей веб-стандартами, лишь в начале
2013 года.
Учитывая, что разработка велась девять лет, можно было бы подумать, что речь
идет об окончательной спецификации, но в Интернете так не бывает. Хотя сайты
появляются и исчезают с большой скоростью, базовое программное обеспечение
разрабатывается довольно медленно и тщательно, поэтому появление твердых
рекомендаций в отношении HTML5 вплоть до публикации данного издания этой
книги, то есть в конце 2014 года, не ожидалось. Догадайтесь почему? Начиная
с 2015 года работа уже пойдет над версиями от 5.1 и выше. Таким образом, нас
ожидает бесконечный цикл разработки.

44

Глава 1. Введение в динамическое содержимое веб-страницы

Но, хотя в �������������������������������������������������������������
HTML���������������������������������������������������������
5.1 планируется привнесение в язык множества удобных усовершенствований (в большей степени это касается холстов), основной HTML5
является именно тем новым стандартом веб-разработок, с которым сейчас уже
нужно работать, и он никуда не денется в течение многих грядущих лет. Поэтому
сейчас о нем нужно знать все, что возможно, и это станет для вас очень весомым
подспорьем.
Этот стандарт действительно внес в HTML много нового (при весьма скромном
объеме измененных или удаленных прежних свойств), но, если говорить вкратце,
с его появлением вы получаете следующее.
 Разметку. Включены такие новые элементы, как и , а в разряде
нерекомендуемых теперь числятся такие элементы, как и .
 Новые API. Например, элемент (холст) для записи и рисования на графических холстах, элементы и , автономные веб-приложения,
микроданные и локальное хранилище.
 Приложения. Включены две новые технологии отображения: MathML (Math
Markup Language — язык математической разметки) — для вывода на экран
математических формул и SVG (Scalable Vector Graphics — масштабируемая
векторная графика) — для создания графических элементов за пределами нового элемента . Но MathML и SVG носят специализированный характер
и содержат столько особенностей, что для их описания потребуется отдельная
книга, поэтому здесь они рассматриваться не будут.
Все это (и не только) будет рассмотрено в главе 22.
Кроме всего прочего, мне в спецификации HTML5 нравится, что для самозакрывающихся
элементов больше не нужен синтаксис XHTML. Раньше перевод на новую строку можно было
изобразить с помощью элемента . Затем для обеспечения совместимости в будущем
с XHTML (так и не состоявшейся заменой HTML) элемент был изменен на с добавленным
символом / (поскольку ожидалось, что характерной особенностью закрывающего тега всех
элементов станет именно этот символ). Но теперь все вернулось на круги своя и можно использовать любую из версий таких элементов. Итак, для большей лаконичности и меньшего
объема набираемого текста в данной книге я вернулся к прежнему стилю: , и т. д.

Веб-сервер Apache
В дополнение к PHP, MySQL, JavaScript, CSS и HTML5 в динамической вебтехнологии фигурирует и шестой герой — веб-сервер. В нашей книге предполагается, что это веб-сервер Apache. Мы уже немного касались того, что делает вебсервер в процессе обмена информацией между клиентом и сервером по протоколу
HTTP, но на самом деле негласно он выполняет куда более масштабную работу.
Например, �����������������������������������������������������������
Apache�����������������������������������������������������
обслуживает не только ������������������������������
HTML��������������������������
-файлы — он работает с широким спектром файлов, начиная с файлов изображений и ����������������������
Flash�����������������
-роликов и заканчивая аудиофайлами формата ������������������������������������������������
MP����������������������������������������������
3, файлами �����������������������������������
RSS��������������������������������
-потоков (����������������������
Really����������������
���������������
Simple���������
��������
Syndication — простое распространение по подписке) и т. д. Для этого каждый элемент,
найденный на HTML-странице веб-клиентом, также запрашивается у сервера,
который затем и осуществляет обслуживание.

А теперь все это, вместе взятое

45

Но эти объекты не должны быть статическими файлами, такими как изображения GIF-формата. Все они могут быть сгенерированы программами, такими как
сценарии PHP. И это действительно возможно: PHP способен даже создавать для
вас изображения и другие файлы либо на лету, либо заранее, в расчете на последующее обслуживание. Для этого обычно имеются модули, либо предварительно
скомпилированные в Apache или PHP, либо вызываемые во время выполнения
программы. Одним из таких модулей является библиотека GD (Graphics Draw —
рисование графики), которую ����������������������������������������������
PHP�������������������������������������������
использует для создания и обработки графических элементов.
Apache������������������������������������������������������������������
поддерживает также обширный арсенал собственных модулей. В дополнение к модулям PHP наиболее важными для вас как для веб-программиста будут
модули, занимающиеся обеспечением безопасности. В качестве других примеров
могут послужить модуль Rewrite, позволяющий веб-серверу обрабатывать широкий
диапазон типов �������������������������������������������������������������
URL����������������������������������������������������������
-адресов и перезаписывать их в соответствии с его внутренними требованиями, и модуль Proxy�����������������������������������������
����������������������������������������������
, который можно использовать для обслуживания часто запрашиваемых страниц из кэша, для того чтобы снизить нагрузку на
сервер.
Далее в книге будет показано практическое применение этих модулей для улучшения свойств, предоставляемых тремя основными технологиями.

Несколько слов о программах
с открытым исходным кодом
Часто спорят, обусловлена или нет популярность этих технологий тем, что они представлены программами с открытым исходным кодом, но PHP, MySQL и Apache
действительно являются наиболее востребованными инструментами в своих категориях. Вполне определенно можно сказать, что их принадлежность к продуктам
с открытым кодом означает, что они были разработаны в сообществе команд программистов, которые придавали им свойства в соответствии со своими желаниями
и потребностями и хранили исходный код доступным для всеобщего просмотра
и изменения. Ошибки и бреши в системе безопасности могли предотвращаться еще
до их проявления.
Есть и еще одно преимущество: все эти программы могут использоваться бесплатно. Если вы наращиваете пропускную способность своего сайта и привлекаете
к его обслуживанию различные серверы, не нужно задумываться о приобретении
дополнительных лицензий. Не нужно также пересматривать свой бюджет перед
тем, как принять решение об обновлении системы и установке самых последних
версий этих продуктов.

А теперь все это, вместе взятое
Истинная красота PHP, MySQL, JavaScript (иногда при содействии jQuery или
других сред), CSS и HTML5 проявляется в том замечательном способе, благодаря
которому они совместно работают над производством динамического веб-контента:

46

Глава 1. Введение в динамическое содержимое веб-страницы

PHP занят основной работой на веб-сервере, MySQL управляет данными, а CSS
и JavaScript вместе заботятся о представлении веб-страницы. JavaScript может
также взаимодействовать с вашим PHP-кодом на веб-сервере, когда ему нужно
что-нибудь обновить (как на сервере, так и на веб-странице). И с новыми, высокоэффективными свойствами �������������������������������������������������
HTML���������������������������������������������
5, такими как холсты, аудио, видео и геолокация, можно придать вашим веб-страницам более высокую динамичность, интерактивность и мультимедийность.
Неплохо бы теперь подвести краткий итог всему, что изложено в данной главе,
и, не пользуясь программным кодом, рассмотреть процесс, сочетающий в себе некоторые из этих технологий в повседневно использующейся многими сайтами
функции AJAX: проверке в процессе регистрации новой учетной записи, не занято
ли выбранное имя другим посетителем сайта. Хорошим примером подобного использования технологий может послужить почтовый сервер Gmail (рис. 1.3).

Рис. 1.3. Gmail применяет технологию AJAX для проверки
допустимости пользовательских имен

Этот AJAX-процесс состоит примерно из следующих шагов.
1. Сервер выдает код HTML для создания веб-формы, запрашивающей необходимые данные: имя пользователя, настоящее имя, настоящую фамилию и адрес
электронной почты.
2. Одновременно с этим сервер вкладывает в HTML JavaScript-код, позволяющий отслеживать содержимое поля ввода имени пользователя и проверять
два обстоятельства:
1) введен ли в это поле какой-нибудь текст;
2) был ли фокус ввода перемещен из этого поля по щелчку пользователя на
другом поле ввода.

Вопросы

47

3. Как только будет введен текст и фокус ввода перемещен на другой элемент
формы, код JavaScript в фоновом режиме передает введенное имя пользователя
PHP-сценарию на веб-сервере и ждет ответной реакции.
4. Веб-сервер осуществляет поиск имени пользователя и возвращает коду JavaScript
ответ, в котором сообщает, было ли уже задействовано такое же имя.
5. Затем JavaScript размещает под полем ввода имени пользователя индикатор
приемлемости имени пользователя, возможно, в виде зеленой галочки или
красного крестика, сопровождая его текстом.
6. Если пользователь ввел неприемлемое имя, но все же пытается отправить форму, код JavaScript прерывает отправку и повторно обращает внимание пользователя (возможно, выводя более крупный графический индикатор и/или открывая окно предупреждения) на необходимость выбора другого имени.
7. Усовершенствованная версия этого процесса может даже изучить имя, запрошенное пользователем, и предложить альтернативное доступное на данный
момент имя.
Все это для удобства пользователя и целостности восприятия им всего происходящего делается без привлечения его внимания в фоновом режиме. Без использования AJAX на сервер будет отправлена вся форма, затем он вернет код HTML
с подсветкой тех полей, в которых были допущены ошибки. Можно, конечно,
сделать и так, но обработка поля на лету будет выглядеть намного интереснее и приятнее.
Технология AJAX может использоваться для решения куда более широкого
круга задач, чем простой контроль и обработка вводимой информации. Далее в этой
книге будет рассмотрено много дополнительныхприемов, реализуемых с применением AJAX.
В этой главе вашему вниманию было представлено довольно полное введение
в основные технологии применения �������������������������������������������
PHP����������������������������������������
, MySQL���������������������������������
��������������������������������������
, JavaScript���������������������
�������������������������������
, CSS����������������
�������������������
�������������
HTML���������
5 (а также ��������������������������������������������������������������������������
Apache��������������������������������������������������������������������
) и рассмотрен порядок их совместной работы. В главе����������������
 ���������������
2 будут рассмотрены способы установки вашего собственного сервера, предназначенного для
веб-разработок, на котором можно будет освоить на практике весь изучаемый материал.

Вопросы
Вопрос 1.1
Какие четыре компонента необходимы для создания полностью динамических
сайтов?
Вопрос 1.2
Что означает аббревиатура HTML?
Вопрос 1.3
Почему в названии MySQL присутствуют буквы SQL?

48

Глава 1. Введение в динамическое содержимое веб-страницы

Вопрос 1.4
И PHP, и JavaScript являются языками программирования, генерирующими
динамическое содержимое веб-страниц. В чем состоит их главное различие
и почему вы будете использовать оба этих языка?
Вопрос 1.5
Что означает аббревиатура CSS?
Вопрос 1.6
Если вам удастся обнаружить ошибку в одном из инструментальных средств
с открытым кодом (что случается довольно редко), то как, по-вашему, можно
получить исправленную версию?
Ответы на эти вопросы можно найти в приложении А, в разделе «Ответы на
вопросы главы 1».

2

Установка сервера,
предназначенного
для разработки

Если у вас есть желание разрабатывать интернет-приложения, но нет собственного сервера для их разработки, то прежде, чем протестировать каждую созданную
модификацию приложения, вам придется загружать ее на сервер, находящийся
где-нибудь в Интернете.
Даже при наличии высокоскоростного широкополосного подключения это
обстоятельство может существенно замедлить разработку. А на локальном компьютере тестирование может быть не сложнее обновления программы (зачастую
запускается простым щелчком на значке) с последующим нажатием кнопки Refresh
(Обновить) в браузере.
Еще одно преимущество разработочного сервера заключается в том, что при
написании и тестировании программ не нужно волноваться о смущающих разработчика ошибках или проблемах безопасности, однако при размещении приложения на публичном сайте следует знать о том, что люди могут увидеть, или о том,
что они могут сделать с вашим приложением. Лучше решить все проблемы, пока
вы работаете дома или в небольшом офисе, который, вероятнее всего, защищен
межсетевыми экранами (брандмауэрами) и другими средствами обеспечения безопасности.
Получив в свое распоряжение разработочный сервер, вы удивитесь, как раньше
могли обходиться без него, а также обрадуетесь легкости его настройки. Нужно
лишь пройти все шаги, изложенные в следующих разделах, и выполнить соответствующие указания для обычных персональных компьютеров, Mac- или Linuxсистем.
В этой главе будет рассмотрена только серверная сторона сетевого взаимодействия, о которой шла речь в главе 1. Но для тестирования результатов вашей работы, особенно потом, когда мы приступим к использованию JavaScript, CSS
и HTML5, понадобится также копия каждого основного браузера, работающего
под управлением удобной для вас системы. В списке браузеров должны быть по
крайней мере Internet Explorer, Mozilla Firefox, Opera, Safari и Google Chrome. Если
вы хотите убедиться, что ваши приложения также хорошо выглядят на мобильных
устройствах, постарайтесь использовать для тестирования телефоны и планшеты
под управлением Apple iOS и Google Android.

50

Глава 2. Установка сервера, предназначенного для разработки

Что такое WAMP, MAMP и LAMP
WAMP, MAMP и LAMP — это сокращения от «Windows, Apache, MySQL и PHP»,
«Mac, Apache, MySQL и PHP» и «Linux, Apache, MySQL и PHP» соответственно.
Данными сокращениями описываются полноценные функциональные установки,
используемые для разработки динамических веб-страниц.
Системы WAMP, MAMP и LAMP поставляются в форме пакетов, связывающих
упакованные программы таким образом, чтобы их не нужно было устанавливать
и настраивать по отдельности. Это означает, что нужно просто загрузить и установить одну программу и следовать простым подсказкам, чтобы подготовить разработочный сервер и запустить его в кратчайшие сроки и с минимальными усилиями.
В процессе установки будут созданы исходные настройки. Конфигурация безопасности при такой установке не будет столь же строгой, как на технологическом
веб-сервере, поскольку она оптимизирована для использования на локальной машине. Поэтому не следует пользоваться такими настройками при установке технологического сервера.
Но для разработки и тестирования сайтов и приложений подобная установка
подойдет как нельзя лучше.
Если для создания своей системы разработки вы решили не использовать WAMP/MAMP/LAMP,
следует учесть, что загрузка и самостоятельная взаимоувязка составных частей займет очень
много времени и может отнять большое количество сил на исследования для создания полноценной конфигурации всей системы. Но если все компоненты у вас уже установлены и согласованы друг с другом, они смогут работать с примерами, приводимыми в этой книге.

Установка XAMPP в систему Windows
Существует несколько доступных WAMP������������������������������������
����������������������������������������
-серверов, каждый из которых предлагает свою немного отличающуюся от других конфигурацию. Наверное, среди различных бесплатных вариантов с открытым кодом самым лучшим будет XAMPP.
Его можно загрузить с сайта http://apachefriends.org (рис. 2.1).
Я рекомендую вам всегда загружать последний стабильный выпуск (в данном
примере это 1.8.3), прямая ссылка на загрузку которого для Windows, OS X и Linux
находится на главной странице.
Когда данное издание выйдет в свет, некоторые виды экранов и настройки, рассмотренные
далее, могут измениться. Если это произойдет, руководствуйтесь здравым смыслом и постарайтесь выполнить все действия как можно ближе к описываемой последовательности.

После того как установщик загрузится, запустите его, чтобы появилось окно, показанное на рис. 2.2. Но если вы используете антивирусную программу или в Windows
активирована система User Account Control, то прежде, чем вы доберетесь до этого
окна, вам могут быть показаны одно или несколько консультативных уведомлений,
требующих для продолжения установки щелчков на кнопках Да или OK.

51

Установка XAMPP в систему Windows

Рис. 2.1. Сайт XAMPP

Рис. 2.2. Исходное окно установщика

52

Глава 2. Установка сервера, предназначенного для разработки

Нажмите кнопку Next (Далее), а затем снимите флажки с компонентов, показанных на рис. 2.3, которые вам не понадобятся. К примеру, для работы с книгой
вам как минимум нужно будет оставить флажки на компонентах Apache, MySQL, PHP
и PHPMyAdmin. Другие свойства этой среды в данной книге не рассматриваются, но
подробные сведения о них, а также об основах XAMPP-технологий можно получить
по адресу http://apachefriends.org/faq_windows.html.

Рис. 2.3. Выберите устанавливаемые компоненты

Нажатие кнопки Next (Далее) приведет к показу экрана, изображенного на
рис. 2.4, где нужно выбрать папку, в которую будет осуществляться установка. При
отсутствии веских причин для выбора какой-то особой папки лучше принять папку, предлагаемую по умолчанию. В данной книге предполагается, что вы так и сделаете. Если выбранная вами папка существует и не пуста, то вы не сможете ею
воспользоваться.
Нажатие кнопки Next (Далее) приведет к показу экрана, изображенного на
рис. 2.5, где уже будет установлен флажок (который нужно снять), инициирующий
предоставление информации о добавлении установщиков сопутствующих свободно распространяемых программных средств в новом окне или на вкладке браузера.
После того как будет сделан выбор, получать данную информацию или отказаться
от этой возможности, следует нажать кнопку Next (Далее).
Предоставив установщику необходимую ему основную информацию, вы перейдете к просмотру окна, показанного на рис. 2.6. Для запуска установки все готово,
поэтому нужно нажать кнопку Next (Далее).
После нажатия кнопки Next (Далее) начнется установка программного средства,
в ходе которой будет показан экран, изображенный на рис. 2.7. Во время установки

Установка XAMPP в систему Windows

53

Рис. 2.4. Выберите папку, в которую будет осуществляться установка

Рис. 2.5. Информация о доступных сопутствующих
свободно распространяемых программных средствах

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

54

Глава 2. Установка сервера, предназначенного для разработки

Рис. 2.6. Запуск установки XAMPP

Рис. 2.7. Окно, показывающее ход установки

По окончании установки появится окно, показанное на рис. 2.8, с уже установленным флажком для запуска панели управления XAMPP. Рекомендую оставить
этот флажок установленным и нажать кнопку Finish (Завершить).

Установка XAMPP в систему Windows

55

Рис. 2.8. Для завершения установки следует нажать кнопку Finish (Завершить)

Теперь все готово к началу использования XAMPP, для чего нужно будет настроить эту среду из панели управления, показанной на рис. 2.9. Если флажок в окне
завершения установки остался нетронутым, то панель будет показана автоматически.
Ее также можно будет вызвать из меню Start (Пуск) или с начального экрана.

Рис. 2.9. Панель управления

56

Глава 2. Установка сервера, предназначенного для разработки

Рекомендую сначала нажать кнопку Config (Настроить), которая находится
в верхнем правом углу, и вызвать окно, показанное на рис. 2.10. В частности, предлагаю установить флажки Apache и MySQL, если они еще не установлены, обеспечив
тем самым автозапуск этих средств. Или же можно просто нажать кнопки Start
(Пуск) для Apache и MySQL с целью запуска этих средств только в текущем сеансе работы.

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

Работая с этим экраном, можно при необходимости изменить настройки портов,
нажав кнопку Service and port settings (Настройки служб и портов) и вызвав тем
самым появление окна, показанного на рис. 2.11.

Рис. 2.11. Для завершения установки нажмите кнопку Save (Сохранить)

Установка XAMPP в систему Windows

57

По умолчанию для веб-сервера Apache назначается порт 80, для SSL — порт 443,
а для MySQL — порт 3306. В случае изменения этих значений не забудьте вставить
измененные значения вместо настроек по умолчанию, используемых в данной
книге.
Панель управления позволяет осуществлять большинство действий, необходимых для управления XAMPP, включая редактирование и просмотр различных
конфигурационных файлов и наблюдение за файлами журналов доступа, ошибок
и других регистрируемых параметров, используя довольно простой интерфейс.
Например, на рис. 2.12 показано, что после нажатия кнопки Apache Log (Журнал
Apache) откроется папка журнальных файлов.

Рис. 2.12. Открытие папки журнальных файлов Apache

Тестирование установки
На данном этапе нужно проверить, что все работает должным образом. Для этого
следует попытаться отобразить исходную веб-страницу, которая была сохранена
в корневой папке сервера (рис. 2.13). Введите любой из следующих URL-адресов
в адресную строку браузера:
localhost
127.0.0.1

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

58

Глава 2. Установка сервера, предназначенного для разработки

Рис. 2.13. Так по умолчанию должна выглядеть главная страница XAMPP

Если на панели управления был выбран серверный порт, отличный от 80 (например, 8080),
то после любого из предыдущих URL-адресов нужно поставить двоеточие и значение порта
(например, �����������������������������������������������������������������������������
localhost��������������������������������������������������������������������
:8080). То же самое придется сделать для всех примеров в данной книге. Например, вместо URL localhost/example.php, следует ввести localhost:8080/example.php
(или то значение, которое вы выбрали).

Обращение к исходному источнику документов
Исходным источником документов является каталог, в котором содержатся главные веб-документы домена. Именно он вводится, когда в браузере набирается
базовый URL без пути, например http://yahoo.com или — на локальном сервере —
http://localhost.
По умолчанию XAMPP использует для этого каталога следующее место:
C:/xampp/htdocs

Теперь, чтобы убедиться в том, что все сконфигурировано должным образом,
напишем тестовую программу Hello World. Создайте небольшой HTML-файл со
следующими строками, воспользовавшись Блокнотом или любым другим приложением или текстовым редактором (при использовании текстовых процессоров, таких
как Microsoft������������������������������������������������������������
���������������������������������������������������������������������
�����������������������������������������������������������
Word�������������������������������������������������������
, которые создают форматированный текст, файл нужно сохранять в виде простого текста):


A quick test


Hello World!



Установка XAMPP в систему Mac OS X

59

После набора сохраните файл под именем test.htm в ранее упомянутом каталоге, являющемся исходным источником документов. Если вы создаете файл в Блокноте, убедитесь, что в окне Сохранить как в списке Тип файла выбран вариант Все
файлы, а не Текстовые документы (*.txt). Или же, если вы предпочитаете сохранять
файлы с использованием расширения .html, можете именно так и поступить — здесь
допустимы оба варианта.
Теперь эту страницу можно вызвать в браузере, введя в адресной строке один
из следующих URL-адресов (в соответствии с использованным расширением)
(рис. 2.14):
http://localhost/test.htm
http://localhost/test.html

Рис. 2.14. Ваша первая веб-страница

Другие системы WAMP
При обновлении программы иногда работают неожиданным образом и в них даже
могут проявиться какие-нибудь ошибки. Поэтому, столкнувшись с непреодолимыми трудностями, вместо этого решения вы можете остановить свой выбор на одном
из многих других решений, доступных в Интернете.
Можно будет точно так же воспользоваться всеми примерами, приводимыми
в данной книге, но при этом придется следовать инструкциям, которые предоставляются с каждым WAMP-сервером и могут оказаться сложнее ранее упомянутого
руководства.
Вот наиболее подходящие, на мой взгляд, серверы:
 EasyPHP — easyphp.org;
 WAMPServer — wampserver.com/en;
 Glossword WAMP — glossword.biz/glosswordwamp.

Установка XAMPP в систему Mac OS X
Среда XAMPP может использоваться и в OS X, а загрузить ее можно со страницы
http://apachefriends.org, которая была показана на рис. 2.1.
После загрузки дважды щелкните на файле с расширением .dmg, а затем дважды
щелкните на установщике и следуйте той же самой последовательности инструкций,
как и при установке среды под Windows (хотя вам будет предложено установить
соответствующие флажки, чтобы выбрать, что именно загружать: файлы ядра, файлы, предназначенные для разработки программных средств или и то и другое).

60

Глава 2. Установка сервера, предназначенного для разработки

Процесс установки такой же, как и под Win�������������������������������
dows���������������������������
, но среда XAMPP устанавливается в следующее место: /Applications/XAMPP.
После успешного завершения установки откроется окно диспетчера — XAMPP
Manadger. Чтобы убедиться, что XAMPP получила должное управление работой
веб-сервера в вашей МАС-системе, сначала нужно отключить любой веб-сервер
Apache, уже запущенный в этой системе, запустив в окне терминала следующую
команду:
sudo apachectl stop

Теперь можно щелкнуть на средней вкладке, озаглавленной Manage Servers (Управление серверами) и расположенной в верхней части окна, и нажать кнопку Start All
(Запустить все), запуская тем самым серверы XAMPP. После этого нужно щелкнуть
на вкладке Welcome (Добро пожаловать!), чтобы вернуться на основной экран Manager
(Диспетчер), а затем нажать кнопку Go to Application (Перейти к приложению),
в результате чего будет вызвана веб-страница, показанная на рис. 2.13. На этом все
настройки для использования программного средства будут сделаны.
Дополнительные сведения по установке и использованию Mac XAMPP можно
найти по адресу http://apachefriends.org/faq_osx.html.
В дальнейшем для вызова диспетчера следует открыть папку Applications, перейти в папку
XAMPP и запустить программу manager-osx.

Обращение к исходному источнику документов
В Mac-системах источник XAMPP-документов (где хранятся и откуда обслуживаются веб-документы) может быть найден по адресу /Applications/XAMPP/htdocs.
Для тестирования новой установки наберите в TextEdit (или любом редакторе,
способном сохранять обычный текст) показанный ниже код HTML, сохранив его в источнике документов как test.html. Если затем в адресной строке вашего браузера набрать localhost/test.html, можно будет увидеть результат, показанный на рис. 2.14:


A quick test


Hello World!



Установка LAMP в Linux
Эта книга ориентирована в основном на пользователей PC�������������������
���������������������
����������������
MAC�������������
, но содержащийся в ней код будет хорошо работать и на Linux���������������������������
��������������������������������
-компьютере. Существуют десятки популярных разновидностей Linux, на каждую из которых LAMP может
устанавливаться со своими особенностями. Но многие версии Linux поступают

Работа в удаленном режиме

61

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

Если все заработает, то у вас, наверное, установлен сервер Apache, а также может
быть установлена и запущена база данных MySQL�����������������������������
����������������������������������
, но, чтобы окончательно удостовериться в этом, проверьте факт их установки вместе со своим системным
администратором.
Если веб-сервер не установлен, можете воспользоваться версией XAMPP, которую можно загрузить со страницы http://apachefriends.org.

Работа в удаленном режиме
Если есть доступ к веб-серверу, на котором уже имеются сконфигурированные PHP
и MySQL, то вы всегда можете применить его для веб-разработок. Но это не самый
лучший вариант, если только вы не пользуетесь высокоскоростным подключением.
Разработка, выполняемая на локальной машине, позволяет протестировать новые
модификации практически без задержки или с небольшой задержкой на загрузку.
Может вызвать трудности и удаленный доступ к MySQL. Для ручного создания
баз данных и установки прав доступа из командной строки может понадобиться
сервер Telnet или SSH. Компания, предоставляющая веб-хостинг, посоветует, как
это можно сделать наилучшим образом, и предоставит пароль для доступа к MySQL
(а в первую очередь, разумеется, для доступа к самому серверу).

Вход в систему
Я рекомендую пользователям Windows�����������������������������������������
������������������������������������������������
для доступа к ��������������������������
Telnet��������������������
�����������������
SSH��������������
(следует помнить, что уровень безопасности у ���������������������������������������������
SSH������������������������������������������
значительно выше, чем у �����������������
Telnet�����������
) как минимум установить программу PuTTY, доступную по адресу http://putty.org.
На компьютере �����������������������������������������������������������
Mac��������������������������������������������������������
система �����������������������������������������������
SSH��������������������������������������������
будет доступна изначально. Нужно только выбрать папку Applications, перейти к папке Utilities, а затем запустить программу Terminal.
В окне терминала нужно войти на сервер, используя SSH в следующей команде:
ssh mylogin @ server.com

где server.com — это имя сервера, на который необходимо войти, а mylogin — имя
пользователя, под которым нужно войти в систему. Затем система запросит у вас
пароль для данного имени пользователя, и, если вы введете правильный пароль,
вход состоится.

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

62

Глава 2. Установка сервера, предназначенного для разработки

На данный момент я рекомендую программу FireFTP, потому что она обладает
следующими преимуществами:
 она является дополнением к браузеру Firefox и поэтому будет работать на любой
платформе, на которой работает этот браузер;
 вызвать ее так же просто, как выбрать закладку;
 это одна из самых быстрых и простых в использовании FTP-программ среди
тех, которые мне когда-либо попадались.
Вы можете возразить: «Но я пользуюсь только �������������������������������������������
Internet�����������������������������������
Explorer��������������������������
����������������������������������
, ����������������������
FireFTP���������������
для него недоступна». Я бы на это ответил, что раз уж вы решили заняться разработкой веб-страниц, вам
все равно понадобится установить на свой компьютер все основные браузеры, что уже
предлагалось сделать в начале этой главы.

Для установки FireFTP нужно пройти на сайт http://fireftp.mozdev.org, используя
Firefox, и щелкнуть на ссылке Download FireFTP (Скачать FireFTP). Программа занимает примерно 500 Кбайт и устанавливается очень быстро. После инсталляции
нужно перезапустить Firefox и тогда можно будет получить доступ к FireFTP из
пункта меню Tools (Инструменты) (рис. 2.15).

Рис. 2.15. FireFTP предоставляет полный доступ к FTP прямо из Firefox

Еще одной замечательной FTP-программой является FileZilla, доступная по
адресу http://filezilla-project.org в версиях для Windows, Linux и Mac OS X 10.5 и выше.
Разумеется, если у вас уже есть FTP-программа, вы можете использовать ее.

Использование редактора программ

63

Использование редактора программ
Хотя для редактирования HTML, PHP и JavaScript подходит любой текстовый
редактор, существуют очень удобные приложения, специально предназначенные
для редактирования текста программ. В них имеются весьма полезные возможности, например цветная подсветка синтаксиса. Современные редакторы программ хорошо продуманы и могут еще до запуска программы на выполнение
показывать места, в которых допущены синтаксические ошибки. Перейдя к использованию современного редактора, вы будете удивлены тому, что раньше обходились без него.
Есть множество хороших и доступных программ, но я остановил свой выбор на
программе Editra, поскольку она распространяется бесплатно и доступна для Mac,
Windows и Linux/UNIX (рис. 2.16). Программы можно загрузить, перейдя на сайт
http://editra.org и выбрав ссылку Download (Скачать) в левом верхнем углу страницы,
где также можно найти и документацию на редактор.

Рис. 2.16. Окно программы Editra

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

64

Глава 2. Установка сервера, предназначенного для разработки

Использование IDE
При всех достоинствах специализированных редакторов программ, позволяющих
повысить производительность труда программиста, они не могут сравниться с интегрированными средами разработки (Integrated Development Environment, IDE),
предлагающими множество дополнительных возможностей, например проведение
отладки и тестирования программ прямо в редакторе, а также отображение описаний функций и многое другое.
На рис. 2.17 показана популярная интегрированная среда разработки phpDesigner
с программой PHP, которая загружена в главное окно, и с расположенным в правой
части анализатором кода Code Explorer, в котором перечислены различные классы,
функции и переменные, используемые в этой программе.

Рис. 2.17. При использовании такой IDE, как phpDesigner, разработка PHP-программы
идет намного быстрее и проще

При разработке продукта в IDE можно установить контрольные точки, а затем
запустить весь код целиком (или по частям), тогда его выполнение будет останавливаться в контрольных точках и вам будет предоставляться информация о текущем
состоянии программы.
Помочь изучению процесса создания программ может то, что приводимые
в данной книге примеры могут быть введены в IDE и запущены в этой среде, —
тогда вызывать браузер уже не понадобится.
Существует несколько интегрированных сред разработки, доступных для различных платформ. Большинство из них являются коммерческими продуктами, но
встречаются и бесплатные версии. В табл.�������������������������������������
 ������������������������������������
2.1 приведены некоторые наиболее по-

65

Вопросы

пулярные интегрированные среды разработки PHP�����������������������������
��������������������������������
-программ и �����������������
URL��������������
-адреса, с которых их можно загрузить.
Таблица 2.1. Интегрированные среды разработки для PHP
IDE

URL-адрес загрузки

Цена

Win

Mac

Linux

Eclipse PDT

http://eclipse.org/pdt/downloads/

Бесплатно







Komodo IDE

http://activestate.com/Products/komodo_ide

$245







NetBeans

http://www.netbeans.org

Бесплатно







phpDesigner

http://mpsoftware.dk

$39







PHPEclipse

http://phpeclipse.de

Бесплатно







PhpED

http://nusphere.com

$119







PHPEdit

http://phpedit.com

$119







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

Вопросы
Вопрос 2.1
В чем разница между WAMP, MAMP и LAMP?
Вопрос 2.2
Что общего у IP-адреса 127.0.0.1 и URL-адреса http://localhost?
Вопрос 2.3
Для чего предназначена FTP-программа?
Вопрос 2.4
Назовите основной недостаток работы на удаленном веб-сервере.
Вопрос 2.5
Почему лучше воспользоваться редактором программ, а не обычным текстовым
редактором?
Ответы на эти вопросы можно найти в приложении А, в разделе «Ответы на
вопросы главы 2».

3

Введение
в PHP

В главе 1 о ������������������������������������������������������������������
PHP���������������������������������������������������������������
говорилось как о языке, заставляющем сервер генерировать динамическую, потенциально разную выходную информацию при каждом запросе браузером веб-страницы. В данной главе начнется изучение этого простого, но мощного языка, которое продолжится в следующих главах и завершится в главе 7.
Я призываю вас выполнять разработку кода PHP в одной из интегрированных
средств разработки (IDE), упомянутых в главе 2. Она поможет выявить опечатки,
что существенно ускорит обучение по сравнению с работой в менее функциональных редакторах.
Многие из ����������������������������������������������������������������
IDE�������������������������������������������������������������
позволяют запускать код, рассматриваемый в этой главе, и изучать производимую им выходную информацию. Мы также разберем методы
вставки кода PHP����������������������������������������������������������
�������������������������������������������������������������
в файл ��������������������������������������������������
HTML����������������������������������������������
, чтобы иметь представление о внешнем виде выходной информации на веб-странице (то есть о том виде, в котором она в итоге
предстанет перед пользователями).
В процессе создания веб-страницы будут представлять собой комбинацию PHP,
HTML���������������������������������������������������������������������
, JavaScript���������������������������������������������������������
�������������������������������������������������������������������
, инструкций MySQL���������������������������������������
��������������������������������������������
и форматирования с помощью CSS и, возможно, использования различных элементов HTML�����������������������������
���������������������������������
5. Кроме того, каждая страница может привести на другие страницы, предоставляя пользователям возможность
щелкать на ссылках и заполнять формы. Хотя при изучении этих языков можно
обойтись и без таких сложностей. На данном этапе нужно сконцентрироваться
исключительно на написании �����������������������������������������������
PHP��������������������������������������������
-кода и на достижении предсказуемости содержимого выходной информации или по крайней мере на умении разбираться в характере этой информации.

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

Включение PHP в HTML

67

Программа на PHP отвечает за возвращение файла в чистом виде, пригодном
для отображения в браузере. В простейшем случае на выходе документа PHP будет
получаться только код HTML. Чтобы убедиться в этом, можно взять любой HTMLдокумент, например файл index.html, сохранить его под именем index.php, и он
будет отображаться точно так же, как исходный файл.
Для запуска команд PHP нужно изучить новый тег. Его открывающая часть
имеет следующий вид:


Небольшая PHP���������������������������������������������������������
������������������������������������������������������������
-программа Hello�����������������������������������������
����������������������������������������������
World�����������������������������������
����������������������������������������
может иметь вид, показанный в примере 3.1.
Пример 3.1. Вызов PHP


Этот тег очень гибок в использовании. Некоторые программисты открывают
его в начале документа, а закрывают в самом конце и выводят любой код HTML
путем непосредственного использования команды PHP.
Другие программисты предпочитают помещать в эти теги как можно меньшие
фрагменты кода ������������������������������������������������������������
PHP���������������������������������������������������������
и именно в тех местах, где нужно воспользоваться динамическими сценариями, а весь остальной документ составлять из стандартного кода
HTML.
Сторонники последнего метода программирования зачастую аргументируют
свой выбор тем, что такой код выполняется быстрее, а сторонники первого метода
утверждают, что увеличение скорости настолько мизерное, что оно не может оправдать дополнительные сложности многочисленных вставок PHP в отдельно взятый
документ.
По мере изучения языка вы, несомненно, определитесь в своих стилевых предпочтениях при создании разработок на PHP�����������������������������������
��������������������������������������
, но для упрощения примеров, приводимых в этой книге, я свел количество переходов между PHP�����������������
��������������������
��������������
HTML����������
к минимуму, в среднем к одному-двум переходам на один документ.
Кстати, существует и несколько иной вариант синтаксиса PHP. Если поискать
примеры PHP������������������������������������������������������������������
���������������������������������������������������������������������
-кода в Интернете, то можно встретить код, где используется следующий синтаксис открывающего и закрывающего тегов:


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

68

Глава 3. Введение в PHP

его использовать, поскольку он несовместим с ��������������������������������
XML�����������������������������
и в настоящее время его применение не приветствуется (это значит, что он больше не рекомендуется и может
быть удален в будущих версиях).
Если в файле содержится только код PHP, то закрывающий тег ?> можно опустить. Именно
так и нужно делать, чтобы гарантировать отсутствие в файлах PHP���������������������
������������������������
лишнего пустого пространства (что имеет особую важность при написании объектно-ориентированного кода).

Примеры в этой книге
Чтобы вы не тратили время на набор примеров, приводимых в этой книге, все они
заархивированы на сайте по адресу http://lpmj.net, откуда можно загрузить файл
2nd_edition_examples.zip, щелкнув на ссылке Download Examples (Загрузить примеры), которая находится в верхней части страницы (рис. 3.1).

Рис. 3.1. Примеры, приводимые в этой книге, можно просмотреть по адресу http://lpmj.net

Все примеры хранятся под номерами и сгруппированы по главам (например,
example3-1.php). Кроме того, на сайте имеется архив, а в нем дополнительно есть
папка named_examples, где можно найти все примеры, которые предлагалось со-

хранять в файлах с конкретными именами (как в показанном далее примере 3.4,
который нужно будет сохранить в файле с именем test1.php).

Структура PHP

69

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

Комментарии
Существует два способа добавления комментариев к коду PHP�������������������
����������������������
. Первый, предусматривающий размещение в начале строки двух прямых слешей, превращает в комментарий отдельную строку:
// Это комментарий

Он хорошо подходит для временного исключения из программы строки кода,
являющейся источником ошибок. Например, такой способ комментирования можно применить для того, чтобы скрыть строку кода до тех пор, пока в ней не возникнет необходимость:
// echo "X equals $x";

Такой комментарий можно также вставить сразу же после строки кода, чтобы
описать ее действие:
$x += 10; // Увеличение значения $x на 10

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


Для открытия и закрытия комментария можно воспользоваться парами символов /* и */ практически в любом произвольно выбранном месте кода. Если не все,
то большинство программистов используют эту конструкцию для временного
превращения в комментарий целого неработоспособного раздела кода или такого
раздела, который по тем или иным причинам нежелательно интерпретировать.
Типичная ошибка — применение пар символов /* и */ для того, чтобы закомментировать
большой фрагмент кода, уже содержащий закомментированную область, в которой используются эти же пары символов. Комментарии не могут быть вложенными друг в друга, поскольку PHP-интерпретатор не поймет, где заканчивается комментарий, и выведет на экран
сообщение об ошибке. Но если вы используете редактор программ или интегрированную
среду разработки с подсветкой синтаксиса, то ошибку такого рода нетрудно будет заметить.

70

Глава 3. Введение в PHP

Основной синтаксис
PHP — очень простой язык, уходящий своими корнями в языки C и Perl, но все же
больше похожий на �����������������������������������������������������������
Java�������������������������������������������������������
. Он очень гибок, но существует несколько правил, относящихся к его синтаксису и структуре, которые следует изучить.

Точки с запятыми
В предыдущих примерах можно было заметить, что команды PHP завершаются
точкой с запятой:
$x += 10;

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

Символ $
Символ $ используется в разных языках программирования в различных целях.
Например, в языке BASIC символ $ применялся в качестве завершения имен переменных, чтобы показать, что они относятся к строкам.
А в PHP символ $ должен ставиться перед именами всех переменных. Это нужно для того, чтобы PHP-парсер работал быстрее, сразу же понимая, что имеет дело
с переменной. К какому бы типу ни относились переменные — к числам, строкам
или массивам, все они должны выглядеть так, как показано в примере 3.3.
Пример 3.3. Три разновидности присваивания значений переменным


Вот, собственно, и весь синтаксис, который нужно усвоить. В отличие от языков,
в которых отношение к способам отступа текста программы и размещения кода
очень строгое (например, от Python), PHP дает полную свободу использования
(или игнорирования) любых отступов и любого количества пробелов по вашему
усмотрению. В действительности же разумное использование того, что называется
свободным пространством, обычно поощряется (наряду с всесторонним комментированием), поскольку помогает разобраться в собственном коде, когда к нему
приходится возвращаться по прошествии некоторого времени. Это помогает и другим программистам, вынужденным поддерживать ваш код.

Переменные
Понять, что такое переменные PHP, поможет простая метафора. Думайте о них как
о небольших (или больших) спичечных коробках! Именно как о спичечных коробках, которые вы раскрасили и на которых написали некие имена.

Структура PHP

71

Строковые переменные
Представьте, что у вас есть коробок, на котором написано слово username (имя пользователя). Затем вы пишете на клочке бумаги Fred Smith и кладете эту бумажку
в коробок (рис. 3.2). Этот процесс похож на присваивание переменной строкового
значения:
$username = "Fred Smith";

Рис. 3.2. Переменные можно представить в виде спичечного коробка,
содержащего какие-то предметы

Кавычки служат признаком того, что Fred Smith является строкой символов.
Каждую строку нужно заключать либо в двойные, либо в одинарные кавычки
(апострофы). Между этими двумя видами кавычек есть весьма существенное различие, которое будет рассмотрено далее.
Когда хочется посмотреть, что находится внутри коробка, вы его открываете,
вынимаете бумажку и читаете, что на ней написано. В �������������������������
PHP����������������������
подобное действие выглядит следующим образом:
echo $username;

Можно также присвоить содержимое другой переменной (сделать ксерокопию
бумажки и поместить ее в другойкоробок):
$current_user = $username;

Если вы стремитесь самостоятельно освоить работу с ���������������������
PHP������������������
, то можете попробовать вводить примеры, приводимые в этой главе, в интегрированную среду разработки (согласно рекомендациям, которые были даны в конце главы 2), чтобы
тут же посмотреть на результаты, или же можете ввести код примера 3.4 в редактор
программ (который также рассматривался в главе 2) и сохранить этот код в каталоге исходного источника документов вашего сервера под именем test1.php.

72

Глава 3. Введение в PHP

Пример 3.4. Ваша первая PHP-программа


Теперь эту программу можно запустить, введя в адресную строку браузера следующий адрес:
http://localhost/test1.php
Если в ходе установки веб-сервера (рассмотренной в главе 2) вы изменили назначенный
серверу порт на какой-нибудь другой, отличающийся от порта 80, вы должны поместить
номер этого порта в URL в данном и всех последующих примерах из этой книги. Например,
если вы изменили порт на 8080, то предыдущий URL приобретет следующий вид:
http://localhost:8080/test1.php
Не забудьте об этом при тестировании других примеров из книги или при написании собственного кода.

Результатом запуска этого кода будет двойное появление имени Fred Smith,
первое — в результате выполнения команды echo $username, а второе — в результате
выполнения команды echo $current_user.

Числовые переменные
Переменные могут содержать не только строки, но и числа. Если вернуться к аналогии со спичечным коробком, сохранение в переменной $count числа 17 будет
эквивалентно помещению, скажем, 17 бусин в коробок, на котором написано слово count:
$count = 17;

Можно также использовать числа с плавающей точкой (содержащие десятичную
точку); синтаксис остается прежним:
$count = 17.5;

Чтобы узнать о содержимом коробка, его нужно просто открыть и посчитать
бусины. В PHP можно присвоить значение переменной $count другой переменной
или вывести его с помощью браузера на экран, воспользовавшись командой echo.

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

Структура PHP

73

Вдоль всей верхней стороны склеенных вместе коробков напишем слово team
(рис. 3.3). В PHP эквивалентом этому действию будет следующий код:
$team = array('Bill', 'Mary', 'Mike', 'Chris', 'Anne');

Рис. 3.3. Массив похож на несколько склеенных вместе спичечных коробков

Этот синтаксис несколько сложнее рассмотренных ранее инструкций. Код создания массива представляет собой следующую конструкцию:
array();

с пятью строками внутри круглых скобок. Каждая строка заключена в одинарные
кавычки.
Когда потребуется узнать, кто является игроком номер 4, можно воспользоваться следующей командой:
echo $team[3]; // Эта команда отображает имя Chris

Использование в предыдущем примере числа 3, а не 4 обусловлено тем, что
первый элемент PHP-массива является, как правило, нулевым, поэтому номера
игроков распределяются в интервале от 0 до 4.

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

74

Глава 3. Введение в PHP

спичечных коробков, вообразите себе девять коробков, склеенных в матрицу, состоящую из трех строк и трех столбцов (рис. 3.4).

Рис. 3.4. Многомерный массив, смоделированный с помощью коробков

Теперь для каждого хода можно класть в нужные коробки клочки бумаги с крестиком или ноликом. Чтобы сделать это в коде PHP, необходимо создать массив,
содержащий три других массива, как в примере 3.5, в котором массив создается для
отображения уже ведущейся игры.
Пример 3.5. Определение двумерного массива


Мы сделали еще один шаг к усложнению, но смысл его нетрудно понять, если
усвоен основной синтаксис массива. Здесь три конструкции array() вложены во
внешнюю по отношению к ним конструкцию array().
Для возвращения в дальнейшем третьего элемента во второй строке этого массива
можно воспользоваться следующей PHP-командой, которая отобразит символ «x»:
echo $oxo[1][2];

Не забывайте о том, что отсчет индексов массива (указателей на элементы внутри массива)
начинается с нуля, а не с единицы, поэтому в предыдущей команде индекс [1] ссылается на
второй из трех массивов, а индекс [2] — на третью позицию внутри этого массива. Эта команда вернет содержимое третьего слева и второго сверху коробка.

Структура PHP

75

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

Правила присваивания имен переменным
При создании PHP-переменных следует придерживаться четырех правил.
 Имена переменных должны начинаться с буквы или с символа _ (подчеркива-

ния).
 Имена переменных могут содержать только символы: a–z, A–Z, 0–9 и _ (под-

черкивание).
 Имена переменных не должны включать в себя пробелы. Если имя переменной

нужно составить более чем из одного слова, то в качестве разделителя следует
использовать символ подчеркивания (например, $user_name).
 Имена переменных чувствительны к регистру символов. Переменная $High_Score
отличается от переменной $high_score.

Чтобы позволить использование ASCII-символов, включающих диакритические знаки,
PHP также поддерживает в именах переменных байты от 127 и до 255. Но пока ваш код
не будет поддерживаться только теми программистами, которые знакомы с такими символами, от их применения лучше отказаться, поскольку программисты, использующие английские раскладки клавиатуры, будут испытывать трудности при доступе к таким символам.

Операторы
Операторы — это математические, строковые, логические команды и команды
сравнения, такие как «плюс», «минус», «умножить» и «разделить». Код PHP во
многом похож на обычные арифметические записи. Например, в результате работы следующего оператора выводится число 8:
echo 6 + 2;

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

Арифметические операторы
Арифметические операторы проделывают вполне ожидаемую работу. Они применяются для выполнения математических операций. Их можно использовать для
проведения четырех основных операций (сложения, вычитания, умножения и деления), а также для нахождения модуля (остатка от деления) и увеличения или
уменьшения значения на единицу (табл. 3.1).

76

Глава 3. Введение в PHP
Таблица 3.1. Арифметические операторы

Оператор

Описание

Пример

+

Сложение

$j + 1



Вычитание

$j – 6

*

Умножение

$j * 11

/

Деление

$j / 4

%

Модуль (остаток от деления)

$j % 9

++

Инкремент (приращение)

++$j

––

Декремент (отрицательное приращение)

––$j

Операторы присваивания
Эти операторы используются для присваивания значений переменным. К ним
относится самый простой оператор =, а также операторы +=, –= и т. д. (табл. 3.2).
Оператор += вместо полного замещения находящегося слева значения добавляет
к нему значение, которое находится справа от него. Итак, если переменная $count
имела начальное значение 5, то оператор:
$count += 1;

устанавливает значение $count равным 6 точно так же, как более привычный оператор присваивания:
$count = $count + 1;
Таблица 3.2. Операторы присваивания
Оператор

Пример

Эквивалент

=

$j = 15

$j = 15

+=

$j += 5

$j = $j + 5

–=

$j –= 3

$j = $j – 3

*=

$j *= 8

$j = $j * 8

/=

$j /= 16

$j = $j / 16

.=

$j .= $k

$j = $j . $k

%=

$j %= 4

$j = $j % 4

У строк есть собственный оператор, точка (.), который более подробно будет
рассмотрен в разделе «Объединение строк».

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

77

Структура PHP
Таблица 3.3. Операторы сравнения
Оператор

Описание

Пример

==

Равно

$j == 4

!=

Не равно

$j != 21

>

Больше

$j > 3

<

Меньше

$j < 100

>=

Больше или равно

$j >= 15

10

or

Низкоприоритетное ИЛИ

$j < 5 or $j > 10

!

НЕ

! ($j == $k)

xor

Исключающее ИЛИ

$j xor $k

78

Глава 3. Введение в PHP

Заметьте, что оператор && обычно взаимозаменяем с оператором and; то же самое
справедливо и для операторов || и or. Но у операторов and и or более низкий приоритет, поэтому в некоторых случаях, для того чтобы принудительно расставить
приоритеты, могут понадобиться дополнительные круглые скобки. В то же время
бывают случаи, когда применимы только операторы and или or, как в следующем
предложении, использующем оператор or:
mysql_select_db($database) or die("Невозможно выбрать базу данных");

Наиболее непривычным из этих операторов является xor, предназначенный для
операции исключающего ИЛИ, который возвращает истинное значение TRUE, если
любое из входных значений истинно, и возвращает ложное значение FALSE, если оба
они имеют значение TRUE или FALSE. Чтобы понять его работу, представьте, что хотите изобрести чистящее средство для дома. Как аммиак (ammonia), так и хлорка (bleach)
обладают хорошими чистящими свойствами, поэтому нужно, чтобы ваше средство
содержало одно из этих веществ. Но оба они не могут в нем присутствовать, поскольку их сочетание опасно. В PHP это можно представить в следующем виде:
$ingredient = $ammonia xor $bleach;

В представленном фрагменте, если любая из двух переменных, $ammonia или
$bleach, имеет значение TRUE, то значение переменной $ingredient также будет установлено в TRUE. Но если обе они имеют значение TRUE или значение FALSE, то значение переменной $ingredient будет установлено в FALSE.

Присваивание значений переменным
Синтаксис присваивания значения переменной всегда имеет вид переменная =
значение. Для передачи значения другой переменной он имеет немного иной вид
другая_переменная = переменная.
Есть еще несколько дополнительных операторов присваивания, которые могут
оказаться полезными. Например, нам уже встречался оператор:
$x += 10;

Он предписывает PHP-парсеру добавить значение, расположенное справа от
него (в данном случае это значение равно 10), к значению переменной $x. Подобным
образом можно вычесть значение:
$y -= 10;

Увеличение и уменьшение значения переменной на единицу
Добавление или вычитание единицы — настолько часто встречающаяся операция, что PHP предоставляет для этого специальные операторы. Вместо операторов
+= и -= можно воспользоваться одним из следующих операторов:
++$x;
--$y;

В сочетании с проверкой (инструкцией if) можно воспользоваться таким кодом:
if (++$x == 10) echo $x;

Структура PHP

79

Этот код предписывает PHP сначала увеличить значение переменной $x на
единицу, а затем проверить, не имеет ли она значение 10; если переменная имеет
такое значение, его следует вывести на экран. Можно также потребовать от PHP
увеличить значение переменной на единицу (или, как в следующем примере,
уменьшить на единицу) после того, как ее значение будет проверено:
if ($y-- == 0) echo $y;

что дает несколько иной результат. Предположим, что первоначальное значение
переменной $y до выполнения оператора было равно нулю. Операция сравнения
вернет результат TRUE, но после того, как она будет проведена, переменной $y
будет присвоено значение –1. Тогда что же отобразит инструкция echo: 0 или –1?
Попробуйте догадаться, а потом, чтобы подтвердить свою догадку, испытайте
работу инструкции в PHP-процессоре. Поскольку такая комбинация операторов
может вас запутать, ее можно применять только в качестве обучающего примера,
но ни в коем случае не рассматривать в качестве приемлемого стиля программирования.
Короче говоря, когда именно увеличено или уменьшено на единицу значение
переменной, до или после проверки, зависит от того, где помещен оператор инкремента или декремента — перед именем переменной или после него.
Кстати, правильный ответ на предыдущий вопрос таков: инструкция echo отобразит результат –1, потому что значение переменной $y было уменьшено на единицу сразу же после того, как к ней получила доступ инструкция if, и до того, как
к ней получила доступ инструкция echo.

Объединение строк
При объединении строк, когда к одной строке символов добавляется другая строка, используется символ точки (.). Самый простой способ объединения строк выглядит следующим образом:
echo "У вас " . $msgs . " сообщений.";

Если предположить, что переменной $msgs присвоено значение 5, то эта строка
кода выведет следующую информацию:
У вас 5 сообщений.

Так же как с помощью оператора += можно добавить значение к числовой переменной, с помощью оператора .= можно добавить одну строку к другой:
$bulletin .= $newsflash;

В данном случае, если в переменной $bulletin содержится сводка новостей,
а в переменной $newsflash — экстренное сообщение, команда добавляет это сообщение к сводке новостей, и теперь переменная $bulletin включает в себя обе строки
текста.

Типы строк
В PHP поддерживаются два типа строк, которые обозначаются типом использу­
емых кавычек. Если требуется присвоить переменной значение текстовой строки,

80

Глава 3. Введение в PHP

сохраняя ее точное содержимое, нужно воспользоваться одинарными кавычками
(апострофами):
$info = 'Предваряйте имена переменных символом $, как в данном примере: $variable';

В данном случае переменной $info присваивается каждый символ, находящийся внутри строки в одинарных кавычках. Если воспользоваться двойными кавычками, то PHP попытается вычислить $variable и получить значение переменной.
В то же время, если требуется включить в состав строки значение переменной,
используется строка, заключенная в двойные кавычки:
echo "На этой неделе ваш профиль просмотрело $count человек ";

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

Изменение предназначения символов
Иногда в строке должны содержаться символы, которые имеют специальное предназначение и могут быть неправильно интерпретированы. Например, следующая
строка кода не будет работать, потому что вторая кавычка (апостроф), встреченная
в слове spelling's, укажет PHP��������������������������������������������������
�����������������������������������������������������
-парсеру на то, что достигнут конец строки. Следовательно, вся остальная часть строки будет отвергнута как ошибочная:
$text = 'My spelling's atroshus'; // Ошибочный синтаксис

Для исправления ошибки нужно непосредственно перед вызывающим неоднозначное толкование символом кавычки добавить обратный слеш, чтобы заставить
PHP рассматривать этот символ буквально и не подвергать его интерпретации:
$text = 'My spelling\'s still atroshus';

Этот прием можно применить практически во всех ситуациях, где в противном
случае PHP вернул бы ошибку, пытаясь интерпретировать символ. Например,
следующая строка, заключенная в двойные кавычки, будет присвоена переменной
без ошибок:
$text = "She wrote upon it, \"Return to sender\".";

Кроме того, для вставки в строку различных специальных символов, например
табуляции, новой строки и возврата каретки, могут применяться управляющие
символы: \t, \n и \r соответственно. Вот пример, в котором символы табуляции
используются для разметки заголовка (они включены в строку исключительно для
иллюстрации применения символа обратного слеша, поскольку существуют более
подходящие способы разметки веб-страниц):
$heading = "Дата\tИмя\tПлатеж";

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

Структура PHP

81

жены нелепые последовательности символов \t. Внутри строк, заключенных в одинарные кавычки, в качестве символов с измененным предназначением распознаются только измененный апостроф (\') и сам измененный обратный слеш (\\).

Многострочные команды
Иногда нужно вывести из ��������������������������������������������������
PHP�����������������������������������������������
большой объем текста, а использование нескольких инструкций echo (или print) заняло бы много времени и было бы неразумным.
PHP���������������������������������������������������������������������������
предлагает два удобных средства, предназначенных для того, чтобы справиться с подобной ситуацией. Первое из них состоит в заключении в кавычки нескольких строк, как в примере 3.6. Переменным также можно присвоить значения способом, показанным в примере 3.7.
Пример 3.6. Инструкция echo, использующая несколько строк


Пример 3.7. Многострочное присваивание


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

На практике все это означает, что вам не стоит слишком волноваться за типы
переменных. Им следует просто присвоить значения, имеющие для вас смысл,
��������������������������������������������������������������������������
PHP�����������������������������������������������������������������������
при необходимости их преобразует. Затем, если понадобится извлечь значение, их нужно просто запросить, например, с помощью инструкции echo.

Константы
Константы, как и переменные, хранят информацию для последующего доступа,
за исключением того, что они оправдывают свое название констант (постоянных).
Иными словами, после определения констант их значения устанавливаются для
всей остальной программы и не могут быть изменены.
К примеру, константа может использоваться для хранения местоположения
корневого каталога вашего сервера (папки, содержащей основные файлы вашего
сайта). Определить такую константу можно следующим образом:
define("ROOT_LOCATION", "/usr/local/www/");

Затем для чтения содержимого константы нужно просто сослаться на нее как
на обычную переменную (но не предваряя ее имя знаком доллара):
$directory = ROOT_LOCATION;

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

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

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

85

Структура PHP

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

Описание

__LINE__

Номер текущей строки в файле

__FILE__

Полное путевое имя файла. Если используется внутри инструкции include,
то возвращается имя включенного файла. В версии PHP 4.0.2 __FILE__
всегда содержит абсолютный путь с раскрытыми символическими ссылками,
а в предыдущих версиях при определенных обстоятельствах она может содержать относительный путь

__DIR__

Каталог файла. Если используется внутри инструкции include, то возвращается
каталог включенного файла. Такой же результат дает применение функции
dirname(__FILE__). В этом имени каталога отсутствует замыкающий слеш, если
только этот каталог не является корневым. (Добавлена в PHP 5.3.0)

__FUNCTION__

Имя функции. Начиная с PHP 5, возвращает имя функции, под которым она
была объявлена (с учетом регистра символов). В PHP 4 возвращаемое значение всегда составлено из символов нижнего регистра. (Добавлена в PHP 4.3.0)

__CLASS__

Имя класса. Начиная с PHP 5, возвращает имя класса, под которым он был
объявлен (с учетом регистра символов). В PHP 4 возвращаемое значение
всегда составлено из символов нижнего регистра. (Добавлена в PHP 4.3.0)

__METHOD__

Имя метода класса. Возвращает имя метода, под которым он был объявлен
(с учетом регистра символов). (Добавлена в PHP 5.0.0)

__NAMESPACE__

Имя текущего пространства имен (с учетом регистра символов). Эта константа определена во время компиляции. (Добавлена в PHP 5.3.0)

Эти константы полезны при отладке, когда нужно вставить строку кода, чтобы
понять, до какого места дошло выполнение программы:
echo "Это строка " . __LINE__ . " в файле " . __FILE__;

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

Различие между командами echo и print
Нам уже встречались разнообразные способы использования команды echo для
вывода текста с сервера в браузер. В одних случаях выводится строковый литерал,
в других сначала происходило объединение строк или вычисление значений переменных. Был также показан вывод, распространяющийся на несколько строк.
Но команде echo есть альтернатива, которой также можно воспользоваться:
команда print. Эти две команды очень похожи друг на друга, но print �����������
— конструкция, похожая на функцию, воспринимающую единственный параметр и имеющую
возвращаемое значение (которое всегда равно 1), а echo — в чистом виде конструкция языка PHP.

86

Глава 3. Введение в PHP

В общем, команда echo работает при выводе обычного текста быстрее print, поскольку она не устанавливает возвращаемое значение.
С другой стороны, поскольку она не является функцией, ее, в отличие от print,
нельзя использовать как часть более сложного выражения. В следующем примере
для вывода информации о том, является значение переменной истинным (TRUE)
или ложным (FALSE), используется функция print, но сделать то же самое с помощью
команды echo не представляется возможным, поскольку она выведет на экран сообщение об ошибке синтаксического разбора — Parse error:
$b ? print "TRUE" : print "FALSE";

Использование вопросительного знака — самый простой способ задать вопрос
о том, какое значение имеет переменная $b, истинное или ложное. Команда, которая
располагается слева от двоеточия, выполняется в том случае, если $b имеет истинное значение, а команда, которая располагается справа, выполняется, если $b имеет ложное значение.
Тем не менее в приводимых здесь примерах чаще всего используется команда
echo, и я рекомендую применять именно ее до тех пор, пока вам при PHP-разработке
реально не потребуется задействовать функцию print.

Функции
Функции используются для выделения блоков кода, выполняющих конкретную
задачу. Например, если вам часто приходится искать какие-то данные и выводить
их в определенном формате, то вполне разумно будет обратиться к функции. Код,
выполняющий эту задачу, может занимать всего три строки, но, пока вы не воспользуетесь функцией, необходимость вставлять этот код в программу десятки раз
делает ее неоправданно большой и сложной. А если вы чуть позже захотите изменить формат вывода данных, помещение кода в функцию будет означать, что вам
придется внести изменения только в одном месте программы.
Помещение кода в функцию не только сокращает размер исходного кода и делает его более удобным для чтения, но и дает дополнительные функциональные
возможности (эта игра слов носит преднамеренный характер), поскольку функциям могут передаваться параметры, которые вносят изменения в характер их работы. Функции также могут возвращать значения вызывающему их коду.
Чтобы создать функцию, нужно ее объявить, как показано в примере 3.12.
Пример 3.12. Простое объявление функции


Эта функция использует в качестве входных данных отметку времени системы
UNIX��������������������������������������������������������������������������
(целое число, отображающее дату и время на основе количества секунд, прошедших с нуля часов 1 января 1970 года), а затем вызывает PHP-функцию date

Структура PHP

87

с нужным форматом строки, чтобы вернуть дату в формате «Вторник май 2 2017».
Между стоящими после имени функции круглыми скобками может размещаться
любое количество параметров, но для этой функции выбран прием только одного
параметра. Весь код, который выполняется при последующем вызове функции,
заключается в фигурные скобки.
Чтобы с помощью этой функции вывести сегодняшнюю дату, нужно поместить
в свой код следующий вызов:
echo longdate(time());

В этом вызове для извлечения текущей отметки времени UNIX и передачи ее
только что созданной функции longdate, которая затем возвращает для отображения
соответствующую строку команде echo, используется встроенная PHP-функция
time. Если требуется вывести дату семнадцатидневной давности, нужно сделать
следующий вызов:
echo longdate(time() - 17 * 24 * 60 * 60);

в котором функции longdate передается текущая отметка времени UNIX, уменьшенная
на количество секунд, которое прошло за 17 дней (17 дней ⋅ 24 ч ⋅ 60 мин ⋅ 60 с).
Функции могут также воспринимать несколько параметров и возвращать несколько результатов, используя технологию, которая будет рассмотрена в следующих главах.

Область видимости переменной
Если программа очень длинная, то с подбором подходящих имен переменных
могут возникнуть трудности, но, программируя на PHP, можно определить область видимости переменной. Иными словами, можно, к примеру, указать, что
переменная $temp будет использоваться только внутри конкретной функции, чтобы
забыть о том, что она после возврата из кода функции применяется где-нибудь еще.
Фактически именно такой в �������������������������������������������������
PHP����������������������������������������������
является по умолчанию область видимости переменных.
В качестве альтернативы можно проинформировать PHP о том, что переменная
имеет глобальную область видимости и доступ к ней может быть осуществлен из
любого места программы.

Локальные переменные
Локальные переменные создаются внутри функции, и к ним имеется доступ только
из кода этой функции. Обычно это временные переменные, которые используются
до выхода из функции для хранения частично обработанных результатов.
Одним из наборов локальных переменных является перечень аргументов
функции. В предыдущем разделе была определена функция, воспринимающая
параметр по имени $timestamp. Значение этого параметра действительно только
в теле функции, за пределами этой функции его значение нельзя ни получить,
ни установить.
Чтобы привести еще один пример локальной переменной, рассмотрим функцию
longdate еще раз в немного измененном варианте (пример 3.13).

88

Глава 3. Введение в PHP

Пример 3.13. Расширенная версия функции longdate


В этом примере значение, возвращенное функцией date, присваивается временной переменной $temp, которая затем вставляется в строку, возвращаемую определяемой функцией. Как только будет осуществлен выход из функции, значение
переменной $temp удаляется, как будто она вообще никогда не использовалась.
Теперь, чтобы посмотреть на области видимости переменных в действии, изучим
похожий код, показанный в примере 3.14. Здесь переменная $temp была создана еще
до вызова функции longdate.
Пример 3.14. Неудачная попытка получить доступ к переменной $temp в функции
longdate


Но поскольку переменная $temp не была создана внутри функции longdate,
а также не была передана ей в качестве параметра, функция longdate не может
получить к ней доступ. Поэтому этот фрагмент кода выведет только дату без
предшествующего ей текста. На самом деле сначала будет отображено сообщение
об ошибке, предупреждающее об использовании неопределенной переменной
(Notice: Undefined variable: temp).
Причина в том, что по умолчанию переменные, созданные внутри функции,
являются локальными для этой функции, а переменные, созданные за пределами
любой функции, могут быть доступны только из того кода, который не входит в код
ни одной из функций.
В примерах 3.15 и 3.16 показано несколько способов исправления кода, приведенного в примере 3.14.
Пример 3.15. Решить проблему можно путем переноса ссылки на переменную $temp в ее
локальную область видимости


В примере 3.15 ссылка на $temp перемещена за пределы функции. Эта ссылка
появляется в той же области видимости, в которой была определена переменная.
Пример 3.16. Альтернативное решение: передача $temp в качестве аргумента


В примере 3.16 принято другое решение: передать значение переменной $temp
функции longdate в качестве дополнительного аргумента. Функция longdate считывает это значение во временную переменную, которую она создает под именем
$text, и выводит желаемый результат.
Программисты часто допускают ошибку, забывая об области видимости переменных, поэтому,
если не помнить принципы ее работы, это поможет в отладке некоторых весьма неочевидных
ошибок программного кода. Достаточно сказать, что, если вы не объявили переменную какимнибудь особым образом, ее область видимости ограничена локальным пространством: либо
в пределах кода текущей функции, либо в пределах кода, не принадлежащего никаким функциям, в зависимости от того, где эта переменная была впервые создана или где к ней впервые был получен доступ, внутри функции или за ее пределами.

Глобальные переменные
Бывают случаи, когда требуется переменная, имеющая глобальную область видимости, поскольку нужно, чтобы к ней имелся доступ из всего кода программы.
К тому же некоторые данные могут быть настолько объемными и сложными, что
их не захочется передавать функциям в качестве аргументов.
Чтобы объявить переменную, имеющую глобальную область видимости,
используется ключевое слово global. Предположим, что существует некий способ входа пользователей на ваш сайт и нужно, чтобы весь код программы знал,
с кем он имеет дело — с зарегистрированным пользователем или с гостем. Один
из способов решения этой задачи заключается в создании глобальной переменной $is_logged_in:
global $is_logged_in;

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

90

Глава 3. Введение в PHP

Но пользоваться глобальными переменными нужно с оглядкой. Я рекомендую
создавать их только в том случае, если без них совершенно невозможно добиться
нужного результата. Вообще-то программы, разбитые на небольшие фрагменты
и отдельные данные, содержат меньше ошибок и проще в обслуживании. Если ваша
программа состоит из нескольких тысяч строк кода (а когда-нибудь такое случится) и оказалось, что где-то глобальная переменная имеет неверное значение, то
сколько времени уйдет на поиски кода, который присваивает ей это значение?
Кроме того, если задействуется слишком много глобальных переменных, возникает риск воспользоваться одним из их имен еще раз в локальном пространстве
или по крайней мере полагать, что такая переменная применяется локально, хотя
на самом деле она уже была объявлена в качестве глобальной. Из таких ситуаций
и возникают разные непонятные ошибки.
Иногда я придерживаюсь соглашения о написании имен всех глобальных переменных в верхнем регистре (что совпадает с рекомендациями о написании в этом же регистре имен констант),
чтобы можно было с первого взгляда определить область видимости переменной.

Статические переменные
В пункте «Локальные переменные» выше было упомянуто, что значение переменной стирается сразу же после выхода из функции. Если функция вызывается многократно, она начинает свою работу со свежей копией переменной и ее прежние
установки не имеют никакого значения.
Интересно, а что, если внутри функции есть такая локальная переменная, к которой не должно быть доступа из других частей программы, но значение которой
желательно сохранять до следующего вызова функции? Зачем? Возможно, потому,
что нужен некий счетчик, чтобы следить за количеством вызовов функции. Решение, показанное в примере 3.17, заключается в объявлении статической переменной.
Пример 3.17. Функция, использующая статическую переменную


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

91

Структура PHP

Планируя использование статических переменных, следует учесть, что при
их определении присвоить им результат какого-нибудь выражения невозможно.
Они могут инициализироваться только предопределенными значениями (пример 3.18).
Пример 3.18. Допустимые и недопустимые объявления статических переменных


Суперглобальные переменные
Начиная с версии PHP�������������������������������������������������������
����������������������������������������������������������
4.1.0, стали доступны некоторые предопределенные переменные. Они известны как суперглобальные переменные. Смысл этого названия
заключается в том, что они предоставляются средой окружения ����������������
PHP�������������
и имеют глобальную область видимости внутри программы, то есть доступны абсолютно из
любого ее места.
В этих суперглобальных переменных содержится масса полезной информации о текущей работающей программе и ее окружении (табл. 3.6). Такие переменные имеют структуру ассоциативных массивов, которые будут рассмотрены
в главе 6.
Таблица 3.6. Суперглобальные переменные PHP
Имя суперглобальной
переменной

Ее содержимое

$GLOBALS

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

$_SERVER

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

$_GET

Переменные, которые передаются текущему сценарию методом
HTTP GET

$_POST

Переменные, которые передаются текущему сценарию методом
HTTP POST

$_FILES

Элементы, подгруженные к текущему сценарию методом HTTP POST

$_COOKIE

Переменные, переданные текущему сценарию посредством
HTTP cookies

$_SESSION

Переменные сессии, доступные текущему сценарию

$_REQUEST

Содержимое информации, переданной от браузера; по умолчанию
$_GET, $_POST и $_COOKIE

$_ENV

Переменные, переданные текущему сценарию методом environment

92

Глава 3. Введение в PHP

В именах всех суперглобальных переменных (за исключением $GLOBALS) присутствует один знак подчеркивания и используются только заглавные буквы, поэтому, чтобы избежать путаницы, не следует присваивать своим переменным
имена, оформленные в таком же стиле.
Для иллюстрации порядка применения суперглобальных переменных рассмотрим часть той информации, которая может быть использована сайтами. Среди
многой другой интересной информации, предоставляемой суперглобальными
переменными, есть и ��������������������������������������������������������
URL�����������������������������������������������������
-адрес той страницы, с которой пользователь был перенаправлен на текущую веб-страницу. Эта информация может быть получена следующим образом:
$came_from = $_SERVER['HTTP_REFERRER'];

Как видите, ничего сложного. Если же пользователь зашел непосредственно на
вашу страницу, к примеру набрав ее URL����������������������������������������
�������������������������������������������
-адрес непосредственно в браузере, переменной $came_from будет присвоена пустая строка.

Суперглобальные переменные и проблемы безопасности
Обратите внимание, что суперглобальные переменные часто используются зло­
умышленниками, пытающимися отыскать средства для атаки и вмешательства
в работу вашего сайта. Они загружают в $_POST, $_GET или в другие суперглобальные
переменные вредоносный код, например команды UNIX или MySQL, которые,
если вы по незнанию к ним обратитесь, могут разрушить или отобразить незащищенные данные.
Именно поэтому перед применением суперглобальных переменных их всегда
следует подвергать предварительной обработке. Для этого можно воспользоваться
PHP-функцией htmlentities . Она занимается преобразованием всех символов
в элементы HTML. Например, символы «меньше» и «больше» (< и >) превращаются в строки &lt; и &gt;, то же самое делается для перевода в безопасное состояние
всех кавычек, обратных слешей и т. д.
Поэтому более подходящий способ доступа к $_SERVER (и другим суперглобальным переменным) выглядит следующим образом:
$came_from = htmlentities($_SERVER['HTTP_REFERRER']);
Использование для санации функции htmlentities считается важной практикой не только
в отношении суперглобальных переменных, но и при любых обстоятельствах, в которых
данные, исходящие от пользователя или поступающие из сторонних источников, обрабатываются для получения выходных данных.

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

Вопросы

93

Вопросы
Вопрос 3.1
Какой тег PHP служит основанием для того, чтобы приступить к интерпретации
программного кода? Как выглядит краткая форма этого тега?
Вопрос 3.2
Какие два вида тегов используются для добавления комментариев?
Вопрос 3.3
Какой символ должен стоять в конце каждой инструкции PHP?
Вопрос 3.4
Какой символ используется в начале имен всех переменных PHP?
Вопрос 3.5
Что может храниться в переменных?
Вопрос 3.6
В чем разница между выражениями $variable = 1 и $variable == 1?
Вопрос 3.7
Как вы считаете, почему подчеркивания разрешено использовать в именах переменных (например, $current_user), а дефисы — нет (например, $current-user)?
Вопрос 3.8
Чувствительны ли имена переменных к регистру букв?
Вопрос 3.9
Можно ли в именах переменных использовать пробелы?
Вопрос 3.10
Как преобразовать значение одного типа переменной в значение другого типа
(скажем, строку в число)?
Вопрос 3.11
В чем разница между ++$j и $j++?
Вопрос 3.12
Являются ли взаимозаменяемыми операторы && и and?
Вопрос 3.13
Как создается многострочный вывод: с использованием команды echo или присвоением многострочного значения?
Вопрос 3.14
Можно ли переопределить константу?
Вопрос 3.15
Как изменить исходное предназначение кавычки?
Вопрос 3.16
В чем разница между командами echo и print?

94

Глава 3. Введение в PHP

Вопрос 3.17
Каково назначение функций?
Вопрос 3.18
Как сделать переменную доступной для всего кода PHP-программы?
Вопрос 3.19
Какими двумя способами можно передать всей остальной программе данные,
которые были созданы внутри функции?
Вопрос 3.20
Что является результатом объединения строки с числом?
Ответы на эти вопросы можно найти в приложении А, в разделе «Ответы на
вопросы главы 3».

4

Выражения
и управление процессом
выполнения программы
в PHP

В предыдущей главе уже упоминались темы, которые более полно будут рассмотрены в данной главе, например выбор (ветвление) и создание сложных выражений. В главе 3 мне хотелось сконцентрировать внимание на наиболее общих вопросах синтаксиса и работы в PHP, но при этом невозможно было не затронуть темы
более высокого уровня. А вот теперь можно преподнести вам основы, необходимые
для полноценного использования всех сильных сторон PHP.
В этой главе будет заложен фундамент практики программирования на PHP
и рассмотрены основные способы управления процессом выполнения программы.

Выражения
Начнем с базовой части любого языка программирования — выражения.
Выражение представляет собой сочетание значений, переменных, операторов
и функций, в результатевычисления которого выдается новое значение. Оно знакомо всем, кто когда-либо имел дело с обыкновенной школьной алгеброй:
y = 3(abs(2x) + 4)

что в PHP приобретает следующий вид:
$y = 3 * (abs(2*$x) + 4);

Возвращаемое значение (в данном случае y или $y) может быть числом, строкой
или булевым (логическим) значением (названным так в честь Джорджа Буля,
английского математика и философа XIX века). Первые два типа значений вам уже
должны быть знакомы, поэтому я объясню, что такое третий тип.

TRUE или FALSE?
Элементарное булево значение может быть либо истинным — TRUE, либо ложным — FALSE. Например, выражение 20 > 9 (20 больше 9) является истинным (TRUE),

96

Глава 4. Выражения и управление процессом выполнения программы в PHP

а выражение 5 == 6 (5 равно 6) — ложным (FALSE). (Булевы, или логические, операции могут быть объединены путем использования таких операторов, как И, ИЛИ
и исключающее ИЛИ, то есть AND, OR и XOR, которые будут рассмотрены в этой
главе.)
Обратите внимание, что для имен TRUE и FALSE я использую буквы верхнего регистра.
Это обусловлено тем, что в ���������������������������������������������������������
PHP������������������������������������������������������
они являются предопределенными константами. При желании можно также применять и их версии, составленные из букв нижнего регистра, поскольку они также являются предопределенными константами. Кстати, версия, в которой задействуются буквы нижнего регистра, более надежна, потому что PHP не допускает ее
переопределения, а версия, использующая буквы верхнего регистра, может быть переопределена, и это нужно иметь в виду при импортировании чужого кода.

В примере������������������������������������������������������������������
 �����������������������������������������������������������������
4.1 показаны некоторые простые выражения: два, о которых уже упоминалось, плюс еще два выражения. Для каждой строки выводится буква от a до d,
за которой следуют двоеточие и результат выражения (тег используется в HTML
для переноса и разбивает выходную информацию на четыре строки).
Теперь, когда HTML5 уже полностью вошел в обиход, и XHTML не планируется на замену
HTML, больше уже не нужно использовать самозакрывающуюся форму тега ,
или любых пустых элементов (не имеющих закрывающих тегов), поскольку теперь символ / необязателен. Поэтому в данной книге мой выбор пал на использование более простого стиля. Если же где-нибудь сделать непустые теги �������������������������������
HTML���������������������������
самозакрывающимися (например, ), в HTML5 они не сработают, потому что символ / будет проигнорирован, и их
нужно будет, к примеру, заменить структурой ... . Но при работе с XHTML
нужно по-прежнему пользоваться формой HTML-синтаксиса .

Пример 4.1. Четыре простых булевых выражения


"a:
"b:
"c:
"d:

["
["
["
["

.
.
.
.

(20 >
(5 ==
(1 ==
(1 ==

9)
6)
0)
1)

.
.
.
.

"]";
"]";
"]";
"]";

Этот код выведет следующую информацию:
a:
b:
c:
d:

[1]
[]
[]
[1]

Обратите внимание, что результаты вычисления обоих выражений, a: и d:, являются истинными (TRUE), имеющими значение 1. А результаты вычисления выражений b: и c: ложны (FALSE) и вообще не показывают никакого значения, поскольку
в PHP константа FALSE определена как NULL (ничто). Чтобы убедиться в этом, можно ввести код, приведенный в примере 4.2.

97

Выражения

Пример 4.2. Вывод значений TRUE и FALSE


Этот код выведет следующую информацию:
a: [1]
b: []

Кстати, в некоторых языках константа FALSE может быть определена как 0 или
даже как –1, поэтому в каждом языке ее определение стоит проверить.

Литералы и переменные
Простейшей формой выражения является литерал, означающий нечто, вычисляющееся само в себя, например число 73 или строка ���������������������������
Hello����������������������
. Выражение может также быть просто переменной, которая вычисляется в присвоенное этой переменной
значение. Обе формы относятся к типам выражений, поскольку они возвращают
значение.
В примере 4.3 показаны три литерала и две переменные, все они возвращают
значения, хотя и разных типов.
Пример 4.3. Литералы и переменные


.
.
.
.
.

"";
"";
"";
"";
"";

//
//
//
//
//

Числовой литерал
Строковый литерал
Литерал константы
Строковая переменная
Числовая переменная

Как и ожидалось, в выходной информации вы увидите возвращаемое значение
всех этих выражений, за исключением выражения c:, результат вычисления которого является FALSE и ничего не возвращает:
a:
b:
c:
d:
e:

73
Hello
Brian
37

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

98

Глава 4. Выражения и управление процессом выполнения программы в PHP

В первой из них осуществляется присваивание результата выражения 366 - $day_number
переменной $days_to_new_year, а во второй выводится приветственное сообщение,
если выражение $days_to_new_year < 30 вычисляется как TRUE.
Пример 4.4. Выражение и инструкция


// Выражение
// Инструкция

Операторы
В PHP имеется множество мощных операторов, от арифметических, строковых
и логических до операторов присваивания, сравнения и многих других операторов
(табл. 4.1).
Таблица 4.1. Типы операторов PHP
Оператор

Описание

Пример

Арифметический

Элементарная математика

$a + $b

Для работы с массивом

Слияние массивов

$a + $b

Присваивания

Присваивание значений

$a = $b + 23

Поразрядный

Манипуляция битами в байте

12 ^ 9

Сравнения

Сравнение двух значений

$a < $b

Выполнения

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

`ls -al`

Инкремента/декремента

Добавление или вычитание единицы

$a++

Логический

Выполнение булевых сравнений

$a and $b

Строковый

Объединение строк

$a . $b

Различные типы операторов воспринимают разное количество операндов.
 Унарные операторы, такие как оператор инкремента ($a++) или изменения знака числа (-$a), воспринимают только один операнд.
 Бинарные операторы, представленные большим количеством операторов PHP,
включая операторы сложения, вычитания, умножения и деления, воспринимают два операнда.
 Один трехкомпонентный оператор, имеющий форму x ? y : z. По сути, это состоящая из трех частей однострочная инструкция if, в которой осуществляется
выбор между двумя выражениями, зависящий от результата вычисления третьего выражения.

99

Операторы

Приоритетность операторов
Если бы у всех операторов был один и тот же уровень приоритета, то они обрабатывались бы в том порядке, в котором встречались интерпретатору. Фактически
многие операторы имеют одинаковый уровень приоритета, что и показано в примере 4.5.
Пример 4.5.
1 + 2 + 3 2 - 4 + 5 +
5 + 2 - 4 +

Три
4 +
3 +
1 +

эквивалентных выражения
5
1
3

Из примера видно, что, несмотря на перестановку чисел (и предшествующих
им операторов), результат каждого выражения имеет значение 7, поскольку у операторов «плюс» и «минус» одинаковый уровень приоритета. Можно проделать
то же самое с операторами умножения и деления (пример 4.6).
Пример 4.6.
1 * 2 * 3 /
2 / 4 * 5 *
5 * 2 / 4 *

Три
4 *
3 *
1 *

выражения, которые также являются эквивалентными
5
1
3

В этом примере получаемое значение всегда равно 7,5. Но все меняется, когда
в выражении присутствуют операторы с разными уровнями приоритета, как в примере 4.7.
Пример 4.7.
приоритета
1 + 2 * 3 2 - 4 * 5 *
5 + 2 - 4 +

Три выражения, в которых присутствуют операторы с разными уровнями
4 * 5
3 + 1
1 * 3

Если бы не существовало приоритетности операторов, то в результате вычисления этих выражений получались бы числа 25, –29 и 12 соответственно. Но поскольку операторы умножения и деления имеют более высокий уровень приоритета по сравнению с операторами сложения и вычитания, вокруг частей выражения
с их участием предполагается наличие скобок, и если их сделать видимыми, выражения будут выглядеть так, как показано в примере 4.8.
Пример 4.8. Три выражения, в которых отображены предполагаемые скобки
1 + (2 * 3) - (4 * 5)
2 - (4 * 5 * 3) + 1
5 + 2 - 4 + (1 * 3)

Очевидно, что PHP должен сначала вычислить подвыражения, заключенные
в скобки, чтобы получились частично вычисленные выражения, показанные в примере 4.9.
Пример 4.9. Выражения после вычисления подвыражений в скобках
1 + (6) - (20)
2 - (60) + 1
5 + 2 - 4 + (3)

100

Глава 4. Выражения и управление процессом выполнения программы в PHP

Окончательный результат вычисления этих выражений равен соответственно –13, –57 и 6 (что абсолютно отличается от результатов 25, –29 и 12, которые мы
увидели бы при отсутствии приоритетности операторов).
Разумеется, исходную приоритетность операторов можно отменить, расставив собственные скобки, и принудительно получить результаты, показанные
в самом начале, которые были бы получены в отсутствие приоритетности операторов (пример 4.10).
Пример 4.10. Принудительное выполнение вычислений справа налево
((1 + 2) * 3 - 4) * 5
(2 - 4) * 5 * 3 + 1
(5 + 2 - 4 + 1) * 3

Теперь, если скобки расставлены правильно, мы увидим значения 25, –29 и 12
соответственно.
В табл.�������������������������������������������������������������������
 ������������������������������������������������������������������
4.2 перечислены операторы ����������������������������������������
PHP�������������������������������������
в порядке их приоритетности от самого высокого до самого низкого уровня.
Таблица 4.2. Операторы PHP, расположенные по уровню их приоритетности (сверху вниз)
Оператор(ы)

Тип

()

Скобки

++ ––

Инкремент/декремент

!

Логический

*/%

Арифметические

+-

Арифметические и строковые

>

Побитовые

< >=

Сравнения

== != === !==

Сравнения

&

Поразрядный (и ссылочный)

^

Поразрядный

|

Поразрядный

&&

Логический

||

Логический

?:

Трехкомпонентный

= += –= *= /= .= %= &= != ^= =

Присваивания

and

Логический

xor

Логический

or

Логический

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

101

Операторы

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

Описание

Взаимосвязанность

CLONE NEW

Создание нового объекта

Отсутствует

< = == != === !==


Сравнение

Отсутствует

!

Логическое НЕ

Правая

~

Поразрядное НЕ

Правая

++ −−

Инкремент и декремент

Правая

(int)

Преобразование в целое число

Правая

(double) (float) (real)

Преобразование в число с плавающей
точкой

Правая

(string)

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

Правая

(array)

Преобразование в массив

Правая

(object)

Преобразование в объект

Правая

@

Подавление сообщения об ошибке

Правая

= += −= *= /=

Присваивание

Правая

.= %= &= |= ^= =

Присваивание

Правая

+

Сложение и унарный плюс

Левая



Вычитание и отрицание

Левая

*

Умножение

Левая

/

Деление

Левая

%

Модуль

Левая

Конкатенация строк

Левая

> & ^ |

Поразрядные операции

Левая

?:

Операция с тремя операндами

Левая

|| && and or xor

Логические операции

Левая

,

Разделение

Левая

Рассмотрим оператор присваивания, показанный в примере 4.11, где всем трем
переменным присваивается значение 0.
Пример 4.11. Оператор множественного присваивания


102

Глава 4. Выражения и управление процессом выполнения программы в PHP

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

Операторы отношения
Операторы отношения проверяют значения двух операндов и возвращают логический результат, равный либо TRUE, либо FALSE. Существует три типа операторов
отношения: операторы равенства, сравнения и логические операторы.

Операторы равенства
С оператором равенства == (двойным знаком равенства) мы уже не раз встречались
в этой книге. Его не следует путать с оператором присваивания = (одинарным знаком равенства). В примере 4.12 первый оператор присваивает значение, а второй
проверяет его на равенство.
Пример 4.12. Присваивание значения и проверка его на равенство


Как видно из примера, возвращая значение TRUE или FALSE, оператор сравнения
позволяет проверять условия, используя инструкцию if. Но это еще не все, поскольку �������������������������������������������������������������������
PHP����������������������������������������������������������������
является языком со слабой типизацией. Если два операнда выражения равенства имеют разные типы, PHP преобразует их к тому типу, который
имеет для него наибольший смысл.
К примеру, любые строки, составленные полностью из цифр, при сравнении
с числами будут преобразованы в числа. В примере 4.13 переменные $a и $b являются двумя разными строками, и поэтому вряд ли стоило ожидать, что какая-то из
инструкций if выведет результат.
Пример 4.13. Операторы равенства и тождественности


Но если запустить этот пример, то он выведет число. Это означает, что результат вычисления первой инструкции if является TRUE. Причина в том, что обе

103

Операторы

строки сначала конвертируются в числа, и 1000 имеет такое же числовое значение, что и +1000.
В отличие от первой, во второй инструкции if используется оператор тождественности — тройной знак равенства, который удерживает PHP�������������
����������������
от автоматического преобразования типов. Поэтому переменные $a и $b сравниваются как
строки и теперь считаются отличающимися друг от друга, и на экран ничего не выводится.
Как и в случае с принудительным заданием уровня приоритетности операторов,
если возникнут сомнения в том, будет ли PHP конвертировать типы операндов,
для отмены такого поведения интерпретатора можно воспользоваться оператором
тождественности.
Аналогично применению оператора равенства для определения равенства
операндов можно проверить их на неравенство, используя оператор неравенства !=. Пример 4.14 является измененным примером 4.13, в котором операторы
равенства и тождественности были заменены противоположными им операторами.
Пример 4.14. Операторы неравенства и нетождественности


Как, наверное, и ожидалось, первая инструкция if не выводит на экран число 1,
потому что в коде ставится вопрос о неравенстве числовых значений переменных $a и $b. Вместо этого будет выведено число 2, поскольку вторая инструкция if
ставит вопрос о нетождественности прежнего типа операндов переменных $a и $b,
и ответом будет TRUE, потому что они не тождественны.

Операторы сравнения
Используя операторы сравнения, можно расширить круг проверок, не ограничивая
его только равенством и неравенством. ����������������������������������������
PHP�������������������������������������
предоставляет вам для этого операторы > (больше), < (меньше), >= (больше или равно) и

Этот пример выводит на экран NULL, 1, 1, NULL. Это значит, что только вторая
и третья инструкции echo получают в результате вычисления значение TRUE. (Следует помнить, что NULL, или ничто, отображает значение FALSE.) Такой результат
получается, потому что оператору AND, чтобы вернуть значение TRUE, нужно, чтобы
оба операнда имели истинное значение, а четвертый оператор проводит над значением переменной $a операцию NOT, превращая его из TRUE (значения, равного единице) в FALSE. Если есть желание поэкспериментировать, запустите этот код, присваивая переменным $a и $b разные значения, выбранные из 1 и 0.

105

Операторы

Занимаясь программированием, следует помнить, что у операторов AND и OR более низкий
уровень приоритета, чем у других версий этих операторов — && и ||. Поэтому в сложных
выражениях более безопасным будет, наверное, применение операторов && и ||.

Использование в инструкции if оператора OR может стать причиной непредвиденных проблем, поскольку второй операнд не будет вычисляться, если в результате вычисления первого операнда уже получено значение TRUE. В примере 4.17
функция getnext никогда не будет вызвана, если переменная $finished имеет значение 1.
Пример 4.17. Инструкция, использующая оператор OR


Если нужно, чтобы функция getnext вызывалась для каждой инструкции if,
следует внести в код изменения, показанные в примере 4.18.
Пример 4.18. Изменения в инструкции if ... OR, гарантирующие вызов функции
getnext


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

В табл. 4.5 показаны все допустимые варианты использования логических операторов. Следует заметить, что !TRUE является эквивалентом FALSE, а !FALSE — эквивалентом TRUE.
Таблица 4.5. Все логические выражения, допустимые в PHP
Входные данные

Операторы и результаты

a

b

AND

OR

XOR

TRUE

TRUE

TRUE

TRUE

FALSE

TRUE

FALSE

FALSE

TRUE

TRUE

FALSE

TRUE

FALSE

TRUE

TRUE

FALSE

FALSE

FALSE

FALSE

FALSE

106

Глава 4. Выражения и управление процессом выполнения программы в PHP

Условия
Условия изменяют процесс выполнения программы. Они позволяют задавать конкретные вопросы и по-разному реагировать на полученные ответы. Условия играют важную роль при разработке динамических веб-страниц��������������������
 �������������������
— основной цели использования PHP, поскольку облегчают создание разных вариантов выводимой
при каждом просмотре веб-страницы информации.
Существует три типа нециклических условных инструкций: if, switch и ?. Называя
их нециклическими, я имел в виду, что после действий, инициированных инструкцией, процесс выполнения программы продолжается, а при использовании циклических условных инструкций (которые еще предстоит рассмотреть) код выполняется снова и снова до тех пор, пока не будет соблюдено определенное условие.

Инструкция if
Процесс выполнения программы можно представить себе как езду на машине по
однополосной магистрали. Эта магистраль большей частью прямолинейна, но иногда встречаются различные дорожные знаки, задающие направление движения.
Когда встречается инструкция if, можно представить, что машина подошла
к знаку объезда, предписаниям которого необходимо следовать, когда определенные
условия вычисляются как TRUE. При этом вы съезжаете с магистрали и следуете по
объездному пути до тех пор, пока не вернетесь снова на магистраль и не продолжите движение по исходному маршруту. Или же, если условие не вычисляется как
TRUE, вы игнорируете объезд и продолжаете ехать по магистрали как ни в чем не бывало (рис. 4.1).

Рис. 4.1. Процесс выполнения программы похож
на движение по однополосной магистрали

Содержимым условной инструкции if может быть любое допустимое PHPвыражение, включая равенство, сравнение, проверку на нуль и NULL и даже зна-

Условия

107

чения, возвращаемые функциями (как встроенными, так и созданными самостоятельно).
Действия, предпринимаемые при вычислении условия в TRUE, помещаются, как
правило, в фигурные скобки { }. Но эти скобки можно опустить, если нужно выполнить всего одну инструкцию. Тем не менее, если всегда использовать фигурные
скобки, можно избежать «охоты» на трудно отслеживаемые ошибки, возникающие,
к примеру, когда к условной инструкции добавляется еще одна строка, но забывается о необходимости добавить фигурные скобки, из-за чего строка не вычисляется.
(Учтите, что в целях экономии места и доходчивости материала, если в примерах,
приводимых в книге, была всего одна исполняемая инструкция, я не следовал
этому совету и опускал фигурные скобки.)
В примере����������������������������������������������������������������
 ���������������������������������������������������������������
4.19 следует представить, что подошел конец месяца и нужно платить по всем счетам, поэтому вы проводите некоторые операции с банковским
счетом.
Пример 4.19. Инструкция if, в которой используются фигурные скобки


В этом примере проверяется, не стал ли баланс ниже $100 (или 100 единиц
другой используемой вами валюты). Если баланс стал ниже этой суммы, вы платите сами себе $1000, а затем прибавляете их к балансу. (Хорошо бы так просто
зарабатывать деньги!)
Если баланс счета в банке равен $100 или превышает эту сумму, условные инструкции игнорируются и процесс выполнения программы переходит на следу­
ющую строку кода (которая здесь не показана).
Одни разработчики предпочитают ставить первую фигурную скобку справа от
условного выражения, а другие начинают с нее новую строку. В этой книге открывающая фигурная скобка располагается обычно на новой строке. Подойдет любой
из этих вариантов, поскольку PHP позволяет оставлять на ваше усмотрение какие
угодно свободные пространства (пробелы, символы новых строк и табуляции).
Но код будет легче читаться и отлаживаться, если у каждого уровня условий будет
свой отступ, сформированный с помощью символа табуляции.

Инструкция else
Бывают случаи, когда условие не вычисляется как TRUE, но вам не хочется сразу же
продолжать выполнение основного кода программы, а вместо этого нужно сделать
что-либо другое. Тогда пригодится инструкция else. С ее помощью на вашей магистрали можно организовать второй объезд, показанный на рис. 4.2.
Если при использовании конструкции if...else условие вычисляется как TRUE,
то выполняется первая условная инструкция. Но если это условие вычисляется

108

Глава 4. Выражения и управление процессом выполнения программы в PHP

как FALSE, то выполняется вторая условная инструкция. Для выполнения должна
быть выбрана одна из этих двух инструкций, но обе сразу они не будут выполнены ни при каких условиях, и обязательно будет выполнена хотя бы одна из них.
Использование конструкции if...else показано в примере 4.20.
Пример 4.20. Конструкция if...else, в которой используются фигурные скобки


Рис. 4.2. Теперь у магистрали есть объезд if и объезд else

Условия

109

Если в этом примере будет установлено, что в банке лежит $100 или более, то
выполняется инструкция else, с помощью которой часть этих денег перемещается
на ваш сберегательный счет.
Точно так же, как и у if, если у инструкции else есть только одна условная инструкция, то фигурные скобки можно не ставить. (Хотя фигурные скобки рекомендуется использовать в любом случае. Во-первых, при их наличии проще разобраться в коде, а во-вторых, они облегчают последующее добавление инструкций
к этому ветвлению.)

Инструкция elseif
Случается, что на основе последовательности условий нужно осуществить сразу
несколько действий. Достичь желаемого результата можно, используя инструкцию
elseif. Можно предположить, что она похожа на инструкцию else, за исключением
того, что до кода условия вставляется еще одно условное выражение. Полноценная
конструкция if...elseif...else показана в примере 4.21.
Пример 4.21. Конструкция if...elseif...else, в которой используются фигурные
скобки


В этом примере инструкция elseif была вставлена между инструкциями if
и else. Она проверяет, не превышает ли баланс банковского счета сумму $200, и если
превышает, принимается решение о том, что в этом месяце можно позволить себе
положить на сберегательный счет $100.
Это все можно представить в виде набора объездов в нескольких направлениях
(рис. 4.3).
Инструкция else завершает либо конструкцию if...else, либо конструкцию if...elseif...else. Если
она не нужна, то финальную инструкцию ������������������������������������������������
else��������������������������������������������
можно опустить, но ни одна из этих инструкций не должна стоять перед инструкцией elseif, точно так же, как ни одна инструкция elseif
не должна стоять перед инструкцией if.

110

Глава 4. Выражения и управление процессом выполнения программы в PHP

Рис. 4.3. Магистраль с объездами if, elseif и else

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

Инструкция switch
Инструкция switch применяется в тех случаях, когда у одной переменной или у результата вычисления выражения может быть несколько значений, каждое из которых должно вызывать особую функцию.
Рассмотрим, например, управляемую кодом PHP����������������������������
�������������������������������
систему меню, которая в соответствии с пожеланием пользователя передает отдельную строку коду основного меню. Предположим, что есть следующие варианты: Home, About, News, Login
и Links, а переменная $page принимает одно из этих значений в соответствии
с информацией, введенной пользователем.
Код реализации этого замысла с использованием конструкции if...elseif...
else может иметь вид, показанный в примере 4.22.

111

Условия

Пример 4.22. Многострочная инструкция if...elseif


($page
($page
($page
($page
($page

==
==
==
==
==

"Home")
"About")
"News")
"Login")
"Links")

echo
echo
echo
echo
echo

"Вы
"Вы
"Вы
"Вы
"Вы

выбрали
выбрали
выбрали
выбрали
выбрали

Home";
About";
News";
Login";
Links";

Код, в котором используется инструкция switch, показан в примере 4.23.
Пример 4.23. Инструкция switch


113

Условия

Оператор ?
Использование трехкомпонентного оператора ? позволяет избежать многословности инструкций if и else. Необычность этого оператора заключается в том, что
он использует не два, как большинство других операторов, а три операнда.
В главе 3 уже состоялось краткое знакомство с этим оператором при выяснении
разницы между print и echo, где он приводился в качестве примера оператора, который хорошо работает с print, но не работает с echo.
Оператору ? передаются выражение, которое он должен вычислить, и два выполняемых оператора: один для выполнения, когда результат вычисления выражения TRUE, а другой — когда FALSE.
В примере 4.26 показан код, который может использоваться для вывода преду­
преждения об уровне топлива в автомобиле на его панель приборов.
Пример 4.26. Использование оператора ?


Если топлива остается всего 1 галлон1 или меньше (иными словами, переменная
$fuel имеет значение, равное единице или меньше ее), то этот оператор возвращает предыдущей команде echo строку «Требуется дозаправка». В противном случае
он возвращает строку «Топлива еще достаточно». Значение, возвращаемое оператором ?, можно также присвоить какой-нибудь переменной (пример 4.27).
Пример 4.27. Присваивание условного результата оператора ? переменной


В этом примере переменной $enough будет присвоено значение TRUE только в том
случае, если в баке более 1 галлона топлива, в противном случае ей будет присвое­
но значение FALSE.
Если вы считаете синтаксис оператора ? слишком запутанным, то можете вместо
него воспользоваться инструкцией if, но о нем все равно нужно знать, поскольку
он может встретиться в программном коде, созданном другим программистом.
Чтение кода, в котором используется этот оператор, может быть сильно затруднено из-за частого применения в нескольких местах одной и той же переменной.
Например, весьма популярен код такого вида:
$saved = $saved >= $new ? $saved : $new;

Понять, что он делает, можно только после тщательного разбора:
$saved =
$saved >= $new
?
$saved
:
$new;
1

//
//
//
//
//
//

Присваивание значения переменной $saved
Сравнение $saved и $new
Если сравнение выдает истинный результат ...
... ей присваивается текущее значение $saved
Если сравнение выдает ложный результат ...
... ей присваивается значение переменной $new

1 галлон (американский) = 3,79 л. — Примеч. ред.

114

Глава 4. Выражения и управление процессом выполнения программы в PHP

Это весьма компактный способ отслеживания самого большого значения, которое может встретиться в процессе выполнения программы. Самое большое значение содержится в переменной $saved и при поступлении нового значения сравнивается со значением переменной $new. Программисты, освоившие оператор ?,
считают, что для таких коротких сравнений его удобнее применять, чем инструкции if.
Если этот оператор не используется для создания компактного кода, то он
обычно применяется для принятия решений, умещающихся на одной строке, например для проверки того, установлено ли значение переменной, перед передачей
ее функции.

Организация циклов
Компьютеры славятся своей способностью быстро и неутомимо повторять вычисления. Зачастую от программы требуется снова и снова повторять одну и ту же
последовательность кода, пока не произойдет какое-нибудь событие, например
ввод значения пользователем или достижение программой своего естественного
окончания. Имеющиеся в PHP разнообразные структуры организации циклов
предоставляют великолепные способы решения подобных задач.
Чтобы представить, как это работает, посмотрите на рис. 4.4. Он очень похож
на метафору с магистралью, которая использовалась для иллюстрации работы
инструкции if, за исключением того, что у объезда также есть замкнутый участок,
из которого машина может выйти только при соблюдении определенных программных условий.

Рис. 4.4. Представление цикла как части программы
магистральной разметки

Организация циклов

115

Циклы while
Превратим автомобильную панель приборов из примера 4.26 в цикл, постоянно
проверяющий уровень топлива при езде на машине, в котором используется инструкция цикла while (пример 4.28).
Пример 4.28. Цикл while


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

В примере 4.29 показан еще один вариант использования цикла while, в котором
выводится таблица умножения на 12.
Пример 4.29. Цикл while для вывода таблицы умножения на 12


В этом примере переменной $count присваивается начальное значение 1, а затем
запускается цикл while, в котором используется выражение сравнения $count

В этом примере оператор ++$count был удален из тела цикла while и помещен
непосредственно в выражение условия цикла. Теперь PHP вычисляет значение
переменной $count в начале каждого прохода цикла (итерации) и, заметив, что
перед именем переменной стоит оператор инкремента, сначала увеличивает значение переменной на 1 и только потом сравнивает его с числом 12. Следовательно,
теперь переменной $count присваивается начальное значение 0, а не 1, поскольку
это значение увеличивается сразу же, как только происходит вход в цикл. Если
оставить начальное значение, равное 1, то будут выведены результаты для чисел
между 2 и 12.

Циклы do...while
Цикл do...while представляет собой небольшую модификацию цикла while, используемую в том случае, когда нужно, чтобы блок кода был исполнен хотя бы один
раз, а условие проверялось только после этого.
В примере 4.31 показана модифицированная версия таблицы умножения на 12,
в которой использован этот цикл.
Пример 4.31. Цикл do...while, используемый для вывода таблицы умножения на 12


Организация циклов

117

Заметьте, что теперь мы вернулись к присваиванию переменной $count начального значения 1 (а не 0), потому что код выполняется сразу же, без увеличения
значения переменной на 1. Во всем остальном этот код очень похож на показанный
в примере 4.29.
Разумеется, если внутри цикла do...while находится несколько инструкций, то
не следует забывать ставить вокруг них фигурные скобки, как показано в примере 4.32.
Пример 4.32. Расширенная версия примера 4.31, использующая фигурные скобки


Циклы for
Цикл for, являющийся последней разновидностью инструкций цикла, к тому же
еще и самый мощный из них, поскольку в нем сочетаются возможности установки
значения переменных при входе в цикл, проверки соблюдения условия при каждом
проходе цикла (итерации) и модификации значений переменных после каждой
итерации.
В примере 4.33 продемонстрирована возможность вывода таблицы умножения
с использованием цикла for.
Пример 4.33. Вывод таблицы умножения на 12 из цикла for


Как видите, весь код сведен к одной инструкции for, в которой содержится одна
условная инструкция. И вот что из этого получается. Каждая инструкция for воспринимает три параметра:
 выражение инициализации;
 выражение условия;
 выражение модификации.
Эти три выражения отделяются друг от друга точкой с запятой: for (выражение1 ;
выражение2 ; выражение3). В начале первой итерации выполняется выражение инициа­
лизации. В нашем коде таблицы умножения переменная $count инициализируется
значением 1. Затем при каждой итерации проверяется выражение условия (в данном случае $count

Cравним условия, при которых следует использовать циклы for, с условиями,
при которых нужно применять циклы while. Цикл for явно создавался под отдельное значение, изменяющееся на постоянную величину. Обычно мы имеем дело
с увеличивающимся значением — это похоже на то, как если бы вам был передан
перечень того, что выбрал пользователь, и от вас требуется обработать каждый его
выбор по очереди. Но переменную можно видоизменять по вашему усмотрению.
Более сложная форма инструкции for позволяет даже осуществлять со всеми тремя параметрами сразу несколько операций:
for ($i = 1, $j = 1 ; $i + $j < 10 ; $i++ , $j++)
{
// ...
}

Но новичкам использовать такую сложную форму не рекомендуется. Здесь
главное — отличать запятые от точки с запятой. Все три параметра должны быть
отделены друг от друга точкой с запятой.
Несколько операторов внутри каждого параметра должны быть отделены друг
от друга запятыми. Первый и третий параметры в предыдущем примере содержат
по два оператора:
$i = 1, $j = 1
$i + $j < 10
$i++ , $j++

// Инициализация переменных $i и $j
// Условие окончания работы цикла
// Модификация $i и $j в конце каждой итерации

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

Организация циклов

119

Прекращение работы цикла
Прекратить работу цикла for можно точно так же, как и работу рассмотренной уже
инструкции switch, — используя команду break. К примеру, это может понадобиться, когда одна из ваших инструкций вернет ошибку и продолжать выполнение
цикла станет небезопасно.
Один из таких случаев может произойти, когда при записи файла возникнет
ошибка, возможно, из-за нехватки места на диске (пример 4.35).
Пример 4.35. Запись файла, использующая цикл for с перехватом ошибки


Это наиболее сложный из всех ранее приведенных фрагментов кода, но вы уже
готовы к его пониманию. Команды обработки файлов будут рассмотрены в одной
из следующих глав, а сейчас нужно лишь знать, что в первой строке кода открывается файл text.txt для записи в двоичном режиме, а затем переменной $fp возвращается указатель на него, который в дальнейшем используется для ссылки на этот
открытый файл.
Затем осуществляется 100 проходов цикла (от 0 до 99), записывающих строку
data в файл. После каждой записи функция fwrite присваивает переменной
$written значение, представляющее собой количество успешно записанных символов. Но если происходит ошибка, то функция fwrite присваивает этой переменной
значение FALSE.
Поведение функции fwrite облегчает коду проверку переменной $written на
наличие значения FALSE, и если она имеет такое значение, код прекращает работу
цикла и передает управление инструкции, закрывающей файл.
При желании улучшить код можно упростить строку:
if ($written == FALSE) break;

за счет использования оператора NOT:
if (!$written) break;

Фактически пара инструкций, находящихся внутри цикла, может быть сокращена до одной:
if (!fwrite($fp, "data")) break;

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

120

Глава 4. Выражения и управление процессом выполнения программы в PHP

чем на один уровень, после команды break можно поставить число, показывающее,
работу скольких уровней нужно прекратить, например:
break 2;

Инструкция continue
Инструкция continue немного похожа на команду break, только она предписывает
PHP�������������������������������������������������������������������������
остановить процесс текущего цикла и перейти непосредственно к его следующей итерации, то есть вместо прекращения работы всего цикла PHP������������
���������������
осуществляет выход только из текущей итерации.
Этот прием может пригодиться в тех случаях, когда известно, что нет смысла
продолжать выполнение текущего цикла и нужно сберечь процессорное время или
избежать ошибки путем перехода сразу к следующей итерации цикла. В примере 4.36 инструкция continue используется для того, чтобы избежать ошибки деления
на нуль за счет ее вызова в тот момент, когда переменная $j имеет значение 0.
Пример 4.36. Перехват ошибки деления на нуль с помощью инструкции continue


Но что делать, если вместо этого нужно получить значение переменной $c в виде
целого числа? Этого можно добиться разными способами, одним из которых
является принудительное преобразование результата $a/$b в целое число путем
использования оператора преобразования (int):
$c = (int) ($a / $b);

Такой способ называется явным преобразованием типов. Обратите внимание,
что для обеспечения преобразования в целое число значения всего выражения это
выражение помещено в круглые скобки. В противном случае преобразованию подверглось бы только значение переменной $a, что не имело бы никакого смысла,
поскольку деление на значение переменной $b все равно вернуло бы результат
в виде числа с плавающей точкой.
Можно провести явное преобразование значений в те типы, которые показаны
в табл. 4.6, но обычно его можно избежать, используя преобразование за счет вызова одной из встроенных функций PHP. Например, для получения целочисленного значения можно использовать функцию intval. Этот раздел, как и многие
другие в данной книге, предназначен в основном для того, чтобы помочь разобраться с чужим кодом, который может вам встретиться.
Таблица 4.6. Типы преобразований, доступных в PHP
Тип преобразования Описание
(int) (integer)

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

(bool) (boolean)

Преобразование в логическое значение

(float) (double) (real)

Преобразование в число с плавающей точкой

(string)

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

(array)

Преобразование в массив

(object)

Преобразование в объект

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

122

Глава 4. Выражения и управление процессом выполнения программы в PHP

будет принимать решение, что делать дальше, в соответствии с различными объектами cookie и/или данными сессии, которые могут быть сохранены.
Но несмотря на возможность создания таким способом целого сайта, этого делать
не рекомендуется, поскольку исходный код будет все время разрастаться и приобретет громадные размеры по мере того, как ему придется принимать во внимание
разнообразные действия пользователя.
Будет куда более благоразумно разделить разработку сайтана несколько разных
частей. Например, один автономный процесс будет заниматься подпиской на сайт
со всеми вытекающими отсюда проверками допустимости адреса электронной почты, незадействованности имени пользователя и т. д.
Второй модуль неплохо было бы создать для регистрации пользователей, предшествующей их допуску к основной части вашего сайта. Затем можно создать
модуль вывода сообщений, в котором пользователи могли бы оставлять свои комментарии, модуль, содержащий ссылки и полезную информацию, еще один модуль,
позволяющий загружать на сайт фотографии, и т. д.
Как только будет создано средство для отслеживания действий пользователя
на вашем сайте, использующее объекты cookie или переменные сессии (оба этих
средства будут более подробно рассмотрены в следующих главах), можно разделить
сайт на удобные секции PHP-кода, каждая из которых будет независима от других.
Таким образом, вы существенно облегчите себе будущую разработку каждого нового свойства и обслуживание уже имеющихся.

Динамическое связывание в действии
Одним из наиболее популярных в настоящее время приложений, управляемых
PHP, является платформа для ведения блогов WordPress (рис. 4.5). При ведении
или чтении блога этого можно и не понять, но для каждой основной секции
выделен свой основной PHP������������������������������������������������
���������������������������������������������������
-файл, а огромное количество совместно используемых функций помещено в отдельные файлы, которые включаются основными
PHP-страницами по мере необходимости.
Вся платформа держится на закулисном отслеживании сессии, поэтому вы
вряд ли знаете о том, когда осуществляется переход от одной подчиненной секции
к другой. Поэтому, если веб-разработчик хочет провести тонкую настройку WordPress,
ему не трудно найти конкретный файл, который для этого применяется, и выполнить
его проверку и отладку, не теряя понапрасну времени на не связанные с ним части
программы.
Когда в следующий раз будете использовать WordPress, проследите за адресной
строкой своего браузера, особенно при управлении блогом, и тогда вы сможете
заметить обращения к разнообразным PHP-файлам, которые используются в этом
приложении.
В текущей главе были рассмотрены обширные сведения, закладывающие основу для дальнейшего изучения материала книги. Теперь вы уже должны уметь составлять свои собственные небольшие PHP-программы. Но перед тем, как перей­
ти к следующей главе, посвященной функциям и объектам, можете проверить
приобретенные знания, ответив на следующие вопросы.

Вопросы

123

Рис. 4.5. Платформа WordPress, предназначенная для ведения блогов, написана на PHP

Вопросы
Вопрос 4.1
Какие основные значения представлены ключевыми словами TRUE и FALSE?
Вопрос 4.2
Что представляют собой две самые простые формы выражений?
Вопрос 4.3
В чем разница между унарными, бинарными и трехкомпонентными операторами?
Вопрос 4.4
В чем заключается наилучший способ установки собственной приоритетности
операторов?
Вопрос 4.5
Что означает понятие взаимосвязанности операторов?
Вопрос 4.6
Когда следует использовать оператор идентичности (===)?

124

Глава 4. Выражения и управление процессом выполнения программы в PHP

Вопрос 4.7
Назовите три типа условных инструкций.
Вопрос 4.8
Какую команду можно использовать для пропуска текущей итерации цикла
и перехода к следующей итерации?
Вопрос 4.9
Почему цикл for считается более мощным, чем while?
Вопрос 4.10
Как инструкции if и while интерпретируют условные выражения, составленные
из разных типов данных?
Ответы на эти вопросы можно найти в приложении А, в разделе «Ответы на
вопросы главы 4».

5

Функции
и объекты PHP

К основным требованиям к любому языку программирования относится наличие
места для хранения данных, средств для направления процесса выполнения программы и других мелочей, таких как вычисление выражений, управление файлами и вывод текста. ����������������������������������������������������������
PHP�������������������������������������������������������
обладает всем этим, и вдобавок у него имеется облегчающий жизнь инструментарий наподобие инструкций else и elseif. Но даже если
все это входит в наш набор инструментов, программирование может быть слишком нудным и утомительным занятием, особенно если регулярно будет возникать
необходимость вновь и вновь набирать очень похожие друг на друга фрагменты
кода.
И тут нам на помощь приходят функции и объекты. Нетрудно догадаться, что
функция �������������������������������������������������������������������
— это набор инструкций, который выполняет конкретную задачу и в дополнение к этому может вернуть какое-нибудь значение. Можно извлечь фрагмент
кода, который используется более одного раза, поместить его в функцию и вызвать
функцию по имени в тот момент, когда этот код нужно будет выполнить.
По сравнению с непрерывным линейным кодом у функций есть масса преимуществ.
 Экономия времени при наборе текста программы.
 Сокращение количества синтаксических и прочих ошибок программирования.
 Сокращение времени загрузки файлов программы.
 Сокращение времени выполнения, поскольку каждая функция компилируется

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

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

126

Глава 5. Функции и объекты PHP

Функции PHP
PHP поставляется с несколькими сотнями готовых к работе встроенных функций,
превращающих его в язык с очень богатыми возможностями. Чтобы воспользоваться функцией, ее нужно вызвать по имени. Посмотрим, например, как работает
функция print:
print("print является псевдофункцией");

Круглые скобки сообщают PHP, что вы ссылаетесь на функцию. В противном
случае будет считаться, что вы ссылаетесь на константу, и может быть выдано
уведомление об использовании неопределенной константы:
Notice: Use of undefined constant fname - assumed 'fname'

за которым последует текстовая строка fname, согласно предположению, что вы,
наверное, хотели поместить в код текстовую строку. (Ситуация запутается еще
больше, если константа по имени fname будет существовать на самом деле и PHP
в таком случае воспользуется ее значением.)
Собственно говоря, print является псевдофункцией, которая обычно называется конструкцией. Разница в том, что при ее использовании круглые скобки можно опустить:
print "print не требует использования круглых скобок";
А после любого другого имени вызываемой функции скобки нужно ставить всегда, даже если
они останутся пустыми (в том случае, когда функции не передаются никакие аргументы).

Функции могут принимать любое количество аргументов, включая нулевое.
Например, показанная ниже функция phpinfo отображает массу информации о текущей установке PHP и не требует никаких аргументов:
phpinfo();

Результат вызова этой функции показан на рис. 5.1.
Функция phpinfo весьма полезна для получения информации о текущей установке PHP, но
этой информацией могут воспользоваться и потенциальные злоумышленники. Поэтому никогда не оставляйте вызов этой функции в коде, подготовленном для работы в сети.

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


127

Функции PHP

Рис. 5.1. Информация, выводимая встроенной в PHP функцией phpinfo

В этом примере используются три функции для обработки строк, выводящие
следующий текст:
Hello world. Hip Hip HOORAY!

Как следует из результата, функция strrev реверсирует порядок символов
в строке, функция str_repeat дважды повторяет строку Hip (в соответствии с требованием второго аргумента), а функция strtoupper переводит буквы в слове hooray!
в верхний регистр.

Определение функции
В общем виде для функции используется следующий синтаксис:
function имя_функции([параметр [, ...]])
{
// Инструкции
}

128

Глава 5. Функции и объекты PHP

Пусть вас не смущают квадратные скобки, их назначение я объясню позже.
В первой строке синтаксиса показано следующее:
 определение начинается со слова function;
 за ним следует имя, которое должно начинаться с буквы или символа подчеркивания; за ними может следовать любое количество букв, цифр или знаков
подчеркивания;
 наличие круглых скобок обязательно;
 к необязательному элементу относится один или несколько параметров, разделенных запятыми.
Имена функций нечувствительны к регистру использующихся в них букв, поэтому все следующие строки могут ссылаться на одну и ту же функцию print: PRINT,
Print и PrInT.
С открывающей фигурной скобки начинаются инструкции, которые будут выполнены при вызове функции; они должны завершаться закрывающей фигурной
скобкой, составляющей пару первой скобке. В составе этих инструкций должны
быть одна или несколько инструкций return, заставляющих функцию прекратить
выполнение и вернуть управление вызывавшему функцию коду. Если инструкция
return продолжена каким-нибудь значением, то вызывающий код может его извлечь,
что мы сейчас и увидим.

Возвращение значения
Рассмотрим простую функцию, преобразующую буквы чьих-нибудь полных имен
в нижний регистр, а затем переводящую в верхний регистр первую букву каждого
имени.
В примере 5.1 нам уже встречалась встроенная PHP-функция strtoupper. Для
нашей текущей функции будет использована ее противоположность: функция strtolower:
$lowered = strtolower("люБОЕ нУжное Вам количество Букв и Знаков Пунктуации");
echo $lowered;

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

Но нам не нужны имена, полностью состоящие из букв нижнего регистра, мы
хотим, чтобы первые буквы были превращены в прописные. (Не будем в этом примере брать в расчет такие редкие имена, как Mary-Ann или Jo-En-Lai.) Нам и здесь
сопутствует удача: PHP предоставляет также функцию ucfirst, которая переводит
первую букву строки в верхний регистр:
$ucfixed = ucfirst("любое нужное вам количество букв и знаков пунктуации");
echo $ucfixed;

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

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

Функции PHP

129

функция strtolower, а затем будет вызвана функция ucfirst. Для этого вызов функции strtolower будет вложен в вызов функции ucfirst. Посмотрим, зачем это делается, потому что нам важно понять порядок вычисления кода.
Если воспользоваться следующим простым вызовом функции print:
print(5-8);

то сначала будет вычислено выражение 5-8 и на выходе будет получено число –3.
(В предыдущей главе уже было показано, что ���������������������������������
PHP������������������������������
для отображения этого результата превращает его в строку.) Если выражение содержит функцию, то сначала
вычисляется эта функция:
print(abs(5-8));

Для выполнения этой короткой инструкции PHP совершает следующие действия.
1. Вычисляет 5-8, выдавая результат –3.
2. Использует функцию abs, превращая –3 в 3.
3. Превращает результат в строку и выводит его, используя функцию print.
Такой порядок работы обусловлен тем, что PHP вычисляет каждый элемент,
начиная с самого внутреннего и заканчивая тем, который находится снаружи. То же
самое происходит при обработке следующего вызова:
ucfirst(strtolower("люБОЕ нУжное Вам количество Букв и Знаков Пунктуации"))

PHP передает нашу строку функции strtolower, а затем функции ucfirst, выдавая следующий результат (который мы уже видели, когда вызывали функции
отдельно друг от друга):
Любое нужное вам количество букв и знаков пунктуации

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


Пользователи часто забывают вовремя выключить режим Caps Lock, случайно
ставят прописные буквы не там, где нужно, и даже вообще забывают о них, от чего
вы тоже не застрахованы. В результате выполнения кода этого примера будет выведен следующий текст:
William Henry Gates

130

Глава 5. Функции и объекты PHP

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


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

Не передавайте аргументы по ссылке
В версиях PHP������������������������������������������������������������
���������������������������������������������������������������
, предшествующих версии 5.3.0, вы привыкли пользоваться возможностью употребления перед именем переменной символа &, который заставлял
парсер передавать ссылку на переменную, а не значение самой переменной. Тем
самым функции предоставлялся доступ к переменной (позволяющий записывать
в нее различные значения), что могло создать угрозу безопасности, а также способствовало возникновению трудно отслеживаемых ошибок. Кроме того, это противоречит принципам объектно-ориентированного программирования — Object
Oriented Programming (OOP).
В версии PHP 5.3.0 передача по ссылке попала в число нерекомендуемых приемов, а из
версии PHP����������������������������������������������������������������������������
�������������������������������������������������������������������������������
5.4.0 возможность такой передачи была удалена. Поэтому вам не следует пользоваться этим приемом нигде, кроме как на устаревших сайтах, и даже при этом рекомендуется переписать код, передающий значения по ссылке, поскольку на новых версиях PHP
он будет приводить к остановке программы с выдачей неустранимой ошибки.

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

Функции PHP

131

поэтому вернемся к метафоре со спичечным коробком, которая использовалась
в главе 3.
Представьте, что вы не вынимаете клочок бумаги из коробка, не читаете то, что
на нем написано, не копируете эту надпись на другой клочок бумаги, не возвращаете
оригинал в коробок и не передаете копию функции, а просто привязываете нитку
к исходному клочку бумаги и передаете функции второй конец этой нитки (рис. 5.2).

Рис. 5.2. Представление ссылки в виде нитки, привязанной к значению переменной

Теперь, чтобы найти данные, к которым она обращается, функция может проследовать по нитке. Таким образом исключаются все издержки на создание копии
переменной, предназначенной только для того, чтобы в функции можно было воспользоваться ее значением. Более того, теперь функция может изменить значение
переменной.
Значит, пример�������������������������������������������������������������
 ������������������������������������������������������������
5.3 можно переписать: передать ссылки на все параметры, чтобы после этого функция напрямую смогла внести в них изменения (пример 5.4).
Пример 5.4. Возвращение значений из функции по ссылке


132

Глава 5. Функции и объекты PHP

Вместо передачи строк непосредственно функции они сначала присваиваются
в качестве значений переменным и выводятся на экран, чтобы посмотреть их состояние «до». Затем, как и раньше, вызывается функция, но сейчас перед именем
каждого параметра ставится символ &, предписывающий PHP передать функции
только ссылки на значения переменных.
Теперь к переменным $n1, $n2 и $n3 привязаны «ниточки», ведущие к значениям
переменных $a1, $a2 и $a3. Иными словами, существует одна группа значений, но
два набора имен переменных, позволяющих к ним обратиться.
Поэтому функции fix_names нужно только присвоить новые значения переменным $n1, $n2 и $n3, чтобы обновить значения переменных $a1, $a2 и $a3. В результате выполнения этого кода будут выведены следующие строки:
WILLIAM henry gatES
William Henry Gates

Как видите, в обеих инструкциях echo используются только значения переменных $a1, $a2 и $a3.
Следует еще раз подчеркнуть, что в PHP такая практика программирования
больше не поддерживается, поэтому весь код, основанный на передаче значений
по ссылкам, должен быть переделан. Иногда переделка заключается в простом
удалении символов &, потому что от них нужно избавляться в первую очередь.
Или же, как в следующем примере, вместо ссылок можно воспользоваться глобальными переменными.

Возвращение глобальных переменных
Лучшим способом предоставления функции доступа к переменной, созданной за ее
пределами, является объявление ее глобальной прямо из тела функции. За ключевым словом global должно следовать имя переменной, тогда полный доступ к этой
переменной можно будет получить из любой части вашего кода (пример 5.5).
Пример 5.5. Возвращение значений в глобальных переменных


fix_names()
$a1; $a1 = ucfirst(strtolower($a1));
$a2; $a2 = ucfirst(strtolower($a2));
$a3; $a3 = ucfirst(strtolower($a3));

Включение и запрос файлов

133

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

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

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

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

Включение и запрос файлов
По мере приобретения навыков программирования на PHP�����������������������
��������������������������
вы, скорее всего, приступите к созданию библиотеки, состоящей из функций, которые, по вашему мнению, смогут пригодиться в будущем. Кроме того, наверное, вы начнете пользоваться библиотеками, созданными другими программистами.
Копировать эти функции и вставлять их в свой код не имеет никакого смысла.
Можно сохранить эти функции в отдельных файлах и воспользоваться командами
для их извлечения. Для этого существуют две команды: include (включить) и require
(затребовать).

Инструкция include
При использовании инструкции include можно потребовать у PHP извлечения
конкретного файла и загрузки всего его содержимого. Это равносильно вставке
включаемого файла в данное место текущего файла. В примере 5.6 показано, как
нужно включать файл под названием library.php.

134

Глава 5. Функции и объекты PHP

Пример 5.6. Включение файла PHP


Инструкция include_once
При каждом использовании директивы include она снова вставляет требуемый
файл, даже если он уже был вставлен. Предположим, к примеру, что в библиотеке library.php содержится масса полезных функций. Вы включаете ее в свой
файл, но, кроме нее, включаете еще одну библиотеку, которая содержит library.php.
Из-за этой вложенности вы непреднамеренно вставляете library.php дважды.
В результате будут появляться сообщения об ошибках, потому что будет предпринята попытка несколько раз объявить одну и ту же константу или функцию.
Поэтому вместо данной директивы нужно использовать инструкцию include_once
(пример 5.7).
Пример 5.7. Однократное включение файла PHP


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

Инструкции require и require_once
Потенциальная проблема, возникающая при использовании инструкций include
и include_once, состоит в том, что для вставки нужного файла PHP предпримет
всего одну попытку. Выполнение программы продолжится даже в том случае, если
файл не будет найден.
Когда вставка файла имеет принципиальную важность, его нужно затребовать,
то есть применить инструкцию require. По тем же причинам, которые излагались
при рассмотрении использования инструкции include_once, я рекомендую, чтобы

Объекты PHP

135

вы, когда нужно затребовать файл, придерживались главным образом использования инструкции require_once (пример 5.8).
Пример 5.8. Однократное востребование файла PHP


Совместимость версий PHP
PHP продолжает совершенствоваться и существует в нескольких версиях. Если
нужно проверить доступность в вашем коде какой-нибудь конкретной функции,
можно воспользоваться функцией function_exists, которая проверяет все предопределенные и созданные пользователем функции.
В примере 5.9 проверяется доступность функции array_combine, которая имеется в PHP версии 5.
Пример 5.9. Проверка существования функции


Используя подобный код, можно воспользоваться любыми функциональными
возможностями, имеющимися в новых версиях ������������������������������
PHP���������������������������
, которые вам придется смоделировать, если нужно будет, чтобы ваш код работал и в более ранних версиях.
Ваши функции могут работать медленнее встроенных, но код по крайней мере
будет обладать более широкой переносимостью.
Чтобы определить версию PHP, под которой запущен ваш код, можно также
воспользоваться функцией phpversion. Возвращаемый результат в зависимости от
версии будет иметь следующий вид:
5.5.11

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

136

Глава 5. Функции и объекты PHP

самая элементарная инструкция GOTO или GOSUB), объектно-ориентированное программирование (ООП) подняло использование функций на совершенно новый
уровень.
Как только у вас появится навык сведения повторно используемых фрагментов
кода в функции, останется сделать еще один небольшой шаг и присмотреться
к связыванию функций и данных, которыми они оперируют, в объекты.
Рассмотрим сайт социальной сети, состоящий из множества различных частей.
Одна из таких частей управляет всеми пользовательскими функциями: ее код позволяет новым пользователям записаться, а уже записавшимся — изменить свои
личные данные. В стандартном PHP можно создать для управления всеми этими
действиями ряд функций и встроить несколько вызовов к базе данных MySQL,
чтобы вести данные по всем пользователям.
А теперь вообразите, насколько проще будет создать объект, представляющий
текущего пользователя. Для этого можно создать класс по имени User, в котором
будут содержаться весь код, необходимый для обслуживания пользователей, и все
переменные, требующиеся для работы с данными внутри класса. Затем, когда понадобится управлять пользовательскими данными, можно будет просто создать
новый объект класса User.
Этот новый объект можно будет рассматривать в качестве настоящего пользователя. Например, объекту можно передать имя, пароль и адрес электронной почты,
спросить его о том, существует ли уже такой пользователь, и если нет, заставить
его создать нового пользователя с данными атрибутами. Можно даже иметь объект
мгновенных сообщений или объект, позволяющий учитывать дружеские отношения
между двумя пользователями.

Терминология
При создании программы, рассчитанной на использование объектов, нужно сконструировать некую совокупность данных и кода, называемую классом. Каждый
новый объект, основанный на этом классе, называется экземпляром (или случаем
употребления) этого класса.
Данные, связанные с объектом, называются его свойствами, а используемые им
функции — методами. При определении класса задаются имена его свойств и код
для его методов. На рис. 5.3 показана метафора объекта в виде музыкального автомата. Компакт-диски в его карусели можно рассматривать в качестве его свойств,
а метод их проигрывания заключается в нажатии кнопки на передней панели.
Есть также щель для опускания монет (метод, используемый для активизации
объекта) и устройство чтения компакт-дисков (метод, используемый для извлечения музыки, или свойств, с компакт-дисков).
При создании объектов предпочтительно воспользоваться инкапсуляцией или
создавать класс таким образом, чтобы с его свойствами могли работать только его
собственные методы. Иными словами, нужно запретить внешнему коду непосредственный доступ к данным объекта. Предоставляемые объектом методы известны
как интерфейс объекта.

Объекты PHP

137

Рис. 5.3. Музыкальный автомат как подходящий пример автономного объекта

Такой подход упрощает отладку: дефектный код придется исправлять только
в пределах класса.
Кроме того, когда нужно будет обновить программу, при использовании надлежащей инкапсуляции и поддержке одинакового интерфейса можно будет просто
разработать новые классы для замены старых, полностью их отладить, а затем заменить ими старые классы. Если они будут в чем-то неработоспособными, можно
будет вернуть назад старые классы для немедленного устранения проблемы перед
дальнейшей отладкой новых классов.
Как только класс будет создан, может выясниться, что нужен еще один, похожий
на него, но все же несколько отличающийся класс. Быстрее и проще всего будет
определить новый класс, воспользовавшись наследованием. При этом ваш новый
класс сохранит все свойства, присущие тому классу, чьим наследником он является. Исходный класс теперь будет называться суперклассом, а новый класс — подклассом (или производным классом).
Вернемся к примеру с музыкальным автоматом. Если вы изобретаете новый
музыкальный автомат, который наряду с музыкой может воспроизводить и видео­
клипы, то можете сохранить все свойства и методы исходного музыкального автомата и добавить несколько новых свойств (видеоклипов) и новых методов (видеоплееров).
Существенным преимуществом этой системы является то, что если вы увеличили скорость работы или улучшили другие аспекты работы суперкласса, его подклассы пользуются теми же самыми усовершенствованиями.

138

Глава 5. Функции и объекты PHP

Объявление класса
Перед тем как получить возможность использования объекта, нужно определить
класс с помощью ключевого слова class. Определение класса включает в себя имя
класса (чувствительное к регистру букв), его свойства и методы. В примере 5.10
дается определение класса User, имеющего два свойства: $name и $password (которые
обозначены ключевым словом public — см. подраздел «Область видимости свойств
и методов в PHP 5» данного раздела). В нем также создается новый экземпляр
этого класса (по имени $object).
Пример 5.10. Объявление класса и проверка объекта


Здесь также задействована поистине бесценная функция под названием print_r.
Она требует от PHP������������������������������������������������������
���������������������������������������������������������
отобразить информацию о переменной в удобной для восприятия человеком форме, о чем говорит элемент _r в ее имени (означающий �����
readable — «читаемый»). Для нового объекта $object эта функция выводит следующую
информацию:
User Object
(
[name] =>
[password] =>
)

Но браузер сжимает все пустые пространства, поэтому выводимая в нем информация читается немного сложнее:
User Object ( [name] => [password] => )

В любом случае выведенная информация свидетельствует о том, что $object является объектом, определенным пользователем, и содержит свойства name и password.

Создание объекта
Для создания объекта определенного класса используется ключевое слово new, применяемое в выражении: объект = new Класс. Вот два способа создания объектов:
$object = new User;
$temp = new User('name', 'password');

139

Объекты PHP

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

Доступ к объектам
Добавим к примеру���������������������������������������������������������
 ��������������������������������������������������������
5.10 еще несколько строк и проверим результаты. В�������
 ������
примере 5.11 предыдущий код расширяется за счет установки свойств объекта и вызова
метода.
Пример 5.11. Создание объекта и взаимодействие с ним


Из примера видно, что для доступа к свойству объекта используется следующий синтаксис: $объект->свойство . Похожим образом можно вызвать и метод: $объект->метод().
Можно было заметить, что перед именами свойств и методов отсутствуют символы доллара ($). Если на первой позиции имен поставить символ $, то код не будет
работать, поскольку он попробует обратиться к значению, хранящемуся в������
 �����
переменной. Например, выражение $object->$property будет пытаться найти значение,
присвоенное переменной по имени $property (скажем, это значение является
строкой brown), а затем обратиться к свойству $object–>brown. Если переменная
$property не определена, то будет предпринята попытка обратиться к свойству
$object->NULL, что спровоцирует возникновение ошибки.
Если организовать просмотр, используя имеющееся в браузере средство
для просмотра исходного кода, то код примера 5.11 выведет следующую информацию:
User Object
(
[name]

=>

140

Глава 5. Функции и объекты PHP

[password] =>
)
User Object
(
[name]
=> Joe
[password] => mypass
)
Сюда помещается код, сохраняющий данные пользователя

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

Клонирование объектов
Если объект уже создан, то в качестве параметра он передается по ссылке. Если
воспользоваться метафорой спичечного коробка, то это похоже на привязывание
сразу нескольких ниток к объекту, хранящемуся в коробке, что позволяет получить
к нему доступ, следуя по любой из привязанных ниток.
Иными словами, присваивание объектов не приводит к их полному копированию.
Как это работает, показано в примере 5.12, где определяется очень простой
пользовательский класс User, который не имеет методов и содержит всего лишь
одно свойство name.
Пример 5.12. Копирование объекта


Мы создали объект $object1 и присвоили свойству name значение Alice. Затем
создали $object2, присвоили ему значение $object1 и присвоили значение Amy непосредственно свойству name объекта $object2 — или подумали, что присвоили. Но этот
код выдаст следующую информацию:
object1 name = Amy
object2 name = Amy

Что же произошло? И $object1, и $object2 ссылаются на один и тот же объект,
поэтому изменение свойства name, принадлежащего $object2, на Amy устанавливает
такое же значение и для свойства, принадлежащего $object1.
Во избежание подобной путаницы следует использовать инструкцию clone, которая
создает новый экземпляр класса и копирует значения свойств из исходного класса
в новый экземпляр. Применение этой инструкции показано в примере 5.13.
Пример 5.13. Клонирование объекта


Вот и все. Этот код выдает то, что нам требовалось получить с самого начала:
object1 name = Alice
object2 name = Amy

Конструкторы
При создании нового объекта вызываемому классу можно передать перечень аргументов. Они передаются специальному методу внутри класса, который называется
конструктором и занимается инициализацией различных свойств.
В прежние времена этому методу обычно давалось имя класса, как в примере 5.14.
Пример 5.14. Создание метода-конструктора


В примере 5.15 показано, что PHP���������������������������������������������
������������������������������������������������
5 предоставляет более логичный подход к присвоению имени конструктору, при котором функции присваивается имя __construct
(то есть к слову construct спереди добавляются два символа подчеркивания).
Пример 5.15. Создание метода-конструктора в PHP 5


Деструкторы в PHP 5
Еще одним нововведением в �������������������������������������������������
PHP����������������������������������������������
5 стала возможность создания методов-деструкторов. Эта возможность подходит для тех случаев, когда код ссылается на объект
в последний раз или когда сценарий подошел к концу. В примере 5.16 показано,
как создается метод-деструктор.
Пример 5.16. Создание в PHP 5 метода-деструктора


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

Объекты PHP

143

тает, посмотрите на код примера 5.17, содержащий еще один метод из определения
класса User, который называется get_password.
Пример 5.17. Использование в методе переменной $this


Метод получения пароля — get_password — применяет переменную $this для
доступа к текущему объекту, а затем возвращает значение свойства password, принадлежащего этому объекту. Обратите внимание на то, как при использовании
оператора -> в имени свойства $password опускается первый символ $. Если оставить
его на прежнем месте, особенно при первом применении этого свойства, будет допущена весьма типичная ошибка.
Класс, определенный в примере 5.17, нужно использовать следующим образом:
$object
= new User;
$object->password = "secret";
echo $object->get_password();

Этот код выводит пароль secret.

Статические методы в PHP 5
При работе в PHP 5 можно также определить метод как статический, что будет
означать возможность его вызова в классе, но не в объекте. Статический метод
не имеет доступа ни к одному из свойств объекта, а создание такого метода и доступ
к нему показаны в примере 5.18.
Пример 5.18. Создание статического метода и доступ к нему


Обратите внимание на то, как наряду со статическим методом вызывается сам класс
и как при этом вместо оператора -> используется оператор двойного двоеточия (::),

144

Глава 5. Функции и объекты PHP

также известный как оператор разрешения области видимости. Статические функции полезны для совершения действий, относящихся к самому классу, но не к конкретным экземплярам этого класса. Еще один пример статического метода показан
в примере 5.21 далее.
При попытке получить доступ к свойству текущего объекта с помощью выражения $this>property или получить доступ к другим свойствам объекта внутри статической функции
будет выдано сообщение об ошибке.

Объявление свойств
В явном объявлении свойств внутри классов нет необходимости, поскольку они
могут быть определены неявным образом при первом же их использовании. Для
иллюстрации этой особенности класс User в примере 5.19 не имеет ни свойств,
ни методов, но при этом в коде его определения нет ничего противозаконного.
Пример 5.19. Неявное объявление свойства


Этот код вполне корректно и без проблем выведет строку Alice, поскольку PHP
неявным образом объявит для вас переменную $object1->name. Но такой стиль программирования может привести к ошибкам, найти которые будет невероятно
трудно, поскольку свойство name было объявлено за пределами класса.
Чтобы не создавать трудностей ни себе, ни тому, кто впоследствии будет обслуживать ваш код, я советую выработать привычку всегда объявлять свойства внутри
класса в явном виде. И поверьте, вы об этом никогда не пожалеете.
К тому же, когда свойство объявляется внутри класса, ему можно присвоить
значение по умолчанию. Используемое вами значение должно быть константой,
а не результатом вызова функции или вычисления выражения. Несколько допустимых и недопустимых присваиваний показано в примере 5.20.
Пример 5.20. Допустимые и недопустимые объявления свойств


=
=
=
=

"Paul Smith";
42;
time();
$level * 2;

//
//
//
//

Допустимое
Допустимое
Недопустимое — вызывает функцию
Недопустимое — использует выражение

145

Объекты PHP

Объявление констант
По аналогии с созданием глобальных констант внутри определения функций
можно определять константы и внутри классов. Чтобы константы выделялись на
общем фоне, обычно для их имен используют буквы верхнего регистра (пример 5.21).
Пример 5.21. Определение констант внутри класса


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

Область видимости свойств
и методов в PHP 5
PHP 5 предоставляет три ключевых слова для управления областью видимости
свойств и методов:
 public (открытые). Свойства с этой областью видимости получаются по умолчанию при объявлении переменной с помощью ключевых слов var или public

или когда переменная объявляется неявно при первом же ее использовании.
Ключевые слова var и public являются взаимозаменяемыми. Хотя сейчас использование var не приветствуется, оно сохранено для совместимости с предыдущими версиями PHP. Методы считаются открытыми по умолчанию;
 protected (защищенные). На свойства и методы с этой областью видимости

можно ссылаться только через принадлежащие объектам методы класса и такие же методы любых подклассов;

146

Глава 5. Функции и объекты PHP

 private (закрытые). К представителям класса с этой областью видимости мож-

но обращаться через методы этого же класса, но не через методы его подклассов.
Решение о том, какую область видимости применить, принимается на основе
следующих положений:
 открытую (public) область видимости следует применять, когда к представителю класса нужен доступ из внешнего кода и когда расширенные классы должны
его наследовать;
 защищенную (protected) область видимости необходимо использовать, когда

к представителю класса не должно быть доступа из внешнего кода, но расширенные классы все же должны его наследовать;
 закрытую (private) область видимости следует применять, когда к представи-

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


Статические свойства и методы
Большинство данных и методов применяются в экземплярах класса. Например,
в классе User следует установить конкретный пароль пользователя или проверить,
когда пользователь был зарегистрирован. Эти факты и операции имеют особое
отношение к каждому конкретному пользователю и поэтому применяют специфические для экземпляра свойства и методы.
Но время от времени возникает потребность обслуживать данные, относящиеся целиком ко всему классу. Например, для отчета о том, сколько пользователей
зарегистрировалось, будет храниться переменная, имеющая отношение ко всему
классу User. Для таких данных PHP предоставляет статические свойства иметоды.
В примере������������������������������������������������������������������
 �����������������������������������������������������������������
5.18 было показано, что объявление представителей класса статическими делает их доступными и без создания экземпляров класса. Свойство, объявленное статическим, не может быть доступно непосредственно из экземпляра
класса, но может быть доступно из статического метода.

Объекты PHP

147

В примере 5.23 определяется класс по имени Test, в котором содержатся статическое свойство и открытый метод.
Пример 5.23. Определение класса со статическим свойством


Когда код будет запущен на выполнение, он выдаст следующую информацию:
Test A: Это статическое свойство
Test B: Это статическое свойство
Notice: Undefined property: Test::$static_property
Test C:

В этом примере показано, что на свойство $static_property можно ссылаться
напрямую из самого класса, используя в Test A оператор двойного двоеточия. Test B
также может получить его значение путем вызова метода get_sp объекта $temp,
созданного из класса Test. Но Test C терпит неудачу, потому что статическое свойство $static_property недоступно объекту $temp.
Обратите внимание на то, как метод get_sp получает доступ к свойству $static_
property, используя ключевое слово self. Именно таким способом можно получить непосредственный доступ к статическому свойству или константе внутри
класса.

Наследование
Как только класс будет создан, из него можно будет получить подкласс. Это сэкономит массу времени: вместо скрупулезного переписывания кода можно будет
взять класс, похожий на тот, который следует создать, распространить его на подкласс и просто внести изменения в те места, которые будут иметь характерные
особенности. Это достигается за счет использования инструкции extends.
В примере 5.24 класс Subscriber объявляется подклассом User путем использования инструкции extends.

148

Глава 5. Функции и объекты PHP

Пример 5.24. Наследование и распространение класса


У исходного класса User имеются два свойства — $name и $password, а также метод
для сохранения данных текущего пользователя в базе данных. Подкласс Subscriber
расширяет этот класс за счет добавления еще двух свойств — $phone и $email и включения метода, отображающего свойства текущего объекта, который использует переменную $this. Данная переменная ссылается на текущее значение объекта, к которому осуществляется доступ. Этот код выведет следующую информацию:
Name:
Pass:
Phone:
Email:

Fred
pword
012 345 6789
fred@bloggs.com

Инструкция parent
Когда в подклассе создается метод с именем, которое уже фигурирует в его родительском классе, его инструкции переписывают инструкции из родительского
класса. Иногда такое поведение идет вразрез с вашими желаниями, и вам нужно
получить доступ к родительскому методу. Для этого можно воспользоваться инструкцией parent, которая показана в примере 5.25.

Объекты PHP

149

Пример 5.25. Переписывание метода и использование инструкции parent


Этот код создает класс по имени Dad (Отец), а затем подкласс по имени Son (Сын),
который наследует свойства и методы родительского класса, а затем переписывает
метод test. Поэтому, когда во второй строке кода вызывается метод test, выполняется новый метод. Единственный способ выполнения переписанного метода test
в том варианте, в котором он существует в классе Dad, заключается в использовании
инструкции parent, как показано в функции test2 класса Son. Этот код выведет
следующую информацию:
[Class Son] Я Лука
[Class Dad] Я твой отец

Если нужно обеспечить вызов метода из текущего класса, можно воспользоваться ключевым словом self:
self::method();

Конструкторы подкласса
При распространении класса и объявлении собственного конструктора вы должны
знать, что ����������������������������������������������������������������
PHP�������������������������������������������������������������
не станет автоматически вызывать метод-конструктор родительского класса. Чтобы обеспечивалось выполнение всего кода инициализации, подкласс, как показано в примере 5.26, всегда должен вызывать родительские конструкторы.

150

Глава 5. Функции и объекты PHP

Пример 5.26. Вызов конструктора родительского класса


В этом примере используются обычные преимущества наследования. В классе
Wildcat (Дикая кошка) создается свойство $fur (мех), которое хотелось бы использовать многократно, потому мы создаем класс Tiger (Тигр), наследующий свойство
$fur, и дополнительно создаем еще одно свойство — $stripes (полосы). Чтобы про-

верить вызов обоих конструкторов, программа выводит следующую информацию:
У тигров есть...
Мех: TRUE
Полосы: TRUE

Методы Final
При необходимости помешать подклассу переписать метод суперкласса можно воспользоваться ключевым словом final. Как это делается, показано в примере 5.27.
Пример 5.27. Создание метода final


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

Вопросы
Вопрос 5.1
Каково основное преимущество, получаемое при использовании функции?
Вопрос 5.2
Сколько значений может вернуть функция?
Вопрос 5.3
В чем разница между доступом к переменной по имени и по ссылке?
Вопрос 5.4
Что в PHP означает термин «область видимости»?
Вопрос 5.5
Как можно включить один файл PHP в другой?
Вопрос 5.6
Чем объект отличается от функции?
Вопрос 5.7
Как в PHP создаются новые объекты?
Вопрос 5.8
Какой синтаксис используется для создания подкласса из существующего класса?
Вопрос 5.9
Как можно вызвать инициализирующую часть кода при создании объекта?
Вопрос 5.10
Почему объявлять свойства внутри класса лучше явным образом?
Ответы на эти вопросы можно найти в приложении А, в разделе «Ответы на
вопросы главы 5».

6

Массивы
в PHP

В главе 3 у нас уже состоялось краткое знакомство с массивами в PHP, позволи­
вшее составить первичное представление об их возможностях. В данной главе будет продемонстрирован большой арсенал приемов работы с массивами, некоторые
из них при наличии у вас опыта работы с языками со строгой типизацией, например C, могут удивить своей простотой и изяществом.
Массивы — одна из составляющих популярности PHP. Кроме того, что они
не дают умереть со скуки при создании кода для работы со сложными структурами
данных, они предоставляют множество невероятно быстрых способов доступа
к данным.

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

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

Основные подходы к массивам

153

Пример 6.1. Добавление элементов в массив


В этом примере при каждом присваивании массиву $paper значения для хранения последнего используется первое же свободное место, а значение существу­ющего
в PHP внутреннего указателя увеличивается на единицу, чтобы указывать на
свободное место, готовое для следующей вставки значения. Уже известная нам
функция print_r (которая выводит на экран содержимое переменной, массива или
объекта) применяется для проверки правильности заполнения массива. Результат
ее работы имеет следующий вид:
Array
(
[0]
[1]
[2]
[3]
)

=>
=>
=>
=>

Copier
Inkjet
Laser
Photo

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


Этот пример выведет такую�����������������������������������������������
 ����������������������������������������������
же информацию, как и предыдущий, но в разрабатываемом сайте вы вряд ли будете пользоваться функцией print_r, поэтому в примере 6.3 показано, как с помощью цикла можно распечатать сведения о различных
типах бумаги, предлагаемых на сайте.
Пример 6.3. Добавление элементов в массив и извлечение их из массива


Этот пример выведет следующую информацию:
0:
1:
2:
3:

Copier
Inkjet
Laser
Photo

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

Ассоциативные массивы
Конечно, можно, отслеживать элементы массива по индексам, но тогда придется
помнить, какой именно номер на какой товар ссылается. Кроме того, за вашим
кодом трудно будет уследить другим программистам.
Самое время обратиться к ассоциативным массивам. Использование этих массивов позволяет ссылаться на элементы массива по именам, а не по номерам. В примере������������������������������������������������������������������������
 �����������������������������������������������������������������������
6.4 приводится расширенная версия предыдущего кода, где каждому элементу массива дается имя для идентификации и более длинное и информативное
строковое значение.
Пример 6.4. Добавление элементов к ассоциативному массиву и извлечение этих
элементов


Теперь у каждого элемента вместо числа (не содержащего никакой полезной
информации, кроме позиции элемента в массиве) имеется уникальное имя, по
которому на него можно сослаться где-нибудь в другом месте, как в случае с инструкцией echo, которая выводит на экран Laser Printer. Имена (copier, inkjet и т. д.)
называются индексами, или ключами, а присвоенные им элементы (например, Laser
Printer) — значениями.
Это весьма мощное свойство �������������������������������������������
PHP����������������������������������������
часто применяется при извлечении информации из кода �������������������������������������������������������
XML����������������������������������������������������
�������������������������������������������������
HTML���������������������������������������������
. Например, ���������������������������������
HTML�����������������������������
-парсер, используемый в поис-

155

Основные подходы к массивам

ковой системе, может помещать все элементы веб-страницы в ассоциативный
массив, имена которого отображают структуру страницы:
$html['title'] = "Моя веб-страница";
$html['body'] = "... тело веб-страницы ...";

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

Присваивание с использованием
ключевого слова array
Мы уже видели, как элементам массива присваиваются значения путем последовательного добавления к этому массиву новых элементов. Но это слишком затянутый процесс, независимо от того, что при этом происходит: вы определяете ключи,
числовые идентификаторы или позволяете �����������������������������������
PHP��������������������������������
неявным образом заниматься присваиванием числовых идентификаторов. Есть более краткий и быстрый способ
присваивания значений с использованием ключевого слова array. В примере 6.5
показаны оба массива — числовой и ассоциативный, значения которым присваиваются именно этим способом.
Пример 6.5. Добавление элементов к массиву с использованием ключевого слова array


В первой части этого кодового фрагмента массиву $p1 присваивается старое,
укороченное описание товара. Здесь используются четыре элемента, поэтому они
занимают позиции от 0 до 3. Инструкция echo выводит следующий текст:
Элемент массива p1: Laser

Во второй части кода массиву $p2 присваиваются ассоциативные идентификаторы и сопутствующие им длинные описания товаров. Для этого применяется
формат индекс => значение. Применение оператора => похоже на использование
простого оператора присваивания =, за исключением того, что значение присваивается индексу, а не переменной. После этого индекс приобретает неразрывную связь

156

Глава 6. Массивы в PHP

с этим значением до тех пор, пока ему не будет присвоено другое значение. Поэтому команда echo выводит следующий текст:
Элемент массива p2: Inkjet Printer

В том, что $p1 и $p2 принадлежат к разным типам массивов, можно убедиться,
если вставить в код две следующие команды, вызывающие ошибку неопределенного индекса или ошибку неопределенного смещения, поскольку для каждого из
массивов используется неподходящий идентификатор:
echo $p1['inkjet']; // Неопределенный индекс
echo $p2['3'];
// Неопределенное смещение

Цикл foreach...as
Создатели �����������������������������������������������������������������
PHP��������������������������������������������������������������
постарались сделать этот язык простым в использовании. Поэтому они не остановились на уже имеющихся структурах организации цикла, а добавили еще одну структуру, специально предназначенную для массивов, — цикл
foreach...as. Используя этот цикл, можно поочередно перебрать все элементы массива и произвести с ними какие-нибудь действия.
Процесс начинается с первого элемента и заканчивается последним, поэтому
вам даже не нужно знать, сколько элементов присутствует в массиве.
В примере 6.6 показано, как цикл foreach...as может использоваться для переписывания кода примера 6.3.
Пример 6.6. Последовательный перебор элементов числового массива с использованием
цикла foreach...as


Когда PHP встречает инструкцию foreach, он извлекает первый элемент массива и помещает его значение в переменную, указанную после ключевого слова as,
и при каждом возвращении управления инструкции foreach в эту переменную помещается значение следующего элемента массива. В данном случае переменной
$item присваиваются по очереди все четыре значения, хранящиеся в массиве $paper.
Как только будут использованы все значения, выполнение цикла завершается. Этот
код выводит точно такую же информацию, что и код примера 6.3.
Теперь посмотрим, как foreach работает с ассоциативным массивом. В примере 6.7 переписана вторая часть примера 6.5.

157

Цикл foreach...as

Пример 6.7. Последовательный перебор элементов ассоциативного массива
с использованием цикла foreach...as


Вспомним, что ассоциативным массивам не требуются числовые индексы, поэтому переменная $j в данном примере не используется. Вместо этого каждый
элемент массива $paper вводится в пару «ключ — значение», представленную переменными $item и $description, из которых эта пара выводится на экран в следующем
виде:
copier: Copier & Multipurpose
inkjet: Inkjet Printer
laser: Laser Printer
photo: Photographic Paper

В качестве альтернативы синтаксису foreach...as можно воспользоваться функцией list в сочетании с функцией each (пример 6.8).
Пример 6.8. Последовательный перебор элементов ассоциативного массива с помощью
функций each и list


В этом примере организуется цикл while, который будет продолжать работу до
тех пор, пока функция each не вернет значение FALSE. Функция each ведет себя
как foreach: она возвращает из массива $paper массив, содержащий пару «ключ —
значение», а затем перемещает встроенный указатель на следующую пару в исходном массиве. Когда возвращать становится нечего, функция each возвращает
значение FALSE.
Функция list в качестве аргументов принимает массив (в данном случае пару
«ключ — значение», возвращенную функцией each), а затем присваивает значения
массива переменным, перечисленным внутри круглых скобок.

158

Глава 6. Массивы в PHP

Лучше понять работу функции list можно из примера 6.9, где массив создается
из двух строк — Alice и Bob, а затем передается функции list, которая присваивает
эти строки переменным $a и $b.
Пример 6.9. Использование функции list


Этот код выводит следующий текст:
a=Alice b=Bob

Итак, для перебора элементов массива можно применять различные подходы.
Можно воспользоваться конструкцией foreach...as для создания цикла, извлекающего значения в переменную, которая следует за as, или воспользоваться функцией each и создать собственную систему циклической обработки.

Многомерные массивы
Простая конструктивная особенность синтаксиса массивов ��������������������
PHP�����������������
позволяет создавать массивы более чем с одним измерением. Фактически можно создавать массивы какой угодно размерности (хотя приложения редко нуждаются в массивах с размерностью больше трех).
Эта особенность заключается в возможности включать целый массив в состав
другого массива, а также делать это снова и снова, как в старом стишке про блох,
которых кусают другие блохи поменьше, а тех, в свою очередь, кусают свои блохи,
и так до бесконечности.
Рассмотрим, как это работает, для чего возьмем ассоциативный массив из предыдущего примера и расширим его (пример 6.10).
Пример 6.10. Создание многомерного ассоциативного массива


Чтобы упростить понимание начинающего разрастаться кода, я переименовал
часть элементов. Например, поскольку предыдущий массив $paper стал лишь подразделом более крупного массива, главный массив теперь называется $products.
В этом массиве присутствуют три элемента: бумага — paper, ручки — pens и разные
товары — misc, и каждый из них содержит другой массив, состоящий из пар «ключ —
значение».
При необходимости эти подмассивы могут содержать другие массивы. Например, элемент шариковые ручки — ball — может содержать множество типовых
и цветовых решений этого товара, имеющихся в интернет-магазине. Но пока я ограничил код глубиной в два измерения.
После присваивания массивам данных для вывода различных значений я воспользовался парой вложенных циклов foreach...as. Внешний цикл извлекает из
верхнего уровня массива основные разделы, а внутренний цикл извлекает для
категорий в каждом разделе пары «ключ — значение».
Если вспомнить, что все уровни массива работают одинаково (являясь парой
«ключ — значение»), можно без особого труда создать код для доступа к любому
элементу на любом уровне.
В инструкции echo используется управляющий символ PHP \t, который выводит знак табуляции.
Хотя знаки табуляции для браузеров, как правило, ничего не значат, я использовал их в разметке, применив теги ..., которые предписывают браузеру форматировать текст с сохранением предварительного формата и фиксированной ширины и не игнорировать неотображаемые символы вроде знаков табуляции
и переводов строки. Текст, выводимый этим кодом, будет иметь следующий вид:
paper:
paper:
paper:
paper:
pens:
pens:
pens:
misc:
misc:
misc:

copier
inkjet
laser
photo
ball
hilite
marker
tape
glue
clips

(Copier & Multipurpose)
(Inkjet Printer)
(Laser Printer)
(Photographic Paper)
(Ball Point)
(Highlighters)
(Markers)
(Sticky Tape)
(Adhesives)
(Paperclips)

160

Глава 6. Массивы в PHP

Непосредственный доступ к конкретному элементу массива можно получить,
используя квадратные скобки:
echo $products['misc']['glue'];

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


В этом примере буквы в нижнем регистре представляют собой черные фигуры,
а в верхнем регистре — белые. Используются следующие обозначения: r — rook
(ладья), n — knight (конь), b — bishop (слон), k — king (король), q — queen (ферзь)
и p — pawn (пешка). Для последовательного перебора массива и демонстрации его
содержимого снова используется пара вложенных циклов foreach...as. Внешний
цикл обрабатывает каждую горизонталь и помещает ее в переменную $row, которая
сама по себе является массивом, поскольку для каждой горизонтали массив шахматной доски — $chessboard — использует подмассив. В этом цикле используются
две инструкции, поэтому они заключены в фигурные скобки.
Внутренний цикл обрабатывает каждую клетку горизонтали, выводя хранящийся в ней символ ($piece), за которым следует пробел (чтобы выводимый текст имел
форму шахматной доски). У этого цикла одна инструкция, которую не нужно заключать в фигурные скобки. Теги и обеспечивают правильную форму
выводимого текста:

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

161

r n b q k b n r
p p p p p p p p

P P P P P P P P
R N B Q K B N R

Используя квадратные скобки, можно получить непосредственный доступ
к любому элементу этого массива:
echo $chessboard[7][3];

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

Использование функций
для работы с массивами
С функциями list и each вы уже знакомы, но в PHP имеется множество других
функций, предназначенных для работы с массивами. Их полный перечень представлен по адресу http://tinyurl.com/phparrayfuncs. Но некоторые из этих функций
играют настолько важную роль в программировании на PHP, что мы изучим их
подробнее.

is_array
Массивы и переменные используют одно и то же пространство имен. Это означает,
что нельзя иметь строковую переменную по имени $fred и массив, который также
называется $fred. Если есть сомнения и в коде программы нужно проверить, является ли переменная массивом, можно воспользоваться функцией is_array:
echo (is_array($fred)) ? "Это массив" : "Это не массив";

Заметьте, что переменной $fred не присвоено никакого значения, поэтому будет
выведено сообщение о неопределенной переменной — Undefined variable.

count
Несмотря на то что функция each и структура организации цикла foreach...as
предоставляют отличные способы последовательного перебора всего содержимого
массива, иногда нужно точно знать, сколько элементов содержится в вашем массиве, особенно если вы будете обращаться к ним напрямую. Для подсчета всех
элементов на верхнем уровне массива используется следующая команда:
echo count($fred);

162

Глава 6. Массивы в PHP

Если нужно узнать, сколько всего элементов содержится в многомерном массиве, можно воспользоваться следующей инструкцией:
echo count($fred, 1);

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

sort
Сортировка является настолько распространенной операцией, что PHP�����������
��������������
предоставляет для нее встроенную функцию. В наипростейшей форме ее можно использовать следующим образом:
sort($fred);

В отличие от некоторых других функций, сортировка будет работать непосредственно с предоставленным ей массивом, а не возвращать новый массив с отсор­
тированными элементами. Вместо этого она вернет значение TRUE при успешном
выполнении сортировки и FALSE — в случае возникновения ошибки. Эта функция
поддерживает также несколько флагов. Основные два, которые вам могут пригодиться, предписывают проведение либо числовой, либо строковой сортировки:
sort($fred, SORT_NUMERIC);
sort($fred, SORT_STRING);

Массив можно также отсортировать в обратном порядке, воспользовавшись
функцией rsort:
rsort($fred, SORT_NUMERIC);
rsort($fred, SORT_STRING);

shuffle
Иногда, например при создании игры или при игре в карты, требуется, чтобы элементы массива располагались в случайном порядке:
shuffle($cards);

Как и функция sort, функция shuffle работает непосредственно с предоставленным ей массивом и возвращает значение TRUE в случае успешного завершения работы и FALSE — при возникновении ошибки.

explode
Это очень полезная функция, позволяющая взять строку, содержащую несколько
элементов, отделенных друг от друга одиночным символом (или строкой символов), а затем поместить каждый из этих элементов в массив. В примере 6.12 показан
один из случаев полезного применения этой функции, который заключается в раз-

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

163

биении предложения на слова и помещении всех слов, из которого оно состоит,
в массив.
Пример 6.12. Извлечение слов из строки в массив с использованием пробелов


Этот пример выводит следующую информацию (которая при просмотре в браузере будет отображена в одной строке):
Array
(
[0]
[1]
[2]
[3]
[4]
)

=>
=>
=>
=>
=>

Это
предложение
из
пяти
слов

Первый параметр — разделитель — не обязательно должен быть пробелом или
даже одиночным символом. В примере 6.13 показан этот же код в несколько измененном виде.
Пример 6.13. Извлечение слов, разделенных символами ***, из строки в массив


Код примера 6.13 выводит следующую информацию:
Array
(
[0]
[1]
[2]
[3]
)

=>
=>
=>
=>

Это
предложение
со
звездочками

extract
Иногда бывает удобно превратить пары «ключ — значение» из массива в переменные PHP. Один из таких случаев — это обработка переменных $_GET или $_POST,
отправленных формой сценарию PHP.
Когда форма передается через Интернет, веб-сервер распаковывает переменные и помещает их в глобальный массив, предназначенный для сценария PHP.
Если переменные были отправлены методом GET, они будут помещены в ассоциативный массив $_GET, а при отправке методом POST будут помещены в ассоциативный массив $_POST.

164

Глава 6. Массивы в PHP

Разумеется, можно перебрать все элементы этих ассоциативных массивов, воспользовавшись уже рассмотренными в этой главе способами. Но иногда нужно
лишь сохранить отправленные значения в переменных для дальнейшего использования. В таком случае можно заставить PHP������������������������������������
���������������������������������������
проделать эту работу за вас в автоматическом режиме:
extract($_GET);

Таким образом, к примеру, если параметр строки запроса q отправлен сценарию
PHP наряду со связанным с ним значением Hi there, будет создана новая переменная по имени $q, которой будет присвоено это значение.
Но к описанному подходу нужно относиться осторожно, поскольку если какиенибудь извлекаемые переменные конфликтуют с уже определенными переменными, то существующие переменные будут переписаны. Чтобы избежать этого, можно воспользоваться одним из многих дополнительных параметров, доступных
в данной функции:
extract($_GET, EXTR_PREFIX_ALL, 'fromget');

В этом случае имена всех новых переменных будут начинаться с заданного строкового префикса, за которым следует символ подчеркивания, в результате чего $q
превратится в $fromget_q. Я настоятельно рекомендую при обработке массивов $_GET
и $_POST или любого другого массива, ключи которого могут контролироваться пользователем, использовать именно эту версию функции. Поскольку злоумышленники
могут отправлять ключи, специально подобранные для того, чтобы переписать переменные с часто используемыми именами и таким образом угрожать вашему сайту.

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


В результате запуска кода из примера�������������������������������������
 ������������������������������������
6.14 будет выведена следующая информация:
Array
(
[fname] => Doctor
[sname] => Who

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

165

[planet] => Gallifrey
[system] => Gridlock
[constellation] => Kasterborous
)

Обратите внимание на то, что функции compact нужны имена переменных, стоящие в кавычках и не содержащие начального символа $. Причина заключается
в том, что функция compact ищет список имен переменных.
Эту функцию можно использовать также для отладки, когда нужно быстро просмотреть несколько переменных вместе с их значениями, как в примере 6.15.
Пример 6.15.


Работа примера основана на использовании функции explode для извлечения
всех слов из строки в массив, который затем передается функции compact, а она,
в свою очередь, возвращает массив функции print_r, которая в итоге показывает
его содержимое.
Если скопировать и вставить строку кода, содержащую вызов функции print_r,
то в ней нужно будет лишь изменить имена переменных, чтобы быстро вывести
группу их значений. В этом примере выводимая информация будет иметь следующий вид:
Array
(
[j] => 23
[temp] => Hello
[address] => 1 Old Street
[age] => 61
)

reset
Когда с помощью конструкции foreach...as или функции each осуществляется последовательный перебор элементов массива, они перемещают внутренний указатель ������������������������������������������������������������������������
PHP���������������������������������������������������������������������
, который показывает, какой из элементов массива нужно извлечь в следующий раз. Если коду программы понадобится вернуться к началу массива, то
можно воспользоваться функцией reset, а она к тому же вернет значение элемента,
на котором остановился указатель. Эта функция может быть использована следующим образом:
reset($fred);
// Отбрасывание возвращаемого значения
$item = reset($fred); // Сохранение первого элемента массива
// в переменной $item

166

Глава 6. Массивы в PHP

end
Можно также переместить внутренний указатель элемента массива PHP�������
����������
на последний элемент, воспользовавшись для этого функцией end, которая, кроме этого,
возвращает значение элемента и может быть использована следующим образом:
end($fred);
$item = end($fred);

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

Вопросы
Вопрос 6.1
В чем разница между числовым и ассоциативным массивом?
Вопрос 6.2
Каковы основные преимущества использования ключевого слова array?
Вопрос 6.3
В чем разница между foreach и each?
Вопрос 6.4
Как создается многомерный массив?
Вопрос 6.5
Как определить количество элементов в массиве?
Вопрос 6.6
Каково назначение функции explode?
Вопрос 6.7
Как вернуть внутренний указатель элемента массива ����������������������
PHP�������������������
на его первый элемент?
Ответы на эти вопросы можно найти в приложении А, в разделе «Ответы на
вопросы главы 6».

7

Практикум
по программированию
на PHP

В предыдущих главах рассматривались элементы языка ������������������������
PHP���������������������
. А эта глава предназначена для приобретения навыков программирования в процессе решения типовых, но тем не менее важных практических задач.
Здесь будут представлены лучшие способы обработки строк, позволяющие
получить вполне понятный и лаконичный код, который включает усовершенствованное управление отображением даты и времени и демонстрируется браузерами
в точном соответствии с вашими желаниями. Вы также узнаете о создании и разнообразных способах изменения файлов, включая файлы, выложенные на сайт
пользователями.
В этой главе будет также дано полноценное введение в ����������������
XHTML�����������
, язык разметки, похожий на HTML и предназначенный для его замены (согласующийся
с синтаксисом XML, который используется для хранения данных, например
RSS�������������������������������������������������������������������������
-потоков). В совокупности все это расширит вашу осведомленность как в области практического программирования на ������������������������������������
PHP���������������������������������
, так и в сфере развития международных веб-стандартов.

Функция printf
Ранее нам уже встречались функции print и echo, которые использовались для
простого вывода текста в браузер. Но существует намного более мощная функция
printf, управляющая форматом выводимых данных путем вставки в строку специальных форматирующих символов. Функция printf ожидает, что для каждого форматирующего символа будет предоставлен аргумент, который будет отображаться
с использованием заданного формата. Например, в следующем фрагменте применяется спецификатор преобразования %d, чтобы значение 3 отображалось в виде
десятичного числа:
printf("В вашей корзине находится %d покупки", 3);

Если заменить %d на %b, значение 3 будет отображено в виде двоичного числа (11). В табл. 7.1 показаны поддерживаемые функцией спецификаторы преобразования.

168

Глава 7. Практикум по программированию на PHP
Таблица 7.1. Спецификаторы преобразования, используемые в функции printf

Специ­фи­катор

Преобразование, осуществляемое
с аргументом arg

Пример (для arg,
имеющего значение 123)

%

Отображение символа % (аргументы не требуются)

%

b

Отображение arg в виде двоичного целого
числа

1111011

c

Отображение ASCII-символа с кодом, содержа- {
щимся в arg

d

Отображение arg в виде целого десятичного
числа со знаком

123

e

Отображение arg с использованием научной
формы записи

1.23000e+2

f

Отображение arg в виде числа с плавающей
точкой

123.000000

o

Отображение arg в виде восьмеричного целого 173
числа

s

Отображение arg в виде строки

u

Отображение arg в виде беззнакового десятич- 123
ного числа

x

Отображение arg в виде шестнадцатеричного
числа с символами в нижнем регистре

7b

X

Отображение arg в виде шестнадцатеричного
числа с символами в верхнем регистре

7B

123

В функции printf можно использовать любое количество спецификаторов, если
им передается соответствующее количество аргументов и если каждый спецификатор предваряется символом %. Поэтому следующий код имеет вполне допустимую
форму и выводит предложение: «Меня зовут Симон. Мне 33 года, то есть 21
в шестнадцатеричном представлении»:
printf("Меня зовут %s. Мне %d года, то есть %X в шестнадцатеричном представлении",
'Симон', 33, 33);

Если пропустить какой-нибудь аргумент, то будет получена ошибка синтаксического разбора, информирующая о том, что правая круглая скобка ()) была встречена в неожиданном месте.
Более полезный с практической точки зрения пример использования функции
printf устанавливает цвета в коде HTML, используя для этого десятичные числа.
Предположим, к примеру, что вам нужен цвет, составленный из трех значений:
65 для красного, 127 для зеленого и 245 для синего цвета, но вам не хочется самостоятельно переводить эти числа в шестнадцатеричный формат. Для этого есть
более простое решение:
printf("Привет", 65, 127, 245);

Функция printf

169

Тщательно разберитесь с цветовой спецификацией, которая заключена в апострофы (''). Сначала ставится знак решетки (#), ожидаемый в цветовой спецификации. Затем следуют три форматирующие спецификации %X, по одной для каждого из ваших чисел. В результате эта команда выдаст следующий текст:
Привет

Обычно представляется удобным в качестве аргументов printf использовать
переменные или выражения. Например, если значения для цветового решения
хранятся в трех переменных — $r, $g и $b, то более темный оттенок можно получить
с помощью выражения:
printf("Привет", $r-20, $g-20, $b-20);

Настройка представления данных
Можно указать не только тип преобразования, но и точность отображаемого результата. Например, суммы в валюте отображаются, как правило, с точностью до
двух цифр. Но после вычисления значение может иметь более высокую точность
(например, если разделить 123,42 на 12, то получится 10,285). Чтобы обеспечить
правильное внутреннее хранение таких значений, но при этом организовать их
отображение с точностью только до двух цифр, можно между символом % и специ­
фикатором преобразования вставить строку .2:
printf("Результат: $%.2f", 123.42 / 12);

Эта команда выводит следующий текст:
Результат: $10.29

Но доступные средства управления на этом не заканчиваются, потому что можно также указать, где и чем — нулями или пробелами — дополнить выводимый
текст, поставив перед спецификатором соответствующие значения. В примере 7.1
показаны пять возможных комбинаций.
Пример 7.1. Настройка преставления данных точности
em { background:lime; }

Селекторы смежных элементов

i + b { color:gray; }

Селекторы атрибутов

a[href='info.htm'] { color:red; }

Псевдоклассы

a:hover { font-weight:bold; }

Псевдоэлементы

p::first-letter { font-size:300%; }

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

Соответствие частям строк
В CSS2 для поиска соответствия строке 'info.htm', находящейся в href-атрибуте,
можно было использовать такой селектор, как a[href='info.htm'], но поиска соответствия только части строки не существовало. Однако в CSS3 пошли дальше
и определили три новых оператора: ^, $ и *. Если один из них непосредственно
предшествует символу равенства (=), то с помощью этих символов в том порядке,
в котором они перечислены, можно искать соответствие в начале, в конце или в любой части строки.

Оператор ^
Этот оператор задает поиск соответствия в начале строки, например, следующему
селектору будет соответствовать любой href-атрибут, чье значение начинается со
строки http://website:
a[href^='http://website']

Таким образом, ему будет соответствовать следующий элемент:


А этот элемент соответствовать не будет:


Свойство box-sizing

471

Оператор $
Для поиска соответствия только в конце строки можно использовать следующий
селектор, которому будет соответствовать любой img-тег, чей src-атрибут заканчивается на .png:
img[src$='.png']

Например, ему будет соответствовать такой тег:


А этот тег соответствовать не будет:


Оператор *
Для поиска соответствия любой подстроке, находящейся где-либо в атрибуте, можно воспользоваться следующим селектором. Он найдет любые ссылки на странице,
имеющие строку google в любом месте ссылки:
a[href*='google']

Например, ему будет соответствовать эта часть кода HTML:


а эта часть соответствовать не будет:


Свойство box-sizing
В модели блока ������������������������������������������������������������
W�����������������������������������������������������������
3����������������������������������������������������������
C���������������������������������������������������������
определено, что ширина и высота объекта должны относиться только к размерам содержимого элемента, игнорируя любые отступы или границы. Но некоторые веб-дизайнеры выразили желание указывать размеры, относящиеся ко всему элементу, включая любые отступы и границы.
Чтобы предоставить такое свойство, CSS3 позволяет вам выбрать желаемую
модель блока со свойством задания размеров блока — box-sizing. Например, для
использования общей ширины и высоты объекта, включая отступы и границы,
нужно применять следующее объявление:
box-sizing:border-box;

Или, чтобы ширина и высота объекта относились только к содержимому, нужно воспользоваться таким объявлением (применяемым по умолчанию):
box-sizing:content-box;
Браузеры на движках WebKit и Mozilla (такие как Safari и Firefox соответственно) требуют для
этого объявления использованиясобственных префиксов (‑webkit- и -moz-), о чем подробно
рассказывается на сайте http://caniuse.com.

472

Глава 19. Расширение CSS с помощью CSS3

Создание фона в CSS3
Спецификация CSS3 предоставляет два новых свойства: background-clip и background-origin, которые могут использоваться для указания, где фон должен начинаться внутри элемента и как усекать фон так, чтобы он не появлялся в тех частях
модели блока, где это нежелательно.
Для выполнения названных задач оба свойства поддерживают следующие значения:
 border-box — относится к внешнему краю границы;
 padding-box — относится к внешнему краю области отступа;
 content-box — относится к внешнему краю области содержимого.

Свойство background-clip
Это свойство определяет, должен ли фон игнорироваться (усекаться), если он появляется либо внутри границы, либо в области отступов элемента. Например, следующее объявление определяет, что фон может отображаться во всех частях элемента, вплоть до внешнего края границы:
background-clip:border-box;

Если не нужно, чтобы фон появлялся в области границы элемента, его можно
ограничить только той частью элемента, которая находится внутри и заканчивается внешним краем его области отступов, например:
background-clip:padding-box;

Или же можно ограничить фон, чтобы он отображался только внутри области
содержимого элемента, воспользовавшись следующим объявлением:
background-clip:content-box;

На рис. 19.1 показаны три ряда элементов, отображаемых в браузере Safari:
в первом ряду для свойства background-clip используется значение border-box,
во втором применяется значение padding-box, а в третьем используется значение content-box.
В первом ряду внутреннему блоку (файлу изображения, загруженному в левую
верхнюю часть элемента с отключенным повторением) разрешается отображаться
в элементе везде. Можно также совершенно отчетливо видеть, что он отображается в области границы первого блока, поскольку стиль границы указан пунктирным.
Во втором ряду в области границы не отображаются ни фоновое изображение,
ни фоновое затенение, поскольку они были усечены по области отступов с помощью
установки для свойства background-clip значения padding-box.
И наконец, в третьем ряду и фоновое затенение, и фоновое изображение были
усечены для отображения только внутри области содержимого каждого элемента
(показанного внутри светлого, ограниченного пунктирной линией блока) путем
установки для свойства background-clip значения content-box.

Создание фона в CSS3

473

Рис. 19.1. Разные способы сочетания свойств фона CSS3

Свойство background-origin
С помощью этого свойства можно также указать, где должно располагаться фоновое изображение, определив для этого, где должен начинаться левый верхний угол
данного изображения. Например, следующее объявление указывает, что начало
фонового изображения должно быть в левом верхнем углу внешнего края границы:
background-origin:border-box;

Чтобы установить начало изображения в левый верхний внешний угол области
отступов, нужно воспользоваться таким объявлением:
background-origin:padding-box;

474

Глава 19. Расширение CSS с помощью CSS3

И чтобы установить начало изображения в левый верхний угол области внутреннего содержимого элемента, нужно воспользоваться следующим объявлением:
background-origin:content-box;

Посмотрите еще раз на рис. 19.1. В каждом ряду для первого блока используется свойство background-origin со значением border-box, для второго блока это же
свойство применяется со значением padding-box, а для третьего — со значением
content-box. Следовательно, в каждом ряду меньший по размеру внутренний блок
отображается для первого блока в левом верхнем углу границы, для второго он
отображается в левом верхнем углу области отступов, а для третьего — в левом
верхнем углу содержимого.
Единственное отличие рядов, которое стоит отметить в отношении начала внутреннего блока на рис. 19.1, состоит в том, что в рядах 2 и 3 внутренний блок усекается соответственно
областями отступов и содержимого, поэтому та часть блока, которая находится за пределами этих областей, не отображается.

Свойство background-size
Точно так же, как это делалось для указания ширины и высоты изображения при
использовании тега , в последних версиях всех браузеров можно сделать то же
самое для изображений фона.
Свойство можно применить следующим образом (здесь ww — ширина, а hh — высота):
background-size:wwpx hhpx;

При необходимости можно использовать только один аргумент, и для обоих
размеров будет установлено указанное значение. Кроме того, если применить данное свойство к блочному элементу, например к (но не к такому встроенному
элементу, как ), можно указать ширину и (или) высоту в процентном отношении, а не в виде фиксированного значения.
Использование значения auto. Если нужно масштабировать только один размер
фонового изображения, чтобы при этом автоматически масштабировался и другой
его размер для соблюдения прежних пропорций, для другого размера можно воспользоваться значением auto:
background-size:100px auto;

Этим объявлением устанавливается ширина, равная 100 пикселам, и высота,
равная значению, пропорциональному увеличению или уменьшению ширины.
Разные браузеры могут требовать различных версий имен свойства background, поэтому
при их использовании обратитесь к сайту http://caniuse.com, чтобы убедиться, что вы
применяете все версии, требуемые тем браузерам, на работу с которыми вы рассчитываете.

Создание фона в CSS3

475

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

Рис. 19.2. Фон, созданный с помощью нескольких изображений

Для вывода нескольких фоновых изображений с помощью одного CSS-объявления
нужно разделить их запятыми. В примере�������������������������������������
 ������������������������������������
19.1 показан код HTML���������������
�������������������
������������
CSS���������
, использованный для создания фона рис. 19.2.

476

Глава 19. Расширение CSS с помощью CSS3

Пример 19.1. Использование в фоне сразу нескольких изображений



CSS3: пример нескольких фоновых изображений

.border {
font-family:'Times New Roman';
font-style :italic;
font-size :170%;
text-align :center;
padding
:60px;
width
:350px;
height
:500px;
background :url('b1.gif') top
left no-repeat,
url('b2.gif') top
right no-repeat,
url('b3.gif') bottom left no-repeat,
url('b4.gif') bottom right no-repeat,
url('ba.gif') top
repeat-x,
url('bb.gif') left
repeat-y,
url('bc.gif') right
repeat-y,
url('bd.gif') bottom
repeat-x
}




Работник месяца
Награжден:
__________________
Дата:
___/___/_____




Первые четыре строки объявления фона в блоке ����������������������������
CSS�������������������������
расставляют угловые изображения по четырем углам элемента, а последние четыре строки помещают
изображения кромок, которые обрабатываются в последнюю очередь, потому что
порядок приоритетности для фоновых изображений имеет направление сверху вниз.
Иными словами, когда они накладываются друг на друга, дополнительные фоновые
изображения будут появляться позади уже размещенных изображений. Если бы
GIF�����������������������������������������������������������������������
-изображения были перечислены в обратном порядке, то повторяющиеся изображения кромок отображались бы поверх углов, что было бы неправильно.
Используя этот код CSS, можно изменять размеры содержащего фон элемента по любым
направлениям, и граница будет всегда правильно изменяться в размерах, чтобы поместиться в элементе, что намного проще, чем применять таблицы или несколько элементов для
получения такого же эффекта.

Границы CSS3

477

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

Свойство border-color
Применять цвета к границе можно двумя способами. Начнем с того, что свойству
можно передать всего один цвет:
border-color:#888;

Это объявление устанавливает светло-серый цвет для всех границ элемента.
Можно также установить цвета границ по отдельности (здесь цвета границы устанавливаются в различные градации серого):
border-top-color :#000;
border-left-color :#444;
border-right-color :#888;
border-bottom-color:#ccc;

Кроме того, можно назначить все цвета по отдельности в одном объявлении:
border-color:#f00 #0f0 #880 #00f;

Это объявление устанавливает цвет верхней границы в #f00, правой границы —
в #0f0, нижней границы — в #880 и левой границы — в #00f (в красный, зеленый,
оранжевый и синий соответственно). Можно также использовать в качестве аргументов названия цветов.

Свойство border-radius
До появления CSS��������������������������������������������������������
�����������������������������������������������������������
3 способные веб-разработчики придумали множество различных настроек с целью получения закругленных границ, используя, как правило,
теги или .
Но теперь добавление закругленных границ к элементу дается по-настоящему
легко, и, как показано на рис. 19.3, работает в последних версиях всех основных
браузеров. На этом рисунке граница толщиной 10 пикселов выведена различными способами. Код HTML�������������������������������������������������
�����������������������������������������������������
для получения такого результата показан в примере 19.2.
Пример 19.2. Свойство border-radius



CSS3: примеры радиусов границ

.box {

478

Глава 19. Расширение CSS с помощью CSS3

margin-bottom:10px;
font-family :'Courier New', monospace;
font-size
:12pt;
text-align
:center;
padding
:10px;
width
:380px;
height
:75px;
border
:10px solid #006; }
.b1 {
-moz-border-radius
:40px;
-webkit-border-radius:40px;
border-radius
:40px; }
.b2 {
-moz-border-radius
:40px 40px 20px 20px;
-webkit-border-radius:40px 40px 20px 20px;
border-radius
:40px 40px 20px 20px; }
.b3 {
-moz-border-radius-topleft
:20px;
-moz-border-radius-topright
:40px;
-moz-border-radius-bottomleft
:60px;
-moz-border-radius-bottomright
:80px;
-webkit-border-top-left-radius
:20px;
-webkit-border-top-right-radius
:40px;
-webkit-border-bottom-left-radius :60px;
-webkit-border-bottom-right-radius:80px;
border-top-left-radius
:20px;
border-top-right-radius
:40px;
border-bottom-left-radius
:60px;
border-bottom-right-radius
:80px; }
.b4 {
-moz-border-radius-topleft
:40px 20px;
-moz-border-radius-topright
:40px 20px;
-moz-border-radius-bottomleft
:20px 40px;
-moz-border-radius-bottomright
:20px 40px;
-webkit-border-top-left-radius
:40px 20px;
-webkit-border-top-right-radius
:40px 20px;
-webkit-border-bottom-left-radius :20px 40px;
-webkit-border-bottom-right-radius:20px 40px;
border-top-left-radius
:40px 20px;
border-top-right-radius
:40px 20px;
border-bottom-left-radius
:20px 40px;
border-bottom-right-radius
:20px 40px; }




border-radius:40px;



Границы CSS3

border-radius:40px 40px 20px 20px;


border-top-left-radius &nbsp;&nbsp;&nbsp;:20px;
border-top-right-radius &nbsp;&nbsp;:40px;
border-bottom-left-radius :60px;
border-bottom-right-radius:80px;


border-top-left-radius &nbsp;&nbsp;&nbsp;:40px 20px;
border-top-right-radius &nbsp;&nbsp;:40px 20px;
border-bottom-left-radius :20px 40px;
border-bottom-right-radius:20px 40px;




Рис. 19.3. Смешивания и сопоставления различных свойств радиусов границы

479

480

Глава 19. Расширение CSS с помощью CSS3

Так, например, для создания закругленной границы с радиусом 20 пикселов
можно просто воспользоваться следующим объявлением:
border-radius:20px;

Хотя многие браузеры (включая Internet Explorer) со свойствами радиусов границы будут
работать хорошо, некоторые текущие (и многие более старые) версии основных браузеров
используют разные имена свойств. Если нужна поддержка всех этих браузеров, придется
также включить для них соответствующие префиксы, характерные для тех или иных браузеров, такие как -moz- и -webkit-. Чтобы обеспечить работу примера 19.2 во всех браузерах,
я добавил в код все требуемые префиксы.

Можно указать отдельные радиусы для каждого из четырех углов (по часовой
стрелке, начиная с левого верхнего угла):
border-radius:10px 20px 30px 40px;

При необходимости можете также указать радиус отдельно для каждого угла
элемента:
border-top-left-radius
:20px;
border-top-right-radius
:40px;
border-bottom-left-radius :60px;
border-bottom-right-radius:80px;

И при ссылке на отдельные углы можно предоставить два аргумента, выбирая
тем самым разные вертикальные и горизонтальные радиусы (в результате чего
получаются более интересные и тонко настраиваемые границы):
border-top-left-radius
:40px
border-top-right-radius
:40px
border-bottom-left-radius :20px
border-bottom-right-radius:20px

20px;
20px;
40px;
40px;

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

Прямоугольные тени
Для применения прямоугольной тени нужно указать горизонтальное и вертикальное смещение от объекта и величину размытости, добавляемой к тени, а также
используемый для тени цвет:
box-shadow:15px 15px 10px #888;

Два значения по 15px задают (по порядку) горизонтальное вертикальное смещение от элемента, и эти значения могут быть отрицательными, нулевыми или
положительными. Значение 10px указывает величину, где меньшие значения приводят к меньшей размытости, а #888 — это цвет тени, который может быть любым
допустимым цветом. Результат этого объявления можно увидеть на рис. 19.4.

Разметка с использованием нескольких колонок

481

Рис. 19.4. Прямоугольная тень, отображенная под элементом element

При использовании этого свойства в браузерах, основанных на движках WebKit и Mozilla,
нужно применять префиксы -webkit- и -moz-.

Выход элемента за пределы размеров
В CSS2 можно определить, что делать, когда один элемент слишком велик, чтобы
полностью поместиться в другом, родительском по отношению к нему элементе,
путем указания для свойства overflow значения hidden, visible, scroll или auto. Но теперь в CSS3 можно также отдельно применить эти значения к горизонтальному
или вертикальному направлению, как в следующих примерах объявлений:
overflow-x:hidden;
overflow-x:visible;
overflow-y:auto;
overflow-y:scroll;

Разметка с использованием
нескольких колонок
Использование нескольких колонок уже давно стало у веб-разработчиков наиболее
востребованным свойством, и в CSS3 оно наконец-то было реализовано, а Internet
Explorer 10 стал последним из основных браузеров, принявшим это свойство.
Теперь перетекание текста по нескольким колонкам задать не сложнее, чем
указать количество колонок, а затем (дополнительно) выбрать разрядку между
ними и тип разделительной линии (если она нужна). На рис. 19.5 показан результат выполнения кода примера 19.3.

482

Глава 19. Расширение CSS с помощью CSS3

Рис. 19.5. Перетекание текста по нескольким колонкам

Пример 19.3. Использование CSS для создания нескольких колонок



Использование колонок

.columns {
text-align
:justify;
font-size
:16pt;
-moz-column-count
:3;
-moz-column-gap
:1em;
-moz-column-rule
:1px solid black;
-webkit-column-count:3;
-webkit-column-gap :1em;
-webkit-column-rule :1px solid black;
column-count
:3;
column-gap
:1em;
column-rule
:1px solid black; }




Now is the winter of our discontent
Made glorious summer by this sun of York;
And all the clouds that lour'd upon our house
In the deep bosom of the ocean buried.
Now are our brows bound with victorious wreaths;

Цвета и непрозрачность

483

Our bruised arms hung up for monuments;
Our stern alarums changed to merry meetings,
Our dreadful marches to delightful measures.
Grim-visaged war hath smooth'd his wrinkled front;
And now, instead of mounting barded steeds
To fright the souls of fearful adversaries,
He capers nimbly in a lady's chamber
To the lascivious pleasing of a lute.




Внутри класса .columns первые две строки просто предписывают браузеру
выровнять текст по правому краю и установить для него размер шрифта 16pt.
Эти объявления для нескольких колонок не нужны, но они улучшают отображение
текста. В остальных строках элемент настраивается таким образом, чтобы внутри
него текст перетекал по трем колонкам с разрывом между колонками, равным 1em,
и с границей 1 пиксел, проходящей по середине каждого разрыва.
В примере������������������������������������������������������������������������������
 �����������������������������������������������������������������������������
19.3 браузеры на основе движков ���������������������������������������������
Mozilla��������������������������������������
�����������������������������������
WebKit�����������������������������
требуют для объявлений соответствующих этим браузерам префиксов.

Цвета и непрозрачность
Способы определения цветов в ���������������������������������������������
CSS������������������������������������������
3 существенно расширились: теперь вы можете также использовать CSS���������������������������������������������������
������������������������������������������������������
-функции для применения цветов в широко распространенных форматах RGB (красный, зеленый, синий), RGBA (красный, зеленый,
синий, альфа), HSL (тон, насыщенность, яркость) и HSLA (тон, насыщенность,
яркость, альфа). Значение альфа определяет прозрачность цвета, позволяющую
увидеть элементы, расположенные ниже.

Цвета HSL
Для определения цвета с помощью функции hsl сначала нужно выбрать из цветового круга значение для тона в диапазоне от 0 до 359. Любой более высокий номер
цвета просто возвращается по кругу к началу, таким образом значение 0 соответствует красному цвету точно так же, как и значения 360 и 720.
В цветовом круге основные цвета — красный, зеленый и синий — занимают
по 120 градусов, поэтому чистый красный цвет соответствует значению 0, зеленый — значению 120, а синий — значению 240. Числа между этими значениями
представляют собой оттенки, содержащие различные пропорции основных цветов
с обеих сторон.
Затем нужен уровень насыщенности, значение которого лежит в диапазоне
от 0 до 100 %. Он определяет то, насколько сильно цвет будет размыт или ярок.
Значения насыщенности начинаются в центре колеса со светло-серого цвета

484

Глава 19. Расширение CSS с помощью CSS3

(насыщенность равна 0 %), а затем по направлению к краю (где насыщенность
равна 100 %) она становится все более отчетливой.
Вам остается только решить, насколько ярким требуется цвет, для чего нужно
выбрать значение яркости в диапазоне от 0 до 100 %. Значение 50 % для яркости
дает наполненный, яркий цвет, а уменьшение значения (вниз, вплоть до минимума
0 %) делает его темнее до тех пор, пока цвет не станет черным. Увеличение значения
(вверх, вплоть до максимума 100 %) делает цвет светлее до тех пор, пока он не станет белым. Вы можете визуально представить это подмешиванием в цвет либо
черного, либо белого цвета.
Так, например, для выбора полностью насыщенного желтого цвета со стандартной яркостью нужно воспользоваться следующим объявлением:
color:hsl(60, 100%, 50%);

Или для выбора темно-синего цвета можно воспользоваться таким объявлением:
color:hsl(240, 100%, 40%);

Этим также можно воспользоваться (как и всеми остальными CSS-функциями,
связанными с заданием цвета) с любым свойством, ожидающим применения цветовых настроек, например с background-color и т. д.

Цвета HSLA
Для обеспечения еще большего контроля над способом цветоообразования можно воспользоваться функцией hsla, предоставив ей четвертый (или альфа) уровень
настройки цвета, значение которого задается числом с плавающей точкой в диапазоне от 0 до 1. Значение 0 определяет, что цвет полностью прозрачный, а число
1 задает полную непрозрачность цвета.
Выбрать желтый цвет с полной насыщенностью, стандартной яркостью и 30%-ной
непрозрачностью можно с помощью следующего объявления:
color:hsla(60, 100%, 50%, 0.3);

Или же для выбора полностью насыщенного, но чуть более светлого синего
цвета с 82%-ной непрозрачностью можно воспользоваться таким объявлением:
color:hsla(240, 100%, 60%, 0.82);

Цвета RGB
Наверное, вам более знакома система выбора цвета RGB, поскольку она похожа на
использование форматов цвета #nnnnnn и #nnn. Например, для задания желтого цвета можно воспользоваться любым из следующих объявлений (первое из них поддерживает 16 миллионов цветов, а второе — 4 тысячи):
color:#ffff00;
color:#ff0;

Цвета и непрозрачность

485

Для получения такого же результата можно также воспользоваться CSSфункцией rgb, но при этом нужно применять не шестнадцатеричные, а десятичные
числа (где десятичное число 255 соответствует шестнадцатеричному числу ff):
color:rgb(255, 255, 0);

Но еще лучше вам будет даже не задумываться больше о том, чему соответствуют значения до 256, поскольку можно указать процентные значения:
color:rgb(100%, 100%, 0);

Фактически теперь вы можете с большой точностью определить настройки для
нужного цвета, просто думая о его основных цветовых составляющих. Например,
сочетание зеленого и синего дает фиолетовый цвет, поэтому для задания цвета,
близкого к фиолетовому, но с синей составляющей, преобладающей над зеленой,
можно составить первое предположение, что для него нужно определить 0 % красного, 40 % зеленого и 60 % синего цвета и попробовать воспользоваться следующим
объявлением:
color:rgb(0%, 60%, 40%);

Цвета RGBA
Как и функция hsla, функция rgba поддерживает четвертый (альфа) аргумент, позволяющий, к примеру, с помощью следующего объявления применить к прежнему фиолетовому цвету 40%-ную непрозрачность:
color:rgba(0%, 60%, 40%, 0.4);

Свойство opacity
Свойство opacity предоставляет такое же альфа-управление, что и функции hsla
и rgba, но позволяет изменять непрозрачность объекта (или прозрачность, если это
вам больше нравится) отдельно от его цвета.
Для использования этого цвета нужно применить к элементу следующее объявление (которое в данном примере устанавливает непрозрачность, равную 25 %, или
прозрачность, равную 75 %):
opacity:0.25;

Для браузеров на основе движков WebKit������������������������������������������������
������������������������������������������������������
���������������������������������������������
Mozilla��������������������������������������
для этого свойства требуются соответствующие этим браузерам префиксы. Кроме того, для обратной совместимости с выпусками
Internet Explorer, предшествующими версии 9, нужно добавить такое объявление (в котором
значение непрозрачности умножено на 100):
filter:alpha(opacity='25');

486

Глава 19. Расширение CSS с помощью CSS3

Эффекты, применяемые к тексту
Теперь с помощью CSS3 к тексту могут применяться новые эффекты, включая
тени текста, наложение, применяемое к тексту и перенос слов.

Свойство text-shadow
Это свойство аналогично свойству box-shadow и получает такой же набор аргументов: горизонтальное и вертикальное смещение, величину размытости и используемый цвет. Например, следующее объявление задает смещение тени на 3 пиксела
как в горизонтальном, так и в вертикальном направлениях и отображает тень темно-серым цветом с размытостью 4 пиксела:
text-shadow:3px 3px 4px #444;

Результат применения этого объявления выглядит, как показано на рис. 19.6.
Это объявление работает в последних версиях всех основных браузеров (кроме
Internet Explorer 9 или ниже).

Рис. 19.6. Применение тени к тексту

Свойство text-overflow
При использовании любого из CSS-свойств overflow со значением, равным hidden,
можно также воспользоваться свойством text-overflow для помещения многоточия
сразу же после текста, подвергшегося усечению:
text-overflow:ellipsis;

Если это свойство не использовать, то когда текст «To be, or not to be. That is the
question�������������������������������������������������������������������������
.» усекается, результат выглядит так, как показано на рис. 19.7. С применением объявления результат выглядит так, как изображено на рис. 19.8.

Рис. 19.7. Текст автоматически усекается

Рис. 19.8. Вместо простого усечения текст завершается многоточием

487

Веб-шрифты

Чтобы это работало, требуется выполнить три условия.
 У элемента должно быть свойство overflow, настроенное на невидимость, например overflow:hidden.
 Элемент должен иметь свойство white-space:nowrap, настраивающее на ограни-

чение текста.
 Ширина элемента должна быть меньше, чем усекаемый текст.

Свойство word-wrap
Когда используется по-настоящему длинное слово, шире того элемента, в котором
оно содержится, оно либо выйдет за пределы, либо будет усечено. Но в качестве
альтернативного варианта свойству text-overflow и усечению текста можно воспользоваться свойством word-wrap со значением break-word для переноса длинных
строк:
word-wrap:break-word;

Например, на рис. 19.9 показано, что слово Honorificabilitudinitatibus шире, чем
содержащее его поле (чей правый край показан в виде сплошной вертикальной
черты между буквами t и a), и, поскольку свойство overflow применено не было,
слово выходит за границу своего контейнера.

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

Но на рис. 19.10 свойству word-wrap элемента было присвоено значение breakword, поэтому слово аккуратно перенесено на следующую строку.

Рис. 19.10. Теперь слово переносится по достижении правого края

Веб-шрифты
Применение веб-шрифтов ����������������������������������������������
CSS�������������������������������������������
3 существенно повысило возможности оформления текста, доступные веб-дизайнерам, позволяя загружать шрифты из Интернета, а не только со своего пользовательского компьютера, и отображать их по

488

Глава 19. Расширение CSS с помощью CSS3

всей Всемирной сети. Для достижения такого результата нужно объявить веб-шрифт
с помощью свойства @font-face:
@font-face
{
font-family:FontName;
src:url('FontName.otf');
}

Функция url требует значение, содержащее путь или URL-адрес шрифта.
В большинстве браузеров можно использовать либо шрифты TrueType (TTF), либо
шрифты OpenType (OTF), но Internet Explorer ограничивает вас применением
шрифтов TrueType, преобразованных в шрифты EOT (EOT).
Чтобы сообщить браузеру тип шрифта, можно воспользоваться функцией format,
как в следующем примере (для шрифтов OpenType):
@font-face
{
font-family:FontName;
src:url('FontName.otf') format('opentype');
}

или в этом примере (для шрифтов TrueType):
@font-face
{
font-family:FontName;
src:url('FontName.ttf') format('truetype');
}

Но поскольку Internet���������������������������������������������������
�����������������������������������������������������������
Explorer������������������������������������������
��������������������������������������������������
принимает только ������������������������
EOT���������������������
-шрифты, он игнорирует объявления @font-face, содержащие функцию format.
Веб-шрифты Google. Один из лучших способов использования веб-шрифтов —
их бесплатная загрузка с серверов �����������������������������������������
Google�����������������������������������
. Дополнительную информацию по данному вопросу можно найти на сайте веб-шрифтов Google (http://google.com/webfonts;
рис. 19.11), где можно получить доступ более чем к 630 семействам шрифтов.
Чтобы вы увидели, насколько легко можно использовать один из этих шрифтов,
в следующем примере показано, как загрузить шрифт Google (в данном случае
Lobster) в ваш HTML-код для использования в заголовках :




h1 { font-family:'Lobster', arial, serif; }




Hello



489

Трансформации

Рис. 19.11. Включить веб-шрифты Google не составляет труда

Трансформации
Используя трансформации, можно наклонять, вращать, растягивать и сжимать элементы в любом из трех измерений (да, 3������������������������������������������
D�����������������������������������������
поддерживается, но пока только в браузерах, работающих на движке ��������������������������������������������������
WebKit��������������������������������������������
). Это упрощает создание впечатляющих эффектов путем выхода за пределы однообразных макетов на основе -контейнеров
и других элементов, поскольку теперь они могут быть показаны под различными
углами и в различных формах.
Для выполнения трансформаций нужно воспользоваться свойством transform
(у которого, к сожалению, должны быть соответствующие префиксы для использования в браузерах Mozilla, WebKit, Opera и Microsoft; по этому вопросу снова
следует обратиться на сайт http://caniuse.com).
К свойству transform можно применять множество значений, начиная со значения none, которое переключает объект в состояние, не допускающее трансформаций:
transform:none;

490

Глава 19. Расширение CSS с помощью CSS3

Свойство transform можно дополнить одной или несколькими из следующих
разнообразных функций:
 matrix — трансформирует объект, применяя к нему матрицу значений;
 translate — перемещает исходную точку элемента;
 scale — масштабирует объект;
 rotate — вращает объект;
 skew — наклоняет объект.
Существуют также отдельные версии многих из этих функций, например translateX,
scaleY и т. д.
Так, например, чтобы повернуть элемент по часовой стрелке на 45°, можно применить к нему такое объявление:
transform:rotate(45deg);

В то же время вы можете увеличить объект, как это делается с помощью следующего объявления, приводящего к увеличению его ширины в полтора, а высоты
в два раза с дальнейшим поворотом:
transform:scale(1.5, 2) rotate(45deg);

На рис. 19.12 показан объект до и после применения трансформации.

Рис. 19.12. Объект до и после трансформации

Трехмерная трансформация
Объекты можно также трансформировать в трех измерениях, используя следу­
ющие свойства трехмерной трансформации CSS3:
 perspective — освобождение элемента из двумерного пространства и создание
третьего измерения, в котором он может перемещаться;
 transform-origin — установка места, где все линии сходятся в одну точку;

491

Переходы

 translate3d — перемещение элемента в другое место трехмерного пространства;
 scale3d — изменение масштаба одного или нескольких измерений;
 rotate3d — вращение элемента вокруг любой из осей X, Y и Z.

На рис. 19.13 показан двумерный объект, подвергшийся вращению в трехмерном
пространстве с помощью следующего CSS-правила:
transform:perspective(200px) rotateX(10deg) rotateY(20deg) rotateZ(30deg);

Рис. 19.13. Вращение объекта в трехмерном пространстве

За дополнительной информацией обратитесь к руководству по адресу http://
tinyurl.com/3dcsstransforms или же воспользуйтесь прямым URL-адресом http://
24ways.org/2010/intro-to-css-3d-transforms.

Переходы
В последних версиях основных браузеров (включая Internet Explorer 10, не ниже)
появилось новое динамичное свойство, называемое переходами. Переходы определяют эффект анимации, который нужно применить при трансформации элемента, и браузер автоматически позаботится за вас обо всех промежуточных
кадрах.
Для настройки перехода можно предоставить четыре свойства:
transition-property
:свойство;
transition-duration
:время;
transition-delay
:время;
transition-timing-function:тип;
Свойства нужно предварять соответствующими префиксами браузеров, работающих на
движках Mozilla, WebKit, Opera и Microsoft.

492

Глава 19. Расширение CSS с помощью CSS3

Свойства, применяемые к переходам
У переходов есть такие свойства, как height и border-color. При указании свойств
преследуется цель изменения CSS-свойства по имени transition-property (здесь
слово property («свойства»), используемое разными инструментами, имеет разные
значения). Можно включить в объявление сразу несколько свойств, разделяя их
запятыми:
transition-property:width, height, opacity;

Или, если вам нужно абсолютно все, относящееся к элементу, подвергаемому
переходу (включая цвета), используется значение all:
transition-property:all;

Продолжительность перехода
Свойство transition-duration требует значения от нуля и более секунд. Следующее
объявление задает завершение перехода через 1,25 с:
transition-duration:1.25s;

Задержка перехода
Если свойству transition-delay дается значение более нуля секунд (то есть более
значения по умолчанию), происходит задержка между исходным отображением
элемента и началом его перехода. Следующее объявление задает начало перехода
после задержки 0,1 с:
transition-delay:0.1s;

Если свойству transition-delay дается значение меньше нуля секунд (иными
словами, отрицательное значение), переход будет выполнен в момент изменения
свойства, но проявится таким образом, будто оно началось с указанным смещением по времени, то есть на каком-то своем промежуточном цикле.

Задание скорости перехода
Свойству transition-timing-function требуется присвоить одно из следующих значений:
 ease — медленное начало, ускорение и медленное завершение;
 linear — переход с постоянной скоростью;
 ease-in — медленное начало, а затем быстрый переход до самого завершения;
 ease-out — быстрое начало, сохранение высокой скорости почти до завершения
и медленное завершение;
 ease-in-out — медленное начало, быстрый переход, затем медленное завершение.
Использование любого из этих значений со словом ease обеспечивает исключительную плавность и естественность перехода в отличие от линейного (linear)

493

Переходы

перехода, который выглядит более механическим. И если этих изменений вам
недостаточно, вы можете также создать свой собственный переход, используя
функцию cubic-bezier.
Например, следующие объявления применялись для создания пяти предыдущих
типов переходов и показывают, как просто можно создавать свои собственные
переходы:
transition-timing-function:cubic-bezier(0.25,
transition-timing-function:cubic-bezier(0,
transition-timing-function:cubic-bezier(0.42,
transition-timing-function:cubic-bezier(0,
transition-timing-function:cubic-bezier(0.42,

0.1,
0,
0,
0,
0,

0.25,
1,
1,
0.58,
0.58,

1);
1);
1);
1);
1);

Сокращенный синтаксис
Возможно, проще будет воспользоваться сокращенной версией этого свойства
и включить все значения в одно объявление (такое, как показано далее), которым
задается переход всех свойств в линейном режиме за период 0,3 с, после начальной
(необязательной) задержки 0,2 с:
transition:all .3s linear .2s;

Это избавит вас от хлопот, связанных со вводом многих очень похожих друг на
друга объявлений, особенно если вы поддерживаете префиксы всех основных брау­
зеров.
В примере�����������������������������������������������������������������
 ����������������������������������������������������������������
19.4 продемонстрировано, как можно сразу воспользоваться и переходом, и трансформацией. С помощью CSS создается квадратный, оранжевый
элемент, с неким текстом внутри, а псевдокласс hover указывает на то, что при проходе над этим объектом указателя мыши объект должен повернуться на 180° и изменить свой цвет с оранжевого на желтый (рис. 19.14).
Пример 19.4. Эффект перемещения, связанный с применением псевдокласса hover



Перемещение при проходе мыши

#square {
position
:absolute;
top
:50px;
left
:50px;
width
:100px;
height
:100px;
padding
:2px;
text-align
:center;
border-width
:1px;
border-style
:solid;
background
:orange;
transition
:all .8s ease-in-out;
-moz-transition
:all .8s ease-in-out;

494

Глава 19. Расширение CSS с помощью CSS3

-webkit-transition:all .8s ease-in-out;
-o-transition
:all .8s ease-in-out;
-ms-transition
:all .8s ease-in-out; }
#square:hover {
background
:yellow;
-moz-transform
:rotate(180deg);
-webkit-transform :rotate(180deg);
-o-transform
:rotate(180deg);
-ms-transform
:rotate(180deg);
transform
:rotate(180deg); }




Square shape
created using
a simple div
element with
a 1px border




Рис. 19.14. Объект поворачивается и меняет цвет
при прохождении над ним указателя мыши

Пример кода удовлетворяет требованиям всех разнообразных браузеров благодаря предоставлению версий объявлений, характерных для тех или иных браузеров.
На всех самых последних браузерах (включая Internet Explorer 10 и выше) объект

Вопросы

495

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

Вопросы
Вопрос 19.1
Чем занимаются операторы селектора атрибутов CSS3 ^=, $= и *=?
Вопрос 19.2
Какое свойство используется для указания размера фонового изображения?
Вопрос 19.3
С помощью какого свойства можно указать радиус границы?
Вопрос 19.4
Как можно задать перетекание текста по нескольким колонкам?
Вопрос 19.5
Назовите четыре функции, с помощью которых можно указать CSS-цвета.
Вопрос 19.6
Как можно создать серую тень под каким-нибудь текстом с диагональным отступом вправо и вниз на 5 пикселов и с размытостью 3 пиксела?
Вопрос 19.7
Как можно показать многоточием, что текст усечен?
Вопрос 19.8
Как включить в состав своей веб-страницы веб-шрифты Google?
Вопрос 19.9
Какое CSS-объявление нужно использовать для поворота объекта на 90°?
Вопрос 19.10
Как указать переход объекта таким образом, чтобы при изменении любого из
его свойств переход осуществлялся сразу в линейном режиме в течение 0,5 с?
Ответы на эти вопросы можно найти в приложении А, в разделе «Ответы на
вопросы главы 19».

20

Доступ к CSS
из JavaScript

После того как вы поняли, что такое объектная модель документа — Document
Object Model (DOM) и каскадные таблицы стилей — CSS, из этой главы вы узнаете,
как к ним можно получать доступ непосредственно из кода JavaScript, что позволит
вам создавать высокодинамичные и быстро реагирующие на действия пользователей сайты.
Мы также рассмотрим использование прерываний, что позволит создавать
анимацию или предоставлять любой код, который должен продолжать работу на
веб-странице (например, часы). Кроме того, я объясню, как в DOM добавляются
новые элементы или удаляются существующие элементы, чтобы вам не приходилось заранее создавать элементы в HTML на тот случай, если коду JavaScript
может чуть позже понадобиться получить к ним доступ.

Еще одно обращение к функции
getElementById
В качестве помощи в работе с примерами, приводимыми в остальной части книги,
я намереваюсь представить вам улучшенную версию функции getElementById, чтобы вы могли работать с элементами DOM и стилями CSS быстро и эффективно,
не испытывая потребности включения таких сред, как jQuery.
Но чтобы избежать конфликтов со средами программирования, использующими символ $, я буду просто применять в качестве имени функции заглавную букву O,
поскольку это первая буква слова Object����������������������������������������
����������������������������������������������
(объект), а именно объект будет возвращаться при вызове этой функции (тот самый объект, представленный идентификатором ID, переданным функции).

Функция O
Основа функции O имеет следующий вид:
function O(i)
{
return document.getElementById(i)
}

Еще одно обращение к функции getElementById

497

Только этот код уже сокращает количество набираемого текста при вызове
функции на 22 символа, но я намерен немного расширить функцию, позволяя передавать ей либо ID��������������������������������������������������������������
����������������������������������������������������������������
, либо объект, как показано в полной версии функции, представленной в примере 20.1.
Пример 20.1. Функция O
function O(i)
{
return typeof i == 'object' ? i : document.getElementById(i)
}

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

Функция S
Ответ на данный вопрос станет ясным, когда вы посмотрите на вспомогательную
функцию, названную S и показанную в примере 20.2, которую я вам предоставляю
для упрощения доступа к стилевым свойствам (или CSS) объекта.
Пример 20.2. Функция S
function S(i)
{
return O(i).style
}

Для этой функции имя S выбрано потому, что это первая буква слова Style,
а функция выполняет задачу возвращения свойства стиля (или подчиненного объекта) того элемента, на который она ссылается. Поскольку встроенная функция O
принимает либо ID, либо объект, вы можете передавать функции S как ID, так
и объект.
Рассмотрим, что получится, когда мы возьмем -элемент с ID myobj и установим для цвета его текста значение green (зеленый):
Some text

O('myobj').style.color = 'green'


Предыдущий код справится с этой задачей, но значительно проще будет вызвать
новую функцию S:
S('myobj').color = 'green'

Теперь рассмотрим случай, при котором объект, возвращенный в результате
вызова функции O, сохранен, к примеру, в объекте по имени fred:
fred = O('myobj')

498

Глава 20. Доступ к CSS из JavaScript

Благодаря тому способу, который используется в работе функции S, мы можем
для изменения цвета на зеленый вызвать и этот объект:
S(fred).color = 'green'

Это означает, что при желании получить доступ к объекту непосредственно или
через его ID, вы можете сделать это, передавая его либо функции O, либо функции S,
в зависимости от того, что вам нужно. Нужно лишь помнить, что при передаче
объекта (а не ID) ни в коем случае не следует брать его имя в кавычки.

Функция C
Вам уже предоставлены две простые функции, упрощающие доступ к любому
элементу на веб-странице и любому свойству стиля элемента. Но иногда вам
понадобится одновременный доступ более чем к одному элементу. Это можно
сделать путем присваивания имени класса CSS каждому такому элементу, как
показано в следующем примере, где для каждого элемента применяется класс
myclass:
Содержимое div-контейнера
Содержимое абзаца

Если нужен доступ ко всем элементам страницы, использующим конкретный
класс, можно обратиться к функции C (чье имя происходит от первой буквы в слове
Class), показанной в примере 20.3. Она вернет массив, состоящий из всех объектов,
которые соответствуют предоставленному имени класса.
Пример 20.3. Функция C()
function C(name)
{
var elements = document.getElementsByTagName('*')
var objects = []
for (var i = 0 ; i < elements.length ; ++i)
if (elements[i].className == name)
objects.push(elements[i])
return objects
}

Разберем код по частям. В аргументе name содержится имя класса, по которому
мы пытаемся извлечь объекты. Затем внутри функции создается новый объект по
имени elements, содержащий все элементы документа, возвращенные путем вызова
функции getElementsByTagName с аргументом'*', который означает «нужно найти
все элементы»:
var elements = document.getElementsByTagName('*')

Затем создается новый массив по имени objects, куда будут помещаться все
найденные объекты, соответствующие условию поиска:
var objects = []

Еще одно обращение к функции getElementById

499

Затем цикл for осуществляет перебор всех элементов, имеющихся в объекте
elements, используя в качестве индекса переменную i:
for (var i = 0 ; i < elements.length ; ++i)

При каждом проходе цикла объект помещается в массив objects при условии,
что значение свойства элемента className совпадает со строковым значением, переданным в аргументе name:
if (elements[i].className == name)
objects.push(elements[i])

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

Для использования эту функцию следует просто вызвать, как показано далее,
сохраняя возвращенный массив, чтобы иметь возможность получить доступ отдельно к каждому нужному элементу или (что чаще всего и бывает) ко всем элементам с помощью цикла:
myarray = C('myclass')

Теперь можете делать с возвращенными объектами все, что нужно, например
установить для их свойства textDecoration значение подчеркивания — 'underline':
for (i = 0 ; i < myarray.length ; ++i)
S(myarray[i]).textDecoration = 'underline'

Этот код осуществляет последовательный перебор объектов в myarray[], а затем
использует функцию S для ссылки на свойство стиля каждого объекта, задавая для
свойства textDecoration значение 'underline'.

Включение функций
Функции O и S используются во всей оставшейся части главы, поскольку делают код
короче и понятнее. Поэтому я сохранил их в файле OSC.js (наряду с функцией C, поскольку я полагаю, что она принесет вам большую пользу) в папке Chapter 20 в сопутствующем архиве примеров, который вы можете загрузить с сайта http://lpmj.net.
Они могут быть включены в веб-страницу с помощью следующей инструкции.
Ее предпочтительнее поместить в блок где-нибудь перед любым сценарием,
работа которого зависит от вызова этих функций:


Содержимое файла OSC.js показано в примере 20.4, где все убрано всего лишь
в три строки.
Пример 20.4. Файл OSC.js
function O(i) {return typeof i == 'object' ? i : document.getElementById(i)}
function S(i) { return O(i).style }
function C(i) { return document.getElementsByClassName(i)

500

Глава 20. Доступ к CSS из JavaScript

Обращение к свойствам CSS из JavaScript
Свойство textDecoration, использовавшееся в ранее показанном примере, представляет свойство CSS, имя которого в обычном виде содержит дефис: text-decoration.
Но поскольку в ���������������������������������������������������������������
JavaScript�����������������������������������������������������
дефис зарезервирован для применения в качестве математического оператора, при доступе к свойству CSS����������������������������
�������������������������������
, в имени которого используется дефис, этот дефис нужно опустить и перевести в верхний регистр символ,
следовавший непосредственно за ним.
Еще одним примером может послужить свойство font-size, на которое в JavaScript
при помещении после оператора точки ссылаются как на fontSize:
myobject.fontSize = '16pt'

Вместо этого можно предоставить более развернутый код и воспользоваться
функцией setAttribute, которая поддерживает (и фактически требует) стандартное
имя свойства CSS:
myobject.setAttribute('style', 'font-size:16pt')
Некоторые устаревшие версии Microsoft Internet Explorer в определенных ситуациях слишком
разборчивы в применении JavaScript-стиля имен, принадлежащих свойствам CSS. Имеется
в виду применение к ним специальных версий правил, в которых используются характерные
для браузера префиксы -ms-.

Некоторые общие свойства
С помощью JavaScript вы можете изменить любое свойство любого элемента,
имеющегося в веб-документе, примерно так же, как это делается с помощью CSS.
Я уже показывал вам, как получить доступ к свойствам �������������������������
CSS����������������������
, используя либо краткую форму JavaScript, либо функцию setAttribute (чтобы применить абсолютно
такие же имена свойств, как и в �����������������������������������������������
CSS��������������������������������������������
). Поэтому я не стану обременять вас детализацией всех этих сотен свойств. Вместо этого я покажу, как получить доступ к некоторым свойствам CSS, чтобы дать обзорное представление о возможностях по
их применению.
Сначала рассмотрим изменение нескольких свойств CSS�����������������������
��������������������������
из JavaScript���������
�������������������
, используя код примера 20.5, который в первую очередь загружает в себя три ранее упомянутые функции, затем создает -элемент и, наконец, запускает инструкции
JavaScript, находящиеся внутри блока кода HTML с целью изменения
различных атрибутов элемента (рис. 20.1).
Пример 20.5. Обращение к свойствам CSS из JavaScript



Обращение к свойствам CSS



Обращение к свойствам CSS из JavaScript

501


Div-объект

S('object').border
S('object').width
S('object').height
S('object').background
S('object').color
S('object').fontSize
S('object').fontFamily
S('object').fontStyle




=
=
=
=
=
=
=
=

'solid 1px red'
'100px'
'100px'
'#eee'
'blue'
'15pt'
'Helvetica'
'italic'

Рис. 20.1. Изменение стилей из JavaScript

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

Другие свойства
JavaScript также открывает доступ к очень широкому диапазону других свойств,
таких как ширина и высота окна браузера и любых появляющихся или присутствующих в браузере окон или фреймов, и к такой полезной информации, как родительское окно (если таковое имеется) и история URL�������������������������
����������������������������
-адресов, по которым осуществлялись визиты в текущем сеансе.
Все эти свойства доступны из объекта window через оператор «точка» (.) (например, window.name). В табл. 20.1 перечислены все эти свойства с описаниями.

502

Глава 20. Доступ к CSS из JavaScript
Таблица 20.1. Общие свойства объекта window

Свойство

Устанавливает и (или) возвращает

closed

Возвращает булево значение, показывающее, было ли закрыто окно

defaultStatus

Устанавливает или возвращает исходный текст панели состояния окна

document

Возвращает объект документа для окна

frames

Возвращает массив, состоящий из всех фреймов и i-фреймов окна

history

Возвращает для окна объект истории

innerHeight

Устанавливает или возвращает внутреннюю высоту области содержимого окна

innerWidth

Устанавливает или возвращает внутреннюю ширину области содержимого окна

length

Возвращает количество фреймов и i-фреймов окна

location

Возвращает местоположение объекта в окне

name

Устанавливает или возвращает имя окна

navigator

Возвращает для окна объект-навигатор

opener

Возвращает ссылку на то окно, из которого было создано данное окно

outerHeight

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

outerWidth

Устанавливает или возвращает внешнюю ширину окна, включая панель инструментов и полосу прокрутки

pageXOffset

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

pageYOffset

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

parent

Возвращает для окна объект родительского окна

screen

Возвращает для окна объект экрана

screenLeft

Возвращает координату x окна относительно экрана во всех последних браузерах, кроме Mozilla Firefox (для которого нужно использовать screenX)

screenTop

Возвращает координату y окна относительно экрана во всех последних браузерах, кроме Mozilla Firefox (для которого нужно применять screenY)

screenX

Возвращает координату x окна относительно экрана во всех последних браузерах, кроме Opera, который возвращает неправильное значение; не поддерживается в версиях Internet Explorer, предшествующих версии 9

screenY

Возвращает координату y окна относительно экрана во всех последних браузерах, кроме Opera, который возвращает неправильное значение; не поддерживается в версиях Internet Explorer, предшествующих версии 9

self

Возвращает the current window

status

Устанавливает или возвращает текст на панели состояния окна

top

Возвращает верхнее окно браузера

В отношении некоторых из этих свойств следует отметить такие моменты.
 Свойства defaultStatus и status могут быть установлены, только если пользователи изменили настройки своих браузеров и разрешили их применение (что
маловероятно).

Встроенный JavaScript

503

 Содержимое объекта history не может быть прочитано (поэтому нельзя посмо-

треть, какие адреса посещались вашими визитерами), но этот объект поддерживает свойство length, чтобы определить длину истории, а также методы back,
forward и go для переходов на указанные страницы в истории.
 Когда нужно узнать, какое пространство доступно в текущем окне браузера,
следует просто прочитать значения свойств window.innerHeight и window.innerWidth.
Я часто использую эти значения для размещения появляющихся в окне браузера диалоговых окон оповещения и подтверждения по центру.
 Объект screen поддерживает свойства, доступные только для чтения, — availHeight,
availWidth, colorDepth, height, pixelDepth и width, поэтому отлично подходит для
извлечения информации о дисплее пользователя.
Многие из этих свойств могут быть просто бесценными при позиционировании на мобильных
телефонах и планшетных устройствах, поскольку дадут точную информацию об экранном
пространстве, с которым придется работать, о типе используемого браузера и т. д.

Этого объема информации вполне достаточно для начала работы и для получения представления о многих новых и интересных приемах работы с JavaScript.
Разумеется, существует намного больше доступных свойств и методов, которые
могли бы быть рассмотрены в данной главе. Но теперь, когда вы знаете о том, как
обращаться к свойствам и использовать их, вам нужен лишь информационный
ресурс, на котором все они перечислены. Я рекомендую для начала обратиться
к сайту http://tinyurl.com/domproperties.

Встроенный JavaScript
Использование тегов не единственный способ выполнения инструкций
JavaScript���������������������������������������������������������������������
. Получить доступ к �������������������������������������������������
JavaScript���������������������������������������
можно также из тегов HTML�������������
�����������������
, что и делается для повышения динамической интерактивности.
Например, для быстрого добавления эффекта при прохождении указателя мыши
над объектом можно воспользоваться таким же кодом, который показан в теге
в примере 20.6. Там изначально отображается картинка с яблоком, которая
при прохождении над ней указателя мыши заменяется картинкой с апельсином
(а при выходе указателя за пределы картинки возвращается картинка с яблоком).
Пример 20.6. Использование встроенного JavaScript



Встроенный JavaScript






504

Глава 20. Доступ к CSS из JavaScript

Ключевое слово this
В предыдущем примере вы можете увидеть применение ключевого слова this. Оно
заставляет JavaScript работать с названным объектом, а именно с тегом .
Результат можно увидеть на рис. 20.2, где указатель мыши только что прошел над
картинкой с яблоком.

Рис. 20.2. Пример встроенного кода JavaScript, обрабатывающего
прохождение указателя мыши над объектом

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

Привязка событий к объектам в сценарии
Предыдущий код является эквивалентом предоставления тегу идентификатора
с последующей привязкой действий к событиям мыши этого тега, как в примере 20.7.
Пример 20.7. Невстроенный JavaScript



Невстроенный JavaScript





O('object').onmouseover = function() { this.src = 'orange.png' }
O('object').onmouseout = function() { this.src = 'apple.png' }




505

Встроенный JavaScript

Этот код применяет ID объекта к тегу в блоке HTML�����������������
���������������������
, а затем продолжает работать с ним отдельно в блоке JavaScript, прикрепив к каждому событию
безымянную функцию.

Прикрепление к другим событиям
Какой бы JavaScript ни использовался, встроенный или отдельный, существуют
события, к которым вы можете прикрепить действия. И активизировать тем самым множество дополнительных функций, которые можете предоставить своим
пользователям. В табл. 20.2 перечислены эти события и указаны условия их наступления.
Таблица 20.2. События и условия их наступления
Событие

Условие его наступления

onabort

Загрузка изображения останавливается до ее завершения

onblur

Элемент теряет фокус

onchange

Изменяется любая часть формы

onclick

Происходит щелчок кнопкой мыши на объекте

ondblclick

Происходит двойной щелчок кнопкой мыши на объекте

onerror

Обнаруживается ошибка JavaScript

onfocus

Элемент получает фокус

onkeydown

Нажата клавиша (включая Shift, Alt, Ctrl и Esc)

onkeypress

Нажата клавиша (исключая Shift, Alt, Ctrl и Esc)

onkeyup

Клавиша отпущена

onload

Объект загрузился

onmousedown

Над элементом нажата кнопка мыши

onmousemove

Указатель мыши проходит над элементом

onmouseout

Указатель мыши покидает элемент

onmouseover

Указатель мыши заходит на элемент со стороны

onmouseup

Отпускается кнопка мыши

onsubmit

Отправляется форма

onreset

Сбрасываются данные формы

onresize

Изменяются размеры окна браузера

onscroll

Документ прокручивается

onselect

Выделяется какой-нибудь текст

onunload

Удаляется документ

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

506

Глава 20. Доступ к CSS из JavaScript

Добавление новых элементов
Работая с ��������������������������������������������������������������������
JavaScript,���������������������������������������������������������
вы можете манипулировать не только элементами и объектами, которые были предоставлены документу его кодом HTML������������������
����������������������
. Вы можете создавать объекты по своему желанию, вставляя их в DOM.
Предположим, к примеру, что вам нужен новый элемент . Способ добавления его к веб-странице показан в примере 20.8.
Пример 20.8. Вставка элемента в DOM



Добавление элементов



В этом документе содержится только этот текст.

alert('Для добавления элемента щелкните на кнопке OK')
newdiv
= document.createElement('div')
newdiv.id = 'NewDiv'
document.body.appendChild(newdiv)
S(newdiv).border
S(newdiv).width
S(newdiv).height
newdiv.innerHTML
tmp

=
=
=
=
=

'solid 1px red'
'100px'
'100px'
"Это новый объект, вставленный в DOM"
newdiv.offsetTop

alert('Для удаления элемента щелкните на кнопке OK')
pnode = newdiv.parentNode
pnode.removeChild(newdiv)
tmp = pnode.offsetTop




На рис. 20.3 показано, как этот код используется для добавления к веб-документу
нового -элемента.
Сначала новый элемент создается с помощью функции createElement, затем вызывается функция appendChild и элемент вставляется в DOM.
После этого элементу присваиваются различные свойства, включая текст для
его свойства innerHTML (внутреннего HTML). А затем, чтобы обеспечить немедленное отображение нового элемента на экране, значение его свойства offsetTop считывается во временную переменную tmp. Это заставляет DOM�����������������
��������������������
обновиться и вывести элемент на экран в любом браузере, который в противном случае выдержал
бы паузу, прежде чем это сделать. В частности, это касается Internet Explorer.

Добавление новых элементов

507

Рис. 20.3. Вставка нового элемента в DOM

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

Удаление элементов
Вы можете также удалить элементы из DOM������������������������������������
���������������������������������������
, включая те, которые не были вставлены с помощью кода JavaScript��������������������������������������������������
������������������������������������������������������������
. Это даже проще, чем добавить элемент. Если предположить, что удаляется объект element, то это делается следующим образом:
element.parentNode.removeChild(element)

Этот код обращается к объекту parentNode элемента, поэтому он может удалить
элемент из этого узла. Затем он вызывает метод этого объекта removeChild, передавая ему удаляемый объект. Но чтобы обеспечить немедленное обновление DOM
во всех браузерах, возможно, будет предпочтительнее заменить предыдущую инструкцию следующим кодом:
pnode = element.parentNode
pnode.removeChild(element)
tmp
= pnode.offsetTop

508

Глава 20. Доступ к CSS из JavaScript

Здесь первая инструкция помещает копию element.parentNode (родительского
элемента объекта) в переменную pnode, которая (после того как дочерний элемент
удаляется) позволяет прочитать значение ее свойства offsetTop во временную переменную tmp, гарантируя тем самым полное обновление DOM.

Альтернативы добавлению
и удалению элементов
Вставка элемента предназначена для добавления к веб-странице абсолютно нового объекта. Но если вы намерены только скрывать и показывать объекты в соответствии с наступлением события onmouseover или какого-нибудь другого события, не забудьте, что есть пара свойств CSS, которые могут использоваться для
этой цели без принятия таких радикальных мер, как создание и удаление элементов DOM.
Например, когда нужно сделать элемент невидимым, но оставить его на месте
(оставляя на своих местах все окружающие его элементы), можно просто установить для свойства visibility объекта значение 'hidden':
myobject.visibility = 'hidden'

А для повторного отображения объекта можно воспользоваться следующим
кодом:
myobject.visibility = 'visible'

Можно также свернуть элемент, чтобы он занимал нулевую ширину и высоту
(и чтобы все окружающие его объекты заняли освободившееся пространство):
myobject.display = 'none'

Для последующего восстановления элемента в его исходных размерах можно
написать такой код:
myobject.display = 'block'

И конечно же, в вашем распоряжении всегда есть свойство innerHTML, с помощью
которого можно изменить код HTML, примененный к элементу. Например:
mylement.innerHTML = 'Замена HTML'

Можно также воспользоваться упомянутой ранее функцией O:
O('someid').innerHTML = 'Новое содержимое'

Можно заставить элемент показаться исчезнувшим:
O('someid').innerHTML = ''
Не забывайте обо всех других полезных свойствах CSS, к которым можно обратиться из
JavaScript����������������������������������������������������������������������������
. Например, для переключения объекта из видимого в невидимое состояние и обратно можно воспользоваться свойством непрозрачности, а для изменения размеров объекта
можно изменить значения свойств width и height. И конечно же, применяя для свойства
position значения 'absolute', 'static' или 'relative', вы можете даже поместить объект в любое
место окна браузера (или снаружи).

Использование прерываний

509

Использование прерываний
JavaScript предоставляет доступ к прерываниям, методу, с помощью которого можно попросить браузер вызвать ваш код после определенного периода времени или
даже продолжать вызовы через указанные интервалы времени. Это дает вам средства обработки фоновых задач, таких как обмен данными с помощью AJAX или
даже такие средства, как анимация веб-элементов.
Существует два типа прерываний — setTimeout и setInterval, сопровождающихся функциями clearTimeout и clearInterval для их выключения.

Использование функции setTimeout
При вызове функции setTimeout передается код ���������������������������������
JavaScript�����������������������
или имя функции и значение в миллисекундах, отображающее продолжительность задержки запуска кода
на выполнение:
setTimeout(dothis, 5000)

Ваша функция dothis может иметь следующий вид:
function dothis()
{
alert('Это ваш будильник!');
}
Как ни удивительно, вы не можете просто указать alert() (с круглыми скобками) в качестве
функции, вызываемой setTimeout, потому что функция будет тут же выполнена. Передавать
имя функции, чтобы код был выполнен только по истечении указанного времени, можно
только без круглых скобок, служащий для указания аргументов (например, alert).

Передача строки
Если исполняемой функции нужно передать аргумент, то функции setTimeout можно также передать строковое значение, которое не будет выполняться, пока не наступит нужное время. Например:
setTimeout("alert('Hello!')", 5000)

Фактически, если после каждой инструкции ставить точку с запятой, можно
передать столько строк кода JavaScript, сколько нужно:
setTimeout("document.write('Starting'); alert('Hello!')", 5000)

Повторение тайм-аутов
Для предоставления повторяющихся прерываний, создаваемых функцией setTimeout,
некоторые программисты используют технологию вызова функции setTimeout из
кода, вызываемого этой же функцией, как в следующем примере, который инициирует бесконечный цикл вывода окон предупреждений:
setTimeout(dothis, 5000)
function dothis()

510
{
}

Глава 20. Доступ к CSS из JavaScript

setTimeout(dothis, 5000)
alert('Я вас раздражаю!')

Теперь окно предупреждения будет появляться каждые 5 с.

Отмена тайм-аута
После установки тайм-аута вы можете отменить его, если предварительно сохранили значение, возвращенное при начальном вызове функции setTimeout:
handle = setTimeout(dothis, 5000)

Теперь, когда у вас есть это значение в переменной handle, вы можете отменить
прерывание в любой момент, вплоть до истечения назначенного срока:
clearTimeout(handle)

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

Функция setInterval
Самый простой способ установки регулярных прерываний заключается в использовании функции setInterval. Она работает точно так же, как и описанная выше,
за исключением того, что, проявив себя после интервала, заданного вами в миллисекундах, она сделает это снова, после того как этот же интервал снова пройдет,
и так до бесконечности, пока вы ее не остановите.
В примере 20.9 эта функция используется для вывода в браузере простых часов,
показанных на рис. 20.4.
Пример 20.9. Часы, созданные с помощью прерываний



Использование setInterval



Текущее время: 00:00:00

setInterval("showtime(O('time'))", 1000)
function showtime(object)
{
var date = new Date()
object.innerHTML = date.toTimeString().substr(0,8)
}




Использование прерываний

511

Рис. 20.4. Поддержка показаний правильного времени с помощью прерываний

При каждом вызове функции ShowTime она присваивает объекту date текущее
время и дату с помощью вызова функции Date:
var date = new Date()

Затем свойству innerHTML объекта, переданного функции showtime (то есть object),
присваивается значение текущего времени в часах, минутах и секундах, как определено вызовом функции toTimeString. В результате возвращается строка «09:57:17
UTC�����������������������������������������������������������������������
+0530», которая затем усекается до первых восьми символов с помощью вызова функции substr:
object.innerHTML = date.toTimeString().substr(0,8)

Использование функции
Чтобы воспользоваться этой функцией, сначала нужно создать объект, чье свойство innerHTML будет применено для отображения времени, как в следующем коде
HTML:
Текущее время: 00:00:00

Затем в блоке кода вызов помещается в функцию setInterval:
setInterval("showtime(O('time'))", 1000)

Этот вызов передает функции setInterval строку, содержащую следующую
инструкцию, настроенную на выполнение один раз в секунду (каждые 1000 мс):
showtime(O('time'))

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

Отмена интервала
Чтобы остановить повторяющийся интервал, при первой установке интервала путем вызова функции setInterval вы должны пометить для себя в переменной handle
дескриптор этого интервала:
handle = setInterval("showtime(O('time'))", 1000)

512

Глава 20. Доступ к CSS из JavaScript

Теперь можно остановить часы в любое время, сделав следующий вызов:
clearInterval(handle)

Можно также настроить таймер на остановку через определенный период времени:
setTimeout("clearInterval(handle)", 10000)

Эта инструкция выдаст прерывание через 10 с (10 000 мс), которое очистит повторяющиеся интервалы.

Использование прерываний для анимации
Путем сочетания нескольких свойств CSS с повторяющимся прерыванием можно
создавать всевозможные анимации и эффекты.
Код в примере 20.10 перемещает прямоугольник по верхней части окна браузера, все время увеличивая его в размерах (рис. 20.5). Когда значение переменной
LEFT сбрасывается в 0, анимация начинается снова.
Пример 20.10. Простая анимация



Простая анимация


#box {
position :absolute;
background:orange;
border
:1px solid red; }





SIZE = LEFT = 0
setInterval(animate, 30)
function animate()
{
SIZE += 10
LEFT += 3
if (SIZE == 200) SIZE = 0
if (LEFT == 600) LEFT = 0
S('box').width = SIZE + 'px'
S('box').height = SIZE + 'px'

513

Вопросы

S('box').left
}




= LEFT + 'px'

Рис. 20.5. Объект плавно движется слева, одновременно меняя свой размер

В блоке документа объекту box устанавливается цвет фона 'orange' (оранжевый) со значением его границы (border) '1px solid red', а его свойству позиционирования position задается значение absolute, чтобы ему разрешалось перемещаться по окну браузера.
Затем в функции animate происходит постоянное обновление глобальных переменных SIZE и LEFT, а их значения применяются к атрибутам стиля width, height
и left объекта box (с добавлением после каждого значения строки 'px' для указания,
что значение в пикселах), таким образом анимируя объект с частотой один раз каждые 30 мс. Тем самым задается скорость 33,33 кадра в секунду (1000 / 30 мс).

Вопросы
Вопрос 20.1
Для чего предназначены функции O, S и C?
Вопрос 20.2
Назовите два способа изменения CSS-атрибута объекта.
Вопрос 20.3
Какие свойства предоставляют доступную в окне браузера ширину и высоту?
Вопрос 20.4
Как можно задать какие-нибудь действия при прохождении указателя мыши
над объектом, а затем при выходе за границы объекта?

514

Глава 20. Доступ к CSS из JavaScript

Вопрос 20.5
Какая функция JavaScript создает новые элементы и какая функция добавляет
их к DOM?
Вопрос 20.6
Как сделать элемент а) невидимым и б) сжатым до нулевых размеров?
Вопрос 20.7
Какая функция задает одиночное событие в будущем времени?
Вопрос 20.8
Какая функция устанавливает повторяющиеся события через указанный интервал времени?
Вопрос 20.9
Как можно освободить элемент от его места на веб-странице, чтобы он мог перемещаться?
Вопрос 20.10
Какая должна быть установлена задержка между событиями (в миллисекундах)
для получения скорости анимации 50 кадров в секунду?
Ответы на эти вопросы можно найти в приложении А, в разделе «Ответы на
вопросы главы 20».

21

Введение
в jQuery

При всей гибкости и эффективности JavaScript, а также при всем изобилии имеющихся в этом языке встроенных функций все же сохраняется потребность в дополнительных уровнях кода, позволяющих упростить, к примеру, получение эффектов
анимации, обработку событий и применение технологии Ajax, то есть сделать то,
чего нельзя достичь применением обычных средств JavaScript или CSS.
Более того, с годами, вследствие различных браузерных войн, то появлялись,
то исчезали досаждающие и раздражающие несовместимости браузеров, ярко проявлявшиеся временами на различных платформах и в программах.
В результате этого гарантировать одинаковый внешний вид веб-страниц во всех
устройствах порой можно было, только применяя требовавший утомительной разработки код JavaScript, учитывающий все расхождения всей линейки браузеров
и их версий, выпущенных за последние годы. Одним словом, сложилась кошмарная
ситуация.
При написании книги (в 2014 году) было ощущение, что мы уже не обходились
без тихих заклинаний, поскольку Internet Explorer компании Microsoft во многих
(но все же не во всех) областях догнал стандарты, в браузере Opera в качестве
основы решено было применять WebKit (ту же самую технологию, которая использовалась компанией Google), а компания Apple ушла с рынка браузеров для
PC-совместимых компьютеров.
И все же унаследованная несовместимость еще осталась, а многие до сих пор
пользуются старыми браузерами. Плюс к тому, если есть желание создать что-либо
более впечатляющее, чем обычные спецэффекты, вам все еще придется писать
весьма существенный объем кода на JavaScript.
Для заполнения пробелов было разработано множество библиотек функций,
предназначенных для сведения к минимуму различий между браузерами, и многие из этих библиотек позволяют, кроме этого, легко привязываться к объектной
модели документа — DOM (Document Object Model), облегчают работу с Ajax,
событиями и анимацией. В их число входят такие наиболее предпочтительные
библиотеки, как AngularJS, jQuery, MooTools, Prototype, script.aculo.us и YUI
(существует и множество других библиотек).

516

Глава 21. Введение в jQuery

Почему же именно jQuery?
В книге выделено место только для одной библиотеки, поэтому я выбрал наиболее широко используемую библиотеку jQuery, которая сегодня, по сведениям
http://w3techs.com, установлена более чем на 60 % сайтов и востребована шире, чем
все ее конкуренты, вместе взятые (насколько можно судить по диаграммам источника). Кстати, если есть желание посмотреть на столбиковую диаграмму, отображающую процентное соотношение востребованности различных библиотек на
любой текущий момент времени, введите в поисковой строке сайта similartech.com
слово javascript.
Используя jQuery, вы получаете не только кросс-браузерную совместимость
весьма высокого уровня (включая совместимость с Internet Explorer), но и быстрый
и легкий доступ к операциям с HTML и DOM, возможность использования специальных функций для непосредственной работы с CSS, управления событиями,
мощные средства для создания профессиональных эффектов и анимации, а также
функции для управления обменом данными с сервером по технологии Ajax. Кроме
того, jQuery является основой для широкого круга дополнительных модулей и других вспомогательных программ.
Использования jQuery вам никто не навязывает, и некоторые борцы за чистоту языка программирования никогда не используют библиотеку, предпочитая
создавать собственный специализированный набор функций (и в этом есть свой
резон, например, не нужно будет дожидаться, пока другие люди исправят замеченные вами недоделки, можно будет разрабатывать собственные средства
безопасности и т. д.). Но библиотека jQuery уже выдержала проверку временем,
и если вы захотите с пользой потратить время на ее изучение и получить возможность делать высококачественные веб-страницы в самые короткие сроки,
из этой главы вы узнаете, как можно приступить к использованию этой библиотеки.

Включение jQuery
Есть два способа включения jQuery в ваши веб-страницы. Можно перейти на сайт
jQuery, выбрать нужную версию, загрузить ее на свой сайт и пользоваться всеми
ее возможностями. Или же можно воспользоваться находящейся в свободном доступе сетью доставки контента — Content Delivery Network (CDN) и просто указать
ссылку на нужную вам версию.

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

Включение jQuery

517

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

Стоит ли учитывать возможность использования
устаревших версий IE?
Помимо всего прочего, наряду с сериями jQuery 1.x теперь имеются серии этой библиотеки с номерами 2.x, в которых больше не поддерживаются версии Internet
Explorer ниже 9-й. Обе эти серии находятся в параллельной разработке. Если есть
уверенность, что у всех ваших пользователей установлена IE 9 или более новая версия
(например, по причине того, что вы пишете мобильные веб-приложения), то можно
будет выбрать самую последнюю версию из серии 2.x, чтобы воспользоваться преимуществами применения более компактного, быстродействующего и эффективного
кода. Но если кто-либо из ваших пользователей имеет старые версии IE, то вам
придется воспользоваться выпусками jQuery, относящимися к серии 1.x.

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

518

Глава 21. Введение в jQuery

Загрузка
На сайте jquery.com/download каждая выпущенная версия jQuery фигурирует в списке
как в сжатой, так и в несжатой форме. Вам остается всего лишь выбрать нужную
версию, щелкнуть правой кнопкой мыши на соответствующей ссылке и сохранить
версию на своем жестком диске. Оттуда ее можно будет выгрузить на ваш вебсервер, а затем включить в веб-страницу с помощью -тегов примерно таким
образом (для минимизированной версии выпуска 1.11.1):

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

Использование сети доставки контента
Библиотека jQuery поддерживается несколькими сетями доставки контента (CDN).
Если вы пользуетесь одной из них, то можете избавить себя от хлопот, связанных
с загрузкой новых версий, и выкладывать их на сервер, просто указав прямые ссылки на URL-адреса, поддерживаемые этими сетями.
Ко всему прочему, эти сети предоставляют свои услуги совершенно бесплатно
и обычно используют каналы с высокой пропускной способностью, которые, возможно, являются самыми скоростными на свете. Кроме того, CDN-сети обычно
хранят свой контент в нескольких различных географических пунктах и предоставляют файл с ближайшего к вам сервера, гарантируя тем самым наиболее быструю
доставку.
В общем, если вам не нужно вносить изменения в исходный код jQuery (для
чего требуется его размещение на ваших собственных веб-серверах) и у ваших
пользователей гарантированно имеется живое интернет-соединение, то, скорее
всего, наилучшим вариантом будет использование CDN-сетей. Тем более что пользоваться ими довольно просто. Достаточно знать имя нужного файла и используемого для его загрузки корневого каталога CDN. Например, все текущие и предыдущие версии можно получить через CDN-сеть, которая используется библиотекой
jQuery, с помощью следующего кода:


Основной каталог доступен по адресу http://code.jquery.com/, и за ним нужно просто
дописать имя нужного для включения файла (в данном случае это jquery-1.11.1.min.js).
Библиотеку jQuery предоставляют в своих сетях как Microsoft, так и Google,
поэтому для ее включения можно воспользоваться любым из следующих двух
вариантов:





Включение jQuery

519

В случае использования Microsoft CDN (aspnetcdn.com) в URL-адресе сначала
нужно указать основной каталог ajax.aspnetcdn.com/ajax/jQuery/, а за ним — имя
требуемого файла.
Но для Google нужно разбить имя файла (например, jquery-1.11.1.min.js) на
имя каталога и имя файла таким вот образом: 1.11.1/jquery.min.js. ����������������
А���������������
��������������
перед���������
��������
этим����
���
поставить строку ajax.googleapis.com/ajax/libs/jquery/.
Дополнительным преимуществом применения CDN-сетей является то, что ими пользуется
большинство других сайтов, поэтому библиотека jQuery может уже находиться в кэше пользовательского браузера и ее, может быть, даже не придется доставлять заново. При практически более чем 60%-ной востребованности jQuery другими сайтами тем самым может
быть сэкономлен большой объем ценных сетевых ресурсов и времени.

Всегда используйте самую последнюю версию
Еще одним преимуществом CDN-сетей является то, что вы всегда можете выбрать
самую последнюю версию jQuery, следовательно, сберечь веб-страницу и напрочь
забыть о необходимости ее обновления до самого последнего выпуска.
Чтобы включить последнюю версию (выпуска из серии 1.x) из CDN-сетей jQuery
или Google, нужно воспользоваться одной из двух форм -тега:



Но при этом нужно проявить особую осторожность, поскольку вполне возможно, что какие-нибудь компоненты вашей веб-страницы не смогут работать с будущим обновлением, и вам следует быть готовыми к тому, что какая-либо из вебстраниц начнет вести себя не так, как нужно.
Полезно знать, что CDN-сети как jQuery, так и Google при использовании префиксов http://
или https:// поддерживают доступ к файлам jQuery либо по HTTP-, либо по HTTPS-протоколу.
Но в примерах, приводимых в данной главе (которые можно загрузить с сайта lpmj.net), я
выбрал локальный вариант загрузки и подачи jQuery, чтобы вы смогли протестировать все
файлы примеров, даже не имея доступа к Интернету, в частности, находясь в поезде или
в самолете.

Заказная сборка jQuery
Если есть настоятельная необходимость свести объем данных, загружаемых вебстраницей, к минимуму, то можно воспользоваться jQuery, создав специальную
сборку этой библиотеки, включающую только те функции, которые будут использоваться вашим сайтом. При ее доставке полагаться на CDN-сеть нельзя, но при
подобных обстоятельствах вы, наверное, все равно не станете планировать использование этой сети.
Для создания собственной заказной сборки jQuery нужно зайти на сайт pro­
jects.jga.me/jquery-builder и выставить флажки возле тех модулей, которые вам

520

Глава 21. Введение в jQuery

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

Синтаксис jQuery
Больше всего людей, ранее незнакомых с jQuery, удивляет символ $, который действует как фабричный метод jQuery. Он был выбран из расчета допустимости
в JavaScript, краткости и отличия от имен обычной переменной, объекта или функции (метода).
Им обозначается вызов функции jQuery (что также при желании можно сделать). Замысел его использования заключается в сохранении краткости и приятного внешнего вида кода, а также избавлении от излишнего набора текста при
каждом обращении к jQuery. Кроме того, при виде этого символа другие, ранее
незнакомые с вашим кодом разработчики сразу же понимают, что в коде используется jQuery (или подобная ей библиотека).

Простой пример
В наипростейшем виде обращение к jQuery осуществляется набором символа $, за
которым следуют заключенный в скобки селектор, точка и метод, применяемый
к выбранному элементу (или элементам).
Например, для изменения семейства шрифтов всех абзацев на моноширинное
можно воспользоваться следующей инструкцией:
$('p').css('font-family', 'monospace')

А для добавления границы к элементу можно применить такую инструкцию:
$('code').css('border', '1px solid #aaa')

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


Первый пример jQuery



В jQuery в качестве имен функции используются либо $(),
либо jQuery().

$('code').css('border', '1px solid #aaa')




521

Синтаксис jQuery

После загрузки этого примера в браузер будет получен результат, показанный
на рис. 21.1. Разумеется, конкретно эта инструкция просто подменяет собой то, что
можно сделать с помощью обычного кода CSS, но я хотел показать синтаксис jQuery,
поэтому пока не стал ничего усложнять.
Еще один способ выдачи этой команды заключается в вызове функции jQuery (которая работает точно так же, как и $):
jQuery('code').css('border', '1px solid #aaa')

Рис. 21.1. Изменение элементов с помощью jQuery

Как избежать конфликта библиотек
Если наряду с jQuery используются и другие библиотеки, может оказаться, что
в них определена собственная $-функция. Для решения данной проблемы можно
в отношении этого символа вызвать методnoConflict, который освобождает этот
символ от управляющей функции, позволяя другим библиотекам воспользоваться им:
$.noConflict()

После этого для доступа к jQuery следует вызывать функцию jQuery. Или же
использование символа $ можно подменить именем объекта по вашему выбору:
jq = $.noConflict()

Теперь в тех местах, где прежде применялся символ $, можно воспользоваться
ключевым словом jq.
Чтобы отличать объекты jQuery и отслеживать их отдельно от объектов стандартных элементов, некоторые разработчики устанавливают символ $ в виде префикса перед любым
объектом, созданным с помощью jQuery (что делает их похожими на переменные PHP!).

522

Глава 21. Введение в jQuery

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

Метод css
Чтобы объяснить применение селекторов в jQuery, сначала посмотрим на один из
более фундаментальных методов jQuery, css, с помощью которого можно динамически менять любое свойство CSS. Этому методу передаются два аргумента: имя
свойства, к которому осуществляется обращение, и значение, которое к этому свойству применяется:
css('font-family', 'Arial')

Как будет показано в следующих разделах, сам по себе этот метод применять
невозможно, поскольку его нужно использовать в селекторе jQuery, который выберет один или несколько элементов, чьи свойства должны быть изменены этим
методом. В следующем примере содержимому всех -элементов предписывается
отображение с полным выравниванием по ширине:
$('p').css('text-align', 'justify')

Метод css можно также использовать для возвращения (а не для установки)
вычисленного значения, для чего ему предоставляется только имя свойства (а второй аргумент опускается). В этом случае возвращается значение первого же соответствующего селектору элемента. Например, выполнение следующего кода приведет к возвращению цвета текста того элемента, чей идентификатор (ID) имеет
значение elem, и это значение будет в том же формате, в котором цвет задается при
применении метода rgb:
color = $('#elem').css('color')

Следует помнить, что возвращаемое значение является вычисленным. Иными
словами, jQuery будет вычислять и возвращать значение, используемое браузером
на момент вызова метода, а не то исходное значение, которое могло быть присвоено свойству посредством таблицы стилей или любым другим способом.
Следовательно, если текст, к примеру, показан синим цветом, значением, присвоенным переменной color в предыдущей инструкции, будет rgb(0, 0, 255), даже

Селекторы

523

если цвет изначально был установлен с использованием имени цвета blue или с использованием строк шестнадцатеричных чисел #00f или #0000ff. Но это вычисленное значение всегда будет в форме, которая может быть снова назначена элементу
(или любому другому элементу) при использовании в качестве второго аргумента
метода css.
К любым вычисленным размерам, возвращаемым этим методом, нужно относиться осмотрительно, поскольку в зависимости от текущих установок свойства box-sizing (см. главу 19)
они могут быть, а могут и не быть именно тем, что вы ожидаете получить. Когда нужно
получить или установить значения ширины и высоты без учета значения свойства box-sizing,
нужно использовать методы width и height (и родственные им), рассматриваемые в разделе
«Изменение размеров изображения».

Селектор элемента
Для выбора элемента, обрабатываемого с помощью jQuery, нужно просто указать
его имя внутри круглых скобок, следующих за символом $ (или за именем функции
jQuery). Например, если нужно изменить цвет фона всех элементов ,
можно воспользоваться следующей инструкцией:
$('blockquote').css('background', 'lime')

Селектор идентификатора
Ссылаться на элементы можно также по их идентификаторам (ID), если перед
именем идентификатора поместить символ #. Следовательно, чтобы, к примеру,
добавить границу к элементу с идентификатором advert, можно воспользоваться
такой инструкцией:
$('#advert').css('border', '3px dashed red')

Селектор класса
Можно также воздействовать на группу элементов в соответствии с используемым
ею классом. Например, для подчеркивания всех элементов, применяющих класс new,
можно воспользоваться следующей инструкцией:
$('.new').css('text-decoration', 'underline')

Сочетание селекторов
Как и при использовании CSS, селекторы можно сочетать друг с другом, составляя
единый jQuery-выбор, для чего, как в следующем примере, применяются запятые:
$('blockquote, #advert, .new').css('font-weight', 'bold')

524

Глава 21. Введение в jQuery

В примере 21.2 все типы селекторов собраны вместе, а инструкции jQuery выделены полужирным шрифтом. Результат выполнения кода примера показан на
рис. 21.2.
Пример 21.2. Использование jQuery с различными селекторами


Второй пример jQuery



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

$('blockquote').css('background', 'lime')
$('#advert').css('border', '3px dashed red')
$('.new').css('text-decoration', 'underline')
$('blockquote, #advert, .new').css('font-weight', 'bold')




Рис. 21.2. Воздействие сразу на несколько элементов

Обработка событий

525

Обработка событий
Если бы библиотека jQuery умела только подменять CSS-стили, толку от нее было
бы маловато, и она, конечно же, способна на гораздо большее. Продолжим исследование и посмотрим, как она обрабатывает события.
Как вы, наверное, помните, большинство событий инициируется действиями
пользователя: при прохождении указателя мыши над элементом, щелчке кнопкой
мыши или нажатии клавиши. Но существуют и другие события, которые могут
инициироваться, к примеру, по завершении загрузки документа.
Прикрепить ваш собственный код к этим событиям с помощью jQuery не составит труда, причем сделано это будет безопасным способом, не блокирующим
для другого кода получение такого же доступа к этим событиям. Вот, к примеру,
как можно заставить код jQuery откликнуться на щелчок на элементе:
$('#clickme').click(function()
{
$('#result').html('You clicked the button!')
})

Когда будет сделан щелчок на элементе с идентификатором clickme, свойство
innerHTML элемента со значением ID, равным result, будет обновлено с использованием jQuery-функции html.
Объекты jQuery, созданные с помощью метода $ либо метода jQuery, не являются аналогами
объектов JavaScript, созданных с помощью getElementById. В обычном коде JavaScript можно использовать такие инструкции, как object = document.getElementById('result'), за которыми, к примеру, следует инструкция object.innerHTML = 'something'. Но в предыдущем
примере код $('#result').innerHTML работать не будет, поскольку innerHTML не является
свойством объекта jQuery. Следовательно, для достижения требуемого результата нужно
использовать jQuery-метод html.

Конкретизация замысла, результат которой можно увидеть на рис. 21.3, показана в примере 21.3.
Пример 21.3. Обработка события



События jQuery



Нажми меня
Я - абзац

$('#clickme').click(function()
{
$('#result').html('Вы щелкнули на кнопке!')

526

Глава 21. Введение в jQuery

})




Рис. 21.3. Обработка события click

При обращении к событию с помощью jQuery префикс on-, который нужно использовать в стандартном JavaScript, следует опустить. Поэтому, к примеру, название события onmouseover
превращается в jQuery в имя функции mouseover, onclick приобретает вид click и т. д.

Ожидание готовности документа
Поскольку тому, что достигается средствами jQuery, мы во многом обязаны весьма
тесной связи этой библиотеки с объектной моделью документа — DOM, вам, прежде чем воздействовать на какие-либо части страницы, скорее всего, придется дождаться ее загрузки. Без jQuery это может быть выполнено с помощью события
onload, но есть более эффективный кросс-браузерный jQuery-метод под названием
ready, который можно вызвать для включения в работу в самый ранний из возможных моментов времени, даже раньше, чем наступит событие onload. Это означает,
что jQuery может начать работать на странице намного быстрее и с минимальными
задержками для пользователя.
Чтобы воспользоваться этой возможностью, поместите свой код jQuery внутрь
следующей структуры:
$('document').ready(function()
{
// Сюда нужно поместить ваш код
})

Теперь код будет ждать готовности документа и только после этого будет вызван
методом ready. На самом деле можно набрать еще меньший объем кода и воспользоваться более краткой версией, показанной в примере 21.4.

Функции и свойства событий

527

Пример 21.4. Наименьший по объему код охватывающей функции, запускаемой по
готовности документа (своеобразный аналог метода ready)
$(function()
{
// Сюда нужно поместить ваш код
})

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

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

Функции и свойства событий
До сих пор был показан только метод события ready, но в jQuery имеется несколько десятков методов событий и связанных с событиями свойств, к которым можно
обратиться (их так много, что подробно рассмотреть здесь весь арсенал не представляется возможным). Но рассматриваемые далее функции и свойства относятся к наиболее востребованным и позволят вам начать их использовать в большинстве проектов. Всестороннее описание всех доступных событий можно найти на
сайте api.jquery.com/category/events.

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

528

Глава 21. Введение в jQuery

получает фокус. Затем ко всем элементам input добавляются два обработчика.
Обработчик события focus устанавливает для этих элементов желтый фон, когда
они получают фокус, а обработчик события blur устанавливает для них светлосерый фон, когда фокус с них убирается (у них теряется).
Пример 21.5. Использование событий focus и blur


События: blur



Щелкните в пределах и за пределами этих полей


$('#first').focus()
$('input').focus(function() { $(this).css('background', '#ff0') } )
$('input') .blur(function() { $(this).css('background', '#aaa') } )



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

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

Рис. 21.4. Прикрепление к событиям blur и focus

Функции и свойства событий

529

Ключевое слово this
Этот пример также служит иллюстрацией применения ключевого слова this.
При вызове события объекту this передается элемент, в отношении которого это
событие было инициировано, и теперь этот объект может быть передан методу $
для обработки. Или же, поскольку он является стандартным объектом JavaScript
(а не объектом jQuery), он может быть использован в качестве такого объекта.
Поэтому, если хотите, можете заменить следующий код:
$(this).css('background', '#ff0')

вот этим кодом:
this.style.background = '#ff0'

События click и dblclick
Событие click ранее уже рассматривалось, но есть также событие, предназначенное
для обработки двойных щелчков. Чтобы воспользоваться любым из них, нужно
прикрепить метод события к селектору jQuery, а в качестве его аргумента поместить jQuery-метод, который будет запущен, когда это событие произойдет:
$('.myclass')
.click( function() { $(this).slideUp() })
$('.myclass').dblclick( function() { $(this).hide()
})

Здесь я решил использовать безымянные функции, но при желании вместо них
можно воспользоваться функциями с именами (но не забудьте, что предоставить
нужно только имя функции без круглых скобок, в противном случае она будет вызвана несвоевременно). Объекту this будет передано то, что и ожидалось, и он
станет доступен именованной функции:
$('.myclass').click(doslide)
function doslide()
{
$(this).slideUp()
}

Подробное описание методов slideUp и hide дается в разделе «Специальные
эффекты» данной главы. А сейчас просто попробуйте запустить код примера 21.6
и сделайте одинарный либо двойной щелчок на кнопках, чтобы посмотреть, как
одни из них исчезают с применением анимации (при использовании slideUp),
а другие просто исчезают (при использовании hide). Результат работы кода показан
на рис. 21.5.
Пример 21.6. Прикрепления к событиям click и dblclick



События: click & dblclick


530

Глава 21. Введение в jQuery



Сделайте на кнопках одинарный и двойной щелчок
Кнопка 1
Кнопка 2
Кнопка 3
Кнопка 4
Кнопка 5

$('.myclass').click( function() { $(this).slideUp() })
$('.myclass').dblclick( function() { $(this).hide() })




Рис. 21.5. На кнопке 3 был сделан одинарный щелчок, и она ускользнула вверх

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



События: keypress

531

Функции и свойства событий




Нажмите какие-нибудь клавиши


$(document).keypress(function(event)
{
key = String.fromCharCode(event.which)
if (key >= 'a' && key = 'A' && key = '0' && key