2013-05-04

Getting Started With Yii Framework 2. A Basic Tutorial

Disclaimer

This guide is meant to help you started with Yii2. Yii2 is by no means "production" ready. I do not recommend using this in production.

Edit

This guide has been updated to reflect some changes that should import the quality of this post. Namely:

1) Getting ActiveRecord to autoincriment the database
2) Changing the charset of utf8.
3) Removal of model() method in Post Model
4) Update findallMethod
5) Added Flash Messages instead of 404 errors.
6) Removal of XSS Injection Vector

Today Yii Framework made the announcement that Yii2 was now available for a public preview. A lot has changed from Yii1 to Yii2,

This tutorial will go over making a simple blog site in Yii2. For this guide, we'll be getting and installing Yii2, creating a base app, connecting to a database, and configuring logic to create, updated, read, and delete posts.

For this tutorial, here's what you'll need:

A webserver, either Apache or Nginx. For this guide I'll be using Nginx. The conversion to Apache should be trivial however, so don't worry if you don't have an Nginx server lying around.

A database to connect our app to. I'll be using MySQL 5.5

Basic PHP knowledge. I'll try to keep it as simple as possible, but the more PHP you know, the easier it will be to follow along.

Basic Knowledge of either Yii or MVC. If you don't have any experience with MVC, I recommend you read up on MVC fundamentals. You can follow this guide without them, however things will make more sense if you have a concept of what MVC is.

So, lets get started!

For this tutorial I'm going to assume that you already have your webserver setup. For this guide, I'm going to be using the following directories and urls:

/var/www/yii2 for my DocumentRoot

yii2.erianna.com for my hosting url

Additionally, by the end of this tutorial you will be able to view a demo of the app we've made at yii2.erianna.com.

Downloading Yii2

Download a copy of Yii2 from Github either by cloning the repository or by downloading a tar archive.

or

Once you've extracted Yii2, navigate to /dir/to/yii2/framework

And run the following commands to setup your first webapp, providing yes to the first prompt.

This is the equivalent of creating a new webapp in Yii 1.x. Now navigate to /var/www/yii2. Inside this folder you'll see one file and one folder.

Before we can get our site up and running, we'll need to make some modifications to our index.php file. In my opinion, there are some questionable design choices. Hopefully these will be fixed before Yii2's final release to make it more user friendly to get setup.

Change your index.php to look like this.

Lets break down the changes we made:

First, we need to change our "require" path to point to to where our framework/yii.php is actually located at. By default, this makes the assuming it is in the current directory, It's possible it might be, but it needs to know exactly where Yii2 is located at.

Next, we updated our config path to use __FILE__ instead of __DIR__. We're making this change so our webapp can actually load.

Before we continue, it's important to notice there's something new in Yii" Name spaces

The point of name spaces is to encapsulate code in logical units to prevent collision of multiple code bases. So you have two classes, both named Foo and that both have the method Bar, assuming they are both name spaces you can call both of them independently of each other as follows, without any collision of classes.

Name spaces are an easy way to prevent collision of code. I'd recommend you'd read up on them, since Yii2 has been name spaced.

And like that, you've just created your fist web app! Navigate to where yii2 is located at, and you should see the following page.

Your First Yii2 App!

Unlike Yii 1.x's skeleton app, the base skeleton app for Yii2 isn't that exciting yet. Lets make it do a little more.

First, open up your /protected/views/layout/main.php file, then replace it with the following code:

Then refresh the page. See? Isn't everything prettier with Twitter Bootstrap? Again, not much has changed from Yii1 to Yii2. You still have $content being the variable you use for displaying content in views. Yii::app() has changed to be Yii::$app however. Again, everything in Yii2 has been name spaced, so it's important to remember to access everything by their new name space instead of just calling the raw class.

Now lets do some real coding!

Connecting To Your Database

For this app, we'll just have a simple Posts table containing our blog posts.

Creating the Database Table

Login to MySQL, and create a user and database both named yii2. Then run the following command to update the db structure for yii2.

Updating Your Config

Then, navigate to /var/www/yii2/protected/ and open up config.php in your favorite editor and replace it with the following.

If you're familiar with Yii2, this is a massive improvement over the hideous config files that were generated in Yii1. While the same structure is there, this is the only thing that is needed to get your database up and running.

Creating a Post Model

Create a new folder called models under protected, and then created a new file call Post.php in models and add the following code to it.

If you're familiar with Yii1, the only thing that has really changed in ActiveRecord (at least in this example) is that the functions primaryKey, and tableName are now static methods. Everything else is basically the same. For the most part, ActiveRecord has remained unchanged.

The most important part of this class is the inclusion of the name space app\models. This tells Yii where we can reference this file at.

Unlike Yii1, where you can just call the class name, Yii2 uses a different type of auto loaded which requires you to explicitly define what classes you intent on using. While this might make development a little slower (Trying to remember to include \yii\framework\web\Html can get old really fast instead of just calling CHtml), it should make Yii2 significantly faster. Since the autoloader won't have to search through the entire framework just to get one class. At least in theory.

CRUD!

Now that we've name spaced our Post model, we can get to working creating our basic CRUD app.

Viewing Everything

First, lets start by updating our index action so that we can view everything. I like to be able to view everything from my index action, so lets start there. Open up controllers/SiteController.php and update your index action so it looks as follows:

A couple of things to notice here. First, ::model()-> is gone. Raw model data from ActiveRecord and Model can now be accessed directly by calling the method you want information on. So $post->find()->all(). While I am personally pretty fond of Post::model()->findAll(), the new way of accessing data pretty standard and is easier to read.

Secondly, findAll has been replaced by find()->all(). All find methods now stem either from find() or findBySql().

Finally, $this->render() now requires an echo in front of it. Personally, I hate this. It feels very CakePHP ish, and is in my opinion redundant. The idea behind this however is that stuff you want to be rendered to the screen should be echoed, otherwise it is simply available as a $variable for you to manipulate. Personally, I prefer the older way of rendering to a variable (passing a function parameter to the render method), but maybe it will grow on me.

Now refresh the page...

If you're familiar with namespaces, your probably screaming at me right now asking me why I didn't include the Post model. If you're not familiar with name spaces, you're probably confuses as to why your getting an error. The reason is simple. _You have to remember your name spaces in Yii2__. Anything you want to use, you have to explicitly define unless it already has been defined.

Add the following line to top of SiteController. Then refresh the page.

Now lets add some markup to display our posts. Open up protected/views/site/index.php and replace the content with the following:

Hmmm, looks different doesn't it! CHtml::link() is gone, and has been replaced by a helper name space called Html. Fortunately, the structure from CHtml::link to Html::a hasn't changed at all. So it's simply a matter of filling in the parameters.

Read

Reading is easy, so lets take care of that next. Create a new method in SiteController with the following definition:

Now, if you navigate to ?r=site/read&id=1. You should see HelloWorld being printed to the screen. See it? Good. That means our method is being triggered. Now lets configure it so that we can get some data from our database.

First, lets add HttpException to our SiteController so that we can throw HttpExceptions if a post isn't found.

Then, lets create our read action

Just for clarity, HttpException is essentially CHttpException. All we're doing is making querying the database for a post if an id of $id, and rendering it. If the post isn't found, or an id isn't provided then we're throwing an HttpException.

Next, we need to create a new file protected/views/site/read.php, and add the following code to it to display our post.

Now, on our index page, click on "Example Post". Tada! You can now view posts for your blog!

Delete

Deleting posts is also very simple, so we'll do that next. Create a new method with the following definition:

For this method, we're going to be a little more complex. We're going to redirect the user back to the homepage after we've successfully deleted their post. Lets get started.

First, lets define our method

A couple things to note with Yii2. First, redirecting is now done through Yii::$app->getResponse->redirect() instead of $this->redirect(). While this makes sense from code organization perspective, it's a pain to type out. Additionally, it also gives the feeling that $app is severely overloaded. While a pain to type, it's maintained the same method definition from Yii1.

Secondly, setFlash is now accessed through $app instead of app(). You should be getting the hange of that by now though. =)

Now that we've handled deleting, lets go back to our protected/views/site/index.php file and catch those flash message we sent.

Just add the following below the first

tag

Now try deleting "Example Post". Pretty neat huh? You're getting the idea of Yii::$app now, right?

Create

Now lets get to the fun stuff, creating new entries in our blog. We're going to need a couple of things to post creation. First, we're going to be use ActiveForm to handle the form itself. Secondly we're going to catch catching and validating $_POST data. And finally we're going to be saving it to the database for storage. Lets get started.

First, we'll need to create a view for our form. Start by creating a file protected/views/site/create.php. Since we'll be using a widget in our view, you'll also need to create a folder "assets" in the root of our web app and make it writable by your web server. Chmod 755 usually does the trick. Then add the following function definition to SiteController.

public function actionCreate()
{
$model = new Post;
if ($this->populate($_POST, $model) && $model->save())
Yii::$app-><span

Show more