PHP передать имя функции как параметр, а затем вызвать функцию?

Мне нужно передать функцию в качестве параметра другой функции, а затем вызвать переданную функцию изнутри функции ... Это, вероятно, легче объяснить в коде ... Я в основном хочу сделать что-то вроде этого:

function ($functionToBeCalled)
{
   call($functionToBeCalled,additional_params);
}

Есть ли способ сделать это .. Я использую PHP 4.3.9

Спасибо!


person JD Isaacks    schedule 09.03.2009    source источник


Ответы (7)


Я думаю, вы ищете call_user_func.

Пример из Руководства по PHP:

<?php
function barber($type) {
    echo "You wanted a $type haircut, no problem";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
?>
person Paolo Bergantino    schedule 09.03.2009
comment
и что же происходит, когда цирюльник принадлежит к другому классу? другое пространство имен? - person abbood; 11.06.2014
comment
Это действительно лучший ответ? Он не демонстрирует, что вызов функции изнутри функции, переданной в качестве параметра. - person PiggyMacPigPig; 24.07.2018
comment
@abbood - публичная функция Foo ($ function = null) {... somecode ... return $ this - ›$ function (@params); } - person PiggyMacPigPig; 24.07.2018
comment
Это лучшее решение: stackoverflow.com/questions / 2700433 / - person Krunoslav Djakovic; 19.06.2019

На php это очень просто.

<?php

function here() {
  print 'here';
}


function dynamo($name) {
 $name();
}

//Will work
dynamo('here');
//Will fail
dynamo('not_here');
person Stewart Robinson    schedule 09.03.2009

function foo($function) {
  $function(" World");
}
function bar($params) {
  echo "Hello".$params;
}

$variable = 'bar';
foo($variable);

Кроме того, вы можете сделать это так. См. функции переменных.

person TJ L    schedule 09.03.2009
comment
Я думаю, вы тут немного прыгаете. IIRC, этот код не заработает, пока не выйдет PHP 5.3. - person Jeremy DeGroot; 09.03.2009
comment
«Bar» необходимо заключить в кавычки, так как это строка. - person Gumbo; 09.03.2009
comment
Функции переменных @Jeremy DeGroot существуют всегда - person Greg; 09.03.2009
comment
Я забыл цитаты, спасибо, что указали на это. Добавил их в редакцию. Можно в 5.3 без кавычек? - person TJ L; 09.03.2009
comment
В старых версиях PHP это можно сделать без кавычек. Он превращает неизвестный символ в строку и выдает предупреждение (при условии наличия соответствующей отчетности) из-за обесценивания поведения (?). - person strager; 09.03.2009
comment
@ tj111, если PHP обнаружит неизвестную CONSTANT, он будет считать, что вы имели в виду строку. - person Pim Jager; 09.03.2009
comment
Для справки - в PHP 5.3 поддерживаются анонимные (безымянные) функции (как и в JavaScript). Они передаются напрямую. В предыдущих версиях PHP поддерживается передача функций в виде строковых имен. - person Nux; 05.03.2014

Вы также можете использовать call_user_func_array(). Он позволяет вам передавать массив параметров в качестве второго параметра, поэтому вам не нужно точно знать, сколько переменных вы передаете.

person Community    schedule 07.05.2009

Я знаю исходный вопрос о PHP 4.3, но теперь прошло несколько лет, и я просто хотел отстаивать свой предпочтительный способ сделать это в PHP 5.3 или выше.

PHP 5.3+ теперь включает поддержку анонимных функций (замыканий), поэтому вы может использовать некоторые стандартные методы функционального программирования, например, в таких языках, как JavaScript и Ruby (с некоторыми оговорками). Переписывание приведенного выше примера call_user_func в «стиль закрытия» будет выглядеть так, что я считаю более элегантным:

$barber = function($type) {
    echo "You wanted a $type haircut, no problem\n";
};

$barber('mushroom');
$barber('shave');

Очевидно, что в данном примере это не принесет вам многого - мощность и гибкость проявляются тогда, когда вы передаете эти анонимные функции другим функциям (как в исходном вопросе). Итак, вы можете сделать что-то вроде:

$barber_cost = function($quantity) {
    return $quantity * 15;
};

$candy_shop_cost = function($quantity) {
    return $quantity * 4.50;   // It's Moonstruck chocolate, ok?
};

function get_cost($cost_fn, $quantity) {
    return $cost_fn($quantity);
}

echo '3 haircuts cost $' . get_cost($barber_cost, 3) . "\n";
echo '6 candies cost $' . get_cost($candy_shop_cost, 6) . "\n";

Конечно, это можно сделать с помощью call_user_func, но я считаю этот синтаксис более ясным, особенно когда задействованы пространства имен и переменные-члены.

Одно предостережение: я первым признаю, что не знаю точно, что здесь происходит, но вы не всегда можете вызвать замыкание, содержащееся в члене или статической переменной, и, возможно, в некоторых других случаях. Но переназначение его локальной переменной позволит вызвать его. Так, например, это приведет к ошибке:

$some_value = \SomeNamespace\SomeClass::$closure($arg1, $arg2);

Но этот простой обходной путь решает проблему:

$the_closure = \SomeNamespace\SomeClass::$closure;
$some_value = $the_closure($arg1, $arg2);
person mercurial    schedule 06.12.2013

Если вам нужна функция передачи с параметром в качестве параметра, вы можете попробовать следующее:

function foo ($param1){
   return $param1;
}

function bar ($foo_function, $foo_param){
    echo $foo_function($foo_param);
}

//call function bar
bar('foo', 'Hi there');  //this will print: 'Hi there'

пример phpfiddle

Надеюсь, это будет полезно ...

person w411 3    schedule 16.05.2016
comment
Кто-нибудь может подтвердить? - person user4951; 17.08.2016
comment
phpfiddle.org/ - person w411 3; 18.08.2016

Если вы хотите сделать это внутри класса PHP, взгляните на этот код:

// Create a sample class
class Sample
{

    // Our class displays 2 lists, one for images and one for paragraphs
    function __construct( $args ) {
        $images = $args['images'];
        $items  = $args['items'];
        ?>
        <div>
            <?php 
            // Display a list of images
            $this->loop( $images, 'image' ); 
            // notice how we pass the name of the function as a string

            // Display a list of paragraphs
            $this->loop( $items, 'content' ); 
            // notice how we pass the name of the function as a string
            ?>
        </div>
        <?php
    }

    // Reuse the loop
    function loop( $items, $type ) {
        // if there are items
        if ( $items ) {
            // iterate through each one
            foreach ( $items as $item ) {
                // pass the current item to the function
                $this->$type( $item ); 
                // becomes $this->image 
                // becomes $this->content
            }
        }
    }

    // Display a single image
    function image( $item ) {
        ?>
        <img src="<?php echo $item['url']; ?>">
        <?php 
    }

    // Display a single paragraph
    function content( $item ) {
        ?>
        <p><?php echo $item; ?></p>
        <?php 
    }
}

// Create 2 sample arrays
$images = array( 'image-1.jpg', 'image-2.jpg', 'image-3.jpg' );
$items  = array( 'sample one', 'sample two', 'sample three' );

// Create a sample object to pass my arrays to Sample
$elements = { 'images' => $images, 'items' => $items }

// Create an Instance of Sample and pass the $elements as arguments
new Sample( $elements );
person drjorgepolanco    schedule 20.11.2018
comment
Посмотрите на этот код, за которым следует стена текста, это не очень полезно. Особенно при ответе на вопрос 10-летней давности шестью другими ответами. Объясните, что делает этот код и как он обеспечивает лучший подход, чем другие, уже упомянутые здесь. - person miken32; 20.11.2018
comment
Привет @ miken32! Спасибо за ваше наблюдение. Где можно посмотреть комментарии внутри блока? Причина, по которой я считаю, что это полезно, заключается в том, что он предоставляет определенный контекст, в котором начинающий разработчик может видеть, что аргумент функции работает внутри класса. У вас есть какие-нибудь рекомендации? - person drjorgepolanco; 20.11.2018