Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign a static function to a variable in PHP

I would like to assign a static function to a variable so that I can send it around as a parameter. For example:

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(); 
         }; 
    }
}

I've tried a few more variations but none of them worked.

I don't even expect this sort of functional hacking to work with PHP but hey, who knows?

Is it possible to do that in PHP or will I need to come up with some hack using eval?

P.S.: LawnGnome on ##php mentioned something about it being possible to do what I want using array('Foo','privateStaticMethod') but I didn't understand what he meant and I didn't press him further as he looked busy.

like image 229
Felipe Avatar asked Sep 26 '12 03:09

Felipe


3 Answers

You want to use call_user_func with an array argument.

$var = array('Foo','privateStaticMethod');
call_user_func($var);

Note that the "private" specifier on that method will make it only callable this way within the Foo class.

call_user_func takes a callable as the first argument. Note that as of PHP 5.2.3, it is possible to avoid the array notation in your case.

Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object at index 0. As of PHP 5.2.3, it is also possible to pass 'ClassName::methodName'.

like image 67
jimp Avatar answered Nov 15 '22 08:11

jimp


As a note, you should set your static variable as so:

static $privateStaticMethod;

$var = self::$privateStaticMethod;

Leaving off a $ when using self:: will try to access a class CONSTANT and not a variable.

In actuality, I think you meant this line to be:

//Fatal error: Undefined class constant 'privateStaticFunction'                    
$var = self::privateStaticFunction("arga", "argb");

If you are on PHP 5.4 you can do the following within your publicStaticFunction:

$var = function(){
    return self::privateStaticFunction(); 
}; 

$var();

Within PHP 5.4, PHP allows you to access class scope from lambda functions.

Also, have you looked into ReflectionClass?

The following would be used to replace call_user_func_array() in a more OOP style:

<?php
$rc = new ReflectionClass('SomeClass');
$class = $rc->newInstanceArgs(array('foo', 'bar'));

echo $class->doSomething();

You could write your own class to use ReflectionMethod which implements ReflectionClass and use setAccessible() to allow access to protected and private methods.

like image 31
Mike Mackintosh Avatar answered Nov 15 '22 09:11

Mike Mackintosh


Here is what I did to solve my issue

class test{
  static function Unix($arr){return implode("/",$arr);}
  static function Windows($arr){return implode("\\",$arr);}
  function test(){
    $slash = "Unix";
    echo self::$slash(["path","to","a","folder"]);
  }
}
like image 1
Isaac Avatar answered Nov 15 '22 10:11

Isaac