Created
October 12, 2015 05:51
-
-
Save tilhom/2d6680c98d0907490617 to your computer and use it in GitHub Desktop.
bootstrap.php (json rpc)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace S3\Cms; | |
/** | |
* Class to call remote methods via protocol JSON-RPC 2.0 | |
* Includes server and client functionality | |
* | |
* According to official JSON-RPC 2.0 specification | |
* http://groups.google.com/group/json-rpc/web/json-rpc-2-0 | |
* Excluding "notifications" and "batch mode" | |
*/ | |
class JsonRpcBase | |
{ | |
const JSON_RPC_VERSION = '2.0'; | |
private $_server_url, $_server_port, $_server_timeout, $_server_object; | |
public function __construct( $pServerUrlOrObject ) | |
{ | |
if ( is_array( $pServerUrlOrObject ) ) | |
{ | |
if ( !$pServerUrlOrObject ) | |
{ | |
throw new \Exception( 'URL string can\'t be empty' ); | |
} | |
$this->_server_url = $pServerUrlOrObject['url']; | |
$this->_server_port = $pServerUrlOrObject['port']; | |
$this->_server_timeout = $pServerUrlOrObject['timeout']; | |
} | |
elseif ( is_object( $pServerUrlOrObject ) ) | |
{ | |
$this->_server_object = $pServerUrlOrObject; | |
} | |
else | |
{ | |
throw new \Exception( 'Input parameter must be URL string or server class object' ); | |
} | |
} | |
public function __call( $pMethod, array $pParams ) | |
{ | |
if ( is_null( $this->_server_url ) ) | |
{ | |
throw new \Exception( 'This is server JSON-RPC object: you can\'t call remote methods' ); | |
} | |
$request = new \stdClass(); | |
$request->jsonrpc = self::JSON_RPC_VERSION; | |
$request->method = $pMethod; | |
$request->params = $pParams; | |
$request->id = md5( uniqid( microtime( true ), true ) ); | |
$request_json = json_encode( $request ); | |
$ch = curl_init(); | |
curl_setopt_array( $ch, | |
array( CURLOPT_URL => $this->_server_url, CURLOPT_HEADER => 0, CURLOPT_POST => 1, | |
CURLOPT_POSTFIELDS => $request_json, CURLOPT_RETURNTRANSFER => 1, | |
CURLOPT_PORT => $this->_server_port, CURLOPT_TIMEOUT => $this->_server_timeout | |
) ); | |
$response_json = curl_exec( $ch ); | |
if ( curl_errno( $ch ) ) | |
{ | |
throw new \Exception( curl_error( $ch ), curl_errno( $ch ) ); | |
} | |
if ( curl_getinfo( $ch, CURLINFO_HTTP_CODE ) != 200 ) | |
{ | |
throw new \Exception( sprintf( 'Curl response http error code "%s"', | |
curl_getinfo( $ch, CURLINFO_HTTP_CODE ) ) ); | |
} | |
curl_close( $ch ); | |
$response = $this->_parseJson( $response_json ); | |
$this->_checkResponse( $response, $request ); | |
//return $response->result; | |
return $response_json; | |
} | |
public function process() | |
{ | |
if ( is_null( $this->_server_object ) ) | |
{ | |
throw new \Exception( 'This is client JSON-RPC object: you can\'t process request' ); | |
} | |
ob_start(); | |
$request_json = file_get_contents( 'php://input' ); | |
$response = new \stdClass(); | |
$response->jsonrpc = self::JSON_RPC_VERSION; | |
try | |
{ | |
$request = $this->_parseJson( $request_json ); | |
$this->_checkRequest( $request ); | |
$response->result = call_user_func_array( | |
array( $this->_server_object, $request->method ), $request->params ); | |
$response->id = $request->id; | |
} | |
catch ( \Exception $ex ) | |
{ | |
$response->error = new \stdClass(); | |
$response->error->code = $ex->getCode(); | |
$response->error->message = $ex->getMessage(); | |
$response->id = null; | |
} | |
ob_clean(); | |
echo json_encode( $response ); | |
} | |
private function _parseJson( $pData ) | |
{ | |
$data = json_decode( $pData, false, 32 ); | |
if ( is_null( $data ) ) | |
{ | |
throw new \Exception( 'Parse error', -32700 ); | |
} | |
return $data; | |
} | |
private function _checkRequest( $pObject ) | |
{ | |
if ( !is_object( $pObject ) || !isset( $pObject->jsonrpc ) || $pObject->jsonrpc !== self::JSON_RPC_VERSION || !isset( | |
$pObject->method ) || !is_string( $pObject->method ) || !$pObject->method || ( isset( | |
$pObject->params ) && !is_array( $pObject->params ) ) || !isset( $pObject->id ) ) | |
{ | |
throw new \Exception( 'Invalid Request', -32600 ); | |
} | |
if ( !is_callable( array( $this->_server_object, $pObject->method ) ) ) | |
{ | |
throw new \Exception( 'Method not found', -32601 ); | |
} | |
if ( is_null( $pObject->params ) ) | |
{ | |
$pObject->params = array(); | |
} | |
} | |
private function _checkResponse( $pObject, $pRequest ) | |
{ | |
if ( !is_object( $pObject ) || !isset( $pObject->jsonrpc ) || $pObject->jsonrpc !== self::JSON_RPC_VERSION || ( !isset( | |
$pObject->result ) && !isset( $pObject->error ) ) || ( isset( $pObject->result ) && ( !isset( | |
$pObject->id ) || $pObject->id !== $pRequest->id ) ) || ( isset( $pObject->error ) && ( !is_object( | |
$pObject->error ) || !isset( $pObject->error->code ) || !isset( $pObject->error->message ) ) ) ) | |
{ | |
throw new \Exception( 'Invalid Response', -32600 ); | |
} | |
if ( isset( $pObject->error ) ) | |
{ | |
throw new \Exception( $pObject->error->message, $pObject->error->code ); | |
} | |
} | |
} | |
class JsonRpcServer | |
{ | |
public function add( $a, $b ) | |
{ | |
return $a + $b; | |
} | |
public function substract($a, $b) | |
{ | |
return $a - $b; | |
} | |
} | |
/** | |
* | |
*/ | |
class JsonRpc | |
{ | |
static public function dispatch() | |
{ | |
$server = new JsonRpcBase( new JsonRpcServer() ); | |
$server->process(); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment