Rob*_*anu 14 php soap currying
我有一个为WSDL文件生成的SoapClient实例.除了一个方法调用之外的所有方法都要求用户名和密码传递id.
有没有办法调整方法调用,以便我可以省略用户名和密码?
Vol*_*erK 21
从php 5.3开始,您可以在变量中存储匿名函数.此匿名函数可以使用某些预定义参数调用"原始"函数.
function foo($x, $y, $z) {
echo "$x - $y - $z";
}
$bar = function($z) {
foo('A', 'B', $z);
};
$bar('C');
Run Code Online (Sandbox Code Playgroud)
编辑:您还可以使用闭包来参数化匿名函数的创建
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');
Run Code Online (Sandbox Code Playgroud)
edit2:这也适用于对象
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');
Run Code Online (Sandbox Code Playgroud)
但是如果你想"增强"一个完整的类,那么使用__call()和包装类的其他建议可能会更好.
小智 7
这是一个实现自动currying和部分应用的类:
class lambda
{
private $f;
private $args;
private $count;
public function __construct($f, $args = [])
{
if ($f instanceof lambda) {
$this->f = $f->f;
$this->count = $f->count;
$this->args = array_merge($f->args, $args);
}
else {
$this->f = $f;
$this->count = count((new ReflectionFunction($f))->getParameters());
$this->args = $args;
}
}
public function __invoke()
{
if (count($this->args) + func_num_args() < $this->count) {
return new lambda($this, func_get_args());
}
else {
$args = array_merge($this->args, func_get_args());
$r = call_user_func_array($this->f, array_splice($args, 0, $this->count));
return is_callable($r) ? call_user_func(new lambda($r, $args)) : $r;
}
}
}
function lambda($f)
{
return new lambda($f);
}
Run Code Online (Sandbox Code Playgroud)
例:
$add = lambda(function($a, $b) {
return $a + $b;
});
$add1 = $add(1);
echo $add1(2); // 3
Run Code Online (Sandbox Code Playgroud)
即使你可以这样做:
$int1 = lambda(function($f, $x) {
return $f($x);
});
$successor = lambda(function($p, $f, $x) {
return $f($p($f, $x));
});
$add = lambda(function($p, $q, $f, $x) {
return $p($f, $q($f, $x));
});
$mul = lambda(function($p, $q, $x) {
return $p($q($x));
});
$exp = lambda(function($m, $n) {
return $n($m);
});
$int2 = $successor($int1);
$int3 = $add($int1, $int2);
$int6 = $mul($int3, $int2);
$int8 = $exp($int2, $int3);
Run Code Online (Sandbox Code Playgroud)