📜 ⬆️ ⬇️

JS-PHP MVC interface - we collect everything together

First, I want to thank m007 , who gave the idea how to simplify Programmer-friendly Client Interface (JS) -Server (PHP), which contributed to the writing of this article.

This article is the final one in which I will integrate JS-Templates , the PHP Model-controller , and add Dynamic creation of UI methods on JS (some ideas of which were taken from article m007 ). Thus, we will get a good and convenient foundation for creating our own AJAX applications.

Dynamic creation of JavaScript methods

First I want to draw your attention that all our methods are in the PHP library. Each method can be called by passing certain parameters in JSON style. And to call the PHP method from JS, I suggested using the server_exec function in the last article. But you can do it more conveniently and
informative for the programmer.
m007 proposed to call functions directly from JS, that is, instead of server_exec (“database_func (...);”, function () {...}) use JS database.func (...) .

In PHP, for non-declared functions, there is a __call method. In JS, there is no such method, but you can preload methods from the PHP library and dynamically add them to the JS class.
')
To do this, a method has been added to the UserInterface PHP class ( see the last article ), which, in an 'empty' query, deduced all registered methods.
The PHPUIclass class is written in Javascript, which is the interface for the UserInterface . This class describes the method for handling the 'empty' request (thanks to DmitryBaranovskiy for putting the code in order):
this .add = function (res) {
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 .
This function is called when the PHP library returns the names of registered UI methods (an answer to an 'empty' request). Based on this data, this method creates new methods inside its class that use the PHP library to call public methods.

When the method starts, the incoming parameters are encoded ( request.push ('"' + methods [index] + '":' + that.methods (Array.prototype.slice.call (arguments))) ) and a zero timer is set for the function to send a request. I think that this moment surprised some readers. By this I will focus on it in more detail.

Javascript has no threads and all code executes sequentially. He has only two states - code execution and interrupt waiting. Interruptions can come, for example, from a timer (by timeout), from an AJAX request (when the status changes), and so on. This starts the execution of code that is not interrupted until it reaches the end.
For this purpose, I use a zero timer, which will start the execution of the function that sends a request to the server after the end of the execution of the main code. This is done in order to send everything in one incremental request, consisting of all the called functions and process the results sequentially.

Now you can proceed to processing the results of the query. Since the handler will not be called immediately, it will be a function or several functions that need to be called when the answer comes.
This is done by the run and ajax_run methods . The first adds features to the launch after receiving a response. Functions should be of the form function (data) . And the function ajax_run deals with their launch.
this .run = function (eee) {
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 .
As a result, we get a modifiable class, depending on the established methods in PHP. And interaction with it looks very convenient:
// Initialization of the class for remote work with files.
/ * Synchronous request to call FileManager.php.
Getting the methods dir, save, read.
Dynamic creation of functions. * /
var File = new PHPUIclass ( 'FileManager.php' );

// Call remote functions
/ * Setting the timer and forming the request * /
File.save ( "edited.txt" , "Edited part of the file" );
File.read ( "save.log" );

File.dir ();

// Set functions to get query results.
/ * Add function to handle read request * /
File.run (show_file);

/ * Add function to process dir request * /
File.run (show_dir);

// The end of the script execution, which means the execution of a POST request for Timeout (0) and the return of the results to show_file and show_dir * This was highlighted with the Source Code Highlighter .
Another example of how to use the result of a function to start another:
function show_file (file) {
// ...
}

function show_error (error) {
// ...
}

function check_file (result) {
if (result.ERROR && result.ERROR.checkfile)
show_error (result.ERROR.checkfile);
else {
// Everything went fine?
// Then another request, already for reading.
File.read (result [ “filename” ]);
File.run (show_file);
}
}

// Call remote functions
File.checkfile ( "edited.txt" );

File.run (check_file); * This source code was highlighted with Source Code Highlighter .
But in this case there will be two requests. This can be avoided in several ways. One way is to implement a call to the required function with return directly in PHP.
function checkfile ($ filename) {
global $ UImethod;
if (file_exists ($ filename))
return $ UImethod-> read ($ filename);
else
return array ( "ERROR" => array ( "checkfile" => $ filename));
}
Loss of modularity, but in this implementation of the Javascript library, while this is the only way out. Maybe in the future I will improve it, if necessary.

Example

And here is a simple example. File-viewer with the ability to edit files.

PHP:
UI.php main class UserInterface - connects to the library.
The mod.fileview.php library for reading and writing files is the read and save functions.
The mod.dirview.php library for reading a directory is a dir function.
mod.backup.php library for forming save.log - functions read, save, dir.
FileManager.php is the main file that includes all the modules and starts the request handler.

Javascript:
PHPUI.js is the main class that deals with connecting to the UserInterface interface in php.
skin.js - class for working with templates.
index.html - loading templates, output files.

HTML:
manager.skin - Templates
manager.css - CSS
rus.xml - Russian language.

Working example

Afterword

Pros:
- Easy programming and creating new methods for JS-interface
- Clarity and transparency of the code
- Universality of methods
- It is possible to call functions with an indefinite number of parameters
Minuses:
- No check on method parameters. The elementary errors are possible at code creation. But for this you can check the parameters in the PHP functions (for example, for DEBUG-MODE). In case of incorrect parameters, output alert (“ERROR”).

ps by the way, the model of this project is MVC .

Source: https://habr.com/ru/post/28814/


All Articles