2017-01-31 14 views
1

내가 작업하고있는 프로젝트에서는 시스템의 모든 곳에서 사용할 수있는 이벤트 관리자 (읽기 전용) 구성 관리자 및 플러그인 관리자를 비롯한 일부 개체가 있어야합니다.PHP에서 어디서나 객체를 사용할 수있는 가장 좋은 방법은 무엇입니까?

"C++ 배경을 가진 사람이"전역 변수가 필요하면 무언가 잘못했을 가능성이 높습니다 "라고 친절하게 지적 할 때까지 전역 변수를 사용하고있었습니다.
그는 그것을 필요로하는 모든 기능에 전달되는 상태 객체를 사용할 것을 제안했습니다.
그래서 내가 그랬어 :

$state = new State(); 
$state->register('eventManager' , new EventManager()); 
$state->register('configManager', new ConfigManager()); 
$state->register('cacheManager' , new CacheManager()); 
$state->register('pluginManager', new PluginManager()); 

$state->get('pluginManager')->initialize($state); 

좀 더 상태 기반 언어에서이 방법의 혜택을 볼 수 있지만, 그것은 상태가 손실 PHP, 같은 (? 대부분) 상태 비 언어 나에게 가지 무의미한 것 같다 페이지로드가 완료되면

상태 개체를 PHP와 같은 (대부분) 상태 비 저장 언어로 전달하면 어떤 이점이 있습니까?이 방법은 다른 접근 방식 (즉, 전역 기반 시스템)보다 이점을 갖고 있으며 더 좋은 방법이 있습니까? 이 작업을 수행하는

+0

많은 좋은 질문들은 전문적인 경험을 토대로 어느 정도의 의견을 제시하지만,이 질문에 대한 대답은 사실, 참고 문헌 또는 특정 전문 지식보다는 의견을 기반으로하는 경향이 있습니다. 일반적으로 문제를 해결하기위한 개발 포럼 (예 : [quora] (http://www.quora.com/Computer-Programming))을 찾고 싶을 수 있습니다. 그런 다음/특정 코딩 문제가있는 경우 StackOverflow로 돌아와서 도와 드리겠습니다. –

+2

당신이 원하는 것은 * dependency injection *이고, 당신의 "state object"는 여기 의존성 주입 컨테이너에서의 첫번째 찌르기 같은 것이다. 여기에 상태가 있는지 여부에 관계없이 모든 것이 코드 관리 *에 관한 것입니다. 그리고 그것은 모든 언어에서 유용합니다. – deceze

+2

또한 PHP는 "stateless"가 아닙니다. 웹 서버에서 주로 stateless 요청을 처리하는 데 사용됩니다. 대신 매우 "상태있는"방법으로 쉽게 사용할 수 있습니다. – deceze

답변

2

제안하는 레지스트리는 여전히 전역 변수입니다. 전역 변수에 액세스하려는 경우 (전역 변수 일지라도 객체 일지라도), 잘못된 결과가 발생합니다.

적절한 응용 프로그램은 글로벌 상태가 역할을하는 단계에서만 사용할 수 있습니다. 부트 스트랩 할 때. 스크립트를 시작하는 요청은 전역 적이며 요청과 함께 전송 된 모든 요청 데이터는 전역이며 응용 프로그램에 영향을 미치고 파일이나 다른 적절한 저장소에 저장되는 구성은 전역 적입니다.

첫 번째 단계는 응용 프로그램을 구성하는 모든 부분을 함께 묶는 일부 종속성 주입을 초기화해야합니다. 요청 처리가 요청에 응답하기 위해 코드의 어느 부분을 호출해야하는지 결정할 때 해당 객체 그래프가 필요할 때 생성됩니다.

일반적으로이 결정은 요청을 처리하는 프레임 워크 내에서 이루어지며 종속성 삽입도 프레임 워크를 통해 수행됩니다. 자신의 코드는 조작에 필요한 값이나 필요한 다른 오브젝트만을 허용합니다.

예를 들어 코드에 데이터베이스가 필요한 경우 데이터베이스 개체가 데이터베이스의 URL 및 자격 증명을 허용하도록 구성한 다음 해당 데이터베이스 개체를 수락하도록 독자 개체를 구성합니다.

하나의 데이터베이스 객체 만 만들거나 여러 객체를 만들려면 종속성 삽입 작업이 필요합니다. 구식의 "싱글 톤 반 패턴"은 많은 결점이 있기 때문에 사용할 필요가 없습니다.

따라서이 시나리오에서는 종속성 삽입 부분에 한 번만 생성되고 필요한 경우 주입되는 개체가 있습니다.이러한 객체는 한 번만 생성되도록 강요하지 않으며 전역 적으로 액세스 가능한 변수 내에 저장되지 않습니다. 그러나 뭔가 전역 변수에 살고있다,하지만 이것은 주요 프레임 워크 개체와 아마도 의존성 주입 컨테이너 일 뿐이며 전역 변수로 남아있는 코드와 절대 공유되지 않으므로 전혀 해롭지 않습니다.

+0

이 경우 프레임 워크가 될 것입니다. 코드에서 명확하지는 않지만 전역 변수 atm으로 $ state에 액세스하지 않고 마지막 행처럼 매개 변수로 전달합니다. 의존성 주입에 대해 조금 읽었을 때, 특정 함수에 많은 매개 변수가 있다는 뜻이 아니겠습니까? 나는. 종속성이있는 다른 함수를 호출하는 함수는 그와 같은 종속성을 얻습니다. 맞습니까? 아주 지저분해질까요? – SharkWipf

+1

@SharkWipf - 아주 잘 할 수 있습니다. 질문에 대한 하나의 해결책은 없습니다. 때로는 특정 클래스에는 싱글 톤과 같은 간단한 솔루션 만 필요합니다. 다른 때에는 Sven의 제안과 같은 해결책이 더 적절합니다. 오늘날의 프레임 워크의 대부분은 부팅에 대한 자신의 말과 의견 세트와 함께이 정확한 작업을 수행하는 방법에 대한 자신의 "맛"을 제공합니다. –

+0

사용이 끝나고 새로운 답변이 들어오지 않는 것에 가장 가깝기 때문에 이것을 승인 된 것으로 표시합니다. – SharkWipf

2

한 가지 방법은 싱글 함께 :

class ConfigManager { 
    private static $instance = NULL; 

    public static function getInstance(){ 
     if(self::$instance === NULL) { 
      self::$instance = new ConfigManager(); 
     } 

     return self::$instance; 
    } 

    private function __construct(){ 
     // Notice that this is private - only getInstance() can call this. 
    } 
} 

// When you need it: 
$config = ConfigManager::getInstance(); 

가 당신이 요구하는지 무엇을 수행하는 방법에 대한 여러 가지 의견이 있습니다 - 그리고 나 자신이 싱글은 항상 생각하지 않는다 이렇게하는 가장 좋은 방법입니다. 실제로 사용 사례에 따라 다릅니다.

하지만 싱글 톤은 모든 인스턴스에 액세스 할 수 있어야하는 인스턴스의 클래스에 대한 하나의 공통 패턴입니다.

+0

정말요? 싱글턴? 그 중 두 가지 의견 만 있습니다. 하나는이 패턴이 [ "Gang of Four"book (https://en.wikipedia.org/wiki/Design_Patterns)에 설명되어 있으므로 좋다고 말합니다. 소프트웨어 패턴에 대한 지식에 대해 물었을 때 인터뷰에서 추정 된 나쁜 개발자의 대답). 다른 사람은 그 책의 원저자가 나중에 그들의 의견을 뒤집었고 그것을 피해야하는 반 패턴이라고 선언했다. – Sven

+0

@Sven - 질문은 "PHP에서 모든 곳에서 객체를 사용할 수있게하는 가장 좋은 방법은 무엇입니까?" 이것은 많은 유효한 답변 중 하나입니다. 나는 당신과 동의하지 않는다. - 나는 싱글 톤이 항상 이것을하는 가장 좋은 방법이라고 생각하지 않는다는 것도 언급하지 않았다? 소규모 응용 프로그램에서 간단한 전역 구성 클래스와 같은 것을 사용하는 것이 가장 좋은 방법 일 수 있습니다. 범위가 더 큰 것, 아마도 그렇지 않은 것 같습니다. 당신이 그렇게 생각한다면 대체 방법을 게시 할 수 있습니다. :-) –