Building a CRUD application using PHP and the YII2 framework.

I have used Yii extensively in my software development experience but since they have moved to version 2 I haven’t gotten to experience it. To do this I created a simple gallery using the Yii2 framework. It allows you to create, edit and delete gallery posts. It gives an understanding of database migrations, composer setup, twig templating engine installation. Also using gii for code generation, directory setup, asset management, authentication and access control. You can access the source code here https://github.com/wyntonfranklin/yii-tutorial.git. Follow along if you can.

Installation

To get started with the yii2 framework I used the composer installation command to create a start up project. Learn more at https://github.com/yiisoft/yii2

composer create-project --prefer-dist yiisoft/yii2-app-basic yii

Once the installation was completed I pointed my virtual host to the web directory. I had to add the rewrite information in the directory section of the virtual host file.

<VirtualHost *:80>
    DocumentRoot "/location/yii/web"
    ServerName yiitutorial.dev
    ServerAlias yiitutorial.dev
    <Directory "/location/yii/web">
        RewriteEngine on
        RewriteRule ^index.php/ - [L,R=404]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . index.php
        AllowOverride All
        Require all Granted
    </Directory>
</VirtualHost>

Also in the config/web.php I added the url manager configuration to ensure the application works correctly and that index.php is removed completely.

       'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '/' => "/gallery/",
                '<controller:\w+>/<id:\d+>'=>'<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
            ],
        ],

The Application Directory

The directory listing of yii is shown below. The web folder has the bootstrap index.php file where you need to point your sever configuration. You could see I did that from my virtual host file above.

yii/                  application base path
    composer.json       used by Composer, describes package information
    config/             contains application and other configurations
        console.php     the console application configuration
        web.php         the Web application configuration
    commands/           contains console command classes
    controllers/        contains controller classes
    models/             contains model classes
    runtime/            contains files generated by Yii during runtime, such as logs and cache files
    vendor/             contains the installed Composer packages, including the Yii framework itself
    views/              contains view files
    web/                application Web root, contains Web accessible files
        assets/         contains published asset files (javascript and css) by Yii
        index.php       the entry (or bootstrap) script for the application
    yii  

Configuration

In the configuration directory [ config folder] you can edit settings for your application. To add a database component go to config/db.php. Here you can add your settings for you database. Mines looked something like below.

<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=127.0.0.1;dbname=wf_tutorials',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

You can change the app name in the config/web.php settings. Just add a name to the config array.

$config = [
    'id' => 'basic',
    'name'=>'Yii Gallery',
]

The Gii Tool

To get started – I had to create my views and to do that I needed a controller. A controller does a lot but one of its main function is to define routes for your application. You can add additional code in it as well though. In creating my controller I used the Gii tool which does code generation for controllers, models and more. To access the Gii tool I proceed to – {base-url}/gii path. For me it was yiitutorial.dev/gii. You can learn more about Gii here.

Gii tool screen

From the screen above I choose the Controller Generator option. I had to add the full namespace of my controller being app\controller\GalleryController. In the form screen I can also add the actions I wanted in the controller. I added the basics where are – create, edit, view, update, delete and index. All controllers by default go to the index if no other route is provided. Once the gallery controller was created I choose to install twig since I’ve since become a fan.

All controllers by default go to the index action if no other route is provided.

Tool Tip

Twig Installation

Twig installation was simple as all it required was a composer require command and adding some configuration to the web.php file. To install twig I used this command once I cd into the root directory of my application.

php composer.phar require --prefer-dist yiisoft/yii2-twig

Once that was done I added the configurations. This is actually components configurations for yii2. So the url manager and the db configuration are all components in yii. Once the code below was added everything worked fine.

'view' => [
'class' => 'yii\web\View',
'renderers' => [
'twig' => [
'class' => 'yii\twig\ViewRenderer',
'cachePath' => '@runtime/Twig/cache',
// Array of twig options:
'options' => [
'auto_reload' => true,
],
'globals' => [
'html' => ['class' => '\yii\helpers\Html'],
],
'uses' => ['yii\bootstrap'],
],
],
],

The url manager and the db configuration are all components in yii.

Tool Tip

I can now return twig views from my controller with ease. Passing in my models.

$this->render('view.twig',['model'=>$model]);

Migrations

To create the tables that we are using for the tutorial I used migrations. I create two tables. A gallery and a user table. Migrations is a great way to manage how you interact with the database and handles changes and versioning.

To create those tables I ran the commands below. Then I edited the migration files and added the arrays that created the tables.

php yii migrate/create create_gallery_table // create gallery table
php yii migrate/create create_yii_users_table // create yii_users table
// for users
  public function safeUp()
    {
        $this->createTable('yii_users', [
            'id' => Schema::TYPE_PK,
            'username' => Schema::TYPE_TEXT,
            'password' => Schema::TYPE_TEXT,
            'authKey' => Schema::TYPE_TEXT,
            'accessToken' => Schema::TYPE_TEXT
        ]);
    }
//for gallery 
  public function safeUp()
    {
        $this->createTable('gallery', [
            'id' => Schema::TYPE_PK,
            'title' => Schema::TYPE_STRING,
            'imageUrl' => Schema::TYPE_STRING,
            'creationDate' => Schema::TYPE_DATETIME
        ]);
    }

Yii requires you to add classes you plan to use. In controllers and views you will need to add some classes that help you out. For example in migrations and controllers.

use yii\db\Schema; // add in migrations

use Yii; // add in controllers and models
use yii\helpers\Url; // add in controllers
use yii\filters\AccessControl; // add in controllers

Helpers

Use the Yii class allows you access to features like :-

Yii::$app->request->post() // for get post request
Yii::$app->request->isPost // is request post
Yii::$app->request->isAjax // is request ajax
Yii::$app->name; // App name

The Url Helper allows you to create urls :-

Url::toRoute(['/gallery/create'])

The access control is used for 🙂 access control. Obviously. That would be show a little later.

Models

Once you create the tables you can use the Gii tool to create the active record model for you table. Model extends \yii\db\ActiveRecord. Learn more here. You can create functions inside of your model to format the data from your table before it is displayed in views. For example I created a function to format the date.

public function getFormatedDate()
{
   return date( "D M j, Y",strtotime( $this->creationDate ) );
}

Controllers

In Yii I can access my routes based on the controller names. So for my create, view and edit routes I created functions in the controller with a prefix action. Once I did this I could access my routes. To create a gallery item the function in my controller is shown below

    public function actionCreate()
    {
        $model = new Gallery();
        if($model->load(Yii::$app->request->post())){
            $model->creationDate = date("Y-m-d h:i:s");
            $model->save();
            $this->redirect("/gallery/");
        }
        return $this->render('create',[
            'model' => $model
        ]);
    }

In controllers any function with a prefix action is seen as a route and is accessible via the url. e.g actionHome in the site controller will point to site/home.

Tool Tip

In the above code I created a new gallery model. Then I checked for post values and I loaded the post values into my model. I added the creation date and I saved my model. I then redirected to the /gallery/index route. If there is no post object the the page renders the create.php view which can be found in views/gallery/create.php.

Assets

If you want to add your own CSS files to you Yii application you need to interact with the asset manager. I removed the default bootstrap and added my own bootstrap files for version 4 as yii-boostrap uses version 3. To add your files you need to go to the /assets/AppAsset.php file and change the configurations to point to your directories.

   public $css = [
        'css/site.css',
        'css/bootstrap.css',
        'css/fontawesome.css',
        'css/all.css',
    ];
    public $js = [
        'js/bootstrap.bundle.js',
        'js/main.js'
    ];
    public $depends = [
        'yii\web\YiiAsset',
       // 'yii\bootstrap\BootstrapAsset',
    ];

I removed the yii\bootstrap line and I added my own css and js files. These files are located in the web/css and web/js directories as this is your public directory

Authentication

Yii creates a default User model that implements the identity interface to facilitate user login and persistence. Since we created a user model named YiiUsers I had direct Yii to that user instead. The first part of this is to ensure the web.php config file knew what class we were using.

     'user' => [
            'identityClass' => 'app\models\YiiUser',
            'enableAutoLogin' => true,
        ],

The user component has a key for identityClass and we placed our own class there. Once that was done we implemented \yii\web\IdentityInterface. You can learn more about it here. The interface requires some methods to operate and once this was filled out we could have used the yii_users table from the database to login.

I had to check whether a user was logged in and retrieve the username of the user if that was the case. The code below shows how and some helper functions.

Yii::$app->user->isGuest // is user a guest
Yii::$app->user->id // get user id
YiiUser::findIdentity($id)->username; // get username 

/** find identity function in YiiUser**/
 public static function findIdentity($id)
    {
        return self::find()
            ->where(['id'=>$id])
            ->one();
    }

Flash Messages

Flash messages are easy in Yii. To create a flash message use the code below

Yii::$app->session->setFlash('success',"Hello World"); // set flash

Forms

Yii has some really cool form features that make creating forms a really lazy task. I didn’t get to involved with it because I’m accustom to Yii even though some things would have changed. But I’ll just go over the create a gallery form that I used.

The class used for forms in Yii2 is ActiveForm. You can learn more about it here. Below shows how I created the form.

<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>

            <?= $form->field($model, 'title')
                ->hint("Please enter the tittle")
                ->textInput(['autofocus' => true]) ?>

            <?= $form->field($model, 'imageUrl')
                ->hint("Enter a Url")
                ->textInput(["autofocus"=>true]) ?>

            <div class="form-group">
                <?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
            </div>

<?php ActiveForm::end(); ?>

Nothing fancy here. The active form widget has a begin and a end command. Between you can add form fields. Notice they are attached to a model which would be the active rec8ord Class Gallery. It allows you to add input and does validation. This is really simple. There are a lot more features to play with.

Access Control

The create, update, edit and delete routes need to be filtered. They should only be accessible to logged in users. To do this – in the behaviours method in my GalleryController I can return some arrays which tell Yii to do this.

use yii\filters\AccessControl; // needs this first

 public function behaviors()
    {
        return [
            'access' => [
                'only' => ["create","update","edit","delete"],
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
        ];
    }

The role has different symbols. The @ sign says authenticated users only. That covers all users that are logged in. As usually things can get more complicated. When you have multiple roles and different permissions.

Summary

Yii2 is a really good framework. Well it has to be Yii one was great. Its surprisingly easy to setup and not complicated to use. I like the style of programming it uses in Yii1.1 and Yii2 seems to go even further. Using views with active forms require php named files so I’m not sure you can use twig with yii widgets. Probably not. I haven’t tried. But that’s fine. Another framework I can work with. Some pictures of the sample gallery is shown below.

One thought on “Building a CRUD application using PHP and the YII2 framework.

  1. Hey, you set down such a great blog, I want to ask something about your blog, Why is PHP still alive? Is it very important for learning purpose? Why is it better and how it can beat other languages? What are the most complimentary uses of PHP?

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s