Для начала я хочу поблагодарить m007, который подал идею, как можно упростить Programmer-friendly интерфейс взаимодействия Клиент(JS)-Сервер(PHP), что и поспособствовало написанию этой статьи.
Данная статья является заключительной, в которой я объединю JS-Шаблоны, PHP Model-controller, и добавлю Динамическое создание UI методов на JS (некоторые идеи которого были взяты из статьи m007). Тем самым мы получим на выходе неплохой и удобный фундамент для создания своих AJAX приложений.
информативно для программиста.
m007 предложил вызывать функции прямо из JS, то есть вместо server_exec(«database_func(...);»,function(){...}) использовать в JS database.func(...).
В PHP, для не объявленных функций, есть метод __call. В JS такого метода нет, но можно предварительно подгрузить методы из PHP-библиотеки и динамически добавить их в JS-класс.
Для этого в PHP-класс UserInterface (см. прошлую статью) был добавлен метод, который при ‘пустом’ запросе выводил все зарегистрированные методы.
На Javascript написан класс PHPUIclass, который является интерфейсом для UserInterface. В этом классе описан метод обработки `пустого` запроса (спасибо DmitryBaranovskiy за приведение кода в порядок):
При запуске метода, происходит кодирование входящих параметров (request.push('"'+methods[index]+'":'+that.methods(Array.prototype.slice.call(arguments)))) и установка нулевого таймера на функцию для отсылки запроса. Думаю, что некоторых читателей этот момент удивил. По этому я остановлюсь на нём поподробнее.
Javascript не имеет потоков и весь код выполняет последовательно. Состояния у него всего два – выполнение кода и ожидание прерывания. Прерывания могут прийти, например, от таймера (по таймауту), от AJAX запроса (при смене статуса) и т д. При этом запускается состояния выполнение кода, который не прерывается, пока не дойдёт до конца.
Именно для этого я использую нулевой таймер, который запустит выполнение функции отсылающей запрос на сервер, после окончания выполнения основного кода. Сделано это для того, чтобы отсылать всё одним инкрементир��ванным запросом, состоящим из всех вызываеммых функций и обрабатывать результаты последовательно.
Теперь можно перейти к обработке результатов запроса. Так как обработчик будет вызван не сразу – то это будет функция или несколько функций, которые необходимо вызвать, когда придет ответ.
Этим занимаются методы run и ajax_run. Первый добавляет функции на запуск после получения ответа. Функции должны иметь вид function(data). А функция ajax_run занимается их запуском.
PHP:
UI.php основной класс UserInterface — подключается в библиотеку.
mod.fileview.php библиотека для чтения-записи файлов — функции read и save.
mod.dirview.php библиотека для чтения дириктории — функция dir.
mod.backup.php библиотека для формирования save.log — функции read,save,dir.
FileManager.php основной файл, который включает в себя все модули и запускает обработчик запроса.
Javascript:
PHPUI.js основной класс, который занимается подключением к интерфейсу UserInterface в php.
skin.js — класс работы с шаблонами.
index.html — загрузка шаблонов, вывод файлов.
HTML:
manager.skin — Шаблоны
manager.css — CSS
rus.xml — русский язык.
Рабочий пример
— Удобство программирования и создания новых методов для JS-интерфейса
— Ясность и прозрачность кода
— Универсальность методов
— Возможен вызов функций с неопределенным количеством параметров
Минусы:
— Нет проверки на параметры методов. Возможны простейшие ошибки при создании кода. Но для этого можно в PHP-функциях проверять пришедшие параметры (например для DEBUG-MODE). В случае не верных параметров, выводить alert(«ERROR»).
p.s. кстати, модель этого проекта является MVC.
Данная статья является заключительной, в которой я объединю JS-Шаблоны, PHP Model-controller, и добавлю Динамическое создание UI методов на JS (некоторые идеи которого были взяты из статьи m007). Тем самым мы получим на выходе неплохой и удобный фундамент для создания своих AJAX приложений.
Динамическое создание методов на JavaScript
Для начала хочу обратить ваше внимание, что все наши методы лежат в PHP-библиотеке. Каждый метод можно вызвать, передав определенные параметры в стиле JSON. И чтобы вызвать PHP-метод из JS, я предлагал в прошлой статье использовать функцию server_exec. Но можно это сделать более удобно иинформативно для программиста.
m007 предложил вызывать функции прямо из JS, то есть вместо server_exec(«database_func(...);»,function(){...}) использовать в JS database.func(...).
В PHP, для не объявленных функций, есть метод __call. В JS такого метода нет, но можно предварительно подгрузить методы из PHP-библиотеки и динамически добавить их в JS-класс.
Для этого в PHP-класс UserInterface (см. прошлую статью) был добавлен метод, который при ‘пустом’ запросе выводил все зарегистрированные методы.
На Javascript написан класс PHPUIclass, который является интерфейсом для UserInterface. В этом классе описан метод обработки `пустого` запроса (спасибо DmitryBaranovskiy за приведение кода в порядок):
this.add=function(res){Эта функция вызывается, когда PHP-библиотека возвращает названия зарегистрированных методов UI (ответ на ‘пустой’ запрос). Исходя из этих данных, этот метод создаёт внутри своего класса новые методы, которые используют для вызова public-методов PHP-библиотеки.
var methods=eval('{' + res.responseText + '}');
for (var index in methods)
that[methods[index]] = (function (name) {
return function () {
request.push('"' + name + '":' + that.methods(Array.prototype.slice.call(arguments)));
if (!timer)
timer=window.setTimeout(function(){
ajax_load(url, «method={»+that.getrequest(request)+"}", that.ajax_run, true);
},0);
};
})(methods[index]);
}* This source code was highlighted with <font size='1'
color='gray'>Source Code Highlighter.
При запуске метода, происходит кодирование входящих параметров (request.push('"'+methods[index]+'":'+that.methods(Array.prototype.slice.call(arguments)))) и установка нулевого таймера на функцию для отсылки запроса. Думаю, что некоторых читателей этот момент удивил. По этому я остановлюсь на нём поподробнее.
Javascript не имеет потоков и весь код выполняет последовательно. Состояния у него всего два – выполнение кода и ожидание прерывания. Прерывания могут прийти, например, от таймера (по таймауту), от AJAX запроса (при смене статуса) и т д. При этом запускается состояния выполнение кода, который не прерывается, пока не дойдёт до конца.
Именно для этого я использую нулевой таймер, который запустит выполнение функции отсылающей запрос на сервер, после окончания выполнения основного кода. Сделано это для того, чтобы отсылать всё одним инкрементир��ванным запросом, состоящим из всех вызываеммых функций и обрабатывать результаты последовательно.
Теперь можно перейти к обработке результатов запроса. Так как обработчик будет вызван не сразу – то это будет функция или несколько функций, которые необходимо вызвать, когда придет ответ.
Этим занимаются методы run и ajax_run. Первый добавляет функции на запуск после получения ответа. Функции должны иметь вид function(data). А функция ajax_run занимается их запуском.
this.run=function(eee){В результате мы получаем модифицируйщийся класс, в зависимости от установленных методов в PHP. И взаимодействие с ним выглядит очень удобно:
func.push(eee);
}
this.ajax_run=function(req){
var ret=eval('('+req.responseText+')');
for (var i in func)
if (func[i])
func[i](ret);
request=[];
func=[];
timer=false;
}* This source code was highlighted with <font size='1'
color='gray'>Source Code Highlighter.
//Инициализация класса удаленной работы с файлами.Ещё один пример, как воспользоваться результатом функции для запуска другой:
/* Синхронный запрос на вызов FileManager.php.
Получение методов dir,save,read.
Динамическое создание функций. */
var File=new PHPUIclass('FileManager.php');
//Вызов удалённых функций
/* Установка таймера и формирования запроса */
File.save(«edited.txt»,«Отредактированная часть файла»);
File.read(«save.log»);
File.dir();
//Установка функций для получения результатов запроса.
/* Добавление функции для обработки запроса read */
File.run(show_file);
/* Добавление функции для обработки запроса dir */
File.run(show_dir);
//Конец выполнения скрипта, а значит выполнение POST-запроса по Timeout(0) и возвращение результатов в show_file и show_dir* This source code was highlighted with Source Code Highlighter.
function show_file(file){Но в этом случае будет происходить два запроса. Этого избежать можно несколькими способами. Один из способов — это реализовать вызов необходимой функции с возвратом пряма в PHP.
//…
}
function show_error(error){
// ...
}
function check_file(result){
if (result.ERROR && result.ERROR.checkfile)
show_error(result.ERROR.checkfile);
else{
// Всё прошло нормально?
// Тогда ещё один запрос, уже на чтение.
File.read(result[«filename»]);
File.run(show_file);
}
}
//Вызов удалённых функций
File.checkfile(«edited.txt»);
File.run(check_file);* This source code was highlighted with Source Code Highlighter.
function checkfile($filename){Теряется модульность, но в данной реализации Javascript библиотеки, пока это единственный выход. Возможно в будующем я усовершенствую её, при необходимости.
global $UImethod;
if (file_exists($filename))
return $UImethod->read($filename);
else
return array(«ERROR» => array(«checkfile»=>$filename));
}
Пример
А вот — простой пример. File-viewer с возможностью редактировать файлы.PHP:
UI.php основной класс UserInterface — подключается в библиотеку.
mod.fileview.php библиотека для чтения-записи файлов — функции read и save.
mod.dirview.php библиотека для чтения дириктории — функция dir.
mod.backup.php библиотека для формирования save.log — функции read,save,dir.
FileManager.php основной файл, который включает в себя все модули и запускает обработчик запроса.
Javascript:
PHPUI.js основной класс, который занимается подключением к интерфейсу UserInterface в php.
skin.js — класс работы с шаблонами.
index.html — загрузка шаблонов, вывод файлов.
HTML:
manager.skin — Шаблоны
manager.css — CSS
rus.xml — русский язык.
Рабочий пример
Послесловие
Плюсы:— Удобство программирования и создания новых методов для JS-интерфейса
— Ясность и прозрачность кода
— Универсальность методов
— Возможен вызов функций с неопределенным количеством параметров
Минусы:
— Нет проверки на параметры методов. Возможны простейшие ошибки при создании кода. Но для этого можно в PHP-функциях проверять пришедшие параметры (например для DEBUG-MODE). В случае не верных параметров, выводить alert(«ERROR»).
p.s. кстати, модель этого проекта является MVC.