Dear owners,
I've tried using your rpc server and it seems a very nice library.
But it did not support the php callback type, which supports calling
methods in a class. See:
http://nl.php.net/callback This supports the
notation array($object,"Method"); call_user_func() obviusly supports
this method too.
This is the patch for the current trunk version to support the
callback type for the addMethod() method. It only supports the PHP5
version, I've not bothered hacking in a PHP4 versions
cheers
Arend
Index: RPCServer.class.php
===================================================================
--- RPCServer.class.php (revision 36)
+++ RPCServer.class.php (working copy)
@@ -23,7 +23,6 @@
# }
# $server->addMethod("getTemp");
# //$server->processRequest() is called automatically by the
destructor
-
class RPCServer {
const JSON_RPC_VERSION = "1.1";
const XML_RPC_VERSION = "1.0";
@@ -40,7 +39,7 @@
public $help;
public $address;
- protected $requestID;
+ protected $requestID;
protected $requestType; #XML | JSON | HTTP_GET
protected $responseType; #XML | JSON | JAVASCRIPT
protected $isJSONOmitResponseWrapper;
@@ -270,11 +269,24 @@
function addMethod($privateProcName, $publicMethodName = null){
if($this->isFinished)
die("The server's request has already been processed. You may only
invoke 'addMethod' before the 'processRequest' is executed.");
- if(!$publicMethodName)
- $publicMethodName = $privateProcName;
-
- if(!function_exists($privateProcName))
- trigger_error("\$RPCServerInstance->addMethod() failed because the
function \"$privateProcName\" does not exist.");
+ if(!$publicMethodName)
+ {
+ if (is_array($privateProcName))
+ {
+ $publicMethodName = $privateProcName[1];
+ } else {
+ $publicMethodName = $privateProcName;
+ }
+ }
+
+ // deterimine if the function is a decent call_user_func function.
+ if(!is_callable($privateProcName)) {
+ if (is_array($privateProcName)) {
+ trigger_error("\$RPCServerInstance->addMethod() failed because
the method \"" . $privateProcName[1] . "\" is not callable in class
\"" . get_class($privateProcName[0]) . "\".");
+ } else {
+ trigger_error("\$RPCServerInstance->addMethod() failed because
the method \"" . $privateProcName . "\" does not exist.");
+ }
+ }
if(isset($this->publicToPrivateMap[$publicMethodName]))
trigger_error("\$RPCServerInstance->addMethod() failed because the
method name \"$publicMethodName\" has already been assigned to the
function \"" . $this->publicToPrivateMap[$publicMethodName] . "\".");
$this->publicToPrivateMap[$publicMethodName] = $privateProcName;
@@ -624,7 +636,13 @@
if(class_exists('ReflectionFunction') &&
method_exists('ReflectionParameter', 'isArray')){
foreach(array_keys($this->publicToPrivateMap) as $publicProc){
$functionName = $this->publicToPrivateMap[$publicProc];
- $rf = new ReflectionFunction($functionName);
+ if (is_array($functionName)) {
+ $rf = new ReflectionMethod($callback[0], $callback[1]);
+ }
+ else
+ {
+ $rf = new ReflectionFunction($callback);
+ }
$parametersForPrivateProcs[$functionName] = array();
foreach($rf->getParameters() as $param){ #$i =>
if($param->isPassedByReference())
@@ -647,7 +665,7 @@
}
//$param->isOptional() and $param->allowsNull() are not needed
since PHP will raise errors
// when call_user_func is invoked.
- array_push($parametersForPrivateProcs[$functionName],
$paramDetails);
+ array_push($parametersForPrivateProcs[$publicProc],
$paramDetails);
}
}
unset($functionName);
@@ -657,6 +675,7 @@
unset($paramDetails);
}
#Using the PHP tokenizer before PHP 5.1.0
+ #Won't support OOP callbacks.
else {
$privateToPublicMap = array_flip($this->publicToPrivateMap);
if($this->isUsingIncludedFunctions)
@@ -807,7 +826,7 @@
}
}
}
- }
+ }
unset($tokens);
unset($sourceFiles);
unset($sourceFile);
@@ -821,7 +840,7 @@
#Iterate over all public methods and see if their parameter lists
have been found
# by parsing the tokens of the PHP functions.
foreach($this->publicToPrivateMap as $publicProc => $privateProc){
- if(!isset($parametersForPrivateProcs[$privateProc]))
+ if(!isset($parametersForPrivateProcs[$publicProc]))
trigger_error("Because this version of PHP does not support the
Reflection API, unable to use the public method \"$publicProc\"
because its associated private ".
"procedure is located in an included file; to get around
this, you must explicitly ".
"allow externally defined functions by calling \
$RPCServerInstance->useIncludedFunctions(true); this will decrease
performance. ".