Using class_alias inside Yii framework and custom autoloader

I would like to do the following structure:




models/

models/residence/BaseResidence.php

models/residence/Site1Residence.php

models/residence/Site2Residence.php

models/sites/BaseSite.php

models/accounts.php



Where Site1 and Site2 extends BaseResidence.php, and all of these are in subfolder.

Now I want to create a custom autoloader to work this way:

Based on theme, the autoloader should do this




if (theme=Site1) 

   eval('class Residence extends Site1Residence {}'); // this creates class Residence


if (theme=Site2) 

   eval('class Residence extends Site2Residence {}'); // this creates class Residence


on the other hand, if there is no Site1XXXXX,php file, it should alias from BaseXXXXX.php file (BaseSite.php-> class Site)

and more, when there is no BaseXXXX.php file it should autoload the XXXX.file (accounts.php -> class accounts)



from now on, I would use just the class Residence/Site/accounts to work in the platform.

How to create such an autoloader, and how to verify if the files exits.

Pleas also note that a subfolder is involved too, and I want to avoid any warnings on the include if the class is missing.[b]

[/b]

This has been here for a few weeks now, anyone on this?

I would use a factory for this:

Something like


class ResidenceFactory{

  public function getInstance($theme = "site1"){

    $className = ucfirst($theme)."Residence";

    $className = Yii::import("application.models.residence.".$className,true);

    $model = new $className();

    return $model;

  }

}

should give you an idea

Forget the autoload, just import them on your main.php config file.




// autoloading model and component classes

	'import'=>array(

		'application.models.*',

                'application.models.residence.*',

                'application.models.sites.*',

		'application.components.*',

	),



Thats it, you can use any of the models there without worrying about the rest of your text. Now, you should consider reviewing as that could slow down your app.

Maybe, you should create the model that extends from a subfolder class by importing the base class first with Yii::import, then you can avoid pre-importing the classes as I explained before.




Yii::import('application.models.residence.MYBASECLASS');


class MYCHILDCLASS extends MYBASECLASS{


}



Cheers

How can I turn this into the autoloader, so I don’t have to create factory classes for all my classes?

I have found the PHP way to do this by using [color="#1C2837"][font=“monospace”][size=“2”][color="#000088"]eval[/color][color="#666600"]([/color][color="#008800"]‘class Residence extends Site2Residence {}’[/color][color="#666600"]); I [color=#000000][font=arial, verdana, tahoma, sans-serif][size=3]don’t know how to include in the Yii autoloader, in YII style.[/size][/font][/color][/color][/size][/font][/color]

I am not having problems with the baseclass and extending. I have found the PHP way to do that with [color=#1C2837][font=monospace][size=2][color=#000088][color=#000088]eval[/color][/color][color=#666600][color=#666600]([/color][/color][color=#008800][color=#008800]‘class Residence extends Site2Residence {}’[/color][/color][color=#666600][color=#666600]); [/color][/color][/size][/font][/color]I am looking to this automatically with autoloading, so I should not create all the classes that are required. And I only know at runtime which class will be used for extend (Site2Residence). But I will refer all the time to the class by its basename eg: Residence.

Please check this links, they might be of help.

Autoloading reference:

http://php.net/manual/en/language.oop5.autoload.php

How to register autoloaders with Yii:

http://www.yiiframework.com/doc/api/1.1/YiiBase/#registerAutoloader-detail

And an example:

http://www.yiiframework.com/extension/zendautoloader

And why do you need new classes that inherit from Residence if they dont have any specific logic? whats the idea of extending if not adding specific funcionality?

(does anyone else think the eval(‘class Residence extends Site2Residence {}’); looks really ugly or is just me?)

The eval() stuff is just the only way to provide class_alias at runtime in PHP prior 5.3.0.

The idea is that I use one code base with reference here there in the portal to class Residence, and I can override specific functionality only by redefining the Site2Residence class that extends BaseResidence class, and I don’t have to rewrite the whole code base to use Site2Residence. It is not important for me on which chain the Residence class got extended/instanciated (eg. BaseResidence->Site2Residence->Residence), more important is that always to have the same name eg: Residence. Actually in fact Residence class by taking this strict reference is never defined in PHP files, it will be either Site1/Site2/BaseResidence aliased into a more generic Residence name.

The whole idea is that I will be able to add custom functionality for Site3 Site4 by just creating one single Site4Residence class file and I won’t need to update existing code that works with Residence across the application.

IMHO, and using Yii, I would extend the functionality of ANY component or defining different methods by just modifying its ‘behaviors’. Once you create one behavior, you can include that in any component throughout any Yii application.

For example:




$classInstance = new Residence();


if($site=='site1')

      $classInstance->attachbehavior('site1residence', new Site1ResidenceBehavior);


if($site=='site2')

      $classInstance->attachbehavior('site2residence', new Site2ResidenceBehavior);



Just an idea…

Edit: BTW, you can add as many behaviors as you wish, better than extending from a bunch of base classes

This would be easy if you have only a few classes and a small code base.

But I have hundreds of classes and I must add the check/instantiation to a lot of lines. It won’t work for me as it introduces a lot of edits when I have to add new SiteX’s.

I was telling in the previous post that I want to avoid the hard edit of the references in all the files when I have to introduce new Site3/Site4 instances.

Perhaps if you show us the big picture we can give you some better ideas.you already said:

But Id like (need) a little more information (I’m slow like homer)so I can actually think of a working architecture.