PHP에서 매개 변수로 함수 허용


104

PHP에서 매개 변수로 함수를 전달할 수 있는지 궁금합니다. JS로 프로그래밍 할 때 다음과 같은 것을 원합니다.

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

내가 원하는 것은 exampleMethod 어딘가에서 해당 함수를 실행하는 것입니다. PHP에서 가능합니까?


답변:


150

PHP 5.3.0 이상을 사용하는 경우 가능합니다.

설명서의 익명 기능 을 참조하십시오 .

귀하의 경우 다음 exampleMethod과 같이 정의 합니다.

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

9
젠장, 가능하다는 걸 알았어. 대답하려고했지만 먼저 링크 할 문서를 찾고 싶었고 정확히 무엇인지 몰랐습니다. 아 글쎄, 이제이 일을해야 할 때도 알게 될 것입니다. 감사.
Rob

3
5.3 이전에는 사용할 수 있습니다create_function
Gordon

정말 고맙습니다. PHP4.3을 위해해야하기 때문에 다른 로직을 사용하여 원하는 것을해야 할 것 같습니다.
Cristian

1
@Casidiablo-Jage의 답변을 참조하면 create_function(). 함수를 코드 문자열로 전달해야하므로 똑같지는 않습니다 eval(). 이상적이지는 않지만 사용할 수 있습니다.
zombat

1
어떻게 부르겠습니까? 기존 기능의 이름을 알려주시겠습니까? 예 :exampleMethod(strpos);
sumid

51

다른 것에 추가하기 위해 함수 이름을 전달할 수 있습니다.

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

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

callFunc('someFunc');

이것은 PHP4에서 작동합니다.


17

당신은 또한 사용할 수 create_function를 변수로하는 함수를 만들고 그것을 주변에 통과 할 수 있습니다. 하지만 익명 기능이 더 좋다는 느낌이 듭니다 . 좀비 이동.


대안은 +1. OP에 필요할 것 같습니다.
zombat

감사! 나는 오래된 PHP 5.2 설치를 고수해야하고 익명 기능이 작동하지 않습니다.
diosney

경고 :이 함수는 PHP 7.2.0부터 더 이상 사용되지 않습니다. 이 기능에 의존하는 것은 매우 권장되지 않습니다.
shamaseen

15

다음과 같이 코딩하십시오.

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

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

다음과 같은 것을 발명 할 수 있다면 좋을 것입니다 (Laravel Illuminate에서 영감을 얻음).

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

정확히 내가 찾던 것
Harvey

5

PHP 버전> = 5.3.0

예 1 : 기본

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

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

예제 2 : std 객체

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

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

예제 3 : 비 정적 클래스 호출

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

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

예제 4 : 정적 클래스 호출

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

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

5

@zombat의 답변에 따르면 먼저 익명 함수를 확인하는 것이 좋습니다.

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

또는 PHP 5.4.0 이후 인수 유형의 유효성을 검사합니다.

function exampleMethod(callable $anonFunc) {}

($ anonFunc 호출 가능) 검사가 실패했을 때 어떻게 처리합니까? 감사합니다
xam

3

PHP 5.3에서 테스트 됨

여기에서 알 수 있듯이 익명 함수가 도움이 될 수 있습니다 : http://php.net/manual/en/functions.anonymous.php

당신이 아마도 필요로 할 것이고 그것은 즉시 생성 된 함수 안에 그것을 래핑하지 않고 함수를 전달하는 방법 전에는 언급되지 않았습니다 . 나중에 보게 되겠지만, 문자열로 작성된 함수 이름을 매개 변수로 전달하고 "호출 성"을 확인한 다음 호출해야합니다.

확인할 기능 :

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

그런 다음이를 호출하려면 다음 코드를 사용합니다 (매개 변수도 필요하면 배열에 배치). http://php.net/manual/en/function.call-user-func.php

call_user_func_array( "string_holding_the_name_of_your_function", $arrayOfParameters );

다음과 같이 (비슷하고 매개 변수가없는 방식으로) :

    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");

비슷한 작업을 수행하는 방법을 설명하는 클래스는 다음과 같습니다.

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

및 사용 예

<?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

클래스를 사용한 간단한 예 :

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;


});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.