Configuring Yii

November 3, 2009 — 133 Comments
The Yii Book If you like my writing on the Yii framework, you'll love "The Yii Book"!
This entry is part 3 of 8 in the series Learning the Yii Framework

This is the third post in my series on Yii, my favorite PHP framework. In the first, I show how to download and test the framework itself. In the second, I show how to create a basic Web application. The end of that post also discusses the files and folders in the application directory. You’ll want to be familiar with those as you go forward. In this post, I discuss how you’ll want to configure your Yii-based application, including handling errors, adding components, and establishing a database connection. This post does assume you have an existing application to work with; if you don’t, follow the steps in the previous two posts.

(Note: In October 2010, I’ve updated this entire series to reflect changes in Yii since this series was written, and to take into account feedback provided through the comments. Some outdated material will be crossed out, but left in to reflect how things have changed since the series was begun in June 2009.)

There are a couple of ways you can configure how your Yii application behaves. For the most part, you’ll do this through the protected/config/main.php file, but first I want to talk about the index.php file, created in the root of your Web application directory. This is a “bootstrap” file, meaning that all user interactions actually go through it. For example, showing an employee record might be through the URL www.example.com/index.php/employee/show/id/34 and updating a department record might involve submitting a form to www.example.com/index.php/department/update/id/3. Both URLs request just that one PHP script.

The index.php file is generated when you use the command-line yiic script. There’s only seven lines of non-commented code in it. The first identifies the location of the Yii framework:

$yii=dirname(__FILE__).'/../framework/yii.php';

The path indicated should already be correct (because it’s created when the framework is used to make the application), but you can change this value if you move the framework or the index file.

The second line identifies where the configuration file is:

$config=dirname(__FILE__).'/protected/config/main.php';

The default behavior is to put the protected directory, where all the application files reside, in the same directory as the index file. My inclination is to move it outside of the Web directory, like so:

Modified Yii Layout

Modified Yii Layout

In such a case, I edit my index.php file to read:

$config= '../protected/config/main.php';

Note that it’s perfectly reasonable to move the location of your application files (i.e., the protected folder), but you should not change the names or structure of the folders found within the protected directory.

Tip: Moving the protected folder outside of the Web root directory is just an extra security precaution. It’s not required, and you may not want to bother with the change, especially as you’re just getting started.

The next line of code turns on debugging mode:

defined('YII_DEBUG') or define('YII_DEBUG',true);

You’ll want debugging enabled when developing a site, but disabled once live. To disable debuggin, remove or comment out that line. I normally just comment it out, so that I can re-enabled debugging later. Or you can change it to something like this, so that you can add debugging to a page on the fly:

if (isset($_GET['debug'])) define('YII_DEBUG', true);

If you do that, then to debug any page on the fly, change the URL from, for example,www.example.com/index.php/site/contact to www.example.com/index.php/site/contact/debug/true.

The next line of code dictates how many levels of “call stack” are shown in a message log:

defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);

The “call stack” is a history of what files, functions, etc., are included, invoked, and so forth. With a framework, the simple loading of the home page could easily involve a dozen actions. In order to limit the logged (i.e., recorded) data to the most recent, useful information, the call stack is limited by that line to just the most recent three actions.

The last two lines of the bootstrap file include the framework and start the application. Don’t mess with these!

require_once($yii);
Yii::createWebApplication($config)->run();

And that’s really all there is to do in the index.php page. As of Yii 1.1., the framework creates another bootstrap file: index-test.php. It is exactly the same as index.php, except that index-test.php includes a different configuration file: /protected/config/test.php instead of /protected/config/main.php. However, the test configuration file just includes the main configuration file, then also enables the CDbFixtureManager component, which is used for unit testing. The index-test.php file also omits the call stack limitation.

Most of the configuration occurs in the main.php configuration file, found within the protected/config directory (see the above image). There’s also a console.php config file, but that’s for a command-line version of the application. I won’t discuss that here, but you would edit it if you have command-line scripts associated with your application.

The configuration file returns a multi-dimensional array of information, some of which is pre-defined. You do want to make sure that the proper syntax is maintained as you edit this, so be careful in matching parentheses and using commas where necessary.

For starters, you’ll want to change the name of the application, which is used in the default HTML design, in page titles, and so forth:

'name'=>'Wicked Cool Yii Site',

Next, under the modules section of the returned array, you should enable Gii. Gii is a Web-based tool that you’ll use to generate Models, Views, and Controllers for the application. To enable Gii, just remove the comment tags—/* and */—that surround this code:

'gii'=>array(
    'class'=>'system.gii.GiiModule',
    'password'=>'SECURE',
),

Also enter a secure password in the code, one that only you will know.

Tip: Gii was added to Yii in version 1.1.2, and it replaces functionality available using the command-line Yii tools.

Moving down the file, in the components section of the returned array, you’ll probably want to enable urlManager. Just remove the comment code that surround the following:

'urlManager'=>array(
    'urlFormat'=>'path',
    'rules'=>array(
        '<controller:w+>/<id:d+>'=>'<controller>/view',
        '<controller:w+>/<action:w+>/<id:d+>'=>'<controller>/<action>',
        '<controller:w+>/<action:w+>'=>'<controller>/<action>',
    ),
),

This component changes URLs to be more search engine and user-friendly. For example, the default URL for a page could be something like www.example.com/index.php?r=site/contact, but urlManager will turn that into www.example.com/index.php/site/contact. If you want to take this further, it’s possible to configure urlManager, along with an Apache .htaccess file, so that index.php no longer needs to be part of the URL.

Next, you’ll almost always want to establish the database connection (unless you’re not using a database, of course). To do so, return an array that includes a connection string, a username, and a password. By default, a connection string is predefined for the SQLite database:

'db'=>array(
    'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db',
),

If you’re using SQLLite, just change the code so that it points to the location of your SQLLite database. If you’re not using SQLLite, comment out or remove those three lines of code.

If you’re using MySQL, the proper code looks like:

'db'=>array(
    'connectionString' => 'mysql:host=localhost;dbname=testdrive',
    'emulatePrepare' => true,
    'username' => 'username',
    'password' => 'password',
    'charset' => 'utf8',
),

The connection string is a DSN (Database Source Name), which has a precise format. It starts with a keyword indicating the database application being used, like mysql, pgsql (PostgreSQL), mssql (Microsoft’s SQL Server), or oci (Oracle). This keyword is followed by a colon, then, depending upon the database application being used, and the server environment, any number of parameters, each separated by a semicolon:

  • mysql:host=localhost;dbname=test
  • mysql:port=8889;dbname=somedb
  • mysql:unix_socket=/<em>path</em>/<em>to</em>/mysql.sock;dbname=whatever

Indicating the database to be used is most important. For me, when using MAMP on Mac OS X, I had to set the port number as it was not the expected default (of 3306). On Mac OS X Server, I had to specify the socket, as the expected default was not being used there. Also do keep in mind that you’ll need to have the proper PHP extensions installed for the corresponding database, like PDO and PDO MySQL. You should obviously change the username and password values to the proper values for your database. You may or may not want to change the character set.

Within the log component section, I enable CWebLogRoute. This is a wonderfully useful debugging tool that adds tons of details to each rendered page. Here’s the code for the config file:

'log'=>array(
    'class'=>'CLogRouter',
    'routes'=>array(
        array(
            'class'=>'CFileLogRoute',
            'levels'=>'error, warning',
        ),
        array (
            'class' => 'CWebLogRoute'
        )
    ),
),

And here’s an example output:

Web Log Output

Web Log Output

Finally, towards the end of the default configuration file you’ll find the adminEmail parameter. Change this to your email address, so that you receive error messages, contact form submissions, whatever:

'params'=>array(
    'adminEmail'=>'whatever@example.edu',
),

As you can tell, editing and adding components is where a lot of the configuration takes place. The ones I’ve highlighted are just the most immediately important, in my opinion, but there are certainly others, involving caching, security, themes, and more. One cool feature of Yii is that not all named components will be loaded for every request. Some, like the logging components are, but others are only loaded when required, thereby minimizing the performance impact of using many components.

One more configuration parameter that used to be in the default configuration file but now needs to be added is an indicator of the default controller. In other words, if no controller is specified in the URL, what controller will be called? Without further configuration, the “site” controller will be the default. To change that to a different controller, add:

'defaultController' => 'login',

Note that this particular line will not work out of the box as only the site controller exists. But you would make this change if you had created a protected/controllers/LoginController.php file (or if any controller file exists for whatever you make be the default). Also note that you add this line so that it’s a top-level array element being returned (i.e., it does not go within any other section; it’s easiest to add it between the “basePath” and “name” elements, for clarity).

And that’s a quick intro to configuring your Yii application. As always, thanks for reading and let me know if you have any questions or comments. In my next post, I’ll discuss a database design I’ll use in subsequent posts. After that, I’ll show you the magic: auto-generated Models, Views, and Controllers using Yii’s tools.

If you enjoyed this post, then please consider following me using your favorite social media, the RSS feed, and/or by subscribing to my newsletter. Or go crazy, and buy one or more of my books . Thanks!

133 responses to Configuring Yii

  1. hi,
    i have yii structure like

    -payment
    m2t
    dmdpaiement.php
    mtc
    -protected
    controllers
    views
    payment
    methods.php

    i want to open file in /payment/m2t/dmdpaiement.php from protected/views/payment/methods.php
    i am opening it in dialog box (popup)..
    but the error occur is “404 not found”.

    as it is outside the protected folder how can i access this dmdpaiement.php and access database to register information.
    if any one has solution plz reply.i need it …

  2. how to change the theme of yii webapp

  3. thank you very much, very well explained
    Greetings from Venezuela x-)

  4. Randhir Rawatlal May 3, 2012 at 7:47 am

    Dear Larry,

    Many thanks for your excellent tutorials. I have been a hack-native-php coder for some time even though I’d downloaded and played around with yii a while ago. Your tutorials have made yii come alive for me and I am revising my attitude toward frameworks as a result.

    Something I’m a bit stuck on: I can’t figure out how to see the yii database in phpMyAdmin. I’ve noticed the yii database is in fact sitting just as a file in the protected/data folder. However, I’m not as yet comfortable with leaving everything to gii. I need to be able to inspect the database using phpMyAdmin, else I feel I’m “flying blind”. The phpMyAdmin of course defaults to the localhost/mysql/data folder and I can’t see how to open up the yii-generated database. I am using xampp.

    This might be more of a phpMyAdmin question than a yii question, but I hope you’d be able to assist me.

    Thanks in advance
    Randhir

    • Thanks for the nice words on my tutorials, Randhir. If the database is a file in your protected/data directory, you’re probably using SQLite as your database application, not MySQL.

  5. Hi,
    Thanks for these great tutorials!!!

    I’ve noticed that the url structure in your examples is always: http://www.example.com/index.php/employee/show/id/34

    However, in the official documentation at yiiframeworks.com, it appears as http://www.example.com/index.php?r=employee/show&id=34 (or something like that, as the examples are not identical)

    I’m confused, because
    -you don’ mention having overridden default configurations regarding URLs
    -“your” url structure is much better
    -it seems unlikely that official documentation is outdated

    Have they changed the default url structure in favor of one which is worse? Or is the official documentation actually outdated? Or did you edit the url rewriting rules to use your own improved url structure??

    thanks

    • Sorry for the confusion. The default Yii behavior is to use ?r=… I normally change the configuration to use the friendlier /whatever I discuss that in the urlManager section of this very post.

  6. I struggled to connect to a MSSQL 2008 database sever, using PHP 5.3.10and the Microsoft MSSQL Native Driver 3.0 and Yii 1.11.

    I was receiving the following error when I tried to use the Gii utility:

    CDbConnection failed to open the DB connection: SQLSTATE[IMSSP]: The given attribute is only supported on the PDOStatement object.

    Eventually I found that if I commented out the “emulatePrepare” entry in the Main.php config file, it worked. ( setting emulatePrepare to true or false gave the same error )

    ‘db’=>array(
    ‘connectionString’ => ‘sqlsrv:server=MY-SERVER-NAME;database=MY-DATABASE;’,
    // The following line is commented out to allow database connection!
    //’emulatePrepare’ => true,
    ‘username’ => ‘MY-USERNAME’,
    ‘password’ => ‘MY-PASSWORD’,
    ‘charset’ => ‘utf8′,
    ),

    Cheers
    Dale

  7. Hi! Larry
    Thanks so much for great jobs !
    You wrote this line
    ‘defaultController’ => ‘login’, sorry I can not find which direction I can add.
    Could you write file direction for this line.
    Thank you for your answer and time!

  8. Yeah, finally I add ‘defaultController’ => ‘login’, line to the main.php and I did exactly that what you wrote and I got this message.
    CException
    Property “CLogRouter.enabled” is not defined.

    C:\wamp\yii\framework\logging\CLogRouter.php(123)

    111
    112 /**
    113 * Collects and processes log messages from a logger.
    114 * This method is an event handler to the {@link CApplication::onEndRequest} event.
    115 * @param CEvent $event event parameter
    116 * @since 1.1.0
    117 */
    118 public function processLogs($event)
    119 {
    120 $logger=Yii::getLogger();
    121 foreach($this->_routes as $route)
    122 {
    123 if($route->enabled)
    124 $route->collectLogs($logger,true);
    125 }
    126 }
    127 }

    Stack Trace
    #0
    + C:\wamp\yii\framework\logging\CLogRouter.php(123): CComponent->__get(“enabled”)
    #1
    + C:\wamp\yii\framework\base\CComponent.php(559): CLogRouter->processLogs(CEvent)
    #2
    + C:\wamp\yii\framework\base\CApplication.php(201): CComponent->raiseEvent(“onEndRequest”, CEvent)
    #3
    + C:\wamp\yii\framework\base\CApplication.php(164): CApplication->onEndRequest(CEvent)
    #4
    + C:\wamp\www\yii\index.php(20): CApplication->run()

    Sorry I am new user for Yii , It is normal ?
    Please could you tell me what I need to do ?
    Thanks a lot for your answers!

  9. I didn’t find these in my main.php

    mysql:port=8889;dbname=somedb
    mysql:unix_socket=/path/to/mysql.sock;dbname=whatever

    Do I have to add them?

  10. When I add this line where you tell us to add it.
    ‘defaultController’ => ‘login’,

    And I navigate to the site with this url http://localhost/yiilearn/ (Instead of http://localhost/yiilearn/index.php/site/index)
    I get this error message

    Error 404
    Unable to resolve the request “login”.

    If I remove that line then all appears fine so far.
    You do warn us that it will not work correctly. I just thought I would share what happens because it surprised me.

    You get the error if you go here
    http://localhost/yiilearn/

    You do NOT get the error if you then hit the home link which would take you here
    http://localhost/yiilearn/index.php/site/index

  11. Loved this whole series & bought the book as a result.

    Just one little detail for me, in this tutorial the line…
    $config= ‘../protected/config/main.php';
    needed the leading slash so…
    $config= ‘/../protected/config/main.php';

    Offering it just in case the same applies to others.

    Cheers, Pedro :)

  12. Hi! Larry
    Thanks so much for great jobs !
    Loved this whole series & bought the book as a result.
    i have learnt a lot from you but i m facing a issue that how i can use a single controller to insert data in multiple table like child parent tables and same as how i can i use joins using Gii kindly help me with that it ll be very kind of you.

  13. I had little troubles with configuration. I did everything according to your tutorial and all the time I had an error “Class ‘Employee’ does not exist or has syntax error.”. I’ve compared my main.php with demo blog file and I found that after adding “import” it works correct.

    ‘import’=>array(
    ‘application.models.*’,
    ‘application.components.*’,
    ),

  14. I installed Yii for the first time today (on Win7+ WAMP). WAsn’t easy and as it already is 1:15am !!! I have to leave reading till tomorrow (hardly started reading your tuts). As far as I can tell after my first ‘hello world’ index page- Yii seems to be fun coding/lightweight framework…

  15. its realy very great thank you

  16. I gave my email -id by it is not working properly :(

  17. hello sir

    where i have to change the line ‘defaultController’ => ‘login’,
    tell me the flow

Trackbacks and Pingbacks:

  1. Larry Ullman's Blog » Yii Framework 1.1 Updates - February 9, 2010

    [...] learning Yii and updating it for the latest version. Here’s what I found so far…From my Configuring Yii [...]

  2. Larry Ullman's Blog » Yii Framework 1.1 Updates - February 9, 2010

    [...] learning Yii and updating it for the latest version. Here’s what I found so far…From my Configuring Yii [...]

  3. Cambiar a modo debug “on the fly” « webeloper - January 15, 2011

    [...] Dejar un comentario Posted by webeloper en 15 enero, 2011 Tip tomado del artículo “Configuring Yii Framework” escritos por Larry Ullman en su blog que pienso que podría llegar a ser de utilidad en algún [...]

  4. Configuriamo Yii | Programmando Facile - June 8, 2012

    [...] Fonte: Larry Ullman [...]

  5. Learning the Yii Framework 3 / 8 | 웁스교교주의 이야기 - July 15, 2013

    [...] Yii 프레임워크 배우기 시리즈의 8편중 세 번째 문서입니다. 원본 글은 http://www.larryullman.com/2009/11/03/configuring-yii/ 에서 보실 수 [...]

Comments are great, but I'd strongly prefer any requests for assistance get made in the support forums. Thanks!