Overview

Packages

  • Jyxo_Beholder
  • Jyxo_Charset
  • Jyxo_Color
  • Jyxo_Css
  • Jyxo_ErrorHandling
  • Jyxo_FirePhp
  • Jyxo_Gettext
    • Parser
  • Jyxo_Html
  • Jyxo_Input
    • Chain
    • Filter
    • Validator
  • Jyxo_Mail
    • Email
    • Parser
    • Sender
  • Jyxo_Rpc
    • Json
    • Xml
  • Jyxo_Shell
  • Jyxo_SpamFilter
  • Jyxo_Spl
  • Jyxo_String
  • Jyxo_Svn
  • Jyxo_Time
  • Jyxo_Timer
  • Jyxo_Webdav
  • Jyxo_XmlReader
  • PHP

Classes

  • Jyxo_Rpc_Client
  • Jyxo_Rpc_Server

Exceptions

  • Jyxo_Rpc_Exception
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * Jyxo PHP Library
  5:  *
  6:  * LICENSE
  7:  *
  8:  * This source file is subject to the new BSD license that is bundled
  9:  * with this package in the file license.txt.
 10:  * It is also available through the world-wide-web at this URL:
 11:  * https://github.com/jyxo/php/blob/master/license.txt
 12:  */
 13: 
 14: /**
 15:  * Class for creating a RPC server.
 16:  *
 17:  * @category Jyxo
 18:  * @package Jyxo_Rpc
 19:  * @copyright Copyright (c) 2005-2011 Jyxo, s.r.o.
 20:  * @license https://github.com/jyxo/php/blob/master/license.txt
 21:  * @author Jaroslav Hanslík
 22:  */
 23: abstract class Jyxo_Rpc_Server
 24: {
 25:     /**
 26:      * Aliases of real functions.
 27:      *
 28:      * @var array
 29:      */
 30:     private $aliases = array();
 31: 
 32:     /**
 33:      * Log file name.
 34:      *
 35:      * @var string
 36:      */
 37:     private $logFile;
 38: 
 39:     /**
 40:      * Function that is called prior to saving a message into logfile.
 41:      * Can be used e. g. for wiping out private data (passwords) from log messages.
 42:      *
 43:      * @var callback
 44:      */
 45:     private $logCallback;
 46: 
 47:     /**
 48:      * Creates a class instance.
 49:      */
 50:     protected function __construct()
 51:     {}
 52: 
 53:     /**
 54:      * Destroys a class instance.
 55:      */
 56:     public function __destruct()
 57:     {}
 58: 
 59:     /**
 60:      * Prevents from singleton cloning.
 61:      *
 62:      * @throws LogicException When trying to clone instance
 63:      */
 64:     public final function __clone()
 65:     {
 66:         throw new LogicException(sprintf('Class %s can have only one instance.', get_class($this)));
 67:     }
 68: 
 69:     /**
 70:      * Returns class instance.
 71:      *
 72:      * @return Jyxo_Rpc_Server
 73:      */
 74:     public static function getInstance()
 75:     {
 76:         static $instance;
 77:         if (null === $instance) {
 78:             $instance = new static();
 79:         }
 80: 
 81:         return $instance;
 82:     }
 83: 
 84:     /**
 85:      * Turns on logging.
 86:      *
 87:      * @param string $filename Log file path.
 88:      * @param callback $callback Function to be called prior to logging a message.
 89:      * @return Jyxo_Rpc_Server
 90:      * @throws InvalidArgumentException If no file or an invalid callback was provided.
 91:      */
 92:     public function enableLogging($filename, $callback = null)
 93:     {
 94:         $filename = (string) $filename;
 95:         $filename = trim($filename);
 96: 
 97:         // A log file has to be provided
 98:         if (empty($filename)) {
 99:             throw new InvalidArgumentException('No log file was provided.');
100:         }
101: 
102:         $this->logFile = $filename;
103: 
104:         // Function must be callable
105:         if ((!empty($callback)) && (!is_callable($callback))) {
106:             throw new InvalidArgumentException('Invalid callback was provided.');
107:         }
108: 
109:         $this->logCallback = $callback;
110: 
111:         return $this;
112:     }
113: 
114:     /**
115:      * Registers class public methods.
116:      *
117:      * @param string $class Class name
118:      * @param boolean $useFullName Register with class name
119:      * @return Jyxo_Rpc_Server
120:      * @throws InvalidArgumentException If no such class exists
121:      */
122:     public function registerClass($class, $useFullName = true)
123:     {
124:         if (!class_exists($class)) {
125:             throw new InvalidArgumentException(sprintf('Class %s does not exist.', $class));
126:         }
127: 
128:         $reflection = new ReflectionClass($class);
129:         foreach ($reflection->getMethods() as $method) {
130:             // Only public methods
131:             if ($method->isPublic()) {
132:                 $func = $class . '::' . $method->getName();
133: 
134:                 // Save short name as an alias
135:                 if (!$useFullName) {
136:                     $this->aliases[$method->getName()] = $func;
137:                     $func = $method->getName();
138:                 }
139: 
140:                 $this->register($func);
141:             }
142:         }
143: 
144:         return $this;
145:     }
146: 
147:     /**
148:      * Registers given method of given class.
149:      * Method does not necessarily have to exist if __call or __callStatic method is defined.
150:      *
151:      * @param string $class Class name
152:      * @param string $method Function name
153:      * @param boolean $useFullName Register with class name
154:      * @return Jyxo_Rpc_Server
155:      * @throws InvalidArgumentException If no such class exists or method is not public
156:      */
157:     public function registerMethod($class, $method, $useFullName = true)
158:     {
159:         if (!class_exists($class)) {
160:             throw new InvalidArgumentException(sprintf('Třída %s neexistuje.', $class));
161:         }
162: 
163:         // If magic methods exist, always register
164:         if ((!method_exists($class, '__call')) && (!method_exists($class, '__callStatic'))) {
165:             try {
166:                 $reflection = new ReflectionMethod($class, $method);
167:             } catch (ReflectionException $e) {
168:                 throw new InvalidArgumentException(sprintf('Method %s::%s does not exist.', $class, $method));
169:             }
170: 
171:             // Only public methods
172:             if (!$reflection->isPublic()) {
173:                 throw new InvalidArgumentException(sprintf('Method %s::%s is not public.', $class, $method));
174:             }
175:         }
176: 
177:         $func = $class . '::' . $method;
178: 
179:         // Save short name as an alias
180:         if (!$useFullName) {
181:             $this->aliases[$method] = $func;
182:             $func = $method;
183:         }
184: 
185:         $this->register($func);
186: 
187:         return $this;
188:     }
189: 
190:     /**
191:      * Registers given function.
192:      *
193:      * @param string $func Function name
194:      * @return Jyxo_Rpc_Server
195:      * @throws InvalidArgumentException If no such function exists
196:      */
197:     public function registerFunc($func)
198:     {
199:         if (!function_exists($func)) {
200:             throw new InvalidArgumentException(sprintf('Function %s does not exist.', $func));
201:         }
202: 
203:         $this->register($func);
204: 
205:         return $this;
206:     }
207: 
208:     /**
209:      * Actually registers a function to a server method.
210:      *
211:      * @param string $func Function name
212:      */
213:     abstract protected function register($func);
214: 
215:     /**
216:      * Processes a request and sends a RPC response.
217:      */
218:     abstract public function process();
219: 
220:     /**
221:      * Calls a server method with given parameters.
222:      *
223:      * @param string $method Method name
224:      * @param array $params Method parameters
225:      * @return mixed
226:      */
227:     protected function call($method, $params)
228:     {
229:         $func = $method;
230:         // If an alias was given, use the actual method
231:         if (isset($this->aliases[$method])) {
232:             $func = $this->aliases[$method];
233:         }
234: 
235:         // Class method
236:         if (false !== strpos($func, '::')) {
237:             list($className, $methodName) = explode('::', $func);
238: 
239:             try {
240:                 // Method exists
241:                 $reflection = new ReflectionMethod($className, $methodName);
242:                 if ($reflection->isStatic()) {
243:                     // Method is static
244:                     $callback = array($className, $methodName);
245:                 } else {
246:                     // Method is not static
247:                     $callback = array(new $className(), $methodName);
248:                 }
249:             } catch (ReflectionException $e) {
250:                 // Method does not exist
251:                 if (method_exists($className, '__call')) {
252:                     // Is __call available
253:                     $callback = array(new $className(), $methodName);
254:                 } else {
255:                     // Is __callStatic available
256:                     $callback = array($className, $methodName);
257:                 }
258:             }
259:         } else {
260:             // Simple function
261:             $callback = $func;
262:         }
263: 
264:         $result = call_user_func_array($callback, $params);
265: 
266:         // Logging
267:         $this->log($method, $params, $result);
268: 
269:         return $result;
270:     }
271: 
272:     /**
273:      * Logs a request.
274:      *
275:      * @param string $method Method name
276:      * @param array $params Method parameters
277:      * @param mixed $result Function result
278:      */
279:     private function log($method, $params, $result)
280:     {
281:         // Log only if a filename is set
282:         if (!empty($this->logFile)) {
283:             // If a callback function is defined, call it
284:             if (!empty($this->logCallback)) {
285:                 list($method, $params, $result) = call_user_func($this->logCallback, $method, $params, $result);
286:             }
287: 
288:             // Method
289:             $text = sprintf("Method: %s\n", $method);
290:             // Parameters
291:             foreach ($params as $paramName => $param) {
292:                 $text .= sprintf("Param %s: %s\n", $paramName, trim(print_r($param, true)));
293:             }
294:             // Result
295:             $text .= sprintf("Result: %s\n", trim(print_r($result, true)));
296: 
297:             // Indent following lines
298:             $text = strtr(trim($text), array("\n" => "\n\t"));
299: 
300:             // Time, ip address, hostname, uri
301:             $text = sprintf("[%s] %s %s %s\n\t%s\n", date('Y-m-d H:i:s'), $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'], $text);
302: 
303:             // Save into logfile
304:             file_put_contents($this->logFile, $text, FILE_APPEND);
305:         }
306:     }
307: }
308: 
Jyxo PHP Library API documentation generated by ApiGen 2.3.0