how does the components not in the core get instanced (be an object)

suppose i have a config file containing the following array items:


‘components’=>array(

                ......


                'timer'=>array(


                              'class'=>'Haha',


                              ),


                ......

in the config file, and Haha is class inherited from CApplicationComponent

(class Haha extends CApplicationComponent);


$app=Yii::createWebApplication($config);

$app->haha->dosomething(); // from here we know that $app->haha is already an instance of Haha,

                       // and call dosomthing();

$app->run();


i just wonder how class Haha get instanced in the source code;

in source code, i found


public function configure($config)

{


	if(is_array($config))


	{


		foreach($config as $key=>$value)


			$this->$key=$value;


	}


}

the above code is actually read config array in and made it index a property of the class and with the value the value of the array itself.


/**


 * Loads static application components.


 */


protected function preloadComponents()


{


	foreach($this->preload as $id)


		$this->getComponent($id);


}

and this above code i found the $this->preload array has nothing to do with the config array, in souce code, it actually empty when declared at the class beginning, so how $this->getComponent($id) get called ?!

so, at the end, so how the customized components get instanced? I know, it actually get instanced, I just wonder how that get done in source code. Can somebody help?

anybody help?

anybody help?

It’s done via autoloading. When PHP is about to fail to load a class it starts calling SPL autoloaders. One that Yii uses is http://www.yiiframework.com/doc/api/1.1/YiiBase/#autoload-detail

as the following, i got it; magic function __get does the trick first, and then autoload. In single file, structure like the following:

class A{

public static function run(){


    return new B();


}

}

class B{

public function __get($name){


return new $name();


}

}

class haha{

public function dosth(){


echo 'asdf';


}

}

$app = A::run();

$app->haha->dosth(); // asdf to screen here.