CoinClient.class.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. namespace Common\Ext;
  3. class CoinClient
  4. {
  5. private $url;
  6. private $timeout;
  7. private $username;
  8. private $password;
  9. public $is_batch = false;
  10. public $batch = array();
  11. public $debug = false;
  12. public $jsonformat = false;
  13. public $res = '';
  14. private $headers = array('User-Agent:localhost Rpc', 'Content-Type: application/json', 'Accept: application/json', 'Connection: close');
  15. public $ssl_verify_peer = true;
  16. public function __construct($username, $password, $ip, $port, $timeout = 3, $headers = array(), $jsonformat = false)
  17. {
  18. $this->url = 'http://' . $ip . ':' . $port;
  19. $this->username = $username;
  20. $this->password = $password;
  21. $this->timeout = $timeout;
  22. $this->headers = array_merge($this->headers, $headers);
  23. $this->jsonformat = $jsonformat;
  24. }
  25. public function __call($method, array $params)
  26. {
  27. if ((count($params) === 1) && is_array($params[0])) {
  28. $params = $params[0];
  29. }
  30. $res = $this->execute($method, $params);
  31. debug(array('method' => $method, 'params' => $params, 'res' => $res), 'Coinclient execute');
  32. return $res ? $res : $this->res;
  33. }
  34. public function execute($procedure, array $params = array())
  35. {
  36. return $this->doRequest($this->prepareRequest($procedure, $params));
  37. }
  38. public function prepareRequest($procedure, array $params = array())
  39. {
  40. $payload = array('jsonrpc' => '2.0', 'method' => $procedure, 'id' => mt_rand());
  41. if (!empty($params)) {
  42. $payload['params'] = $params;
  43. }
  44. return $payload;
  45. }
  46. private function doRequest(array $payload)
  47. {
  48. $stream = @(fopen(trim($this->url), 'r', false, $this->getContext($payload)));
  49. if (!is_resource($stream)) {
  50. $this->error('Unable to establish a connection');
  51. }
  52. $metadata = stream_get_meta_data($stream);
  53. $response = json_decode(stream_get_contents($stream), true);
  54. $this->debug('==> Request: ' . PHP_EOL . json_encode($payload, JSON_PRETTY_PRINT));
  55. $this->debug('==> Response: ' . PHP_EOL . json_encode($response, JSON_PRETTY_PRINT));
  56. $header_1 = $metadata['wrapper_data'][0];
  57. preg_match('/[\\d]{3}/i', $header_1, $code);
  58. $code = trim($code[0]);
  59. if ($code == '200') {
  60. return isset($response['result']) ? $response['result'] : 'nodata';
  61. } else if ($response['error'] && is_array($response['error'])) {
  62. $detail = 'code=' . $response['error']['code'] . ',message=' . $response['error']['message'];
  63. $this->error('SERVER 返回' . $code . '[' . $detail . ']');
  64. } else {
  65. $this->error('SERVER 返回' . $code);
  66. }
  67. }
  68. private function getContext(array $payload)
  69. {
  70. $headers = $this->headers;
  71. if (!empty($this->username) && !empty($this->password)) {
  72. $headers[] = 'Authorization: Basic ' . base64_encode($this->username . ':' . $this->password);
  73. }
  74. return stream_context_create(array(
  75. 'http' => array('method' => 'POST', 'protocol_version' => 1.1, 'timeout' => $this->timeout, 'max_redirects' => 2, 'header' => implode("\r\n", $headers), 'content' => json_encode($payload), 'ignore_errors' => true),
  76. 'ssl' => array('verify_peer' => $this->ssl_verify_peer, 'verify_peer_name' => $this->ssl_verify_peer)
  77. ));
  78. }
  79. protected function debug($str)
  80. {
  81. if (is_array($str)) {
  82. $str = implode('#', $str);
  83. }
  84. debug($str, 'CoinClient');
  85. }
  86. protected function error($str)
  87. {
  88. if ($this->jsonformat) {
  89. $this->res = json_encode(array('data' => $str, 'status' => 0));
  90. } else {
  91. echo json_encode(array('info' => $str, 'status' => 0));
  92. exit();
  93. }
  94. }
  95. }
  96. ?>