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();
일반적인 Base 클래스의 서브 클래 싱은 거의 항상 나쁜 생각입니다. 당신은'Some' * is-a *'Manager'라는 관계를 만들고 있습니다. 실제로는 그렇지 않습니다.또한 인스턴스를 객체 인스턴스로 저장하는 경우 Manager를 확장하는 모든 클래스는 자체 인스턴스 만 별도로 만듭니다. db 및 config의 경우에는 필요하지 않을 수 있습니다. 싱글 톤은 이것을 완화 할 수 있지만 싱글 톤을'new'로 인스턴스화 할 수 없으므로'__get'의 코드는 더 이상 작동하지 않습니다. 그리고 싱글 톤은 일반적으로 나쁜 생각입니다. – Gordon
당신이 맞습니다, Gordon, 그래서 모든 글로벌 클래스의 단 하나의 인스턴스 만 생성되는 솔루션을 만들었습니다. 하지만 왜 Singletons가 나쁜 생각입니까? – codez
방금 문제를 교환했습니다 :) 이제 어떻게 Singleton이 아닌 것을 만들 수 있습니까? 또한, 당신은 여전히 *를 작성하는 것은 * 관계-A이며, 지금은 효과적으로 마법 게터에 기본 클래스를 감소시키는'__get' 방법으로 하드 코딩하여 공장 기본 클래스를 결합. 내 말은, 확실히 작동하지만 IMO가 좋지 않다는 뜻입니다. * 글로벌 * 것들을 피하십시오. – Gordon