Programing

PHP 중첩 함수는 무엇입니까?

lottogame 2020. 10. 16. 07:02
반응형

PHP 중첩 함수는 무엇입니까?


자바 스크립트에서 중첩 된 함수는 매우 유용합니다 : 클로저, 개인 메서드 및 무엇을 가지고 있는지 ..

중첩 된 PHP 함수는 무엇입니까? 누구든지 그들을 사용하고 무엇을 위해?

내가 한 작은 조사가 있습니다.

<?php
function outer( $msg ) {
    function inner( $msg ) {
        echo 'inner: '.$msg.' ';
    }
    echo 'outer: '.$msg.' ';
    inner( $msg );
}

inner( 'test1' );  // Fatal error:  Call to undefined function inner()
outer( 'test2' );  // outer: test2 inner: test2
inner( 'test3' );  // inner: test3
outer( 'test4' );  // Fatal error:  Cannot redeclare inner()

기본적으로는 없습니다. 저는 항상 이것을 파서의 부작용으로 취급했습니다.

Eran Galperin은 이러한 기능이 어떻게 든 비공개라고 착각하고 outer()실행될 때까지 단순히 선언되지 않습니다. 그들은 또한 개인적으로 범위가 지정되지 않았으며 지연되었지만 글로벌 범위를 오염시킵니다. 그리고 콜백으로서 외부 콜백은 여전히 ​​한 번만 호출 될 수 있습니다. 나는 여전히 별칭을 두 번 이상 호출 할 가능성이 매우 높은 배열에 적용하는 것이 얼마나 도움이되는지 알지 못합니다.

내가 발굴 할 수있는 유일한 '현실 세계'예는 한 번만 실행할 수 있으며 IMO 청소기를 다시 쓸 수있는합니다.

내가 생각할 수있는 유일한 용도는 모듈이 전역 공간에 여러 중첩 메서드를 설정하는 [name] _include 메서드를 호출하는 것입니다.

if (!function_exists ('somefunc')) {
  function somefunc() { }
}

체크 무늬.

PHP의 OOP가 분명히 더 나은 선택이 될 것입니다. :)


PHP 5.3을 사용하는 경우 익명 함수로 Javacript와 유사한 동작을 더 많이 얻을 수 있습니다.

<?php
function outer() {
    $inner=function() {
        echo "test\n";
    };

    $inner();
}

outer();
outer();

inner(); //PHP Fatal error:  Call to undefined function inner()
$inner(); //PHP Fatal error:  Function name must be a string
?>

산출:

test
test

[@PierredeLESPINAY의 댓글에 따라 재 작성 됨]

이것은 단지 부작용이 아니라 실제로 프로그램의 논리 동적으로 수정 하는 데 매우 유용한 기능입니다 . 절차적인 PHP 시대에서 왔지만, 가능한 가장 간단한 방법으로 특정 독립형 함수에 대한 대체 구현을 제공하려는 경우 OO 아키텍처에서도 유용 할 수 있습니다. (OO가 대부분의 경우 더 나은 선택이지만 의무가 아니라 옵션이며 일부 간단한 작업에는 추가 작업이 필요하지 않습니다.)

예를 들어, 프레임 워크에서 플러그인을 동적 / 조건부로로드하고 플러그인 작성자의 수명을 매우 쉽게 만들고 싶다면 플러그인이 재정의하지 않은 일부 중요한 기능에 대한 기본 구현을 제공 할 수 있습니다.

<?php // Some framework module

function provide_defaults()
{
    // Make sure a critical function exists:
    if (!function_exists("tedious_plugin_callback"))
    {
        function tedious_plugin_callback()
        {
        // Complex code no plugin author ever bothers to customize... ;)
        }
    }
}

함수 내에 정의 된 함수는 많이 사용할 수 없지만 조건부로 정의 된 함수는 할 수 있습니다. 예를 들면 :

if ($language == 'en') {
  function cmp($a, $b) { /* sort by English word order */ }
} else if ($language == 'de') {
  function cmp($a, $b) { /* sort by German word order; yes it's different */ }
} // etc

그런 다음 코드 전체에서 언어 검사를 낭비하지 않도록 usort () 호출과 같은 작업에서 'cmp'함수를 사용하기 만하면됩니다. 이제 나는 이것을하지 않았지만 그것을하기위한 논쟁을 볼 수 있습니다.


위에서 말한 모든 내용은 함수 내에서 지역화되고 반복적 인 코드 (부모 함수 내에서만 사용됨)를 대체하기 위해 중첩 함수를 생성 할 수 있습니다. 익명 함수가 이에 대한 완벽한 예입니다.

어떤 사람들은 클래스에서 프라이빗 메서드 (또는 더 작은 코드 블록)를 생성한다고 말할 수 있지만, 이는 초 특이 작업 (부모에게만 해당)을 모듈화해야 할 때 물을 혼란스럽게하지만 나머지 사람들이 반드시 사용할 수있는 것은 아닙니다. 수업. 좋은 소식은 다른 곳에서 해당 기능이 필요하다는 것이 밝혀지면 수정이 다소 기본적이라는 것입니다 (정의를보다 중앙 위치로 이동).

일반적으로 JavaScript를 표준으로 사용하여 다른 C 기반 프로그래밍 언어를 평가하는 것은 나쁜 생각입니다. JavaScript는 PHP, Python, Perl, C, C ++ 및 Java와 비교할 때 확실히 그 자체의 동물입니다. 물론 일반적인 유사점은 많이 있지만, 핵심적인 세부 사항 ( JavaScript : The Definitive Guide, 6th Edition, Chapters 1-12 참조 )에주의를 기울이면 핵심 JavaScript를 독특하고 아름답고 다르며 단순하게 만들고 동시에 복잡합니다. 그것은 내 2 센트입니다.

명확하게 말하면 중첩 함수가 비공개라고 말하는 것이 아닙니다. 그 중첩만으로도 사소한 것을 모듈화해야 할 때 (부모 함수에서만 필요함) 혼란을 피할 수 있습니다.


내 모든 PHP는 OO이지만, 특히 함수가 재귀적이고 반드시 객체가 아닌 경우 중첩 함수가 사용되는 것으로 보입니다. 즉, 중첩 된 함수 외부에서는 호출되지 않지만 재귀 적이므로 나중에 함수 여야합니다.

하나의 다른 방법을 명시 적으로 사용하기위한 새로운 방법을 만드는 데는 별 의미가 없습니다. 나에게 그것은 서투른 코드이며 OO의 요점은 아닙니다. 다른 곳에서는이 함수를 호출하지 않으려면 중첩하십시오.


웹 서비스 호출에서 우리는 중첩 된 방식으로 1,000 개의 함수로 가득 찬 라이브러리에 대한 개별 함수를 동적으로 포함하여 훨씬 낮은 오버 헤드 (메모리 및 속도)를 발견했습니다. 일반적인 호출 스택은 5-10 호출 깊이 일 수 있습니다. 12 개의 1-2kb 파일을 동적으로 연결하는 것이 메가 바이트를 포함하는 것보다 낫습니다. 이것은 래핑이 필요한 작은 util 함수를 생성함으로써 수행되었습니다. 포함 된 함수는 호출 스택 위의 함수 내에 중첩됩니다. 모든 웹 서비스 호출에 필요하지는 않았지만 php의 내장 된 지연 로딩 기능을 사용할 수 있었던 수백 개의 함수로 가득 찬 클래스와는 대조적으로 생각해보십시오.


나는 이것이 오래된 게시물이라는 것을 알고 있지만 fwiw는 기능이 로컬로만 필요할 때 재귀 호출에 깔끔하고 깔끔한 접근 방식을 제공하기 위해 중첩 된 함수를 사용합니다. 한 번 호출 됨) :

function main() {
    // Some code

    function addChildren ($parentVar) {
        // Do something
        if ($needsGrandChildren) addChildren ($childVar);
    }
    addChildren ($mainVar); // This call must be below nested func

    // Some more code
}

예를 들어 JS와 비교하여 PHP에서 주목할 점은 중첩 된 함수에 대한 호출이 함수 선언 이후에 이루어져야한다는 것입니다.


만약 당신이 php 7에 있다면 다음을보십시오 : 이 구현은 중첩 된 함수에 대한 명확한 아이디어를 제공 할 것입니다. 함수 foo ()에 중첩 된 세 가지 함수 (too (), boo () 및 zoo ())가 있다고 가정합니다. boo () 및 zoo ()에는 동일한 이름의 중첩 함수 xoo ()가 있습니다. 이제이 코드에서 중첩 함수의 규칙을 명확하게 설명했습니다.

   function foo(){
        echo 'foo() is called'.'<br>';
        function too(){
            echo 'foo()->too() is called'.'<br>';
        }
        function boo(){
            echo 'foo()->boo() is called'.'<br>';
            function xoo(){
                echo 'foo()->boo()->xoo() is called'.'<br>';
            }
            function moo(){
                echo 'foo()->boo()->moo() is called'.'<br>';
            }
        }
        function zoo(){
            echo 'foo()->zoo() is called'.'<br>';
            function xoo(){     //same name as used in boo()->xoo();
                echo 'zoo()->xoo() is called'.'<br>';
            }
        #we can use same name for nested function more than once 
        #but we can not call more than one of the parent function
        }
    }

/****************************************************************
 * TO CALL A INNER FUNCTION YOU MUST CALL OUTER FUNCTIONS FIRST *
 ****************************************************************/
    #xoo();//error: as we have to declare foo() first as xoo() is nested in foo()

    function test1(){
        echo '<b>test1:</b><br>';
        foo(); //call foo()
        too();
        boo();
        too(); // we can can a function twice
        moo(); // moo() can be called as we have already called boo() and foo()
        xoo(); // xoo() can be called as we have already called boo() and foo()
        #zoo(); re-declaration error
        //we cannont call zoo() because we have already called boo() and both of them have same named nested function xoo()
    }

    function test2(){
        echo '<b>test2:</b><br>';
        foo(); //call foo()
        too();
        #moo(); 
        //we can not call moo() as the parent function boo() is not yet called
        zoo(); 
        xoo();
        #boo(); re-declaration error
        //we cannont call boo() because we have already called zoo() and both of them have same named nested function xoo()

    }

Now if we call test1() the output will be this:

test1:
foo() is called
foo()->too() is called
foo()->boo() is called
foo()->too() is called
foo()->boo()->moo() is called
foo()->boo()->xoo() is called

if we call test2() the output will be this:

test2:
foo() is called
foo()->too() is called
foo()->zoo() is called
zoo()->xoo() is called

But we cannot call both text1() and test2() at same time to avoid re-declaration error


I have only really used this characteristic when it was useful to execute a small recursive function inside a primary, more categorical function, but didn't want to move it to a different file because it was fundamental to the behavior of a primary process. I realize there are other "best practice" ways of doing this, but I want to make sure my devs see that function every time they look at my parser, it's likely what they should modify anyway...


Nested functions are useful in Memoization (caching function results to improve performance).

<?php
function foo($arg1, $arg2) {
    $cacheKey = "foo($arg1, $arg2)";
    if (! getCachedValue($cacheKey)) {
        function _foo($arg1, $arg2) {
            // whatever
            return $result;
        }
        $result = _foo($arg1, $arg2);
        setCachedValue($cacheKey, $result);
    }
    return getCachedValue($cacheKey);
}
?>

Nested functions are useful if you want the nested function to utilize a variable that was declared within the parent function.

<?php
ParentFunc();
function ParentFunc()
{
  $var = 5;
  function NestedFunc()
  {
    global $var;
    $var = $var + 5;
    return $var;
  };
  echo NestedFunc()."<br>";
  echo NestedFunc()."<br>";
  echo NestedFunc()."<br>";
}
?>

참고URL : https://stackoverflow.com/questions/415969/what-are-php-nested-functions-for

반응형