18

I have a variable like $string = "blah";

How can I create a function that has the variable value as name? Is this possible in PHP?

Like function $string($args){ ... } or something, and be able to call it like:

blah($args);
Alex
  • 66,732
  • 177
  • 439
  • 641
  • Are you looking for [Anonymous functions](http://php.net/manual/en/functions.anonymous.php)? – Indranil Dec 18 '11 at 02:50
  • 6
    Awful idea. What are you *really* trying to do? – Ignacio Vazquez-Abrams Dec 18 '11 at 02:50
  • no no, I need the name to be available trough the same code :) – Alex Dec 18 '11 at 02:51
  • but people create class properties like this any time. I don't see why functions should be special in this case.. – Alex Dec 18 '11 at 02:53
  • @Alex I can't say I've ever seen people doing that with class properties - is it possible you're confusing people accessing static properties for this? (To access a static property of a class, the syntax is Class::$property) – Richard John Dec 18 '11 at 03:02
  • possible duplicate of [Use Variable as Function Name in PHP](http://stackoverflow.com/questions/8466473/use-variable-as-function-name-in-php) – mario Dec 18 '11 at 03:14
  • 2
    @IgnacioVazquez-Abrams but Doctrine does this all the time. You declare a property in your entity's class, and then you can call doctrine methods like $this->getDoctrine()->findByFirstName(); How's that bad design? I find it very intuitive. – ILikeTacos Oct 01 '13 at 16:01
  • If you store "blah" in $string, why don't you call the function as $result = $string();? Because if $string has always "blah" as value, you don't need to use a variable, and if $string don't has always the same value, you can't call blah() but you need to call $ret = $string(). – Peter Apr 06 '19 at 21:22

5 Answers5

17

this might not be a good idea, but you can do something like this:

$string = "blah";
$args = "args"
$string = 'function ' . $string . "({$args}) { ... }";
eval($string);
fardjad
  • 20,031
  • 6
  • 53
  • 68
  • hmm interesting, this should work, I didnt thought of that :D – Alex Dec 18 '11 at 02:59
  • 6
    This should be the accepted answer. This is the only solution here that defines a function, not a closure. Try `get_defined_functions()['user']` and `get_defined_vars()` to see the difference. – jameshfisher Dec 17 '13 at 15:21
  • @downvoter I hope you have read the disclaimer at the beginning of my answer. – fardjad Sep 26 '14 at 21:25
  • Yup, this is the right answer in some cases.. example use: If you're using expression engine and want to write unit tests without having to bootstrap EE you may still need the global ee() function.. this won't work as a closure. – John Hunt Mar 18 '15 at 10:02
  • 3
    Oh come on, this is the best answer to the question. Using `eval` is not bad if you use it wisely. If it was so bad then why do most respectable scripting languages support it? Just assuming that a language interpreter will fork another interpreter process for `eval` is absurd; for if it does, the language is utterly flawed. Mostly `eval` is accomplished by running the text through the process' `stdin` - just as the rest of the code does. –  Feb 10 '16 at 22:24
  • I'm downvoting it because a lot of unexperienced people might just see it, say WOW and simply use it. – Adam Pietrasiak Apr 13 '16 at 08:00
12

That doesn't sound like a great design choice, it might be worth rethinking it, but...

If you're using PHP 5.3 you could use an anonymous function.

<?php
$functionName = "doStuff";
$$functionName = function($args) {
    // Do stuff
};

$args = array();
$doStuff($args);
?>
Richard John
  • 487
  • 6
  • 15
  • 2
    Technically, this doesn't define a function, but a closure. Try `get_defined_functions()['user']` and `get_defined_vars()` to see the difference. – jameshfisher Dec 17 '13 at 15:18
  • 1
    @jameshfisher PHP's "closures" are also known as [anonymous ***functions***](http://php.net/manual/en/functions.anonymous.php), and the keyword `function` is used in the syntax. Sure, this doesn't define a *named function*, but I think it goes beyond pedantry to the point of unreasonableness to say that it doesn't define a 'function' at all. – Mark Amery Oct 05 '14 at 20:51
  • @MarkAmery PHP's "functions" and "vars" lie in different namespaces. They are fundamentally different. This is a semantic issue, not a syntactic one. – jameshfisher Oct 08 '14 at 09:40
  • Why to make code example so complex: `$foo = function () { ... }; $foo();`. Nuff said. – mms27 Jul 20 '15 at 21:16
  • 1
    @mms27 Because that doesn't answer the original question, that just defines and executes an anonymous function. – Richard John Jul 21 '15 at 02:10
11

Okay, challenge accepted!

No matter how weird the question is (it's not btw), let's take it seriously for a moment! It could be useful to have a class that can declare functions and make them real:

<?php

customFunctions::add("hello",                 // prepare function "hello"

    function($what) {
        print "Hello $what, as Ritchie said";
        print "<br>";
    }

);

customFunctions::add("goodbye",               // prepare function "goodbye"

    function($what,$when) {
        print "Goodbye cruel $what, ";
        print "I'm leaving you $when";
        print "<br>";
    }

);

eval(customFunctions::make());                // inevitable - but it's safe!

That's it! Now they're real functions. No $-prefixing, no runtime evaluations whenever they get called - eval() was only needed once, for declaration. After that, they work like any function.

Let's try them:

    hello('World');                 // "Hello World"
    goodbye('world','today');       // "Goodbye cruel world, I'm leaving you today" 

Magic behind

Here's the class that can do this. Really not a complex one:

class customFunctions {

    private static $store = [];
    private static $maker = "";
    private static $declaration = '
        function %s() {
            return call_user_func_array(
                %s::get(__FUNCTION__),
                func_get_args()
            );
        }
    ';

    private static function safeName($name) {
        // extra safety against bad function names
        $name = preg_replace('/[^a-zA-Z0-9_]/',"",$name);
        $name = substr($name,0,64);
        return $name;
    }

    public static function add($name,$func) {
        // prepares a new function for make()
        $name = self::safeName($name);
        self::$store[$name] = $func;
        self::$maker.=sprintf(self::$declaration,$name,__CLASS__);
    }

    public static function get($name) {  
        // returns a stored callable
        return self::$store[$name];
    }

    public static function make() {  
        // returns a string with all declarations
        return self::$maker;
    }

}

It provides an inner storage for your functions, and then declare "real" functions that call them. This is something similar to fardjad's solution, but with real code (not strings) and therefore a lot more convenient & readable.

Community
  • 1
  • 1
dkellner
  • 8,726
  • 2
  • 49
  • 47
2

Try call_user_func_array()

php.net link

Indranil
  • 2,451
  • 1
  • 23
  • 31
1

You can call a function by its name stored in a variable, and you can also assign a function to variables and call it using the variable. If it's not what you want, please explain more.

LeleDumbo
  • 9,192
  • 4
  • 24
  • 38