我想为变量分配一个静态函数,以便我可以将它作为参数发送。例如:
class Foo{
private static function privateStaticFunction($arg1,$arg2){
//compute stuff on the args
}
public static function publicStaticFunction($foo,$bar){
//works
$var = function(){
//do stuff
};
//also works
$var = function($someArg,$someArg2){
//do stuff
};
//Fatal error: Undefined class constant 'privateStaticFunction'
$var = self::privateStaticMethod;
//same error
$var = Foo::privateStaticFunction;
//compiles, but errors when I try to run $var() somewhere else, as expected
//Fatal error: Call to private method Foo::privateStaticMethod() from context ''
$var = function(){
return Foo::privateStaticMethod();
};
}
}
我尝试了一些其他变种,但都没有奏效。
我甚至不希望这种功能性的黑客攻击与PHP协同工作,但嘿,谁知道呢?
是否可以在PHP中执行此操作,还是需要使用eval
来解决某些问题?
PS: ## php 上的LawnGnome提到了可以使用array('Foo','privateStaticMethod')
做我想做的事情,但我不明白他的意思当他看起来很忙的时候,我没有再按他了。
答案 0 :(得分:3)
您希望将call_user_func与数组参数一起使用。
$var = array('Foo','privateStaticMethod');
call_user_func($var);
请注意,该方法的“私有”说明符只能在Foo
类中以这种方式调用。
call_user_func将callable作为第一个参数。请注意,从PHP 5.2.3开始,可以避免使用数组表示法。
也可以在不实例化的情况下传递静态类方法 通过传递类名而不是对象来传递该类的对象 从PHP 5.2.3开始,它也可以通过 '类名::方法名'。
答案 1 :(得分:3)
注意,您应该将静态变量设置为:
static $privateStaticMethod;
$var = self::$privateStaticMethod;
使用$
时离开self::
将尝试访问类CONSTANT而不是变量。
实际上,我认为你的意思是:
//Fatal error: Undefined class constant 'privateStaticFunction'
$var = self::privateStaticFunction("arga", "argb");
如果您使用的是PHP 5.4,则可以在publicStaticFunction
中执行以下操作:
$var = function(){
return self::privateStaticFunction();
};
$var();
在PHP 5.4中,PHP允许您从lambda函数访问class scope
。
另外,你看过ReflectionClass
吗?
以下内容将用于以更多OOP样式替换call_user_func_array()
:
<?php
$rc = new ReflectionClass('SomeClass');
$class = $rc->newInstanceArgs(array('foo', 'bar'));
echo $class->doSomething();
您可以编写自己的类来使用ReflectionMethod
来实现ReflectionClass
并使用setAccessible()
来允许访问受保护和私有方法。
答案 2 :(得分:1)
以下是我为解决问题所做的工作
string urlAddress = "http://www.brownells.com/";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlAddress);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = null;
.................................
response.Close();
readStream.Close();