복붙노트

PHP의 전역 변수가 나쁜 습관으로 간주됩니까? 그렇다면 왜?

PHP

PHP의 전역 변수가 나쁜 습관으로 간주됩니까? 그렇다면 왜?

function foo () {
    global $var;
    // rest of code
}

내 작은 PHP 프로젝트에서 나는 일반적으로 절차적인 방법을 사용한다. 나는 일반적으로 시스템 구성을 포함하는 변수를 가지고 있으며 함수에서이 변수에 액세스 할 때는 전역 변수 $ var;를 사용합니다.

이 나쁜 습관인가?

해결법

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

    1.

    사람들이 다른 언어로 전역 변수에 관해 말할 때 그것은 PHP에서하는 것과 다른 것을 의미합니다. PHP에서 변수가 실제로 전역 적이 지 않기 때문입니다. 일반적인 PHP 프로그램의 범위는 하나의 HTTP 요청입니다. 세션 변수는 실제로 많은 "HTTP"요청을 포함하기 때문에 PHP "전역"변수보다 넓은 범위를가집니다.

    종종 (항상?) preg_replace_callback ()과 같은 메소드에서 멤버 함수를 다음과 같이 호출 할 수 있습니다.

    preg_replace_callback('!pattern!', array($obj, 'method'), $str);
    

    자세한 내용은 콜백을 참조하십시오.

    요점은 객체가 PHP에 고정되어 있고 어떤면에서는 다소 어색함을 유발한다는 것입니다.

    다른 언어의 표준이나 구문을 PHP에 적용하는 데 지나치게 신경 쓰지 마십시오. 또 다른 공통적 인 함정은 객체 모델을 모든 것에 덧붙여서 PHP를 순수 OOP 언어로 바꾸려고하는 것입니다.

    다른 말처럼 "전역 변수", 절차 코드, 특정 프레임 워크 및 OOP를 사용하는 것이 좋습니다. 문제를 해결하고, 작성해야하는 코드의 양을 줄이며, 유지 보수가 쉽고 이해하기 쉬워지기 때문입니다. 너해야 해.

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

    2.

    신중하게 사용하지 않으면 전역 변수로 인해 문제를 찾기가 더 어려워 질 수 있습니다. 예를 들어 PHP 스크립트를 요청하고 일부 함수에 존재하지 않는 배열의 색인에 액세스하려고한다는 경고 메시지가 표시된다고 가정 해 봅시다.

    액세스하려는 배열이 함수에 대해 로컬 인 경우 함수를 검사하여 실수를했는지 확인합니다. 함수에 대한 입력에 문제가있어서 함수가 호출되는 곳을 확인할 수 있습니다.

    그러나 해당 배열이 전역 변수 인 경우 전역 변수를 사용하는 모든 위치를 검사해야하며 그뿐만 아니라 전역 변수에 대한 참조에 액세스하는 순서를 알아야합니다.

    코드에 전역 변수가 있으면 해당 코드의 기능을 분리하기가 어렵습니다. 왜 기능을 분리하고 싶습니까? 그래서 당신은 그것을 테스트하고 그것을 다른 곳에서 재사용 할 수 있습니다. 테스트 할 필요가 없으며 재사용 할 필요가없는 코드가 있으면 전역 변수를 사용하는 것이 좋습니다.

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

    3.

    나는 cletus에 동의한다. 나는 두 가지를 추가 할 것이다 :

    친애하는, 님

  4. ==============================

    4.

    경험, 대학 학위, 소프트웨어 엔지니어링에 반대 할 수있는 사람은 누구입니까? 나 아니야. 객체 지향 단일 페이지 PHP 응용 프로그램을 개발할 때 네임 스페이스 충돌을 염려하지 않고 처음부터 전체를 빌드 할 수 있다는 것을 알았을 때 더 재미 있습니다. 처음부터 건물은 많은 사람들이 더 이상하지 않는 무언가입니다. 그들은 직업, 기한, 보너스 또는 관심을 가질 명성이 있습니다. 이러한 유형은 전역 변수를 사용하여 위험을 감수 할 수 없으므로 지분이 많은 사전 빌드 된 코드를 사용하는 경향이 있습니다.

    프로그램의 전역 영역에서만 사용되는 경우에도 전역 변수를 사용하는 것은 좋지 않을 수 있지만 재미 있고 뭔가 효과가 있도록하려는 사람들은 잊지 말자.

    이것이 전역 네임 스페이스에서 몇 가지 변수 (<10)를 사용한다는 것은 프로그램의 전역 영역에서만 사용된다는 의미입니다. 네, 예, MVC, 의존성 주입, 외부 코드, ㅋㅋㅋ, ㅋㅋㅋ, ㅋㅋㅋ. 그러나 네임 스페이스와 클래스에 99.99 %의 코드가 포함되어 있고 외부 코드가 샌드 박싱 된 경우 전역 변수를 사용하면 세상이 끝나지 않을 것입니다 (반복, 세계는 끝나지 않습니다).

    일반적으로 전역 변수를 사용하는 것은 나쁜 습관이라고 말하지 않습니다. 전역 변수 (플래그 및 기타)를 프로그램의 전역 영역 외부에서 사용하면 문제를 묻는 것이고 (장기적으로) 부적절하다고 생각할 수 있습니다. 왜냐하면 여러분은 자신의 상태를 쉽게 잃어 버릴 수 있기 때문입니다. 또한, 더 많이 배울수록 사용과 관련된 버그를 추적하는 "즐거움"을 경험하게 될 것이기 때문에 글로벌 변수에 덜 의존하게 될 것이라고 말하고 싶습니다. 이것만으로도 동일한 문제를 해결할 다른 방법을 찾도록 인센티브를줍니다. 우연히도 이것은 PHP 사람들이 네임 스페이스와 클래스 (정적 멤버 등)를 사용하는 방법을 배우는 방향으로 밀고가는 경향이 있습니다.

    컴퓨터 과학 분야는 광대합니다. 우리가 라벨을 붙이기 때문에 모든 사람이 무언가를하는 것을 두려워한다면, 레이블 뒤에있는 추론을 진정으로 이해하는 즐거움을 잃게됩니다.

    필요한 경우 전역 변수를 사용하십시오. 그러나 전역 변수를 사용하지 않고 문제를 해결할 수 있는지 확인하십시오. 충돌, 테스트 및 디버깅은 문제에 대한 설명뿐만 아니라 문제의 진정한 본질을 철저히 이해할 때 더욱 중요합니다.

  5. ==============================

    5.

    같이:

    global $my_global; 
    $my_global = 'Transport me between functions';
    Equals $GLOBALS['my_global']
    

    나쁜 연습 (Wordpress $ pagenow처럼) ... 흠

    이걸 고려하세요:

    $my-global = 'Transport me between functions';
    

    PHP 오류입니다. 그러나 :

    $GLOBALS['my-global'] = 'Transport me between functions';
    

    오류가 아닌 경우, hypens는 $ pagenow와 같은 "공통"사용자 선언 변수와 충돌하지 않습니다. 그리고 UPPERCASE를 사용하면 사용중인 슈퍼 글로벌을 나타내며 코드에서 쉽게 찾을 수 있고 파일에서 찾기를 사용하여 추적 할 수 있습니다.

    Im가 게으른 경우 다음과 같이 단일 솔루션에 대한 모든 클래스를 빌드하려면 하이픈을 사용합니다.

    $GLOBALS['PREFIX-MY-GLOBAL'] = 'Transport me ... ';
    

    그러나 더 넓은 사용의 경우, 배열로 하나의 전역 변수를 사용합니다 :

    $GLOBALS['PREFIX-MY-GLOBAL']['context-something'] = 'Transport me ... ';
    $GLOBALS['PREFIX-MY-GLOBAL']['context-something-else']['numbers'][] = 'Transport me ... ';
    

    후자는 나를 위해, "콜라 라이트"목표 또는 사용에 좋은 연습, 대신에 싱글 톤 클래스를 혼란스럽게하는 대신에 일부 데이터를 "캐시"합니다. 임이 틀리거나 뭔가 어리석은 짓을 한거라면 ...

  6. ==============================

    6.

    이 문제는 다음의 의사 코드로 설명 할 수 있습니다.

    function foo() {
         global $bob;
         $bob->doSomething();
    }
    

    첫 번째 질문은 분명한 것입니다.

    너 혼란 스럽니? 좋은. 당신은 왜 세계가 혼란스럽고 나쁜 습관을 생각 하는지를 배웠습니다. 이것이 진짜 프로그램이라면, 재미있는 부분은 $ bob의 모든 인스턴스를 추적하여 올바른 것을 찾을 수 있기를 바란다 ($ bob이 어디에서나 사용된다면 악화된다). 더 나쁜 것은, 다른 사람이 가서 $ bob을 정의한 경우 (또는 그 변수를 잊어 버리고 재사용 한 경우) 코드가 손상 될 수 있습니다 (위의 코드 예에서는 잘못된 객체가 있거나 전혀 객체가 없으면 치명적인 오류가 발생할 수 있음). 거의 모든 PHP 프로그램은 include ( 'file.php')와 같은 코드를 사용하기 때문에; 이와 같이 코드를 유지 관리하면 더 많은 파일을 추가할수록 기하 급수적으로 어려워집니다.

    지구본을 어떻게 피할 수 있습니까?

    전역을 피하는 가장 좋은 방법은 Dependency Injection이라는 철학입니다. 이것은 우리가 필요로하는 도구를 기능 또는 클래스에 전달하는 곳입니다.

    function foo(\Bar $bob) {
        $bob->doSomething();
    }
    

    이것은 이해하고 유지하는 것이 훨씬 쉽습니다. 호출자가 (우리가 알아야 할 것을 우리에게 알려주고 있다는 것을) 알기 때문에 $ bob이 설정된 곳을 추측 할 필요가 없습니다. 더 좋은 방법은 타입 선언을 사용하여 전달되는 것을 제한하는 것입니다. 그래서 우리는 $ bob이 Bar 클래스의 인스턴스이거나 Bar의 자식 인스턴스입니다. 즉,이 클래스의 메서드를 사용할 수 있음을 의미합니다. 표준 오토로더 (PHP 5.3부터 사용 가능)와 결합하여 이제 Bar가 정의 된 위치를 추적 할 수 있습니다. PHP 7.0 또는 이후 버전에는 확장 유형 선언이 포함되어 있으며 여기에는 int 또는 string과 같은 스칼라 유형도 사용할 수 있습니다.

  7. from https://stackoverflow.com/questions/1557787/are-global-variables-in-php-considered-bad-practice-if-so-why by cc-by-sa and MIT lisence