在PHP中为变量分配静态函数

时间:2012-09-26 03:31:50

标签: php functional-programming

我想为变量分配一个静态函数,以便我可以将它作为参数发送。例如:

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')做我想做的事情,但我不明白他的意思当他看起来很忙的时候,我没有再按他了。

3 个答案:

答案 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();