2009-07-18 2 views
6

저는 현재 블로그 시스템을 만들고 있는데 앞으로는 완전한 CMS로 바뀌기를 바랍니다.PHP 전역 객체 사용을 피하는 방법은 무엇입니까?

전역 액세스 (mysqli 데이터베이스 연결 및 사용자 로그인 여부를 확인하는 사용자 정의 클래스)에 유용한 두 가지 클래스/개체가 있습니다.

전역 개체를 사용하지 않고이 작업을 수행 할 수있는 방법을 찾고 있습니다. 가능한 경우 개체를 호출 할 때마다 각 기능에 개체를 전달하지 마십시오.

답변

13

개체를 정적으로 만들면 아무 데나 액세스 할 수 있습니다. 예 :

myClass::myFunction(); 

스크립트의 어느 위치에서나 작동합니다. 그러나 정적 클래스를 읽을 수도 있고, Singleton 클래스를 사용하여 어디서나 사용할 수있는 정적 객체 안에 일반 클래스를 만들 수도 있습니다.

는 확장

나는 당신이 일을하려고하는 것은 내 DB 클래스와 함께 할 것과 매우 유사하다 생각합니다. 당신이 $ 객체 = myClass가 :: get_connection()를 사용하여 연결을 얻을 후 어떻게됩니까

class myClass 
{ 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     return self::$class; 
    } 
    // Then create regular class functions. 
} 

는, 당신은 정기적으로 어떤 기능을 할 수있을 것입니다. 정적 선언, 당신은 단지 get_connection를 호출하고 반환 값을 변수에 할당해야 그렇게되면

$object = myClass::get_connection(); 
$object->runClass(); 

을 확장. 그런 다음 나머지 함수는 $ class = new myClass를 사용하여 호출 한 클래스와 동일한 동작을 할 수 있습니다 (이는 우리가 수행했기 때문입니다). 클래스 변수를 정적 클래스에 저장하면됩니다. 당신은 이미 당신이 블로그 시스템을 참조하는 일부 개체가있는 경우가 $blog->db()$blog->auth()이든 뭐든있어 있도록

class myClass 
{ 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     return self::$class; 
    } 
    // Then create regular class functions. 
    public function is_logged_in() 
    { 
     // This will work 
     $this->test = "Hi"; 
     echo $this->test; 
    } 
} 

$object = myClass::get_connection(); 
$object->is_logged_in(); 
+0

안녕하세요, 답변 주셔서 감사합니다. 정적 클래스에 변수를 저장할 수 있습니까? 즉, 사용자가 로그인했는지 확인하기 위해 함수를 호출 한 다음이 변수를 페이지에서 몇 번 뒤에 액세스 할 수 있습니까? –

+2

예, 정적 클래스의 경우 변수 $ class를 선언 할 때와 동일한 작업을 수행합니다. 유일한 것은 당신이 사용하는 모든 변수를 선언해야한다는 것입니다. –

+1

하지만, 내가 준 코드는 정규 수업을 잘 사용하도록 허용합니다. 정적 인 부분은 전역 화하는 것이 아니라 단순히 클래스를 제공합니다. 조금 더 보여주기 위해 편집하겠습니다. –

1

글쎄, 당신은, 그에 이러한 개체를 구성 할 수 있습니다.

+0

할 수는 있지만 개체도 블로그 클래스 외부에서 액세스해야합니다. –

8

현재 전역 개체를 생성자에 전달할 수 있습니다.

<?php 
    class Foo { 
    protected $m_db; 
    function __construct($a_db) { 
     $this->m_db = $a_db; 
    } 
    } 
?> 
3

최근에 우리 회사의 CMS의 두 번째 버전을 준비하기 위해 프레임 워크를 개선했습니다. I undid 정상적인 개체로 교체하기 위해 내가 만든 물건이 엄청나게 큽니다. 그렇게하면서, 나는 코어 파일을 거치고 해킹하는 데 의존했던 엄청난 유연성을 창출했다. 유일한 대안은 저수준 핵심 기능에만 관련된 전역 함수 일 때 정적 구조 만 사용합니다.

내 bootstrap.php 파일 몇 줄을 보여 드리겠습니다. (모든 요청은 해당 파일을 통해 전송되지만, 모든 파일의 맨 위에 포함하여 동일한 결과를 얻을 수 있습니다) 내 말은. 이것은 당신의 상황에서 당신이 사용하는 것의 꽤 무거운 버전이지만, 그 아이디어가 도움이되기를 바랍니다. (이것은 모두 약간 수정되었습니다.) 당신이 볼 수 있듯이, 내가 그들에게이 "글로벌"필수품에 대한 액세스 권한을 부여하는 다른 객체 생성자의 인수로 제공 할 수 있습니다 내 응용 프로그램 객체를 생성하기위한 옵션의 모든 종류가

//bootstrap.php 

... 

// CONSTRUCT APPLICATION 

{  
    $Database = new Databases\Mysql(
     Constant::get('DATABASE_HOST'), 
     Constant::get('DATABASE_USER'), 
     Constant::get('DATABASE_PASSWORD'), 
     Constant::get('DATABASE_SCHEMA') 
    ); 

    $Registry  = new Collections\Registry; 
    $Loader  = new Loaders\Base; 
    $Debugger  = new Debuggers\Dummy; // Debuggers\Console to log debugging info to JavaScript console 

    $Application = new Applications\Base($Database, $Registry, $Loader, $Debugger); 
} 

... 

.

데이터베이스 개체 자체적으로 설명이 필요합니다. 레지스트리 객체는 응용 프로그램의 다른 위치에 액세스하려는 객체의 컨테이너 역할을합니다. 로더는 템플릿 파일과 같은 다른 리소스를로드하는 유틸리티 역할을합니다. 그리고 디버거는 디버그 출력을 처리합니다.

예를 들어, 인스턴스화 한 데이터베이스 클래스를 변경할 수 있으며, SQLite 데이터베이스에 연결할 수 있습니다. 디버거의 클래스를 변경할 수 있습니다 (언급 한대로) 이제 모든 디버그 정보가 자바 스크립트 콘솔에 기록됩니다.

이제 문제가 해결되었습니다. 다른 개체에이 모든 것에 대한 액세스 권한을 어떻게 부여합니까? 그것을 생성자에 인수로 전달하기 만하면됩니다.

뿐만 아니라 라우터 (또는 내가 구성한 개체)도 유연합니다. 이제 응용 프로그램 객체를 다르게 인스턴스화 할 수 있으며 라우터는 그에 따라 다르게 동작합니다.

관련 문제