함수의 PHP 전역


100

global 키워드 의 유용성은 무엇입니까 ?

한 방법을 다른 방법보다 선호하는 이유가 있습니까?

  • 보안?
  • 공연?
  • 다른 건 없나요?

방법 1 :

function exempleConcat($str1, $str2)
{
  return $str1.$str2;
}

방법 2 :

function exempleConcat()
{
  global $str1, $str2;
  return $str1.$str2;
}

언제 사용하는 것이 합리적 global입니까?

나에게는 위험 해 보이지만 지식이 부족한 것일 수도 있습니다. 나는에 관심이 있어요 문서화 (예 : 코드, 문서에 링크 ...의 예에) 기술적 인 이유.

미리 감사드립니다!


하사품

이것은 주제에 대한 좋은 일반적인 질문입니다. I (@Gordon)는 추가 답변을 얻기 위해 현상금을 제공하고 있습니다. 귀하의 답변이 저와 일치하는지 또는 다른 관점을 제공하는지 여부는 중요하지 않습니다. global주제가 가끔 나오기 때문에 좋은 "표준"답변을 링크에 사용할 수 있습니다.


2
이 링크를보세요 : stackoverflow.com/questions/1557787 이 페이지의 오른쪽 하단에 관련 기사가 많이 있습니다
JohnP 2011 년

귀하의 질문에 대한 직접적인 대답은 아니지만 이 이전 SO 질문을 읽어보십시오 .
Ólafur Waage 2011 년

1
그래서 저는 전 세계적 키워드를 읽을 수 없습니다. 1) 여기에있는 이유. 2) 사람들이 왜 그것을 사용합니까?
Pascal Qyy 2011 년

@ G.Qyy 왜 거기에 goto? 사람들은 왜 그것을 사용합니까? 그들은 그것을 사용하지 않습니다 (적어도 희망합니다) : P
PeeHaa

작년 말 (12 월 14 일)에 누군가이 질문에 반대표를 던졌습니다. 부정적인 관점을 포함한 모든 관점이 흥미로운 이유를 알고 싶습니다. 이 경우 그 어느 때보 다! 그것에 대한 단서에 대해 매우 감사하겠습니다.
Pascal Qyy

답변:


158

글로벌은 악하다

이것은 global키워드뿐만 아니라 로컬 범위에서 전역 범위 (정적, 싱글 톤, 레지스트리, 상수)에 도달하는 다른 모든 것에 대해서도 마찬가지입니다 . 당신은 그것들을 사용하고 싶지 않습니다. 함수 호출은 외부에 의존 할 필요가 없습니다.

function fn()
{
    global $foo;              // never ever use that
    $a = SOME_CONSTANT        // do not use that
    $b = Foo::SOME_CONSTANT;  // do not use that unless self::
    $c = $GLOBALS['foo'];     // incl. any other superglobal ($_GET, …)
    $d = Foo::bar();          // any static call, incl. Singletons and Registries
}

이 모든 것이 코드를 외부에 의존하게 만듭니다. 즉, 이들 중 하나를 안정적으로 호출하기 전에 애플리케이션이있는 전체 글로벌 상태를 알아야합니다. 그 환경 없이는 기능이 존재할 수 없습니다.

슈퍼 글로벌을 사용하는 것은 명백한 결함이 아닐 수 있지만 명령 줄에서 코드를 호출하면 $_GET또는 $_POST. 코드가 이러한 입력에 의존하는 경우 웹 환경으로 제한됩니다. 요청을 객체로 추상화하고 대신 사용하십시오.

하드 코딩 된 클래스 이름 (정적, 상수)을 결합하는 경우 해당 클래스를 사용할 수 없으면 함수도 존재할 수 없습니다. 동일한 네임 스페이스의 클래스 인 경우에는 문제가되지 않지만 다른 네임 스페이스에서 혼합을 시작하면 엉망이됩니다.

재사용은 위의 모든 사항에 의해 심각하게 방해를받습니다. 단위 테스트도 마찬가지입니다 .

또한 전역 범위에 연결하면 함수 서명이 거짓말을합니다.

function fn()

아무것도 전달하지 않고 그 함수를 호출 할 수 있다고 주장하기 때문에 거짓말 쟁이입니다. 내가 배운 것은 함수 본체를 볼 때만 환경을 특정 상태로 설정해야한다는 것을 알게되었습니다.

함수를 실행하는 데 인수가 필요한 경우이를 명시 적으로 지정하고 전달합니다.

function fn($arg1, $arg2)
{
    // do sth with $arguments
}

서명에서 호출해야하는 것을 명확하게 전달합니다. 특정 상태에있는 것은 환경에 의존하지 않습니다. 당신은 할 필요가 없습니다

$arg1 = 'foo';
$arg2 = 'bar';
fn();

끌어들이는 (글로벌 키워드) 대 밀어 넣는 (인수)의 문제입니다. 의존성을 밀어 넣거나 주입 할 때 함수는 더 이상 외부에 의존하지 않습니다. 당신이 fn(1)할 때 당신은 어딘가에 1을 보유하는 변수를 가질 필요가 없습니다. 그러나 $one함수 내 에서 전역을 가져 오면 전역 범위에 연결되고 어딘가에 정의 된 변수가있을 것으로 예상합니다. 이 기능은 더 이상 독립적이지 않습니다.

더 나쁜 것은 함수 내에서 전역을 변경할 때 함수가 사방에 부작용이 있기 때문에 코드를 완전히 이해할 수 없게됩니다.

더 나은 예가 없으면

function fn()
{
    global $foo;
    echo $foo;     // side effect: echo'ing
    $foo = 'bar';  // side effect: changing
}

그리고 당신은

$foo = 'foo';
fn(); // prints foo
fn(); // prints bar <-- WTF!!

$foo이 세 줄에서 변경된 것을 볼 방법이 없습니다 . 동일한 인수를 사용하여 동일한 함수를 호출하면 갑자기 출력이 변경되거나 전역 상태의 값이 변경되는 이유는 무엇입니까? 함수는 정의 된 입력 Y에 대해 X를 수행해야합니다. 항상.

OOP는 캡슐화에 관한 것이고 전역 범위에 도달하면 캡슐화를 깨뜨리기 때문에 OOP를 사용할 때 더욱 심각해집니다. 프레임 워크에서 볼 수있는 이러한 모든 싱글 톤 및 레지스트리는 종속성 주입을 위해 제거해야하는 코드 냄새입니다. 코드를 분리하십시오.

더 많은 리소스 :


10
PHP는 왜 그런 것들을 구현합니까? 유틸리티가 있습니까? 많은 사람들이 매번 사용하는 PHP의 위험한 구현에 항상 놀랐습니다 ... 논리적 이유가 없다고 믿기가 어렵습니다!
Pascal Qyy 2011 년

5
나는 당신이 Globals를 더 크게 만들 수 있기를 바랍니다 .
Kermit 2013

3
와우, 드디어 누군가 글로벌이 왜 악한 지 잘 설명했습니다 ... 나는 항상 그들이 그렇게 들었다고 들었고 그 이유에 대한 매우 구체적인 예를 보았지만 이것은 일반적인 이유에 대한 정말 좋고 포괄적 인 설명입니다. +1
Wingblade 2013-08-27

나는 정말 늦었고 당신이 말하는 것을 이해하지만 mysqli 연결은 어떻습니까? 매번 매개 변수로 전달되어야하거나 글로벌 $ 링크 여야합니다. 당신의 눈에 허용?
Mave

2
상수를 제외하고는 맞습니다. 그들은 응용 프로그램의 "상태"를 나타내지 않으며 함수 내에서 참조하는 것이 좋습니다. 함수는 내부에서 상수를 사용하는 경우 "거짓말"하지 않습니다. 나는 프로그래머가 한때 외부에 대한 지식을 가졌다는 것을 의미한다는 데 동의하지만 상수가 무엇인지에 대한 매우 수용 가능한 트레이드 오프입니다. 또한 진지하게, 그것은 너무 큰 거래가 아닙니다.
Sebas

35

반대하는 한 가지 큰 이유 global는 기능이 다른 범위에 종속된다는 것을 의미합니다. 이것은 매우 빨리 지저분해질 것입니다.

$str1 = 'foo';
$str2 = 'bar';
$str3 = exampleConcat();

$str = exampleConcat('foo', 'bar');

함수가 작동하기 위해 호출 범위에서 요구 $str1되고 $str2설정된다는 것은 불필요한 종속성을 도입한다는 것을 의미합니다. 함수에서 이름을 바꾸지 않고는 더 이상이 범위에서 이러한 변수의 이름을 바꿀 수 없습니다. 따라서이 함수를 사용하는 다른 모든 범위에서도 이름을 바꿀 수 있습니다. 이것은 곧 변수 이름을 추적하려고 할 때 혼란스러워집니다.

global심지어 같은 글로벌 것을 포함에 대한 나쁜 패턴 $db자원. 이 됩니다 이름을 바꿀 때 일을 올 $db하지만 전체 응용 프로그램 이름에 의존하기 때문에, 할 수 없습니다.

중간 정도의 복잡한 응용 프로그램을 작성하려면 변수 범위를 제한하고 분리하는 것이 필수적 입니다.


1
죄송합니다. 왜 이름을 바꾸고 $db싶습니까? 모든 곳에서 전달되는 PDO입니다. 연결 정보를 별도로 업데이트 할 수 있는데 왜 변경 되나요?
Casey Dwayne

3
@kcd 언젠가 종속성 주입이 얼마나 큰지 깨닫고 앱을 재구성하고 싶습니까? 일일 때문에 당신은 몇 가지 다른 물건과 물건을 통합해야합니다 또한 글로벌 사용하여 $db변수를? 언젠가 단위 테스트를 발견하고이를 위해 한 번에 둘 이상의 데이터베이스 연결을 관리해야하기 때문에? 많은 이유가 있습니다.
deceze

35

글로벌은 피할 수 없습니다.

오래된 토론이지만 위에서 언급 한 답변에서 그리워서 몇 가지 생각을 추가하고 싶습니다. 이러한 대답은 글로벌이 너무 많은 것을 단순화하고 문제에 대한 해결책이 아닌 해결책을 제시합니다. 문제는 글로벌 변수와 글로벌 키워드를 사용하는 적절한 방법은 무엇입니까? 이를 위해 먼저 글로벌이 무엇인지 조사하고 설명해야합니다.

이 Zend 코드를 살펴보십시오. Zend가 잘못 작성되었다고 제안하지 않습니다.

class DecoratorPluginManager extends AbstractPluginManager
{
/**
 * Default set of decorators
 *
 * @var array
 */
protected $invokableClasses = array(
    'htmlcloud' => 'Zend\Tag\Cloud\Decorator\HtmlCloud',
    'htmltag'   => 'Zend\Tag\Cloud\Decorator\HtmlTag',
    'tag'       => 'Zend\Tag\Cloud\Decorator\HtmlTag',
   );

여기에는 보이지 않는 종속성이 많이 있습니다. 이러한 상수는 실제로 클래스입니다. 이 프레임 워크의 일부 페이지에서 require_once를 볼 수도 있습니다. Require_once는 전역 종속성이므로 외부 종속성을 생성합니다. 그것은 프레임 워크에서 불가피합니다. 의존하는 많은 외부 코드없이 DecoratorPluginManager와 같은 클래스를 어떻게 만들 수 있습니까? 많은 추가 기능 없이는 작동 할 수 없습니다. Zend 프레임 워크를 사용하여 인터페이스 구현을 변경 한 적이 있습니까? 인터페이스는 사실 글로벌입니다.

전 세계적으로 사용되는 또 다른 응용 프로그램은 Drupal입니다. 그들은 적절한 디자인에 대해 매우 염려하지만 다른 큰 프레임 워크와 마찬가지로 많은 외부 종속성을 가지고 있습니다. 이 페이지에서 글로벌을 살펴보십시오.

/**
 * @file
 * Initiates a browser-based installation of Drupal.
 */

/**
 * Root directory of Drupal installation.
 */
define('DRUPAL_ROOT', getcwd());

/**
 * Global flag to indicate that site is in installation mode.
 */
define('MAINTENANCE_MODE', 'install');

// Exit early if running an incompatible PHP version to avoid fatal errors.
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
  print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the     <a     href="http://drupal.org/requirements">system requirements</a> page for more     information.';
  exit;
}

// Start the installer.
require_once DRUPAL_ROOT . '/includes/install.core.inc';
install_drupal();

로그인 페이지에 대한 리디렉션을 작성한 적이 있습니까? 그것은 글로벌 가치를 변화시키고 있습니다. (그리고 당신은 내가 당신의 응용 프로그램의 나쁜 문서에 대한 좋은 반응이라고 생각하는 'WTF'를 말하는 것이 아닙니다.) 전역의 문제는 그들이 전역이라는 것이 아니라 의미있는 응용 프로그램을 갖기 위해 그것들이 필요하다는 것입니다. 문제는 전체 애플리케이션의 복잡성으로 인해 처리하기가 악몽이 될 수 있습니다. 세션은 전역이고, $ _POST는 전역이고, DRUPAL_ROOT는 전역이며, includes / install.core.inc '는 수정할 수없는 전역입니다. 그 기능이 제 역할을하도록하기 위해 필요한 기능 외에는 큰 세계가 있습니다.

Gordon의 대답은 틀 렸습니다. 왜냐하면 그는 함수의 독립성을 과대 평가하고 함수를 거짓말 쟁이라고 부르는 것이 상황을 지나치게 단순화하기 때문입니다. 함수는 거짓말을하지 않으며 그의 예제를 살펴보면 함수가 부적절하게 설계되었습니다. 그의 예제는 버그입니다. (덧붙여서 저는 코드를 분리해야한다는 결론에 동의합니다.) 속임수에 대한 대답은 실제로 상황에 대한 적절한 정의가 아닙니다. 함수는 항상 더 넓은 범위 내에서 작동하며 그의 예는 너무 단순합니다. 우리는 그 함수가 상수를 반환하기 때문에 완전히 쓸모 없다는 데 동의 할 것입니다. 그 기능은 어쨌든 나쁜 디자인입니다. 관행이 나쁘다는 것을 보여주고 싶다면 관련 예를 들어주세요. 응용 프로그램 전체에서 변수의 이름을 바꾸는 것은 좋은 IDE (또는 도구)가 있으면 큰 문제가 아닙니다. 문제는 함수와의 범위 차이가 아니라 변수의 범위에 관한 것입니다. 함수가 프로세스에서 역할을 수행 할 적절한 시간이 있으며 (즉, 처음에 생성 된 이유입니다) 적절한시기에 애플리케이션 전체의 기능에 영향을 미치므로 전역 변수에 대해서도 작업 할 수 있습니다. . xzyfer의 대답은 논증이없는 진술입니다. 절차 적 기능이나 OOP 디자인이있는 경우 전역은 응용 프로그램에있는 것과 같습니다. 글로벌 값을 변경하는 다음 두 가지 방법은 본질적으로 동일합니다. 따라서 전역 변수에 대해서도 작업합니다. xzyfer의 대답은 논증이없는 진술입니다. 절차 적 기능이나 OOP 디자인이있는 경우 전역은 응용 프로그램에있는 것과 같습니다. 글로벌 값을 변경하는 다음 두 가지 방법은 본질적으로 동일합니다. 따라서 전역 변수에 대해서도 작업합니다. xzyfer의 대답은 논증이없는 진술입니다. 절차 적 기능이나 OOP 디자인이있는 경우 전역은 응용 프로그램에있는 것과 같습니다. 글로벌 값을 변경하는 다음 두 가지 방법은 본질적으로 동일합니다.

function xzy($var){
 global $z;
 $z = $var;
}

function setZ($var){
 $this->z = $var;
}

두 경우 모두 특정 함수 내에서 변경된 $ z의 값입니다. 두 가지 프로그래밍 방법 모두 코드의 다른 여러 위치에서 이러한 변경을 수행 할 수 있습니다. global을 사용하면 어디에서나 $ z를 호출하여 변경할 수 있다고 말할 수 있습니다. 그래 넌 할수있어. 하지만 당신은? 그리고 부적합한 장소에서 작업을 할 때 버그라고 부르지 않습니까?

Bob Fanger는 xzyfer에 대해 언급합니다.

그렇다면 누구나 무엇이든 특히 '글로벌'이라는 키워드를 사용해야합니까? 아니요,하지만 모든 유형의 디자인과 마찬가지로 무엇이 의존하고 무엇이 의존하는지 분석하려고 노력하십시오. 그것이 언제 바뀌고 어떻게 바뀌는 지 알아보십시오. 전역 값 변경은 모든 요청 / 응답으로 변경 될 수있는 변수에서만 발생해야합니다. 즉, 기술 구현이 아니라 프로세스의 기능 흐름에 속하는 변수에만 해당됩니다. URL을 로그인 페이지로 리디렉션하는 것은 기술 구현에 대한 인터페이스에 사용되는 구현 클래스 인 프로세스의 기능 흐름에 속합니다. 애플리케이션의 다른 버전에서 후자를 변경할 수 있지만 모든 요청 / 응답에서 변경해서는 안됩니다.

globals 및 키워드 global로 작업하는 데 문제가있는 경우를 더 이해하기 위해 블로그에 대해 쓸 때 Wim de Bie에서 제공하는 다음 문장을 소개하겠습니다. 'Personal yes, private no'. 함수가 자체 기능을 위해 전역 변수의 값을 변경할 때 전역 변수와 버그의 사적인 사용을 호출 할 것입니다. 그러나 사용자를 로그인 페이지로 리디렉션하는 것과 같이 응용 프로그램 전체를 적절하게 처리하기 위해 전역 변수를 변경하면 정의상 나쁘지 않고 확실히 좋은 디자인이 아니라고 생각합니다. 안티 패턴.

Gordon, deceze 및 xzyfer의 답변을 되돌아 보면 모두 'private yes'(및 버그)를 예로 들어 있습니다. 그것이 그들이 글로벌 사용에 반대하는 이유입니다. 나도 할 것입니다. 그러나 그들은 '개인적 예, 비공개 아니오'와 함께 제공되지 않습니다.이 답변에서 여러 번했던 것과 같은 예입니다.


Drupal 코드 샘플은 전역을 사용하지 않고 상수를 사용합니다. 매우 중요한 차이점은 상수가 정의 된 후에는 다시 정의 할 수 없다는 것입니다. 또한 함수 xyzsetZ. 첫 번째는 전역 상태를 변경하고 두 번째는 클래스 메서드이며 호출 된 인스턴스의 상태 만 변경합니다.
Arjan 2014 년

@Arjen : Drupal 7.14에서 global 키워드를 검색하면 수백 개의 히트를 얻을 수 있습니다. 공개 세터의 오래된 문제입니다. 일단 공개 한 후에는 변경되는 위치를 제어 할 수 없습니다. 전혀 사용하지 않거나 비공개로 선언하는 것이 좋으므로 나중에 추가 할 수 없습니다.
Loek Bergman 2014

@Arjan : 귀하의 이름 철자 오류로 인해 귀하에 대한 내 응답에 대한 알림을받지 못했습니다. 이제 당신은 할 것입니다. :-)
Loek Bergman 2014

@LoekBergman : globaldrupal 7.26 (최신 버전) 의 단어 에 대해 약 400 개의 히트 가 있으며, 그중 일부는 주석에 포함되어 있으며 다른 일부는 수년 동안 수정되지 않은 코드로 나타납니다. 나는 확실히 그들이 사용하지 않습니다 희망 global의에서 드루팔 (8)
Arjan

@LoekBergman 세터와 게터를 사용하십시오. 설정하는 데 많은 시간이 걸리지 않으며 다른 사용자가 코드를 사용하고 클래스를 확장하여 더 많은 제어 권한을 가질 수 있습니다. 매개 변수를 공개하면 그게 전부입니다. 나중에 숨길 수있는 옵션이 없습니다.
mAsT3RpEE

15

간단히 말해서 global현대 PHP 코드 IMHO 에는 이유가 거의 없으며 결코 좋은 이유가 없습니다 . 특히 PHP 5를 사용하는 경우 특히 객체 지향 코드를 개발하는 경우 더욱 그렇습니다.

전역은 코드의 유지 관리 성, 가독성 및 테스트 가능성에 부정적인 영향을 미칩니다. 의 많은 용도는 global종속성 주입으로 대체하거나 단순히 전역 개체를 매개 변수로 전달해야합니다.

function getCustomer($db, $id) {
    $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
    return $row;
}

10

PHP의 함수 내에서 전역 키워드를 사용하는 것을 망설이지 마십시오. 특히 세계인이 어떻게 '악한 지'라고 외치며 외치는 사람들을 받아들이지 마십시오.

첫째, 사용하는 것은 상황과 문제에 전적으로 의존하고 코딩에서 아무것도 할 수있는 해결책 / 방법이 없기 때문입니다. '악'과 같은 정의 할 수없는, 주관적인, 종교적 형용사의 오류를 방정식에 완전히 제쳐두십시오.

지목 사항 :

Wordpress와 그 생태계는 기능에 글로벌 키워드를 사용합니다. 코드 OOP이거나 OOP가 아닙니다.

그리고 현재 Wordpress는 기본적으로 인터넷의 18.9 %이며 Reuters에서 Sony, NYT, CNN에 이르기까지 수많은 거대 기업의 거대한 메가 사이트 / 앱을 운영하고 있습니다.

그리고 그것은 잘합니다.

함수 내에서 글로벌 키워드를 사용하면 Wordpress가 거대한 생태계에서 일어날 수있는 엄청난 팽창으로부터 해방됩니다. 모든 함수가 다른 플러그인, 코어 및 리턴에서 필요한 변수를 요청 / 전달한다고 상상해보십시오. 플러그인 상호 의존성이 추가되어 변수의 악몽이나 변수로 전달되는 배열의 악몽으로 끝날 것입니다. 추적 할 지옥, 디버그 할 지옥, 개발할 지옥. 코드 팽창과 변수 팽창으로 인해 엄청나게 방대한 메모리 사용량. 쓰기도 더 어렵습니다.

Wordpress, 생태계, 관행 및 그 부분에서 일어나는 일을 비판하는 사람들이있을 수 있습니다.

이 생태계는 대략 전체 인터넷의 거의 20 %를 차지하기 때문에 의미가 없습니다. 분명히, 그것은 일을하고, 그 일을하는 등의 일을합니다. 이는 global 키워드에 대해서도 동일 함을 의미합니다.

또 다른 좋은 예는 "iframes are evil"근본주의입니다. 10 년 전에는 iframe을 사용하는 것이 이단이었습니다. 그리고 수천 명의 사람들이 인터넷을 통해 그들을 반대하는 설교를했습니다. 그런 다음 페이스 북이 온 다음 소셜이됩니다. 이제 iframe은 '좋아요'상자에서 인증에 이르기까지 모든 곳에 있습니다. 정당하거나 부당하게 여전히 입을 다물지 않은 사람들이 있습니다. 그러나 여러분은 그러한 의견에도 불구하고 삶은 계속되고 있으며, 10 년 전에 iframe에 대해 설교했던 사람들조차도 이제는 한마디도하지 않고 다양한 소셜 앱을 조직의 자체 애플리케이션에 통합하기 위해이를 사용해야합니다.

......

Coder Fundamentalism은 아주 아주 나쁜 것입니다. 우리 중 소수는 정보 기술의 끊임없는 변화와 경쟁, 시간, 예산 및 기타 고려 사항과 관련하여 초래하는 압력을 견딜 수있는 충분한 영향력을 가진 견고한 모 놀리 식 회사에서 편안한 직업으로 은총을받을 수 있습니다. 근본주의와 인식 된 '악'또는 '상품'에 대한 엄격한 고수. 거주자가 어리더라도 노년기를 연상시키는 편안한 자세입니다.

그러나 대다수의 경우 IT 세계는 개방적이고 실용적이어야하는 끊임없이 변화하는 세계입니다. 근본주의의 여지가 없습니다. 정보 기술의 최전선에서 '악'과 같은 터무니없는 키워드를 제쳐두십시오.

단기, 중기 및 장기 미래에 대한 적절한 고려 사항과 함께 문제에 가장 적합한 것을 사용하십시오. 특정 코더 하위 집합 중에서 이데올로기 적 적대감이 만연하기 때문에 기능이나 접근 방식을 사용하는 것을 주저하지 마십시오.

그들은 당신의 일을하지 않을 것입니다. 당신은 할 것입니다. 상황에 따라 행동하십시오.


3
반 근본주의의 경우 +1입니다.하지만 "많은 사람들이 그것을 사용합니다. / 작동합니다."라고 말하는 것은 단지 "인수 광고 포 퓰럼", 기본적인 궤변입니다. 대다수의 사람들이 자신이 옳다는 것을 증명하지 못한다는 사실은 생각하거나 행동합니다! 군중 속에서 위험이 나타나면 대다수의 사람들이 어리석은 일을하고 어떤 사람들은 다른 사람들에게 밟혀 죽을 것입니다. 5 살짜리 소녀의 얼굴에 발을 올려 놓는 것이 맞습니까? 나는 그렇게 생각하지 않는다…
Pascal Qyy 2014 년

1
물론 무엇인가를하는 대다수는 그 자체로 아무것도 검증하지 않습니다. 그러나 사례는 소프트웨어입니다. 그리고 대다수가 그것을하고 있고,이 사람들이 만든 앱과 서비스의 대부분이 잘 유지되고 있다면 (다른 많은 사람들에게 워드 프레스) 사용할 수 있음을 의미합니다.
unity100 2014 년

7

나는 모든 사람들이 글로벌의 부정적인 측면에 대해 꽤 많이 설명했다고 생각합니다. 그래서 나는 글로벌의 적절한 사용을위한 지침뿐만 아니라 긍정적 인 것들을 추가 할 것입니다.

  1. 글로벌의 주요 목적은 기능간에 정보를 공유하는 것이 었습니다. 클래스와 같은 것이 없었을 때 PHP 코드는 여러 기능으로 구성되었습니다. 때로는 기능간에 정보를 공유해야합니다. 일반적으로 전역 데이터를 전역으로 만들어 데이터가 손상 될 위험이있는이 작업을 수행하는 데 사용되었습니다.

    이제 행운을 빕니다 멍청이가 의존성 주입에 대한 코멘트를 시작하기 전에 예제와 같은 함수의 사용자가 함수의 get_post(1)모든 의존성을 어떻게 알 수 있는지 물어보고 싶습니다 . 또한 종속성은
    버전 및 서버 마다 다를 수 있습니다 . 의존성 주입의 주된 문제는 의존성을 미리 알아야한다는 것입니다. 이것이 불가능하거나 원치 않는 전역 변수가이 목표를 달성하는 유일한 방법 인 상황에서.

    클래스 생성으로 인해 이제 공통 함수를 쉽게 클래스로 그룹화하고 데이터를 공유 할 수 있습니다. 중재자와 같은 구현을 통해 관련이없는 개체도 정보를 공유 할 수 있습니다. 더 이상 필요하지 않습니다.

  2. 전역에 대한 또 다른 용도는 구성 목적입니다. 대부분 자동 로더가로드되기 전, 데이터베이스 연결이 이루어지기 전 스크립트 시작 부분에 있습니다.

    리소스를로드하는 동안 전역을 사용하여 데이터를 구성 할 수 있습니다 (즉, 라이브러리 파일이있는 위치에서 사용할 데이터베이스, 서버의 URL 등). 이를 수행하는 가장 좋은 방법은 define()이러한 값이 자주 변경되지 않고 구성 파일에 쉽게 배치 될 수 있으므로 함수 를 사용하는 것입니다 .

  3. 전역의 최종 용도는 공통 데이터 (예 : CRLF, IMAGE_DIR, IMAGE_DIR_URL), 사람이 읽을 수있는 상태 플래그 (예 : ITERATOR_IS_RECURSIVE)를 보유하는 것입니다. 여기서 전역은 응용 프로그램 전체에서 사용되는 정보를 저장하는 데 사용되어 변경 될 수 있고 이러한 변경 사항이 응용 프로그램 전체에 표시되도록합니다.

  4. 싱글 톤 패턴은 객체의 각 인스턴스가 메모리를 차지할 때 php4 동안 PHP에서 인기를 얻었습니다. 싱글 톤은 하나의 객체 인스턴스 만 생성되도록 허용함으로써 램을 절약하는 데 도움이되었습니다. 참조 이전에 의존성 주입조차도 나쁜 생각이었을 것입니다.

    PHP 5.4 이상에서 객체의 새로운 PHP 구현은 이러한 문제의 대부분을 처리하여 더 이상 패널티없이 객체를 안전하게 전달할 수 있습니다. 더 이상 필요하지 않습니다.

    싱글 톤의 또 다른 용도는 객체의 인스턴스가 한 번에 하나만 존재해야하는 특수 인스턴스입니다. 해당 인스턴스는 스크립트 실행 전 / 후에 존재할 수 있으며 해당 객체는 다른 스크립트 / 서버 / 언어 등간에 공유됩니다. 여기서 싱글 톤 패턴은 문제를 해결합니다. 솔루션을 아주 잘.

따라서 결론적으로 1, 2 또는 3 위에 있다면 글로벌을 사용하는 것이 합리적입니다. 그러나 다른 상황에서는 방법 1을 사용해야합니다.

전역을 사용해야하는 다른 인스턴스를 자유롭게 업데이트하십시오.


6

global 키워드를 사용하여 concat 함수를 만드는 것은 의미가 없습니다.

데이터베이스 개체와 같은 전역 변수에 액세스하는 데 사용됩니다.

예:

function getCustomer($id) {
  global $db;
  $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
  return $row;
}

Singleton 패턴 의 변형으로 사용할 수 있습니다.


"말도 안 돼"-실제로 그렇습니다 : 예는 OOP를 사용하지 않고 조회 테이블을 구현하는 것입니다.
Nir Alfasi 2012 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.