Powered by PmWiki
PHP Proxy vs. Overloaded Class
Many communication libraries use the Proxy design pattern to provide client access to remote functions and HessianPHP is no exception here. But there are two styles of proxies you can use when consuming remote services: a traditional proxy class and an overloaded class that resembles a normal object.
They both do the same thing but there may be times when one is better suited than the other.
PHP Proxy class: HessianProxy
The core of the client part of HessianPHP is a class called HessianProxy which performs the actual remote procedure call, handle protocol issues, traps errors and execute filters.
You can create a Hessian client by just creating a new HessianProxy object like this:
$proxy = new HessianProxy($url,$options);
Where $url is an string with the location of the remote service and $options is an optional array of different configuration options. Then, to call remote methods, you just need to execute the call() function with two arguments, the name of the method and an array of parameters, like this:
$return = $proxy->call( 'add' , array(2,5) );
Additionally, you can use any of this object's utility functions such as remoteMethod(),addFilter() or setoption() any time you like so it is more dynamic in nature.
A number of other web services libraries (XML-RPC, SOAP) use something like this to operate. This model is convenient since it encapsulates the minimun requirements to perform a remote procedure call while providing flexibility to the user. But is has two small caveats: one is that it is not natural to just call an object's function by using another function and two, it is more verbose. Fortunately, newer PHP versions provide a facility do this in a more natural way.
Client overloaded class: HessianClient
Since version 4.3.x, PHP comes with an extension that allows overloading of object property access and method calls, thus, creating an in-memory proxy for another object. Although initial versions of this extension were very buggy and unstable, latest PHP versions of overload work pretty good and in the new PHP 5 engine, all user declared classes are overloaded by default.
For more details about the overloading extension, please consult the PHP reference manual.
In HessianPHP, there is a class called HessianClient that wraps a HessianProxy object and calls the call() function when a user just executes any function on the object, for example:
// construction is the same as above, only the class is different $client = new HessianClient($url, $options ); $return = $client->add(2,5);
Internally, HessianClient, uses the magic method __call() that is executed everytime a non-declared function of the class is called, passing 3 arguments (2 for PHP 5), the name of the method and an array of arguments, just like call() from HessianProxy.
HessianClient is the preffered way to consume Hessian services because it is simple to use and it seems more natural to work on a "real object" that can be passed around others and have a defined interface. For instance, in Java and C# Hessian libraries, this is the only way the library works. The problem with this overloaded class is that it depends on the correct implementation of the extension, for example, in PHP 4, the __call() method takes 3 arguments, the function name, an array of parameters and a reference to the result of the function while in PHP 5 it takes *exactly* 2 parameters, leaving the result of the function to be returned by the user code.
This detail makes impossible to create a single implementation of an overloaded class for both platforms.
Another problem is that you cannot call dynamic methods in an overloaded object, so, something like
Although its caveats, HessianClient is still the most practical way to create HessianPHP clients as it behaves in a more onject oriented way. However, if you need more flexibility to do dynamic method/argument construction or configuration on the fly, then perhaps HessianProxy is a better option.
In the end, all depends on your coding style and the needs of the project.