문제

에서 JavaScript 중첩된 기능은 매우 유용합니다:마감,개인 방법 그리고 무엇이 있..

무엇이 중첩되어 있는 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()
도움이 되었습니까?

해결책

없음 기본적으로,나는 항상 처리 부작용으로의 parser.

Eran Galperin 은 착각하는 이러한 기능은 어떻게든 개인,그들은 단순히 선언하지 않을 때까지 outer() 이 실행됩니다.그들은 또한 개인 범위,그들이 할 polute 글로벌 범위를 이기는 하지만 지연됩니다.와 콜백으로 외부 콜백을 수도만이라고 한다.나는 여전히 보이지 않는 어떻게 도움이 적용에 배는 매우 가능성이 전화를 별칭이다.

다만'실로'세계를 들어 내가할 수 없습을 발굴가 는 실행할 수 있습니다 한번에 다시 작성할 수 있습 청소기 전용입니다.

으로만 사용할 생각할 수 있는 모듈에 대한 전화[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는 대부분 더 나은 선택이지만, 그것은 의무가 아닌 옵션이며, 일부 간단한 작업에는 추가 cruft가 필요하지 않습니다.)

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

<?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'함수를 사용하여 코드 전체에서 언어 점검을 쓰지 않도록하는 것입니다. 이제 나는 이것을하지 않았지만 그것을하는 것에 대한 주장을 볼 수 있습니다.

위의 모든 내용은 단순히 중첩 된 함수를 만들어 함수 내에서 일부 지역화 된 반복 코드를 대체 할 수 있습니다 (부모 함수 내에서만 사용됩니다). 익명의 기능은 이것의 완벽한 예입니다.

일부는 클래스에서 개인 메소드 (또는 작은 코드 블록) 만 생성한다고 말할 수도 있지만, 이는 초 특이 적 작업 (부모에게만 해당)을 모듈화해야하지만 나머지 부분이 반드시 사용할 수는 없을 때 물을 진흙 투성시키는 것입니다. 수업. 좋은 소식은 다른 곳에서 해당 기능이 필요하다는 것이 밝혀지면 수정이 다소 기본적입니다 (정의를 더 중심 위치로 이동).

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

분명히, 나는 중첩 된 기능이 비공개라고 말하는 것이 아닙니다. 그 중첩은 사소한 것이 모듈화되어야 할 때 혼란을 피할 수 있습니다 (부모 기능에만 필요합니다).

내 모든 PHP는 OO이지만, 특히 기능이 재귀 적이며 반드시 객체 일 때 중첩 된 기능에 사용됩니다. 즉, 그것이 중첩 된 함수 외부에서 호출되지는 않지만 재귀 적이며 그 후에는 함수가 필요합니다.

단일 다른 방법을 명시 적으로 사용하기위한 새로운 방법을 만들 때는 거의 없습니다. 나에게 그것은 서투른 코드이며 OO의 요점이 아닙니다. 다른 곳에서는 그 기능을 부르지 않겠다면 둥지를 맞추십시오.

Webservice Call에서 우리는 중첩 된 방식을 포함하여 동적으로 오버 헤드 (메모리 및 속도)가 훨씬 낮은 오버 헤드 (메모리 및 속도)를 발견했습니다. 일반적인 통화 스택은 5-10 통화 사이에서 깊은 곳에있을 수 있습니다. 수십 개의 1-2kb 파일을 동적으로 연결하는 것이 메가 바이트를 포함하는 것보다 낫습니다. 이것은 작은 Util 기능 포장 요구를 만들어서 만 수행되었습니다. 포함 된 기능은 통화 스택 위의 함수 내에 중첩됩니다. 모든 웹 서비스 호출에 필요하지 않았지만 PHP의 내장 게으른로드 기능을 사용할 수도있는 100 대의 기능으로 가득 찬 클래스와 달리 고려하십시오.

나는 이것이 오래된 게시물이라는 것을 알고 있지만 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 ()에 중첩 된 세 가지 함수 (TO (), 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()

    }

이제 우리가 test1 () 호출하면 출력이 다음과 같습니다.

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

우리가 test2 () 호출하면 출력이 다음과 같습니다.

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

그러나 우리는 재 선포 오류를 피하기 위해 Text1 () 및 test2 ()를 모두 호출 할 수 없습니다.

나는 1 차, 더 범주적인 함수 내에서 작은 재귀 함수를 실행하는 것이 유용했을 때만이 특성을 실제로 사용했지만 기본 프로세스의 동작의 기본이기 때문에 다른 파일로 이동하고 싶지 않았습니다. 나는이 작업을 수행하는 다른 "모범 사례"방법이 있다는 것을 알고 있지만, 내 Devs가 내 파서를 볼 때마다 그 기능을 볼 수 있도록하고 싶습니다. 어쨌든 그들이 수정해야 할 것입니다 ...

중첩 함수는 메모 화에 유용합니다 (캐싱 기능 결과 성능 향상).

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

중첩 함수는 중첩 함수가 부모 함수 내에서 선언 된 변수를 활용하려는 경우 유용합니다.

<?php
ParentFunc();
function ParentFunc()
{
  $var = 5;
  function NestedFunc()
  {
    global $var;
    $var = $var + 5;
    return $var;
  };
  echo NestedFunc()."<br>";
  echo NestedFunc()."<br>";
  echo NestedFunc()."<br>";
}
?>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top