PHP'de işlevi parametre olarak kabul edin


105

PHP'de bir işlevi parametre olarak geçirmenin mümkün olup olmadığını merak ediyordum; JS'de programlama yaparkenki gibi bir şey istiyorum:

object.exampleMethod(function(){
    // some stuff to execute
});

İstediğim şey, bu işlevi exampleMethod içinde bir yerde çalıştırmak. PHP'de bu mümkün mü?


Yanıtlar:


151

PHP 5.3.0 veya üstünü kullanıyorsanız mümkündür.

Kılavuzdaki Anonim İşlevler bölümüne bakın .

Sizin durumunuzda şu şekilde tanımlarsınız exampleMethod:

function exampleMethod($anonFunc) {
    //execute anonymous function
    $anonFunc();
}

9
Kahretsin, bunun mümkün olduğunu biliyordum. Cevap verecekti, ancak önce bağlantı kurmak için bazı belgeler bulmak istiyordu ve tam olarak ne dendiğini bilmiyordum. Pekala, şimdi bunu ne zaman yapmam gerektiğini de bileceğim. Teşekkürler.
Rob

3
5.3'ten önce kullanabilirsinizcreate_function
Gordon

Çok teşekkür ederim. PHP4.3 için yapmam gerektiğinden, sanırım istediğimi başka bir mantık kullanarak yapmam gerekecek.
Cristian

1
@Casidiablo - Jage'in cevabına bakın, onunla bir şeyler yapabilirsiniz create_function(). İşlevinizi bir kod dizisi olarak geçirmeniz gerektiğinden, tam olarak aynı değildir, bu da daha sonra eval()perde arkasına geçer. İdeal değil, ama onu kullanabilirsin.
zombat

1
Nasıl adlandırırsın Mevcut fonksiyona bir isim verebilir misiniz? Örneğin:exampleMethod(strpos);
toplam

52

Sadece diğerlerine eklemek için bir işlev adı geçebilirsiniz:

function someFunc($a)
{
    echo $a;
}

function callFunc($name)
{
    $name('funky!');
}

callFunc('someFunc');

Bu PHP4'te çalışacaktır.


17

Ayrıca bir değişken olarak bir işlev oluşturmak ve onu iletmek için create_function işlevini de kullanabilirsiniz . Yine de, anonim işlevler hissini daha çok seviyorum . Zombat gidin.


Alternatif için +1. Görünüşe göre OP'nin ihtiyacı olabilir.
zombat

Teşekkürler! Eski bir PHP 5.2 kurulumuna bağlı kalmalıyım ve anonymoys işlevleri orada çalışmıyor.
diosney

Uyarı: Bu işlev PHP 7.2.0'dan itibaren KULLANIMDAN KALDIRILMIŞTIR. Bu işleve güvenmek kesinlikle önerilmez.
shamaseen

15

Bunu şu şekilde kodlayın:

function example($anon) {
  $anon();
}

example(function(){
  // some codes here
});

Böyle bir şey icat edebilseydiniz harika olurdu (Laravel Illuminate'den esinlenerek):

Object::method("param_1", function($param){
  $param->something();
});

tam olarak aradığım şey
Harvey

5

PHP SÜRÜMÜ> = 5.3.0

Örnek 1: temel

function test($test_param, $my_function) {
    return $my_function($test_param);
}

test("param", function($param) {
    echo $param;
}); //will echo "param"

Örnek 2: std nesne

$obj = new stdClass();
$obj->test = function ($test_param, $my_function) {
    return $my_function($test_param);
};

$test = $obj->test;
$test("param", function($param) {
    echo $param;
});

Örnek 3: Statik olmayan sınıf çağrısı

class obj{
    public function test($test_param, $my_function) {
        return $my_function($test_param);
    }
}

$obj = new obj();
$obj->test("param", function($param) {
    echo $param;
});

Örnek 4: Statik sınıf çağrısı

class obj {
    public static function test($test_param, $my_function) {
        return $my_function($test_param);
    }
}

obj::test("param", function($param) {
    echo $param;
});

5

@ Zombat'ın cevabına göre, önce Anonim İşlevleri doğrulamak daha iyidir:

function exampleMethod($anonFunc) {
    //execute anonymous function
    if (is_callable($anonFunc)) {
        $anonFunc();
    }
}

Veya PHP 5.4.0'dan beri bağımsız değişken türünü doğrulayın:

function exampleMethod(callable $anonFunc) {}

(çağrılabilir $ anonFunc) kontrolü başarısız olduğunda nasıl başa çıkarsınız? teşekkürler
xam

3

PHP 5.3 için test edildi

Burada gördüğüm gibi, Anonim İşlev size yardımcı olabilir: http://php.net/manual/en/functions.anonymous.php

Muhtemelen ihtiyacınız olacak ve bir işlevi anında oluşturulmuş bir işlevin içine sarmadan nasıl geçireceğiniz söylenmez . Daha sonra göreceğiniz gibi, bir dizgede yazılmış işlevin adını parametre olarak iletmeniz, "çağrılabilirliğini" kontrol etmeniz ve ardından çağırmanız gerekir.

Kontrol edilecek işlev:

if( is_callable( $string_function_name ) ){
    /*perform the call*/
}

Ardından, onu çağırmak için, şu kod parçasını kullanın (parametrelere ihtiyacınız varsa, bunları bir diziye koyun), şu adreste görülüyor: http://php.net/manual/en/function.call-user-func.php

call_user_func_array( "string_holding_the_name_of_your_function", $arrayOfParameters );

aşağıdaki gibi (benzer, parametresiz bir şekilde):

    function funToBeCalled(){
        print("----------------------i'm here");
    }
    function wrapCaller($fun){
        if( is_callable($fun)){
            print("called");
            call_user_func($fun);
        }else{
            print($fun." not called");
        }
    }

    wrapCaller("funToBeCalled");
    wrapCaller("cannot call me");

İşte benzer bir şeyin nasıl yapılacağını açıklayan bir ders:

<?php
class HolderValuesOrFunctionsAsString{
    private $functions = array();
    private $vars = array();

    function __set($name,$data){
        if(is_callable($data))
            $this->functions[$name] = $data;
        else
            $this->vars[$name] = $data;
    }

    function __get($name){
        $t = $this->vars[$name];
        if(isset($t))
            return $t;
        else{
            $t = $this->$functions[$name];
            if( isset($t))
                return $t;
        }
    }

    function __call($method,$args=null){
        $fun = $this->functions[$method];
        if(isset($fun)){
            call_user_func_array($fun,$args);
        } else {
            // error out
            print("ERROR: Funciton not found: ". $method);
        }
    }
}
?>

ve bir kullanım örneği

<?php
    /*create a sample function*/
    function sayHello($some = "all"){
    ?>
         <br>hello to <?=$some?><br>
    <?php
    }

    $obj = new HolderValuesOrFunctionsAsString;

    /*do the assignement*/
    $obj->justPrintSomething = 'sayHello'; /*note that the given
        "sayHello" it's a string ! */

    /*now call it*/
    $obj->justPrintSomething(); /*will print: "hello to all" and
        a break-line, for html purpose*/

    /*if the string assigned is not denoting a defined method
         , it's treat as a simple value*/
    $obj->justPrintSomething = 'thisFunctionJustNotExistsLOL';

    echo $obj->justPrintSomething; /*what do you expect to print?
        just that string*/
    /*N.B.: "justPrintSomething" is treated as a variable now!
        as the __set 's override specify"*/

    /*after the assignement, the what is the function's destiny assigned before ? It still works, because it's held on a different array*/
     $obj->justPrintSomething("Jack Sparrow");


     /*You can use that "variable", ie "justPrintSomething", in both ways !! so you can call "justPrintSomething" passing itself as a parameter*/

     $obj->justPrintSomething( $obj->justPrintSomething );
         /*prints: "hello to thisFunctionJustNotExistsLOL" and a break-line*/

    /*in fact, "justPrintSomething" it's a name used to identify both
         a value (into the dictionary of values) or a function-name
         (into the dictionary of functions)*/
?>

2

Bir sınıf kullanarak basit bir örnek:

class test {

    public function works($other_parameter, $function_as_parameter)
    {

        return $function_as_parameter($other_parameter) ;

    }

}

$obj = new test() ;

echo $obj->works('working well',function($other_parameter){


    return $other_parameter;


});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.