Advertisement
Guest User

Untitled

a guest
Oct 14th, 2015
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.74 KB | None | 0 0
  1. <?php
  2. /*
  3. JSON-RPC Server implemenation
  4. Copyright (C) 2009 Jakub Jankiewicz <http://jcubic.pl>
  5.  
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program. If not, see <http://www.gnu.org/licenses/>.
  18.  
  19. */
  20. /*
  21. USAGE: create one class with public methods and call handle_json_rpc function
  22. with instance of this class
  23.  
  24. <?php
  25. require('json_rpc.php');
  26. class Server {
  27. public function test($message) {
  28. retrun "you send " . $message;
  29. }
  30.  
  31. }
  32.  
  33. handle_json_rpc(new Server());
  34. ?>
  35.  
  36. you can provide documentations for methods
  37. by adding static field:
  38.  
  39. class Server {
  40. ...
  41. public static $test_documentation = "doc string";
  42. }
  43.  
  44. It alway create one method 'help' which return string
  45. with list of methods if call with no arguments and
  46. return documentation string for method passed as parameter.
  47. */
  48. // ----------------------------------------------------------------------------
  49. function json_error() {
  50. switch (json_last_error()) {
  51. case JSON_ERROR_NONE:
  52. return 'No error has occurred';
  53. case JSON_ERROR_DEPTH:
  54. return 'The maximum stack depth has been exceeded';
  55. case JSON_ERROR_CTRL_CHAR:
  56. return 'Control character error, possibly incorrectly encoded';
  57. case JSON_ERROR_SYNTAX:
  58. return 'Syntax error';
  59. case JSON_ERROR_UTF8:
  60. return 'Malformed UTF-8 characters, possibly incorrectly encoded';
  61. }
  62. }
  63.  
  64.  
  65. // ----------------------------------------------------------------------------
  66. // check if object has field
  67. function has_field($object, $field) {
  68. //return in_array($field, array_keys(get_object_vars($object)));
  69. return array_key_exists($field, get_object_vars($object));
  70. }
  71.  
  72. // ----------------------------------------------------------------------------
  73. // return object field if exist otherwise return default value
  74. function get_field($object, $field, $default) {
  75. $array = get_object_vars($object);
  76. if (isset($array[$field])) {
  77. return $array[$field];
  78. } else {
  79. return $default;
  80. }
  81. }
  82.  
  83.  
  84. // ----------------------------------------------------------------------------
  85. //create json-rpc response
  86. function response($result, $id, $error) {
  87. return json_encode(array("jsonrpc" => "2.0",
  88. 'result' => $result,
  89. 'id' => $id,
  90. 'error'=> $error));
  91. }
  92.  
  93. // ----------------------------------------------------------------------------
  94. // try to extract id from broken json
  95. function extract_id() {
  96. $regex = '/[\'"]id[\'"] *: *([0-9]*)/';
  97. if (preg_match($regex, $GLOBALS['HTTP_RAW_POST_DATA'], $m)) {
  98. return $m[1];
  99. } else {
  100. return 0;
  101. }
  102. }
  103.  
  104. // ----------------------------------------------------------------------------
  105. function handle_json_rpc($object) {
  106. $input = file_get_contents('php://input');
  107. if (!$input) {
  108. $input = $GLOBALS['HTTP_RAW_POST_DATA'];
  109. }
  110. $encoding = mb_detect_encoding($input, 'auto');
  111. //convert to unicode
  112. if ($encoding != 'UTF-8') {
  113. $input = iconv($encoding, 'UTF-8', $input);
  114. }
  115. $json = json_decode($input);
  116. header('Content-Type: text/plain');
  117.  
  118. // handle Errors
  119. if (!$json) {
  120. if ($input == "") {
  121. echo response(null, 0, array("code"=> -32700,
  122. "message"=>"Parse Error: no data"));
  123. } else {
  124. // json parse error
  125. $error = json_error();
  126. $id = extract_id();
  127. echo response(null, $id, array("code"=> -32700,
  128. "message"=>"Parse Error: $error"));
  129. }
  130. exit;
  131. } else {
  132. $method = get_field($input, 'method', null);
  133. $params = get_field($input, 'params', null);
  134. $id = get_field($input, 'id', null);
  135.  
  136. // json rpc error
  137. if (!($method && $id)) {
  138. if (!$id) {
  139. $id = extract_id();
  140. }
  141. if (!$method) {
  142. $error = "no method";
  143. } else if (!$id) {
  144. $error = "no id";
  145. } else {
  146. $error = "unknown reason";
  147. }
  148. echo response(null, $id, array("code" => -32600,
  149. "message" => "Invalid Request: $error"));
  150. exit;
  151. }
  152. }
  153.  
  154. // fix params (if params is null set it to empty array)
  155. if (!$params) {
  156. $params = array();
  157. }
  158. // if params is object change it to array
  159. if (is_object($params)) {
  160. if (count(get_object_vars($params)) == 0) {
  161. $params = array();
  162. } else {
  163. $params = get_object_vars($params);
  164. }
  165. }
  166.  
  167. // call Service Method
  168. try {
  169. $class = get_class($object);
  170. $methods = get_class_methods($class);
  171. if (strcmp($method, 'help') == 0) {
  172. if (count($params) > 0) {
  173. if (!in_array($params[0], $methods)) {
  174. $no_method = 'There is no ' . $params[0] . ' method';
  175. throw new Exception($no_method);
  176. } else {
  177. $static = get_class_vars($class);
  178. $help_str_name = $params[0] . "_documentation";
  179. //throw new Exception(implode(", ", $static));
  180. if (array_key_exists($help_str_name, $static)) {
  181. echo response($static[$help_str_name], $id, null);
  182. } else {
  183. throw new Exception($method . " method has no documentation");
  184. }
  185. }
  186. } else {
  187. $url = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
  188. $msg = 'PHP JSON-RPC - in "' . $url . "\"\n";
  189. $msg .= "class \"$class\" has methods: " . implode(", ", array_slice($methods, 0, -1)) . " and " . $methods[count($methods)-1] . ".";
  190. echo response($msg, $id, null);
  191. }
  192. } else if (!in_array($method, $methods)) {
  193. $msg = 'There is no ' . $method . ' method';
  194. echo response(null, $id, array("code" =>-32601, "message" => $msg));
  195. } else {
  196. //throw new Exception('x -> ' . json_encode($params));
  197. $result = call_user_func_array(array($object, $method), $params);
  198. echo response($result, $id, null);
  199. }
  200. exit;
  201. } catch (Exception $e) {
  202. //catch all exeption from user code
  203. $msg = "Internal error: " . $e->getMessage();
  204. echo response(null, $id, array("code"=>-32603, "message"=>$msg));
  205. }
  206. }
  207.  
  208.  
  209. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement