📜 ⬆️ ⬇️

Javascript Interface <==> PHP

Surprised that my habrayum habralyudi understand with difficulty, proceeded to write another interesting habratopik. :)

I want to offer one convenient method for interacting Javascript with PHP.

You can add a class in PHP, with the ability to 'remote' start functions from there with parameters.
')

Parameter passing

What is the best way to pass functions to PHP input?
The most suitable way is using an array.
How to pass an array? The simplest and most optimal method (considering that we are dealing with Javascript) is JSON. Passing parameters to the launch will look, for example:
{
"Init_timer": [],
"Savedb": [200],
"Check_timer": []
}
which corresponds to:
init_timer ();
savedb (200);
check_timer ();
You can convert this into an array on the PHP side very simply - using json_decode. It remains only to parse the resulting array on the shelves, and output the result back as JSON to the client.

User interface

I implemented this using the PHP class UserInterface.
class UserInterface {
private $ if ;
public $ result = array ();

function add ($ groupname, $ if ) {
$ this -> if [$ groupname] [] = $ if ;
}

function __call ($ name, $ args) {
if (isset ($ this -> if [$ name]))
foreach ($ this -> if [$ name] as $ func)
! is_array ($ res = & call_user_func_array ($ func, $ args)) ||
$ this -> result = array_merge_recursive ($ this -> result, $ res);
}

function run ($ info) {
if (is_array ($ info))
foreach ($ info as $ func => $ parameters)
! is_array ($ res = & call_user_func_array (array (& $ this , $ func), $ parameters)) ||
$ this -> result = array_merge_recursive ($ this -> result, $ res);
}
} * This source code was highlighted with Source Code Highlighter .
We will add new methods (functions) to this class, and then, with a little refinement, we will teach Javascript to “see” and launch them, getting the results of their work.

The class has the following functions:
- $ this-> add ({method name}, {function}) allows to add a new method. If the method exists, adds another function to it.
- $ this -> {method name} ({parameters}) there is a call of all added functions in the method.
- $ this-> run ({array}) runs several methods sequentially for execution, using parameters from the array.

Immediately make remarochku for non-professionals:
!is_array($res=&call_user_func_array($func,$args)) || $result=array_merge_recursive($result,$res);
tantamount to
$res=&call_user_func_array($func,$args);
if(is_array($res))
$result=array_merge_recursive($result,$res);


Example:
It is necessary to create a database interface with receiving information.
To begin, we initialize the interface that we will use:
$ UImethod = new UserInterface ();
Add a group that should add information to the database (savedb):
class db {
static function save ($ num) {
// Function for writing to the database
// $ num -> ...
}

static function load ($ num) {
// Function to load from DB
// $ db <-...
return array ("DBresult" => $ db);
}
}

$ UImethod-> add ( 'savedb' , 'db :: save' );
$ UImethod-> add ( 'loaddb' , 'db :: load' );
The launch will be carried out using the function:
$ UImethod-> savedb ($ xxx);
In this case, if we suddenly need to add a log generation module, then processing can be easily added to the same group:
class log {
static function add_savelog ($ num) {
// Add new log
// ...
}
}

$ UImethod-> add ( 'savedb' , 'log :: add_savelog' );
Now both functions will be launched sequentially when the 'savedb' group is started.

Javascript work with UserInterface class

First I want to dwell a bit on the run method. This will help us in borrowing.
The run method allows you to run several groups with different parameters in sequence. It takes the names of groups in the form of an array:
$ a = array (
"Savedb" => array (200)
"Loaddb" => array (200)
)
Then, by running $ UImethod-> run ($ a); can be saved to the database - 200, then read it using 'loaddb' .

You may have noticed that db :: load returns the results as an array. These results are encapsulated (added) or in simple words fall into the general array $ this-> result. As a result, we will use this array as a response to JavaScript for the request.

Ie, for example, by running loaddb (200) and loaddb (300) - we will get an array with filled fields: 'DBresult' => ('200' => ... and '300' => ...).

And now the most important thing is the implementation of decoding (as input) and coding (as output) JSON arrays in PHP, with the launch of methods called using Javascript:
if (! isset ($ _ REQUEST [ 'method' ]))
die ();
$ functions = json_decode ($ _ REQUEST [ 'method' ], TRUE);
$ UImethod-> run ($ functions);
echo json_encode ($ UImethod-> result);

Running methods from javascript

Got to sweet.
<html> <head> </ head> <body>
<script type = "text / javascript" >
// Function that implements the AJAX request to the server
// URL parameters, JS-function, additional parameters, [next URL, JS-func ...]
function ajax_load (url, parcer, par, next) {
var req, ab, done = 0;
this .request = function () {
if (window.XMLHttpRequest)
ajaxRequest = new XMLHttpRequest ();
else if (window.ActiveXObject) {
ajaxRequest = new ActiveXObject ( "Msxml2.XMLHTTP" );
if (! ajaxRequest)
ajaxRequest = new ActiveXObject ( "Microsoft.XMLHTTP" );
}
return ajaxRequest;
}

this .ReqStatus = function () {
if (req.readyState == 4) {
clearTimeout (ab);
if (req.status == 200) {
parcer (req, par);
if (next)
ajax_load (next [0], next [1], next [2], next [3]);
} else
alert ( "AJAX Error: \ n" + req.statusText + "\ n" + url);
}
}

if (! url)
return parcer (par);

req = this .request ();
req.onreadystatechange = this .ReqStatus;
req.open ( "GET" , url, true );
req.send ( null );
ab = window.setTimeout ( function () {req.abort ();}, 10,000);
return req;
}

// Function that encodes the request in JSON format ( func (param) -> “func”: [param] ) and sends it to the server (making the request “JSON.php? Method = ...”)
function server_eval (mod, ret) {
mod = mod.replace (/ \ s * ([\ w \ d _] +) \ s * \ (([\ w \ d_. \\, \ [\] "] *) \) \ s *;? / gi, '" $ 1 ": [$ 2],'). replace (" '",' "');
mod = '{' + mod.substr (0, mod.length-1) + '}';
ajax_load (" JSON.php? method =" + mod, ret, null );
}

// Request handler
function time_result (res) {
db = eval ( '(' + res.responseText + ')' );
document .write (db [ 'DBresult' ]);
}

// Request to server with time_result response handler
server_eval ( 'savedb (200); loaddb (200); loaddb (300);' , time_result);
</ script>
</ body> </ html> This was the code highlighted with the Source Code Highlighter .
Actually that's all.

server_eval sends a request to the UserInterface of the JSON.php file and, when receiving a response, runs the time_result function, passing the response in the parameters. In this case, it is possible to carry out completely different requests in the interface and process the results as your heart desires.

What can it be used for


At this stage of implementation, I had a problem - to make a universal library, in which it is possible to change, add new functions by several developers.

Examples:
1) Again, back to the development of a space game.
The player chose a different target for the ship. There is a transfer of a choice of purpose. "Ship_new_target (180,320); return_space_objects (1220,1334);". 180 is a ship, and 320 is a new target.
A new goal can be anything. In case it is a ship, we will need to select it as an enemy. If this is a station, we will select it as a station and automatically send the ship to fly to it. If this is a planet, then we will not allocate it at all.
At the same time, we can add any new type of object without changing the code, but simply by adding the necessary calls and how we need to respond to them when they are needed.
By the way, the ship_new_target function returns nothing. But the function return_space_objects is engaged in the fact that it creates in the general array an array of objects lying near the coordinates (1220.1334). At the same time - again, they are processed, for example, portals and added to the array (using some rules). Then, ships, stations, calling the functions of the return_space_objects method sequentially and adding the results of the DB samples to the common array.
Thus, it is easier for me to communicate with all objects and my code is not scattered over php files, but each site lies in its place.

2) Forum.
A simple example - Each post has its own ID. Each topic also has its own ID. They do not intersect.
For any answer, the function 'add_reply (12345, “comment”); return_topic (12345);' is called.
There are several functions in add_reply - the function to add to the topic, the function to add to the comment.
If the ID (12345) to which the message is attached is a new topic, then we use one function, adding this message as a topic. If the ID is a user comment, then we use a completely different function that attaches a comment to it.
Then, by simply adding a library, you can add comments to anything, such as pictures, to personal messages (if a friend has an ID that does not overlap with other topics, comments), and so on.
The return_topic method also works the same. If the topic ID is, then we return the topic with comments. If this is a comment ID, then only a comment with its attachments. The same can be done for the use of pictures, music and everything your heart desires.

Returning errors, by the way, is also possible - using, for example, 'ERROR', to which you simply add errors. With several errors, it will look something like this:
{“ERROR”: [“Not enough characters”, “No title present”, etc]}.

PS

You can, of course, make eval ($ _ REQUEST ['method']) , but the method I considered is more reliable in terms of security. :)

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


All Articles