
- •В.С. Романчик
- •Глава 2. Использование php.
- •Глава 3.
- •Введение
- •Возможности php.
- •Инструменты для разработки
- •Как php работает
- •Глава 1. Язык php Типы данных
- •Массивы и инициализация массивов
- •Объектно-ориентированное программирование в php Основные понятия ооп
- •Классы и Объекты
- •Конструкторы и деструкторы
- •Наследование классов и интерфейсов
- •Магические методы
- •Обработка ошибок
- •Ошибки php и директива error_reporting
- •Чтение и запись бинарных файлов
- •Работа с каталогами в рнр
- •MySql – сервер: бд1; бд2; бд3; бд4;
- •Язык запросов sql
- •Операция соединения.
- •Команды sql для создания баз данных и таблиц
- •Выборка данных из таблиц бд
- •Работа с MySql (сохранение данных в базе данных).
- •Работа с MySql занесение и получение данных из базы данных
- •Некоторые улучшения в организации работы с данными
- •Передача данных от клиента к серверу и от сервера клиенту
- •Клиентские методы http get, post, head
- •Обработка html-форм и передача переменных в скрипт.
- •Передача значений переменных по методу get
- •Ниже рассмотрен еще один пример передачи данных из клиентской формы на сервер по методу get
- •Передача данных на сервер по методу post
- •Php и обработка различных форм
- •Примеры обработки форм
- •Работа с e-mail
- •Отправка почты на php (Функция mail)
- •Cookies-наборы: сохраненное состояние
- •Сессии (Сеансы) Переменные сеанса
- •Отмена регистрации сеансовых переменных
- •Работа с сеансовыми переменными
- •Постоянные данные, использующие сеансы и cookie-наборы
- •Вывод графических данных с помощью рнр Основной способ создания изображений
- •Получение информации об изображении
- •Функции рисования прямых и кривых линий
- •Заливка изображений
- •Работа с палитрой изображения
- •Удаление и изменение цветов палитры
- •Создание прозрачности в изображениях
- •Рисование с помощью кистей
- •Использование специальных стилей для заливки
- •Использование шрифтов и вывод строк
- •Манипулирование и копирование изображений
- •Создаём графический информер на php
- •Слияние изображений с помощью gd
- •Включения удаленных файлов
- •Различные приложения и полезные скрипты на php
- •Пример. Определение типа и версии браузера
- •Генератор паролей на php
- •Время выполнения скрипта
- •Календарь
- •Загрузка файла от клиента на сервер
- •Работа с ftp на уровне php
- •Сбор статистики на php
- •Проверка ввода емайл
- •Чтение почты через Web-интерфейс
- •Разработка собственных листов рассылки
- •Рассылаем письма
- •Добавляем адреса в список рассылки
- •Редактирование адресов
- •Автоответчик
- •Почтовые функции в рнр
- •Задания для выполнения
- •Приложение 1. Протокол передачи гипертекстов http
- •Клиентские методы и заголовкиHttp
- •Указатель ссылки ("Referer")
- •Медиа-типы
- •Кодирование
- •Безопасность и авторизация
- •Кэширование содержимого http на стороне клиента
- •Http идентификация с php
- •Сжатие данных в протоколе http
- •Модель ajax: между загруженной в браузер страницей и сервером появляется прослойка - уровень ajax, который обеспечивает следующую последовательность выполнения приложения.
- •Класс xmlHttpRequest
- •Методы класса xmlHttpRequest
- •Свойства класса xmlHttpRequest
- •Создание экземпляра объекта xmlHttpRequest
- •Использование dom
- •Проблема с кешированием
- •Информируйте пользователя
- •Нет принципов написания кода
- •Аутентификация средствами php
- •Отделение клиентская части программы от серверной части и шаблоны
- •Использование шаблонов в php
- •Шаблоны подстановки
- •Создаем свои шаблоны в php
- •Теги, атрибуты, значения
- •Структура документа
- •Разрыв строки
- •Предварительное форматирование
- •Комментарии
- •Физическая и логическая разметка документа
- •«Физические» теги:
- •«Логические» теги:
- •Специальные символы
- •Графика
- •Формы html
- •Метатеги
- •Способы включения каскадных таблиц стилей
- •Синтаксис
- •Группирование
- •Наследование
- •Множественные классы.
- •Селекторы идентификаторов (id-селекторы).
- •Комментарии
- •Свойства шрифтов.
- •Свойства текста.
- •Представление документа в виде специальных областей – блоков
- •Отступы, поля, позиционирование.
- •Границы элементов.
- •Визуальные эффекты
- •Свойства списков
- •Свойства таблиц
- •Псевдоклассы
- •Псевдостили текста
- •Псевдоэлементы
- •Различные свойства
- •Css. Примеры
- •Типы данных
- •Ассоциированные массивы
- •Операторы
- •Подпрограммы
- •Приложение 11. Популярные веб-приложения и фреймворки
- •Фреймворки
Сжатие данных в протоколе http
Благодаря автоматической генерации, сложной разметке и внедрению Unicode, современные web-страницы могут иметь довольно большой размер. В протоколе HTTP предусмотрена возможность сжатия передаваемых данных. Для этого могут применяться способы сжатия, сходные с программами zip, gzip, bzip2, rar. Но сжатые сервером данные (например, передаваемая HTML-стрница) не записываются в файл на диске, а сразу передаются клиенту в сжатом виде. При этом может быть достигнута существенная экономия трафика и времени передачи.
Клиент, способный принимать информацию в сжатом виде, сообщает об этом серверу при помощи заголовка Accept-Encoding:
GET /~dimss/ HTTP/1.1
Host: localhost
Accept-Encoding: gzip,deflate
........
Сервер, видя такой заголовок, имеет право сжать содержимое своего ответа одним из предложенных методов. О том, что данные передаются в сжатом виде, сервер извещает клиента заголовком Content-Encoding:
HTTP/1.x 200 OK
Content-Encoding: gzip
........
Content-Type: text/html; charset=utf-8
[сжатые данные, на вид -- полная абракадабра]
Использование сжатия оговаривается в спецификации протокола HTTP/1.1 Спецификацией предусмотрено три способа сжатия: deflate (RFC 1951), compress (аналогичен Unix-программе compress) и gzip (RFC 1952, аналогичен Unix-программе gzip). Наиболее практичным является метод gzip. Его поддерживают большинство современных Web-клиентов. Использование сжатия для динамических HTML-документов целесообразно, несмотря на дополнительную процедуру сжатия. Статические HTML-документы можно хранить в сжатом виде, и разжимать перед передачей, если клиент не понимает gzip. Эти функции можно возложить на Web-сервер, см. далее.
Естественно, внедрение сжатия в прикладном коде - это не лучший вариант. О сжатии должна заботиться среда программирования или сам Web-сервер.
Так, язык PHP позволяет автоматически сжимать передаваемые страницы, для этого в php.ini есть опция zlib.output_compression.
Модули поддержки сжатия существуют для большинства Web-серверов. Для сервера Apache существуют модули mod_deflate и mod_gzip. Сжатие gzip поддерживается набирающим популярность сервером nginx. Сжатие deflate и gzip поддерживает также сервер Microsoft IIS.
Приложение 2. Сериализация объектов
Сериализация - это процесс, посредством которого массив или объект класса преобразуется в символьную строку для дальнейшей передачи или хранения. Сериализация выполняется следующим образом: serialize($obj); где Sobj — объект для сериализации. Рассмотрим пример:
<?php //pr30
$a= array("key" =>"testing", 1 => 10, 2 => "mystring");
echo $b=serialize($a) ,"<br>";
print_r (unserialize($b));
?>
Вывод :
a:3:{s:3:"key";s:7:"testing";i:1;i:10;i:2;s:8:"mystring";}
Array ( [key] => testing [1] => 10 [2] => mystring )
Строка сериализации не может непосредственно использоваться для передачи с помощью HTTP-протокола или для сохранения в базе данных, так как она содержит недопустимые символы. Если данные нужно сохранить в базе данных, то подойдет простое использование функции addslashes(). При работе с HTTP-протоколом нужно использовать функцию urlencode(). После сериализации и кодирования строка может быть передана в базу данных как скрытый элемент HTML-формы или записана в файл для дальнейшего использования.
Для восстановления переменной из ее сериализованного представления в РНР предусмотрена функция unserialize ():
unserialize($obj_string [, $callback_function])
где $obj_string представляет строку сериализации для восстановления переменной, $callback_function — имя необязательной функции обратного вызова для использования, если unserialize () реконструирует объект, который не был определен. При успешном завершении функция unserialize() возвращает реконструированный объект, или же false, если РНР не может реконструировать сериализованные данные.
Сериализация объектов в сессиях
Функция serialize() возвращает строку, содержащую представление объекта в виде потока байтов. При сериализации объекта PHP сохраняет в строке имя класса и значения свойств объекта. Методы объекта и данные о родительских классах или имплементируемых интерфейсах не сохраняются. Чтобы иметь возможность дессериализации объекта, должен быть определён класс этого объекта. То есть, если у вас имеется объект $a класса A в файле page1.php и вы его сериализуете, вы получите строку, которая ссылается на класс A и содержит все значения переменных, содержащихся в $a. Если вы хотите выполнить десериализацию в файле page2.php, воссоздав объект $a класса A, определение класса A обязано иметься в page2.php. Это можно сделать, например, сохранив определение класса A в include-файле и подключив этот файл и в page1.php, и в page2.php.
//classa.php:
<?php
class A
{
private $one = 1;
public function show_one()
{
echo $this->one;
}
}
?>
<?php
//pr31.php:
include 'classa.php';
$a = new A;
$s = serialize($a);
echo 's=',$s;
// сохраняем $s там, где pr32.php может его найти.
$fp = fopen("store", "w");
fputs($fp, $s);
fclose($fp);
?>
Вывод:
s=O:1:"A":1:{s:6:"Aone";i:1;}
<?php
//pr32.php:
// это необходимо для правильной работы десериализации.
include ("classa.php");
$s = implode("", @file("store"));
$a = unserialize($s);
// теперь используем функцию show_one() объекта $a.
$a->show_one();
?>
Вывод:
1
Если вы используете сессии и session_register() для регистрации объектов, эти объекты сериализуются автоматически в конце каждой PHP-страницы и десериализуются автоматически на каждой последующей странице. Это означает, что эти объекты могут появиться на любой странице, после того как стали частью вашей сессии. Рекомендуется включать определение классов всех таких зарегистрированных объектов во все страницы, даже если вы и не используете эти классы во всех. Если объект десериализуется в отсутствие определения класса, он потеряет ассоциацию с этим классом и станет практически бесполезен.
Итак, если в вышеприведённом примере $a стало частью сессии через запуск session_register("a"), вы должны включить/include файл classa.inc во все ваши страницы, а не только в page1.php и page2.php.
Подготовка данных к сохранению.
Данные сессии, хранятся в массиве $_SESSION.
Данные хранятся на стороне сервера и об их наличии и составе пользователь может только догадываться. В программе эти данные могут состоять из любых типов данных, доступных программисту: строки, числа, массивы и объекты, но не ресурсы (об этом ниже). При записи данные подвергаются процедуре сериализации (serialization) - преобразования структур любой сложности (не содержащих ресурсов) в строку, из которой в последствии можно восстановить структуру назад. Для сериализации используется функция serialize(). Для обратного процесса - десериализации - unserialize(). При старте сессии эти PHP, получив от обработчика сессии строку, посредством функции unserialize() восстанавливает данные и помещает их в массив $_SESSION. При завершении программы происходит обратный процесс: массив $_SESSION автоматически сериализуется и строка передается обработчику сессии для записи. Т.е. обработчик сессии работает только со строкой и не зависит от сложности структуры хранимых данных.
Рассмотрим особенности работы сериализации:
1. Ссылки.
Массив $_SESSION, как и любой другой массив, может содержать ссылки на другие переменные, а так же может содержать объекты и массивы, которые тоже содержат ссылки. Возможна да же рекурсивная связь.
Код:
<?php
$array['b'] = array();
$array['a'] = array('bRef' => &$array['b']);
$array['b']['aRef'] = &$array['a'];
echo "<pre>" . htmlspecialchars(print_r($array, true)) . "</pre>";
?>
Можно сериализовать массив целиком и потом восстановить его. Но если попытаться сериализовать отдельно $array['a'] и $array['b'], а потом их восстановить, то связи будут нарушены. Вот пример такого разрушения связей.
<?php
$array['b'] = array();
$array['a'] = array('bRef' => &$array['b']);
$array['b']['aRef'] = &$array['a'];
$array['a']['val'] = 1;
echo "<pre>" . htmlspecialchars(print_r($array, true)) . "</pre>";
$str_a = serialize($array['a']);
$str_b = serialize($array['b']);
echo "<pre>" . htmlspecialchars($str_a) . "</pre>";
echo "<pre>" . htmlspecialchars($str_b) . "</pre>";
$array2['a'] = unserialize($str_a);
$array2['b'] = unserialize($str_b);
$array2['a']['val'] = 2;
echo "<pre>" . htmlspecialchars(print_r($array2, true)) . "</pre>";
?>
2. Объекты и их классы.
Особенность сериализации объекта в том, что сохраняется только состояние объекта - его данные, а для "оживления" обязательно заранее должен быть объявлен класс.
Выходов из этого положения два: заранее загружать объявления необходимых классов, либо воспользоваться специальным обработчиком, который сможет попытаться подгрузить требуемый класс. Назначается обработчик в ini.php (unserialize_callback_func'), но может быть изменен во время работы программы.
Выглядит этот обработчик так:
Код:
<?php
ini_set("unserialize_callback_func", "my_unserialize_callback_func");
function my_unserialize_callback_func($classname)
{
// Предпологаем, что файлы, содержащие классы,
// находятся в поддиректории classes и имеют имя
// соответствующее имени класса.
$filename = "classes/$classname.php";
if (!is_file($filename))
die("Не удалось подгрузить класс '$classname'");
include_once($filename);
}
?>
Для того чтобы можно было управлять процессом сериализации/десериализации в классах PHP предусмотрены специальные "волшебные" методы: __sleep() и __wakeup(). Метод __sleep() должен возвращать массив с именами своих свойств, которые будут сохранены. __sleep вызывается перед сериализацией чтоб можно было убрать ненужные связи.
Метод __wakeup() нужен для выполнения процедур инициализации объекта после десериализации. __wakeup вызывается после unserialize, чтоб можно было необходимые связи вернуть.
Метод __sleep обязательно должен вернуть массив со списком свойств, которые нужно сериализовать; Если объект сериализуется, а потом продолжает использоваться, он может быть испорчен, так как при сериализации был вызван метод __sleep.
Пример использования:
<?php
class Connection {
protected $link;
private $server, $username, $password, $db;
public function __construct($server, $username, $password, $db)
{
$this->server = $server;
$this->username = $username;
$this->password = $password;
$this->db = $db;
$this->connect();
}
private function connect()
{
$this->link = mysql_connect($this->server, $this->username, $this-> password);
mysql_select_db($this->db, $this->link);
}
public function __sleep()
{
return array('server', 'username', 'password', 'db');
}
public function __wakeup()
{
$this->connect();
}
}
?>
Пример сериализации
class A implements Serializable {
private $x='y';
function __construct()
{
echo __METHOD__ . " called\n";
}
function __destruct()
{
echo __METHOD__ . " called\n";
}
function serialize()
{
return $this->x;
}
function unserialize($s)
{
$this->x=$s;
}
}
class B {
private $x='y';
function __construct()
{
echo __METHOD__ . " called\n";
}
function __destruct()
{
echo __METHOD__ . " called\n";
}
function __sleep()
{
return array('x');
}
}
echo "Serializable (the new way)\n";
$x1=new A;
$s=serialize($x1);
var_dump($s);
$y1=unserialize($s);
var_dump($y1);
echo "__sleep/__wakeup (the old way)\n";
$x2=new B;
$s=serialize($x2);
var_dump($s);
$y2=unserialize($s);
var_dump($y2);
Сериализация объектов и автозагрузка.
При сериализации объекта PHP сохраняет в итоговой строке имя класса и значения свойств объекта. Методы объекта и данные о родительских классах или имплементируемых интерфейсах не сохраняются. Следовательно, необходимый класс должен быть определён до того, как объект будет обратно десериализован из строки. В большинстве случаев все классы системы не имеет смысла подключать при каждом запросе. А если класс с нужным именем не был определён, PHP инстанцирует объект класса __PHP_Incomplete_Class_Name и определяет в нём свойства, сохранённые при сериализации объекта. Само собой, нормальная работа с таким объектом невозможна.
Положение исправляет автозагрузка классов, но одного наличия определённой функции __autoload() недостаточно, чтобы интерпретатор попытался автоматически подключить нужный класс. Для этого должна быть установлена директива конфигурации unserialize_callback_func, в которой указывается имя метода автозагрузки. Устанавливать значение этой директивы можно в любом месте, поэтому самое простое и правильное — на этапе инициализации приложения присвоить этой директиве значение __autoload. При этом нужно помнить, что если функция автозагрузки указана, но не определена, при вызове функции unserialize() возникнет warning.
Проблема становится ещё актуальнее, если вспомнить, что сессии для хранения данных используют именно сериализацию. Десериализация производится при вызове функции session_start(), которая часто вызывается в самом начале работы приложения. Ещё хуже, если сессия стартует автоматически (с использованием директивы session.auto_start). В этом случае не помогает и использование директивы auto_prepend_file, то есть нет возможности стандартными средствами определить функцию автозагрузки до старта сессии.
В конечном итоге получается, что для нормального сохранения объектов в сессии нужно обязательное выполнение следующих условий:
1. Автоматический запуск сессий отключён.
2. Функция __autoload() определяется до момента старта сессии.
3. До момента старта сессии выполняется команда ini_set('unserialize_callback_func', '__autoload').
Установку директивы unserialize_callback_func лучше размещать сразу после определения функции автозагрузки, чтобы сгруппировать эти важные элементы вместе.
Приложение3. Взаимодействие PHP и JavaScript
Скрипты JavaScript выполняются на машине клиента, в то время как PHP-приложения выполняются на сервере. Существует две простые возможности взаимодействия PHP и JavaScript: передача переменных из JavaScript в PHP и динамическое формирование скриптов JavaScript средствами PHP.
Передача переменных из JavaScript в PHP может осуществлятся по методу GET или POST. Рассмотрим пример определения разрешения экрана и глубину цвета монитора посетителя страницы средствами JavaScript и передачи этих данные в PHP-скрипт.
<script language="JavaScript">
//javasphp.htm
var height=0;
var width=0;
var colorDepth = screen.colorDepth;
if (self.screen)
{
width = screen.width
height = screen.height
}
if (width > 0 && height > 0)
{
/*перенаправление на скрипт javasphp.php */
window.location.href=
"http://localhost/mypr/javasphp.php?wid="+width+"&hei="+height+"&col="+colorDepth;
}
else exit();
</script>
После выполнения этого кода происходит автоматический переход на страницу javasphp.php, на которой происходит вывод разрешения экрана и глубины цветопередачи в окно браузера.
Файл javasphp.php
?php
echo "Ширина : ".$_GET['wid'],"<br>";
echo "Высота : ".$_GET['hei'],"<br>";
echo "Цветовое разрешение:".$_GET['col'];
?>
Вывод:
Ширина : 1024 Высота : 768 Цветовое разрешение:32
Передача данных из JavaScript, происходит по методу GET.
JavaScript и AJAX
Название AJAX - это аббревиатура от "Asynchronous JavaScript And XML”. Технология AJAX позволяет создавать интерактивные веб-приложения, для которых измененные страницы могут полностью не перегружаться, а перегружаются лишь изменившиеся в результате работы приложения данные. Отметим, что новые сервисы Google, в том числе GMail, Orkut, Google Groups, Google Maps, Google Suggest, Google Finance , являются AJAX-приложениями.
Рассмотрим отличия классической модели веб-приложения и модели AJAX.
Классическая модель веб-приложения. Последовательность выполнения приложения:
- Пользователь загружает в браузер веб-страницу и генерирует событие.
- Браузер отправляет HTTP запрос серверу.
- Cервер генерирует новую веб-страницу и возвращает ее в ответ браузеру.
- Браузер отображает новую страницу.