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);
8
  • Are you looking for Anonymous functions? Commented Dec 18, 2011 at 2:50
  • 6
    Awful idea. What are you really trying to do? Commented Dec 18, 2011 at 2:50
  • no no, I need the name to be available trough the same code :) Commented Dec 18, 2011 at 2:51
  • but people create class properties like this any time. I don't see why functions should be special in this case.. Commented Dec 18, 2011 at 2:53
  • 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. Commented Oct 1, 2013 at 16:01

5 Answers 5

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);
Sign up to request clarification or add additional context in comments.

6 Comments

hmm interesting, this should work, I didnt thought of that :D
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.
@downvoter I hope you have read the disclaimer at the beginning of my answer.
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.
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.
|
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);
?>

5 Comments

Technically, this doesn't define a function, but a closure. Try get_defined_functions()['user'] and get_defined_vars() to see the difference.
@jameshfisher PHP's "closures" are also known as anonymous functions, 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.
@MarkAmery PHP's "functions" and "vars" lie in different namespaces. They are fundamentally different. This is a semantic issue, not a syntactic one.
Why to make code example so complex: $foo = function () { ... }; $foo();. Nuff said.
@mms27 Because that doesn't answer the original question, that just defines and executes an anonymous function.
12

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.

Comments

2

Try call_user_func_array()

php.net link

Comments

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.

1 Comment

This answer would have been great as a comment :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.