복붙노트

참조 : 변수 범위 란 무엇이며 어디에서 그리고 무엇이 "정의되지 않은 변수"오류에서 액세스 할 수 있습니까?

PHP

참조 : 변수 범위 란 무엇이며 어디에서 그리고 무엇이 "정의되지 않은 변수"오류에서 액세스 할 수 있습니까?

PHP에서 "가변 범위"란 무엇입니까? 다른 .php 파일의 변수에 액세스 할 수 있습니까? 왜 때로는 "정의되지 않은 변수"오류가 발생합니까?

해결법

  1. ==============================

    1.

    변수에는 제한된 "범위"또는 "접근 가능한 장소"가 있습니다. 그냥 $ foo = 'bar'라고 썼기 때문에; 한 번 응용 프로그램의 어딘가에서 응용 프로그램 내부의 다른 곳에서 $ foo를 참조 할 수있는 것은 아닙니다. 변수 $ foo는 유효 범위가 유효하며 동일한 범위에있는 코드 만 변수에 액세스 할 수 있습니다.

    아주 간단합니다 : PHP는 기능 범위를 가지고 있습니다. 이것이 PHP에 존재하는 유일한 범위 구분 기호입니다. 함수 내의 변수는 해당 함수 내에서만 사용할 수 있습니다. 함수 밖의 변수는 함수 외부에서는 사용할 수 있지만 함수 내부에서는 사용할 수 없습니다. 즉, PHP에는 하나의 특별한 범위가 있습니다 : 전역 범위. 함수 외부에서 선언 된 변수는이 전역 범위 내에 있습니다.

    <?php
    
    $foo = 'bar';
    
    function myFunc() {
        $baz = 42;
    }
    

    $ foo는 전역 범위에 있고 $ baz는 myFunc 내부의 로컬 범위에 있습니다. myFunc 내부의 코드 만 $ baz에 액세스 할 수 있습니다. myFunc 외부의 코드 만 $ foo에 액세스 할 수 있습니다. 어느 쪽도 다른쪽에 접근 할 수 없다 :

    <?php
    
    $foo = 'bar';
    
    function myFunc() {
        $baz = 42;
    
        echo $foo;  // doesn't work
        echo $baz;  // works
    }
    
    echo $foo;  // works
    echo $baz;  // doesn't work
    

    파일 경계는 범위를 분리하지 않습니다.

    a.php

    <?php
    
    $foo = 'bar';
    

    b.php

    <?php
    
    include 'a.php';
    
    echo $foo;  // works!
    

    동일한 규칙이 다른 코드에도 적용되는 포함 된 코드에 적용됩니다. 기능 만 분리 된 범위입니다. 범위를 위해 코드 복사 및 붙여 넣기와 같은 파일을 포함시킬 수 있습니다.

    c.php

    <?php
    
    function myFunc() {
        include 'a.php';
    
        echo $foo;  // works
    }
    
    myFunc();
    
    echo $foo;  // doesn't work!
    

    위의 예제에서, a.php는 myFunc 안에 포함되어 있으며, a.php 내의 변수는 로컬 함수 범위만을 가지고 있습니다. a.php에서 전역 범위에있는 것처럼 보이기 때문에 반드시 그럴 필요는 없다. 실제로 코드가 포함 / 실행되는 컨텍스트에 따라 달라진다.

    모든 새로운 함수 선언은 새로운 범위를 도입합니다. 간단합니다.

    function foo() {
        $foo = 'bar';
    
        $bar = function () {
            // no access to $foo
            $baz = 'baz';
        };
    
        // no access to $baz
    }
    
    $foo = 'foo';
    
    class Bar {
    
        public function baz() {
            // no access to $foo
            $baz = 'baz';
        }
    
    }
    
    // no access to $baz
    

    범위 지정 문제를 처리하는 것은 성가신 것처럼 보일 수 있지만 제한된 가변 범위는 복잡한 응용 프로그램을 작성하는 데 필수적입니다. 선언 한 모든 변수가 응용 프로그램 내의 다른 곳에서도 사용할 수 있다면 변수를 추적하여 실제 변수를 추적하지 않고 변수 전체를 단계적으로 수행 할 수 있습니다. 변수에 줄 수있는 의미있는 이름이 너무 많기 때문에 둘 이상의 위치에서 변수 "$ name"을 사용하려고합니다. 앱에서이 고유 한 변수 이름을 한 번만 가질 수 있다면 변수 이름이 고유하고 잘못된 변수에서 잘못된 변수를 변경하지 않도록 정말 복잡한 명명 체계를 사용해야합니다.

    관찰하십시오 :

    function foo() {
        echo $bar;
    }
    

    범위가 없으면 위의 함수는 무엇을할까요? $ bar의 출처는 어디입니까? 어떤 상태입니까? 심지어 초기화 되었습니까? 매번 확인해야합니까? 이것은 유지 보수 할 수 없습니다. 우리를 데려온 건 ...

    function foo($bar) {
        echo $bar;
        return 42;
    }
    

    변수 $ bar는 함수 인수로 명시 적으로이 범위에 들어갑니다. 이 함수를 보면, 그것이 작동하는 값의 출처가 명확합니다. 그런 다음 명시 적으로 값을 반환합니다. 호출자는 함수에서 사용할 변수와 반환 값의 출처를 알 수 있습니다.

    $baz   = 'baz';
    $blarg = foo($baz);
    
    $foo = 'bar';
    
    $baz = function () use ($foo) {
        echo $foo;
    };
    
    $baz();
    

    익명의 함수는 그것의 주변 범위로부터 $ foo를 명시 적으로 포함한다. 이것은 전역 범위와 동일하지 않습니다.

    전에 말했듯이, 전역 범위는 다소 특별하며, 함수는 명시 적으로 변수를 가져올 수 있습니다.

    $foo = 'bar';
    
    function baz() {
        global $foo;
        echo $foo;
        $foo = 'baz';
    }
    

    이 함수는 전역 변수 $ foo를 사용하고 수정합니다. 이러지 마! (당신이 정말로하고있는 일을 정말로 정말로 정말로 알지 못한다면, 심지어 그렇다고해서 :하지 마세요!)

    이 함수의 호출자는 모두 다음과 같습니다.

    baz(); // outputs "bar"
    unset($foo);
    baz(); // no output, WTF?!
    baz(); // outputs "baz", WTF?!?!!
    

    이 기능에 부작용이 있다는 징후는 없지만 아직까지는 없습니다. 이것은 일부 기능이 일부 글로벌 상태를 수정하고 필요로하므로 매우 쉽게 엉망이됩니다. 함수가 무 상태이고, 입력에 대해서만 작용하고, 정의 된 출력을 반환하기를 원한다.

    가능한 한 전역 범위를 사용하지 않는 것이 좋습니다. 가장 확실하게 전역 범위 밖의 변수를 로컬 범위로 "끌어 들이지"않아야합니다.

  2. ==============================

    2.

    함수의 범위 안에 정의 된 변수는 외부에서 액세스 할 수 없지만 함수가 완료된 후에는 값을 사용할 수 없다는 것을 의미하지는 않습니다. PHP는 정적 메서드와 속성을 정의하기 위해 객체 지향 PHP에서 널리 사용되는 잘 알려진 static 키워드를 가지고 있지만 정적 함수를 정적 변수를 정의하는 함수 내에서 사용할 수도 있음을 명심해야합니다.

    정적 변수는 프로그램 실행이이 범위에서 벗어날 때 값을 잃지 않는 경우 함수의 범위에 정의 된 일반 변수와 다릅니다. 정적 변수를 사용하는 다음 예제를 고려해 보겠습니다.

    function countSheep($num) {
     static $counter = 0;
     $counter += $num;
     echo "$counter sheep jumped over fence";
    }
    
    countSheep(1);
    countSheep(2);
    countSheep(3);
    

    결과:

    1 sheep jumped over fence
    3 sheep jumped over fence
    6 sheep jumped over fence
    

    $ counter를 정적으로 정의하지 않았다면 매번 echo 된 값은 함수에 전달 된 $ num 매개 변수와 같을 것입니다. 정적을 사용하면 추가 해결 방법없이이 간단한 카운터를 작성할 수 있습니다.

    정적 변수는 로컬 함수 범위에만 존재합니다. 그럴 수 없다     정의 된 함수 밖에서 액세스됩니다.     다음 번에 전화 할 때까지 값을 변경하지 않도록하십시오.     그 기능.

    정적 변수는 스칼라 또는 스칼라로만 정의 될 수 있습니다.     표현식 (PHP 5.6부터). 다른 값을 필연적으로 할당     적어도이 기사가 쓰여진 순간에는 실패로 이어진다. 그럼에도 불구하고 코드의 다음 줄에서만 그렇게 할 수 있습니다.

    function countSheep($num) {
      static $counter = 0;
      $counter += sqrt($num);//imagine we need to take root of our sheep each time
      echo "$counter sheep jumped over fence";
    }
    

    결과:

    2 sheep jumped over fence
    5 sheep jumped over fence
    9 sheep jumped over fence
    

    정적 함수는 개체의 메서드간에 다소 '공유'됩니다.     같은 학급. 다음 예제를 보면 쉽게 이해할 수 있습니다.

    class SomeClass {
      public function foo() {
        static $x = 0;
        echo ++$x;
      }
    }
    
    $object1 = new SomeClass;
    $object2 = new SomeClass;
    
    $object1->foo(); // 1
    $object2->foo(); // 2 oops, $object2 uses the same static $x as $object1
    $object1->foo(); // 3 now $object1 increments $x
    $object2->foo(); // 4 and now his twin brother
    

    이것은 같은 클래스의 객체에서만 작동합니다. 객체가 다른 클래스 (심지어 서로 확장)에서 나온 것이라면 정적 변수의 동작은 예상대로입니다.

    함수 호출간에 값을 유지하는 또 다른 방법은 클로저를 사용하는 것입니다. 클로저는 PHP 5.3에서 소개되었습니다. 두 단어를 사용하면 함수 범위 내의 일부 변수 집합에 대한 액세스를 다른 익명 함수로 제한 할 수 있습니다.이 익명 함수는 액세스 할 수있는 유일한 방법입니다. 클로저 변수에있는 것은 구조적 프로그래밍에서 '클래스 상수'(값에 의해 클로저로 전달 된 경우) 또는 '개인 속성'(참조로 전달 된 경우)과 같은 OOP 개념을 모방 할 수 있습니다.

    후자는 실제로 정적 변수 대신 클로저를 사용할 수 있습니다. 사용하는 것은 개발자가 결정할 때까지 항상 결정해야하지만 재귀로 작업 할 때 정적 변수가 유용하며 개발자가 알아야 할 가치가 있다고 언급해야합니다.

  3. ==============================

    3.

    변수의 범위는 정의 된 문맥입니다. 대부분의 경우 모든 PHP 변수는 단일 범위만을 가지고 있습니다. 이 단일 범위 범위 포함 및 필수 파일도 포함됩니다. 예 :

    <?php
    $a = 1;
    include 'b.inc';
    ?>
    

    여기서 $ a 변수는 포함 된 b.inc 스크립트에서 사용할 수 있습니다. 그러나 사용자 정의 함수 내에서 지역 함수 범위가 도입되었습니다. 함수 내에서 사용되는 변수는 기본적으로 로컬 함수 범위로 제한됩니다. 예 :

    <?php
    $a = 1; /* global scope */ 
    
    function test()
    { 
        echo $a; /* reference to local scope variable */ 
    } 
    
    test();
    ?>
    

    echo 문이 $ a 변수의 로컬 버전을 참조하고이 범위 내에서 값이 지정되지 않았으므로이 스크립트는 결과를 생성하지 않습니다. C 언어의 전역 변수는 지역 정의에 의해 명시 적으로 무시되지 않는 한 함수에서 자동으로 사용할 수 있다는 점에서 C 언어와 조금 다르다는 것을 알 수 있습니다. 이로 인해 사람들이 실수로 전역 변수를 변경할 수있는 몇 가지 문제가 발생할 수 있습니다. PHP 전역 변수는 함수 내에서 전역 변수로 선언되어야합니다.

  4. from https://stackoverflow.com/questions/16959576/reference-what-is-variable-scope-which-variables-are-accessible-from-where-and by cc-by-sa and MIT lisence