How to organize ajax server-side scripts

Most of my work lately has been related to extending and fixing bugs in ajax actions. But the action lists are pretty unmanageable in size, and since I was not the original author and the comments are sparse, I spend a lot of time tracking code paths and trying to figure out which jquery event triggered the action and if it sent the correct data with the request.

At the moment, ajax request scripts basically comprise about a hundred if-else blocks, divided into different files based on their functions.

Is there an appropriate design template or php idiom to help me better organize the php part of ajax requests?

I was thinking about creating some kind of submit interface. (I donโ€™t know if this is a good good job.) Where can I register actions and somehow indicate what data they require. Then the dispatcher will call the function from the appropriate place. Then I could forward all ajax requests through one script and organize my functions, but I want to. And I can get an overview of what data is needed to invoke a specific action without reading its implementation line by line. I would potentially have access to my client-side hierarchical class hierarchy.

Is this sound workable? It is safe? Are there other ways that might work better? The inspiration for this was basically a small message style. My main concern is that I am going to introduce a fake vulnerability in cross-access, or that there is already one instance in the code, and because of it is difficult to read, I missed it.

+4
source share
2 answers

I use the RPC style engine to achieve what I think you need. Disclaimer I have successfully implemented this scheme in JS + PHP and JS + Python, so it works. But it can be unsafe. You must take all necessary verification steps to ensure that it is safe (especially wrt for encoding / SQL injections and XSS attacks).

The idea is to have one PHP script that processes RPC requests, getting the method name and its argument via GET and POST, and outputs JSON back to the Javascript side.

For example, on the client side:

API.rpc('getItemById', 1532, function(item) { console.log(item); }); 

will write

Object (ID = 1532, name = "Foo", regardless = "bar")

on the console.

Communication Protocol Used:

  • the client sends an HTTP request to the RPC script handler using either GET or POST. Limitations are that the "method" must always be provided in GET and that all arguments must be URL encoded. Otherwise, all arguments are specified as key = value pairs and can be part of a request (GET) or payload (POST)
  • the server always responds with HTTP 200 (otherwise it means a very unpleasant thing has happened). It responds only with JSON data. The returned object has at least 2 members.
    • the success member is always present and indicates whether the call was successful, i.e. that exception was not thrown
    • if successful, the 'ret' members contain the return value of the function
    • If an exception is thrown, the 'message' member contains an exception message (I prefer to send all the backtracking here, but this is certainly not suitable for sensitive environments)

(1) On the javascript side (assuming jQuery, coding, as I think, so this could be a mistake):

 API = function() { this.rpc = function(method, args, callback) { return $.ajax({ url: 'rpcscript.php?method='+encodeURIComponent(args.method), data: args, type: 'post', //only the method name is sent as a GET arg dataType: 'json' error: function() { alert('HTTP error !'); // This is eg an HTTP 500, or 404 }, success: function(data) { if (data.success) { callback(data.ret); } else { alert('Server-side error:\n'+data.message); } }, }); } } 

Then you can add shortcuts like syncRPC () to make synchronous calls, etc.

(2) On the PHP side (slightly modified startup code):

 class MyAPI { function getItemById($id) { // Assuming the $db is a database connection returning eg an associative array with the result of the SQL query. Note the (int) typecast to secure the query - all defensive measures should be used as usual. return $db->query("SELECT * FROM item WHERE id = ".(int)$id.";"); } } class RemoteProcedureCall { function __construct() { $this->api = new MyAPI(); } function serve() { header("Content-Type: application/json; charset=utf-8"); try { if (!isset($_GET['method'])) throw new Exception("Invalid parameters"); $methodDesc = array($this->api, $_GET['method']); if (!method_exists($methodDesc[0], $methodDesc[1]) || !is_callable($methodDesc)) throw new Exception("Invalid parameters"); $method = new ReflectionMethod($methodDesc[0], $methodDesc[1]); $params = array(); foreach ($method->getParameters() as $param) { // The arguments of the method must be passed as $_POST, or $_GET if (isset($_POST[$param->getName()])) // OK, arg is in $_POST $paramSrc = $_POST[$param->getName()]; elseif (!in_array($param->getName(),array('action','method')) && isset($_GET[$param->getName()]) && !isset($paramSrc[$param->getName()])) // 'action' and 'method' are reserved $_GET arguments. Arguments for the RPC method // can be any other args in the query string, unless they are already in $_POST. $paramSrc = $_GET[$param->getName()]; if (!isset($paramSrc)) { // If the argument has a default value (as specified per the PHP declaration // of the method), we allow the caller to use it - that is, not sending the // corresponding parameter. if ($param->isDefaultValueAvailable()) $p = $param->getDefaultValue(); else throw new Exception("Invalid parameters"); } else { $p = $paramSrc; } $params[$param->getName()] = $p; unset($paramSrc); } $ret = $method->invokeArgs($db, $params); echo json_encode(array('success' => true, 'ret' => $ret)); } catch (Exception $e) { echo json_encode(array('success' => false, 'message' => $e->getMessage()."\n".$e->getBacktrace())); } } }; $rpc = RemoteProcedureCall(); $rpc->serve(); 

There are many assumptions for specific applications, including the types of exclusions that can be selected, reserved keywords, etc.

In any case, I hope this will be a good starting point for your problem.

+2
source

You can look here: http://www.phpapi.org/

From the description:

โ€œThis is a skeleton with which you can create a web system from a simple web calculator to the most complex CRM / ERP / CMS / ETC. What the PHP API offers: general code structure, very simple extensible structure of API code, the ability to connect JavaScript with API (with an easy way to add new modules / method handlers), ... "

0
source

All Articles