I have a SoapClient instance generated for a WSDL file. All except one of the method invocations require the username and the password to be passed id.
Is there any way of currying the method calls so that I can omit the username and password?
I have a SoapClient instance generated for a WSDL file. All except one of the method invocations require the username and the password to be passed id.
Is there any way of currying the method calls so that I can omit the username and password?
As of php 5.3 you can store an anonymous function in a variable. This anonymous function can call the "original" function with some predefined parameters.
function foo($x, $y, $z) {
echo "$x - $y - $z";
}
$bar = function($z) {
foo('A', 'B', $z);
};
$bar('C');
edit: You can also use a closure to parametrise the creation of the anonymous function
function foo($x, $y, $z) {
echo "$x - $y - $z";
}
function fnFoo($x, $y) {
return function($z) use($x,$y) {
foo($x, $y, $z);
};
}
$bar = fnFoo('A', 'B');
$bar('C');
edit2: This also works with objects
class Foo {
public function bar($x, $y, $z) {
echo "$x - $y - $z";
}
}
function fnFoobar($obj, $x, $z) {
return function ($y) use ($obj,$x,$z) {
$obj->bar($x, $y, $z);
};
}
$foo = new Foo;
$bar = fnFoobar($foo, 'A', 'C');
$bar('B');
But the other suggestions using __call() and a wrapper class may be better if you want to "enhance" a complete class.
Although a not very good solution, you could write a basic wrapper class that used PHPs magic methods (Specifically __call) to call the actual function but append the user name and password to the argument list.
Basic example:
class SC{
private $usr;
private $pass;
public function __construct($usr, $pass){
$this->usr = $usr;
$this->pass = $pass;
}
public function __call($name, $arguments) {
$arguments = array_merge(array($this->usr, $this->pass), $arguments);
call_user_func($name, $arguments);
}
}
PHP doesn't have currying per se, but you can do something like that in several ways. In your specific case, something like this may work:
class MySoapClient extends SoapClient {
...
public function __call($meth,$args) {
if (substr($method,0,5) == 'curry') {
array_unshift($args,PASSWORD);
array_unshift($args,USERNAME);
return call_user_func_array(array($this,substr($meth,5)),$args);
} else {
return parent::__call($meth,$args);
}
}
}
$soapClient = new MySoapClient();
...
// now the following two are equivalent
$soapClient->currysomeMethod($additionalArg);
$soapClient->someMethod(USERNAME,PASSWORD,$additionalArg);
Although here's a more general solution for currying in PHP >= 5.3:
$curriedMethod = function ($additionalArg) use ($soapClient) { return $soapClient->method(USERNAME,PASSWORD,$additionalArg); }
$result = $curriedMethod('some argument');