Jun 27 2007
Написал: Bambino в AJAX, web2.0
Ищем подопытных
Для этого обзора я выбрал 3 довольно сильно различающихся по функционалу библиотеки. Почему только 3? Дело в том, что другие интересные AJAX-решения обычно являются частью полноценных фреймворков для создания сайтов, поэтому их обзор занял бы слишком много места. Стало быть, о них – в следующий раз, а пока мы познакомимся с участниками сегодняшнего состязания.
Итак, внимание на сцену! Первым выступает представитель легкой весовой категории – Sajax, за ним уверенно двигается крепкий середнячок – Xajax, и, наконец, могучий тяжеловес, жонглер гирями, способный удержать на своей груди платформу с роялем, оркестром и взводом королевских мушкетеров, – Projax.
А что делать-то будем?
Сколько «пустых» статей и других материалов об AJAX и втором поколении веб-технологии публикуются ежедневно? Трудно сосчитать :). В них популярно и доказательно обосновывается, что все это очень круто и прогрессивно, но при этом авторы забывают рассказать нам одну малость – как всего этого добиться. Чтобы не быть голословным, я покажу тебе все это на конкретных примерах, часть из которых ты сможешь сразу использовать на своих веб-сайтах. Начнем с самой простой библиотеки – Sajax.
Sajax
Sajax – довольно простая библиотека, поэтому серверный и клиентский код мы можем (и будем :)) писать в одном файле. Функционал у нашей первой программы будет очень простым: мы нажимаем кнопку, и в текстовое поле загружается текст, разумеется, без перезагрузки страницы.
Для начала сделаем серверную часть, в которой будет экспортироваться функция, возвращающая текст для клиента:
ЯЗЫК: PHP
ОПИСАНИЕ: Серверная часть скрипта< ?php
require(”Sajax.php”);
function hello_world() {
return “Hello, world!”;
}
sajax_init();
// Раскомментировать для отладочного режима
// $sajax_debug_mode = 1;
sajax_export(”hello_world”);
sajax_handle_client_request();
?>
Последняя строка этого скрипта автоматически обрабатывает запросы клиента.
Ну что же, перейдем к клиентской части, которой надо выдать HTML и JavaScript (поместим мы ее в тот же файл, сразу за закрывающимся тэгом PHP).
Для автоматической генерации JavaScript мы воспользуемся библиотечной функцией sajax_show_javascript(), а для асинхронной работы JavaScript - определим функцию do_hello_world, которая будет вызываться при нажатии кнопки, и функцию do_hello_world_callback, которая сработает при получении ответа сервера и положит результат в текстовое поле.
Вся соль библиотеки Sajax кроется в работе do_hello_world, которая вызывает автоматически сгенерированную x_hello_world. Фактически, мы из JavaScript вызываем функцию, которая написана на PHP и хранится на сервере, а в качестве параметра передаем ей функцию обратного вызова:
ЯЗЫК: HTML и JavaScript
ОПИСАНИЕ: Клиентская часть скрипта
<html>
<head>
<title>Hello, world! by sAJAX</title>
<script>
<?php sajax_show_javascript(); ?>
function do_hello_world_callback(result) {
document.getElementById(”return_string”).value = result;
}
function do_hello_world() {
x_hello_world(do_hello_world_callback);
}
</script>
</head>
<body>
<input type=”text” id=”return_string” value=”Здесь будет результат запроса”>
<input type=”button” value=”Послать запрос” onclick=”do_hello_world(); return false;”>
</body>
</html>
Запустим скрипт и посмотрим описание функции x_hello_world, которое автоматически генерируется при вызове PHP-функции sajax_export(”hello_world”):
ЯЗЫК: JavaScript
ОПИСАНИЕ: Функция x_hello_world, сгенерированная библиотекой Sajax
// оболочка для функции hello_world
function x_hello_world() {
sajax_do_call(”hello_world”, x_hello_world.arguments);
}
В результате происходит прозрачный вызов PHP-функции, которая хранится на сервере. Теперь попробуем вызвать серверную функцию с параметрами, для чего напишем гостевую книгу, в которую сообщения будут добавляться без перезагрузки страницы, а отображение новых сообщений будет происходить автоматически. Для простоты я предположу, что у нас есть API для работы с сообщениями. Это может быть программный интерфейс к базе данных или XML-хранилищу. В нем нам нужны 3 функции:
«Название функции» и «Описание функции»
messages_api_print_messages() – печать всех сообщений в виде HTML
messages_api_add_message($message) – добавление сообщения
messages_api_get_messages() – возврат всех сообщений в виде HTML
Теперь напишем серверную часть, в которой изменится только описание функции и ее экспорт:
ЯЗЫК: PHP
ОПИСАНИЕ: Серверная часть скрипта<?
require(”Sajax.php”);
require(”messages_api.php”);function add_message($message) {
messages_api_add_message($message);
return messages_api_get_messages();
}
sajax_init();
sajax_export(”add_message”);
sajax_handle_client_request();
?>
На стороне клиента у нас будет поле для ввода текста и кнопка для отправления. Сообщения будут отображаться ниже:
ЯЗЫК: HTML, JavaScript, PHP
ОПИСАНИЕ: Клиентская часть скрипта<html>
<head>
<title>Гостевая книга by sAJAX</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<script>
<?php sajax_show_javascript(); ?>
function do_add_message_callback(result) {
document.getElementById(”messages”).innerHTML = unescape(result);
}
function do_add_message() {
message = document.getElementById(”message”).value;
x_add_message(message, do_add_message_callback);
}
</script>
</head>
<body>
<textarea id=”message”></textarea><br />
<input type=”button” value=”Отправить” onclick=”do_add_message(); return false;”>
<hr />
<div id=”messages”>
<?php
messages_api_print_messages();
?>
</div>
</body>
</html>
При нажатии на кнопку «Отправить» вызывается функция x_add_message, которой в качестве параметра передается не только функция обратного вызова, но и содержимое текстового поля. Надеюсь, внимательный читатель обратил внимание и на вызов функции unescape(result) для нормального отображения кириллических символов. Если нет желания каждый раз вызывать ее, можно пропатчить саму библиотеку.
Xajax
Несмотря на то что эта библиотека чуть мощнее предыдущей, работать с ней не намного сложнее. Чтобы быстро войти в курс дела, посмотрим, как можно с помощью Xajax загрузить файл по нажатию кнопки:
ЯЗЫК: HTML, JavaScript, PHP
ОПИСАНИЕ: Загрузка файла при помощи Xajax<?php
require (’xajax.inc.php’);
function loadFile($file) {
$objResponse = new xajaxResponse();
$objResponse->addAssign(”result”, “innerHTML”, file_get_contents($file));
$objResponse->addAssign(”result”, “style.visibility”, ‘visible’);
return $objResponse;
}
$xajax = new xajax();// Раскомментировать для отладки
//$xajax->debugOn();
$xajax->registerFunction(”loadFile”);
$xajax->processRequests();
?>
<html>
<head>
<title>Загрузка файла</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<?php $xajax->printJavascript(”); ?>
</head>
<body style=”text-align: center;”>
<button onclick=”xajax_loadFile(’file.data’)”>Загрузить файл</button>
<div style=”border: 1px solid black; visibility:hidden;” id=”result”></div>
<br/>
</body>
</html>
Первое, что бросается в глаза при прочтении кода, - поддержка ООП в Xajax, ведь мы работаем не с функциями, а с классами и объектами, которые при желании можно расширить. Общая схема работы аналогична Sajax, по-другому идет разве что отправка ответа с сервера клиенту – для этого используется объект $objResponse класса xajaxResponse. Я использовал метод addAssign, который ищет объект HTML с заданным id и определенному полю присваивает нужное значение. То есть мы можем не только прозрачно вызывать серверные функции на клиенте, но и прозрачно модифицировать HTML с сервера (и добавлять JavaScript).
Кстати, помнится, я обещал продемонстрировать, как надо разделять AJAX-систему на клиента и сервер. Настало время исполнить обещание, а заодно – показать, как Xajax умеет автоматически отсылать формы на сервер.
На каждом сайте, который поддерживает создание сетевого сообщества, имеется процедура регистрации с помощью специальной формы. Чтобы зарегистрироваться, надо потратить немало сил: то пароль слишком легкий, то логин занят - проще просто бросить это дело. Попробуем сделать эту процедуру безболезненной, быстрой и интерактивной.
Логин, введенный пользователем, должен быть незанятым и отвечать некоторым требованиям, например состоять более чем из трех символов. На пароль мы наложим только ограничение по длине: 6 символов. Дополнительные проверки можешь придумать сам – все зависит от твоей фантазии ;). Вся система будет содержать 3 файла:
«Имя файла» и «Описание»
register.common.php – общий функционал для клиента и сервера
register.server.php – серверная часть для проверки логина, пароля и обработки формы
register.php – клиентская часть с интерактивной формой ввода
Начнем с общей части для клиента и сервера, в которой будут регистрироваться 3 функции для проверки логина, пароля и для приема данных с клиента. Поскольку серверная часть будет у нас в отдельном файле, это надо указать в конструкторе объекта $xajax:
ЯЗЫК: PHP
ОПИСАНИЕ: register.common.php
<?php
require (’xajax.inc.php’);
$xajax = new xajax(”register.server.php”);
// Раскомментировать для отладки
//$xajax->debugOn();
$xajax->registerFunction(”checkUserName”);
$xajax->registerFunction(”checkUserPass”);
$xajax->registerFunction(”submitForm”);
$xajax->processRequests();
?>
Функции для проверки я предлагаю описать отдельно, так как они будут вызываться у нас в двух случаях: когда форма будет передана на сервер и когда по мере набора текста пользователем будет происходить автоматическая проверка:
ЯЗЫК: PHP
ОПИСАНИЕ: Функции для проверки логина и пароля (register.server.php)
function isUserNameGood($userName) {
// Их надо брать из базы![]()
$users = array(”bill”, “john”, “vasya”);
if (strlen($userName) <= 3)
return array(false, “Имя пользователя должно быть длиннее трех символов”);
foreach ($users as $user)
if ($user == $userName)
return array(false, “Имя пользователя уже используется”);
return array(true, “Имя пользователя подходит”);
}function isUserPassGood($userPass) {
$objResponse = new xajaxResponse();
if (strlen($userPass) <= 6)
return array(false, “Пароль должен быть длиннее шести символов”);
return array(true, “Пароль подходит”);
}
Обе функции возвращают 2 значения, первое имеет булевский тип и определяет, подходят ли логин и пароль соответственно, а второе содержит пояснительный текст. Теперь реализовать функции, которые будут вызываться клиентом, не составит труда:
ЯЗЫК: PHP
ОПИСАНИЕ: Функции, которые будут вызываться из JavaScript (register.server.php)
function checkUserName($userName) {
$objResponse = new xajaxResponse();
list($isUserNameGood, $message) = isUserNameGood($userName);
$objResponse->addAssign(”userNameOk”, “innerHTML”, $message);
return $objResponse;
}
function checkUserPass($userPass) {
$objResponse = new xajaxResponse();
list($isUserPassGood, $message) = isUserPassGood($userPass);
$objResponse->addAssign(”userPassOk”, “innerHTML”, $message);
return $objResponse;
}
Отмечу, что результат у меня помещается в специальные ячейки в таблице с айдишниками - userNameOk и userPassOk, которые мы опишем на стороне клиента. И последнее, что нам осталось сделать на сервере, - это создать функцию, которая будет обрабатывать данные из формы для регистрации пользователя. Все содержимое передается этой функции в виде параметра, который представляет собой ассоциативный массив (аналог $_POST и $_GET):
ЯЗЫК: PHP
ОПИСАНИЕ: Функция для обработки формы (register.server.php)
function submitForm($formData) {
$objResponse = new xajaxResponse();
list($isUserNameGood, $message) = isUserNameGood($formData['userName']);
$objResponse->addAssign(”resultDiv”, “innerHTML”, $message);
list($isUserPassGood, $message) = isUserPassGood($formData['userPass']);
$objResponse->addAppend(”resultDiv”, “innerHTML”, “<br/>” . $message);
if ($isUserNameGood && $isUserPassGood)
$objResponse->addAppend(”resultDiv”, “innerHTML”, “<br/><strong>Регистрация прошла успешно</strong>”);
else
$objResponse->addAppend(”resultDiv”, “innerHTML”, “<br/><strong>Регистрация завершилась неудачей</strong>”);
return $objResponse;
}
Обрати внимание, что в этих скриптах я нигде не использую базу данных или любое другое постоянное хранилище, чтобы код не потерял ясность. В реальных условиях при успешной регистрации пользователя обязательно надо сохранять его данные, да и получать список пользователей надо тоже из какого-то хранилища. Теперь напишем клиентский код, который будет описывать форму регистрации. Чтобы браузер отправил форму без перезагрузки страницы, нужно «обнулить» (точнее, «завойдить» :)) параметр action у формы и прописать событие onsubmit. При этом событии будет вызвана JavaScript-функция xajax_sumbitForm, которая является оберткой нашей серверной функции submitForm, а параметром будут как раз данные формы. Проверка данных формы во время их набора пользователем осуществляется при помощи вызова соответствующих функций по событию onkeyup:
ЯЗЫК: HTML, JavaScript, PHP
ОПИСАНИЕ: Клиентский код (register.php)
<?php
require (’register.common.php’);
?>
<html>
<head>
<title>Регистрация пользователя</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<?php $xajax->printJavascript(”); ?>
<script type=”text/javascript”>
function submitForm() {
xajax.$(’submit’).disabled=true;
xajax.$(’submit’).value=”Регистрируется пользователь…”;
xajax_submitForm(xajax.getFormValues(”registrationForm”));
return false;
}
</script>
</head>
<body>
<form id=”registrationForm” action=”javascript:void(null);” onsubmit=”submitForm();”>
<table border=”1″ width=”50%”>
<tr>
<td width=”40%”>Имя пользователя </td>
<td><input onkeyup=”xajax_checkUserName(this.value)” type=”text” id=”userName” name=”userName” /></td></tr>
<tr>
<td id=”userNameOk” colspan=”2″> </td>
</tr>
<tr>
<td width=”40%”>Пароль</td>
<td><input type=”text” onkeyup=”xajax_checkUserPass(this.value)” id=”userPass” name=”userPass” /></td>
</tr>
<tr>
<td id=”userPassOk” colspan=”2″> </td>
</tr>
<tr>
<td> </td>
<td><input type=”submit” id=”submit” value=”Submit” /></td>
</tr>
</table>
<div id=”resultDiv”> </div>
</form>
</body>
</html>
Projax
Настало время десерта – самой мощной библиотеки в нашем обзоре. Я покажу ее возможности на очень распространенном сейчас виджете – поле ввода с автозавершением (a-ля Google Suggest). Для этого у нас есть все необходимое, остается только подключить JavaScript-файлы и вызвать метод text_field_with_auto_complete – на этом клиентская часть заканчивается.
ЯЗЫК: HTML, JavaScript, PHP
ОПИСАНИЕ: Клиентский код – «поле ввода с автозавершением»
<?php
include (”projax.php”);
$projax= new Projax();
?>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Демонстрация автозавершения by Projax</title>
<script src=”js/prototype.js” mce_src=”js/prototype.js” type=”text/javascript”></script>
<script src=”js/scriptaculous.js” mce_src=”js/scriptaculous.js” type=”text/javascript”></script>
</head>
<body>
Введите имя пользователя :<br />
<?=$projax->text_field_with_auto_complete(’name’, null, array(’url’=>’get_names.php’));?>
</body>
</html>
Серверная часть будет просто печатать список строк, в котором есть подстрока, набранная пользователем:
ЯЗЫК: PHP
ОПИСАНИЕ: Серверная – «поле ввода с автозавершением» (get_names.php)
<?php
// Имена пользователей берутся из базы
$names = array(’boris’, ‘vasya’, ‘bill’);
foreach($names as $name)
$ret_val .= (strstr($name,$_POST['name'])) ? ‘<li>’.$name.’</li>’:”;
echo ‘<ul>’ . $ret_val . ‘</ul>’;
?>
Как видишь, всего несколько строк кода - и мы уже у цели (посмотри на скрин «Поле с автозавершением» и возрадуйся – у тебя будет такой же :)).
Заключение
В этой статье мы рассмотрели 3 библиотеки, которые позволяют быстро писать эффективные приложения в связке PHP и JavaScript, реализуя таким образом методологию AJAX. Каждая из этих библиотек имеет как плюсы, так и минусы, которые надо знать, чтобы выбрать нужную из них для конкретного проекта. Поэтому мой вердикт таков – срочно бери с диска библиотеки и материалы к этой статье и ковыряй их до выхода в свет следующего «Кодинга» :).
Sajax (www.modernmethod.com/sajax)
Sajax (Simple Ajax Toolkit) – это простая библиотека для создания AJAX-приложений на PHP путем прозрачного вызова серверных функций с клиента. Общий вес клиентского и серверного кода составляет чуть меньше 9 Кб, что делает библиотеку незаменимой для небольших и быстрых приложений. Ее можно посоветовать использовать тем, кто собирается переделывать свое AJAX-приложение без использования фреймворков, поскольку Sajax - довольно низкоуровневая библиотека, не содержащая лишних наворотов. В комплект поставки входят фреймворки для следующих языков: ASP, Cold Fusion, Io, Lua, Perl, PHP, Python и Ruby. К минусам библиотеки можно отнести некорректную работу с кириллицей (правда, проблема довольно просто решается).
Xajax (www.xajaxproject.org)
Для 90% всех веб-проектов хватит библиотеки Xajax, которая обеспечивает полностью прозрачное взаимодействие клиента и сервера (причем в обе стороны). Размер клиентской части в сжатом виде составляет 15 Кб, что вполне приемлемо для библиотеки с таким функционалом. В дистрибутив входят примеры (в том числе XUL-приложение для Mozilla Firefox) и тесты для этой библиотеки. Кроме того, хочу отметить наличие в интернете большого количества документации и сообщества, которое сложилось вокруг этого проекта. По моему очень скромному мнению, эта библиотека является наиболее сбалансированной по параметрам «функционал» и «легкость использования». Выбор редакции, так сказать ;).
Projax (www.ngcoders.com/projax)
Projax представляет собой порт проекта Prototype, который был первоначально написан для Ruby on Rails и проекта script.aculo.us. Такой мощный функционал объясняет общий размер клиентской части - более 170 Кб кода JavaScript. За эти «деньги» мы получаем полную «корзину фруктов» - от манипуляций с DOM до визуальных эффектов. Projax идеально подходит для «суперинтерактивных» проектов, например, онлайн-игр, где нужен мощный функционал на стороне пользователя. Минусом опять же является некоторая сложность этой библиотеки, которую ты, конечно, не заметишь, если раньше работал с Prototype и script.aculo.us
Информация
Библиотеки обычно содержат отладочный режим, при включении которого выдаются сообщения о ходе выполнения программы.
Для эффективной отладки AJAX-приложений необходимо настроить отладку как серверного PHP-кода, так и клиентского JavaScript.
Для отладки JavaScript проще всего использовать расширения для Mozilla Firefox - JavaScript Debugger и FireBug.
Источник: xakep.ru
4 Responses
Саня
August 22nd, 2007 at 16:11
1Bambino
August 23rd, 2007 at 09:12
2А разве в тексте статьи не приведены примеры?! Ну может не такие готовые…
Но ведь соль в том, чтобы самому их сделать. А сложности в ajax нет. Идея проста - javascript вызывает серверный скрипт, посредством встроенного в браузер объекта xmlHTTPRequest, который возвращает в скрипт полученные данные, которые можно использовать дальше.
sanyva
August 27th, 2007 at 14:34
3все равно сколько с другом не читаем Эту страницу. так и не можем запустить ее чтобы заработала…. вроде все правильно делаем …. но УВЫ…. если не трудно выложите а архиве готовый наглядный пример, что бы можно было его разобрать просмотреть.. просто в интернете довольно мало толковых, и главное понятных статей по этой тематике
Bambino
September 5th, 2007 at 08:56
4Какая библиотека тебя интересует… лично я пользоваля xajax и projax. Правда, что-то projax у меня не заработал в Опере и Осле. Еще не разбирался почему..
RSS feed for comments on this post · TrackBack URI
Оставьте комментарий