Using import and autoloading
When programming with PHP, one of the most annoying things is loading additional code with include
and require
. Fortunately, you can do it automatically using the SPL
class loader (http://php.net/manual/en/function.spl-autoload.php).
Autoloading is one of the features which Yii relies on. Still, there are many questions about it on the forums. Let's get it clear and show how we can use it.
When we are using a class, for example, CDbCriteria
, we are not including it explicitly so PHP initially cannot find it and is trying to rely on the autoloading feature; SPL autoloader to be precise. In most cases, Yii default autoloader (YiiBase::autoload
) will be used.
For the sake of speed and simplicity, almost all core framework classes are loaded when needed without including or importing them explicitly. It's done through YiiBase::$_coreClasses
map, so loading core classes is very fast. Zii classes, such as CMenu
, extension classes or your own classes are not loaded automatically, so we need to import them first.
To import classes, we will use Yii::import
:
- Import does not include a class immediately by default
- It does not include a class if it is not used
- It will not load a class twice, so it is safe to import the same class multiple times
How to do it...
- Let's assume that we have a custom class named
LyricsFinder
that finds lyrics for a given song. We have put it underprotected/apis/lyrics/
and in ourprotected/controllers/TestController.php
, we are trying to use it in the following way:class TestController extends CController { public function actionIndex($song) { $lyric = 'Nothing was found.'; $finder = new LyricsFinder(); if(!empty($song)) $lyric = $finder->getText($song); echo $lyric; } }
- When executing it, we will get the following PHP error:
include(LyricsFinder.php) [<a href='function.include'>function.include</a>]: failed to open stream: No such file or directory.
- Yii helps us there a bit because at the error screen, we can see that autoloader fails because it doesn't know where to look for our class. Therefore, let's modify our code:
class TestController extends CController { public function actionIndex($song) { $lyric = 'Nothing was found.'; // importing a class Yii::import('application.apis.lyrics.LyricsFinder'); $finder = new LyricsFinder(); if(!empty($song)) $lyric = $finder->getText($song); echo $lyric; } }
Now our code works.
Note
The built-in Yii class loader requires that each class should be placed into a separate file named the same as the class itself.
How it works...
Let's look at application.apis.lyrics.LyricsFinder
:
application
is a standard alias that points to your application
protected folder and is translated into a filesystem path. The following table shows some more standard aliases:
Note
You can define your own aliases using the Yii::setPathOfAlias
method. Typically, it can be done as the first lines of protected/config/main.php
, so all other config parts will be able to use these new aliases.
apis.lyrics
are translated to apis/lyrics
and are appended to a path retrieved from the application
alias, and LyricsFinder
is the class name we want to import.
If LyricsFinder
requires some additional classes located in its directory, then we can use Yii::import('application.apis.lyrics.*')
to import the whole directory. Note that *
does not include subfolders, so if you need lyrics/includes
, you should add another import statement Yii::import('application.apis.lyrics.includes.*')
.
For performance reasons, it is better to use explicit paths with a class name instead of *
if you are importing a single class.
There's more...
If you want your classes to be imported automatically like the Yii core classes, then you can configure global imports in your main.php
configuration file:
return array( // … // global imports 'import'=>array( 'application.models.*', 'application.components.*', 'application.apis.lyrics.*', 'application.apis.lyrics.includes.*', 'application.apis.albums.AlbumFinder', ),
Note
Note that using *
, with a huge amount of global imports could slow your application down as there will be too many directories to check.
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.