《Agile Web Application Development with Yii1.1 and PHP5》

Chapter 4: Iteration 1: Creating the Initial TrackStar Application

In the previous chapter, we introduced our development methodology, which embraces an incremental and iterative approach. Within this methodology there is the concept of an iteration. For our purposes, an iteration can be thought of as an opportunity for a development team to create working, tested, and production-ready features of an application within a specified time constraint. The development team and other project stakeholders decide which features will be worked on within this fixed amount of time. Creating such a timebox around our desired features cannot really be done in a book. So, we will let the scope of each chapter define our iteration.

From now on, we'll treat each of our chapters as a new iteration, and begin each chapter with the iteration planning section. In this section we will:

  • Identify the features and functionality that we want to focus on within the iteration
  • Provide a little upfront design and analysis if necessary, and then quickly break the items into more granular tasks for implementation

Iteration planning

From what we learned in the previous chapter about our task tracking application, we know that we are going to be building a web-based application. We also learned in Chapter 2, Getting Started, just how easy it is to create a new working Yii web application using the yiic command-line tool.

We also talked about data in Chapter 3, The Trackstar Application, but did not talk specifically about how we want to handle that data. Now is the time to provide some explicit implementation answers to the questions posed in Chapter 3. Do we need persistent data at all? Would flat files on the filesystem work just as well as a relational database?

Based on this being a web-based application and the nature of the information that we need to store, retrieve, and manipulate, we can safely say that we need to persist the data in this application. Also, based on the relationships that exist between the types of data we want to capture and manage, we feel that the best approach to storing this data would be in a relational database. Because of its ease of use, excellent price point, general popularity among PHP application developers and its compatibility with the Yii Framework, we will be using MySQL as the specific database server.

Getting a basic, working skeleton application in place and successfully connected to a database is all we want to attempt in this first iteration. So in this first iteration, we will focus only on the following basic tasks:

  • Creating a new Yii web application to be the foundation to the TrackStar application
  • Creating a new MySQL database
  • Configuring the new web application to connect to the newly created database

In Chapter 2, Getting Started, we saw how easy it is to create a new application. Even though this first iteration will be a short one, at the end, we will have a working, tested, and deployable web application.

Creating the new application

First things first, let's create the initial Yii web application. We have already seen how easy this is to accomplish in Chapter 2. As we did there, we will assume the following:

  • YiiRoot is the folder where you have installed Yii
  • WebRoot is configured to be the document root of your web server (that is,to where http://localhost/ resolves)

So, from the command line, change to your WebRoot folder, and execute the following:

% cd WebRoot
% YiiRoot/framework/yiic webapp trackstar
Create a Web application under '/Webroot/trackstar'? [Yes|No] Yes

This provides us with our skeleton folder structure and our out of the box working application. You should be able to view the homepage of this new application by navigating to:http://localhost/trackstar/index.php?r=site/index

Connecting to the database

Now that we have our skeleton application up and running, let's work on getting it properly connected to a database. Although this is more a matter of configuration than writing code, we will maintain a test-first approach, so that basic database connectivity becomes a part of our routine test suite.

Testing the connection

Chapter 3, introduced us to the testing framework provided by Yii. So, we know we add our unit tests under protected/tests/unit/. Let's create a simple database connectivity test file under this folder called DbTest.php. Create this new file with the following contents:

class DbTest extends CTestCase
     public function testConnection()

Here we have added a fairly trivial test. The assertTrue() method, which is part of phpUnit, is an assertion that will pass if the argument passed to it is true, and it will fail if it is false. So, in this case, it will pass if true is true. Of course it is, so this test will pass. We are doing this to make sure our new application is working as expected for testing. Navigate to the tests folder and execute this new test:

%cd /WebRoot/trackstar/protected/tests
%phpunit unit/DbTest.phpTime: 0 seconds, Memory: 10.00Mb
OK (1 test, 1 assertion)

Configuring the test suite If for some reason this test failed on your system, you many need to change protected/tests/bootstrap.php so that the variable $yiit properly points to your /YiiRoot/yiit.php file.

Confident that our testing framework is working as expected within our newly created TrackStar application, we can actually test for a db connection.

Change the trivial assertEquals(true) statement in the testConnection() test method to:

$this->assertNotEquals(NULL, Yii::app()->db);

And rerun the test:

%phpunit unit/DbTest.php
There was 1 error:
1) DbTest::testConnection
CDbException: CDbConnection failed to open the DB connection: could not
find driverFAILURES!
Tests: 1, Assertions: 0, Errors: 1.

Now we have a failing test. The test is assuming the application has been configured with a database connection application component called db. (We'll talk a little more about application components later). The test is written to assert that when the application is asked for a db connection, the result is not a null value.

In fact, the skeleton application was auto-configured to use a database. A by-product of using the yiic tool is that our new application is configured to use an SQLite database. If you take a peek into the main application configuration file, located at protected/ config/main.php, you will see the following declaration about halfway down:

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

And you can also verify the existence of protected/data/testdrive.db, which is the SQLite database it is configured to use.

In our case, this test fails because we don't have an SQLite driver configured in our development environment. This test may not have failed for you if you happen to have the correct driver available. Before we change the configuration to use a MySQL database server, let's briefly talk about Yii and databases more generally.

Yii and databases

Yii provides great support for database programming. Yii Data Access Objects (DAO) is built on top of the PHP Data Objects (PDO) extension (http://php.net/ pdo). This is a database abstraction layer that enables the application to interact with the database independent of the specific choice of database server. All supported database management systems (DBMS) are encapsulated behind a single uniform interface. This way, the code can remain database independent, and applications developed using Yii DAO can be easily switched to use a different DBMS without the need for modification.

To establish a connection with a supported DBMS, one can simply create a new CDbConnection class and instantiate it:

$connection=new CDbConnection($dsn,$username,$password);

Here the format of the $dsn variable depends on the specific PDO database driver being used. Some common formats include:

  • SQLite:sqlite:/path/to/dbfile
  • MySQL:mysql:host=localhost;dbname=testdb
  • PostgreSQL:pgsql:host=localhost;port=5432;dbname=testdb
  • SQL Server:mssql:host=localhost;dbname=testdb
  • Oracle:oci:dbname=//localhost:1521/testdb

CDbConnection also extends from CApplicationComponent, which allows it to be configured as an application component. This means that we can add it to the components property of the application, and customize the class and property values that are there in the configuration file. This is our preferred approach.

Adding a db connection as an application component

To take a quick step back. When we created the initial application, we specified the application type to be a web application. Doing so actually specified that the application singleton class that is created upon each request should be of type CWebApplication. This Yii application singleton is the execution context within which all request processing is run. Its main task is to resolve the user request and route it to an appropriate controller for further processing. This was represented as the Yii Application Router back in our Chapter 1, Meet Yii diagrams, when we covered the request routing. It also serves as the central place for keeping application-level configuration values.

To customize our application configuration, we normally provide a configuration file to initialize its property values when the application instance is being created. The main application configuration file is located in /protected/config/main.php. This is actually a PHP file containing an array of key-value pairs. Each key represents the name of a property of the application instance, and each value is the corresponding property's initial value. If you open up this file, you will see that a few settings have already been configured for us by the yiic tool.

Adding an application component to the configuration is easy. Open up the main config file and locate the components property.

We see that there are already entries specifying a log and a user application component. These will be covered in subsequent chapters. We also see ( as we noted previously) that there is a db component there as well, configured to use an SQLite connection to an SQLite database located at protected/data/testdrive.db. We are going to replace that connection with one for a MySQL database. It can be defined as follows:

// application components
        'connectionString' => 'mysql:host=;dbname=trackstar_dev',
        'emulatePrepare' => true,
        'username' => 'your_db_user_name',
        'password' => 'your_db_password',
        'charset' => 'utf8',

This assumes that a MySQL database has been created called trackstar_dev and is available to connect to the localhost IP of One of the great benefits of making this an application component is that from now on, we can reference the database connection simply as a property of the main Yii application: Yii::app()->db anywhere throughout our application. Similarly, we can do this for any of the components defined in the config file.

All of our examples will be using the MySQL database. However, we will be providing the low-level DDL statements for the table structures, and we will try to keep things generic from a database implementation perspective. It is entirely possible to follow along using any Yii-compatible database of your choice. At the time of writing, Yii has Active Record support for MySQL, PostgresSQL, SQLite, SQL Server, and Oracle.

The charset property set to utf8 sets the character set used for database connection. This property is only used for MySQL and PostgreSQL databases. We are setting it here to ensure proper utf8 unicode character support for our PHP application. The emulatePrepare => true configuration sets a PDO attribute (PDO::ATTR_EMULATE_PREPARES) to true which is recommended if you are using PHP 5.1.3 or higher.

So, we have specified a MySQL database called trackstar_dev as well as the username and password needed to connect to this database. We did not show you how to create such a database in MySQL. We assume you have a favorite database you are going to use as you follow along and know how to create a new database. Please refer to your specific database documentation if you are unsure of how to create a new database called trackstar_dev, and define a username and password for connectivity.

Once the database is in place, we can test it again by running our unit test again:

%phpunit unit/DbTest.php
PHPUnit 3.3.17 by Sebastian Bergmann.
Time: 0 seconds
OK (1 test, 1 assertion)

Our test now passes


We have completed our first iteration, and we have a working and tested application that is ready to be deployed if necessary. However, our application certainly does not do much of anything. All we have is the functionality that comes out of the box from the autogenerated code when we created the application, and a valid connection to a database. This is certainly far from what we have described when we introduced the TrackStar application. But we are taking small, incremental steps towards achieving our desired functionality, and this first iteration was a great milestone towards that end.

In the next chapter, we will finally get to sink our teeth into more meaningful features. We will begin to do some actual coding as we implement the needed functionality to manage our project entities within the application.

评论 X

      Copyright 2011-2014. YiiBook.com