2010-07-26 4 views
2

다른 클래스 (예 : 데이터베이스, 유틸리티, 구성)가 모두 하나의 중앙 Main 클래스를 구성하는 데 사용되는 스크립트를 만들려고합니다. 나는 그들의 체인을 확장 시도 :

홈페이지 -> 유틸리티 -> 데이터베이스 -> 구성

하지만 그들은 다음과 같이 호출 할 수 있도록 나는 다른 부분을 설정하는 방법 :

<?php 

    $this->db->select("WAFFLES"); 
    echo($this->config->app_path); 

?> 

답변

1

class Main{ 

    private $db = NULL; 
    private $config = NULL; 

    $this->db = new Database; 
    $this->config = new Config; 

} 

:

당신처럼 자신의 메인 클래스에 변수로 각각의 새로운 객체를 선언 할 필요가

나는 전문적인 코더가 아니지만 나는 이것보다 나은 접근법을 고려할 것이다. 이러한 종류의 객체 처리로 인해 부풀어 오른 주 클래스가 발생할 수 있으며 최악의 경우 성능 문제가 발생할 수 있습니다.

include 'db.php'; // include db class 
include 'config.php'; // include config class 

class main{ 
    public $db = NULL; 
    public $config = NULL; 

    function __construct() { 
    $this->db = new db; 
    $this->config = new config; 
    } 

} 
0

샘플 프로토 타입
class Foo extends Base { 

    public function bar() { 
    $this->var1->someOpertaion(); 
    } 
} 
3

당신은 그런 다음 클래스는 기본 클래스를 확장하고 데이터

에 액세스 할 수 있습니다

class Base { 

$var1, var2; 

public function __construct() { 
    $this->var1 = new DB(); 
    $this->var2 = new Config(); 
    .... 
} 
} 

초기화 기본을 수행하는 글로벌 클래스를 만들 수 있습니다 : 여기

0

필요한 모든 인스턴스가있는 복합 개체 만들기 durin g 코드 실행은 자원 낭비입니다. 필요한 경우에만 인스턴스를 작성하려고합니다. 이것을 달성하는 한 가지 방법은 클래스에 매직 __get 방법을 추가하는 것입니다 :

public function __get($name) { 
    // if self::$instances (or main) contains instance of $name, return instance 
    // else if class_exists $name, create, store and return instance 
    // else throw exception 
} 

그러나 그렇다하더라도, 기회는 당신이 God Object을 만드는 마법 방법은 정기적으로 접근보다 다소 느린이다. 이 방법으로 인스턴스를 작성해야한다면 Symfony Dependency Injection Container을 보거나 Registry을 구현하십시오.

1

1) 알 수없는 속성을 가져올 때 함수를 호출하는 마법의 방법을 사용) 클래스

2로드 __autoload 또는 spl_autoload_register를 사용합니다. 다음 예제는 __get 및 동적 사용 초기화 방법을 사용하는 방법을 보여줍니다.

//use __autoload to load db and config class when they are called. 
class db{ 
    function lol(){ 
    echo 'Hello from db->lol() <br />'; 
    } 
} 
class config{ 
    function lol(){ 
    echo 'Hello from config->lol() <br />'; 
    } 
} 


//Manager class to use with classes where you want to access other object trough $this 
class Manager{ 
    private $_instances=array(); 
    function __get($name){ 
    //if instance does not exists, create one 
    if (!isset($this->_instances[$name])){ 
     $this->_instances[$name]=new $name(); 
    } 

    //return instance 
    return $this->_instances[$name];  
    } 

} 

class Some extends Manager{ 
    function f1(){ 
    $this->db->lol(); 
    $this->config->lol(); 
    } 
} 

$some=new Some(); 
$some->f1(); //echoes 'Hello from db->lol()' and 'Hello from config->lol()' 

그러나 글로벌 클래스 인스턴스에 액세스하는 나는 다음과 같은 방법을 사용하여 선호 : 를 사용하여 싱글 톤 패턴을 글로벌 수준의 트로프 GloballClass에 액세스 할 수 :: 나는()와 글로벌 클래스가 정의되지 않은 경우 사용 자동로드가 클래스를로드 할 수는.

class db extends mysqli{ 
    private static $_i; 
    //Access to singleton instance 
    public static function i() {  
    return (self::$_i instanceof self)?self::$_i:self::$_i = new self(); 
    } 

    //class functions 
    function q($q){ 
    echo 'Hello from db->q()'; 
    } 
} 

class config{ 
    private static $_i; 
    //Access to singleton instance 
    public static function i() {  
    return (self::$_i instanceof self)?self::$_i:self::$_i = new self(); 
    } 

    //class functions 
    function somefunction(){ 
    echo 'Hello from config->somefunction()'; 
    } 
} 


db::i()->q('SELECT * FROM users'); 
config::i()->somefunction(); 

다음 고든 코멘트 영감 솔루션입니다 : 그것은 글로벌 클래스의 인스턴스를 정의하는 GlobalClassFactory 클래스를 사용합니다.

class db{ 
    function lol(){ 
    echo 'Hello from db->lol() <br />'; 
    } 
} 
class config{ 
    function lol(){ 
    echo 'Hello from config->lol() <br />'; 
    } 
} 

class GlobalClassFactory{ 
    private static $_classes=array(); 
    public static function getInstance($name){ 
    if (!isset(self::$_classes[$name])){ 
     self::$_classes[$name]=new $name(); 
    } 
    return self::$_classes[$name]; 
    } 
} 

class Base{ 
    function __get($name){ 
    return GlobalClassFactory::getInstance($name); 
    } 
} 

class Some extends Base{ 
    function f1(){ 
    $this->db->lol(); 
    $this->config->lol(); 
    } 
} 

$some=new Some(); 
$some->f1(); 
+0

일반적인 Base 클래스의 서브 클래 싱은 거의 항상 나쁜 생각입니다. 당신은'Some' * is-a *'Manager'라는 관계를 만들고 있습니다. 실제로는 그렇지 않습니다.또한 인스턴스를 객체 인스턴스로 저장하는 경우 Manager를 확장하는 모든 클래스는 자체 인스턴스 만 별도로 만듭니다. db 및 config의 경우에는 필요하지 않을 수 있습니다. 싱글 톤은 이것을 완화 할 수 있지만 싱글 톤을'new'로 인스턴스화 할 수 없으므로'__get'의 코드는 더 이상 작동하지 않습니다. 그리고 싱글 톤은 일반적으로 나쁜 생각입니다. – Gordon

+0

당신이 맞습니다, Gordon, 그래서 모든 글로벌 클래스의 단 하나의 인스턴스 만 생성되는 솔루션을 만들었습니다. 하지만 왜 Singletons가 나쁜 생각입니까? – codez

+0

방금 ​​문제를 교환했습니다 :) 이제 어떻게 Singleton이 아닌 것을 만들 수 있습니까? 또한, 당신은 여전히 ​​*를 작성하는 것은 * 관계-A이며, 지금은 효과적으로 마법 게터에 기본 클래스를 감소시키는'__get' 방법으로 하드 코딩하여 공장 기본 클래스를 결합. 내 말은, 확실히 작동하지만 IMO가 좋지 않다는 뜻입니다. * 글로벌 * 것들을 피하십시오. – Gordon