programing

레퍼런스:가변 범위란 무엇이며, 어디에서 접근할 수 있는 변수와 "정의되지 않은 변수" 오류는 무엇입니까?

goodsources 2023. 1. 23. 10:14
반응형

레퍼런스:가변 범위란 무엇이며, 어디에서 접근할 수 있는 변수와 "정의되지 않은 변수" 오류는 무엇입니까?

주의: 이것은 PHP의 가변 범위를 다루기 위한 참조 질문입니다.이 패턴에 맞는 많은 질문 중 하나를 이 패턴의 복사본으로 닫아주세요.

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

"가변 범위"란 무엇입니까?

변수는 제한된 "범위" 또는 "변수에 액세스할 수 있는 위치"를 가집니다.라고 썼다고 $foo = 'bar';어플리케이션 내 어딘가에 있다고 해서$foo다른 모든 곳에서 사용할 수 있습니다.변수$foo에는 유효한 특정 범위가 있으며 같은 범위의 코드만 변수에 액세스할 수 있습니다.

PHP에서는 스코프가 어떻게 정의되어 있습니까?

매우 간단합니다. 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.discloss (a.discloss)

<?php

$foo = 'bar';

b.discuse(복수)

<?php

include 'a.php';

echo $foo;  // works!

include 코드에 되는 d : d 코드만:function른른른범범범다다범위를 위해 복사 및 붙여넣기 코드와 같은 파일을 포함할 수 있습니다.

c.c.discloss.

<?php

function myFunc() {
    include 'a.php';

    echo $foo;  // works
}

myFunc();

echo $foo;  // doesn't work!

예에서는 " " " 입니다.a.php에 들어있었어요.myFunc의 변수, 「」a.php로컬 기능 범위만 있습니다.글로벌 범위 내에 있는 것처럼 보인다는 이유만으로a.php반드시 그렇다는 것은 아닙니다.실제로 그 코드가 어떤 컨텍스트에 포함되어 있는지 또는 어떤 컨텍스트에 포함되어 있는지에 따라 다릅니다.

기능 및 클래스 내부의 기능은 어떻습니까?

새로운 ★★★★★★function선언문에는 새로운 범위가 도입되어 있습니다.그것은 매우 간단합니다.

(7) 기능 내부의 기능

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주변 시야에서 볼 수 있습니다.이것은 글로벌 스코프와는 다릅니다.

방법: 못된 the the the:global

앞에서 설명한 바와 같이 글로벌스코프는 다소 특수하며 함수는 이 스코프에서 변수를 명시적으로 Import할 수 있습니다.

$foo = 'bar';

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

는 글로벌 '이러다'를 합니다.$foo 이러지 (Unless you really really really really know what you're doing, and even then: don't!)마!

이 함수의 발신자에게 표시되는 것은, 다음과 같습니다.

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

이 기능에 부작용이 있다는 징후는 없지만 실제로 나타나고 있습니다.일부 함수는 계속 수정하고 글로벌 상태를 요구하기 때문에 이 문제는 쉽게 복잡해집니다.함수를 스테이트리스로 하고, 그 입력에 의해서만 동작해, 정의된 출력을 반환할 필요가 있습니다.이 경우 함수를 호출하는 횟수는 몇 번이 됩니다.

글로벌 스코프의 사용은 가능한 한 피해야 합니다.글로벌 스코프에서 로컬 스코프로 변수를 「풀」하지 않는 것이 가장 중요합니다.

함수의 스코프 내부에서 정의된 변수는 외부에서 액세스할 수 없지만 함수가 완료된 후에는 해당 값을 사용할 수 없습니다.에는 잘 PHP가 .static오브젝트 및단, 이 키워드는 "PHP"는 "PHP"로, "PHP"는 "PHP"로 정의됩니다.static정적 변수를 정의하는 데 함수 내부에서 사용할 수도 있습니다.

정적 변수란 무엇입니까?

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 없이static.$num이치노「」를 사용합니다.static그럼 추가 회피책 없이 이 단순한 카운터를 구축할 수 있습니다.

정적 변수 사용 사례

  1. 기능하기 위한 후속 호출 사이의 값을 저장합니다.
  2. 재귀 콜을 파라미터로 전달할 방법이 없을 때(또는 목적이 없을 때) 재귀 콜 간에 값을 저장합니다.
  3. 일반적으로 한 번 취득하는 것이 좋은 값을 캐시합니다.예를 들어, 서버에서 불변 파일을 읽은 결과입니다.

트릭

스태틱 변수는 로컬 함수 범위에만 존재합니다.정의된 기능 이외에는 액세스할 수 없습니다.따라서 해당 함수에 대한 다음 호출까지 값은 변경되지 않습니다.

정적 변수는 스칼라 또는 스칼라 식으로만 정의할 수 있습니다(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

이것은 같은 클래스의 오브젝트에서만 동작합니다.객체가 다른 클래스의 경우(서로 확장되는 경우에도), 정적 변수의 동작은 예상대로 됩니다.

함수에 대한 호출 간에 값을 유지하는 방법은 static 변수뿐입니까?

함수 호출 사이의 값을 유지하는 또 다른 방법은 폐쇄를 사용하는 것입니다.폐쇄는 PHP 5.3에서 도입되었습니다.즉, 함수 범위 내의 일부 변수 세트에 대한 액세스를 다른 익명 함수로 제한할 수 있으며, 이 함수에 액세스할 수 있는 유일한 방법이 됩니다.폐쇄 변수에 있는 것은 구조화된 프로그래밍에서 '클래스 상수'(값에 의해 폐쇄된 경우) 또는 '프라이빗 속성'(기준에 의해 전달된 경우)와 같은 OOP 개념을 모방할 수 있다.

후자는 실제로 정적 변수 대신 폐쇄를 사용할 수 있습니다.어떤 것을 사용할지는 항상 개발자가 결정하지만 정적 변수는 재귀에 대해 작업할 때 반드시 유용하며 개발자에 의해 인식될 가치가 있다는 것을 언급해야 합니다.

기존 질문과 PHP 매뉴얼이 이 대부분을 잘 설명하고 있기 때문에 질문에 대한 완전한 답변을 게시하지는 않을 것입니다.

하지만 놓친 한 가지 주제는 슈퍼글로벌에 관한 것이었다.$_POST,$_GET,$_SESSION, 는 임의의수 이러한 변수는, 「」를 하지 않습니다.global★★★★★★ 。

예를 들어, 이 함수는 PHP 스크립트를 실행하는 사용자의 이름을 출력합니다.변수는 함수에서 문제없이 사용할 수 있습니다.

<?php
function test() {
    echo $_ENV["user"];
}

일반적으로 PHP에서는 "글로벌은 나쁘지만 슈퍼글로벌은 괜찮다"는 식으로 "글로벌은 나쁘지만 슈퍼글로벌은 괜찮다"는 규칙이 수정되어 있습니다(이 변수들은 모두 쓰기 가능하기 때문에 정말 형편없을 경우 의존성 주입을 피하기 위해 사용될 수 있습니다).

이러한 변수가 존재한다고 보증되는 것은 아닙니다.관리자는 의 디렉티브를 사용하여 이들 변수의 일부 또는 전부를 디세블로 할 수 있습니다.php.ini하지만 이것은 일반적인 행동이 아닙니다.


현재 슈퍼글로벌 목록:

  • $GLOBALS - 현 - - in in in in in 。
  • $_SERVER 및 - 서버 및 실행 환경 정보 - 서버 및 실행 환경 정보
  • $_GET값 - HTTP URL
  • $_POST값 - HTTP POST " " " " " :application/x-www-form-urlencoded ★★★★★★★★★★★★★★★★★」multipart/form-dataMIME 입 mime
  • $_FILES - POST:multipart/form-dataMIME 입 mime
  • $_COOKIE - 현재 요청으로 전달된 쿠키
  • $_SESSION에 된 세션
  • $_REQUEST - 아, 아, 아, 아, 아, 아, 아, 아.$_GET ★★★★★★★★★★★★★★★★★」$_POST, 에 따라서는.$_COOKIES내용은 의 지시에 따라 결정됩니다.php.ini.
  • $_ENV - 현재 스크립트의 환경 변수입니다.

언급URL : https://stackoverflow.com/questions/16959576/reference-what-is-variable-scope-which-variables-are-accessible-from-where-and

반응형