Click to share! ⬇️

Super Easy CRUD With Gii And The Yii2 Framework

Gii is an incredible piece of software that is part of the Yii Framework. It is a wonderful tool that writes code for you. So many of the development requirements of web applications in PHP include repetitive code, which is why we have these frameworks in the first place. The Gii tool takes it a step further, and creates the code needed to power Create Read Update and Delete functions, new Active Record Models, new Controllers, Forms, Modules, and extensions. It really is incredible. If you have been following along so far in this Yii Tutorial Series, you already have Gii installed and you’re ready to go. Let’s check it out.

Confirm Gii Is Installed

Like we mentioned, if you created a project along with us, you already have Gii installed. Visit the following URL to check.

http://localhost/yii/basic/web/index.php?r=gii

yii gii code generator

The code that enables this is found in config/web.php and web/index.php.

config/web.php

if (YII_ENV_DEV) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = 'yiidebugModule';

    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = 'yiigiiModule';
}

web/index.php

// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

Create A New Model

Now we can create a new model using Gii. First up, we need a table to work with. We’re going to create a simple no nonsense database table that will hold information about guitars. It will have an ID field, brand, and model. Here is the code to generate that new table.

mysql> use yii_framework_database;
Database changed

mysql> create table guitars (
    -> id int not null auto_increment primary key,
    -> brand varchar(64),
    -> model varchar(64)
    -> );
Query OK, 0 rows affected (0.03 sec)

Now that we have our table, we’ll choose the option to generate a Model in the Gii tool. Note that you provide the exact name of the table to generate a model for in lower case for the table name field. The Model Class will be the exact same name with just the first letter in uppercase. You must follow this convention. We will uncheck the option to generate relations on this first pass through, since we don’t have any. This is just a plain vanilla table with 3 basic fields.
yii guitars model

models/Guitars.php source

<?php

namespace appmodels;

use Yii;

/**
 * This is the model class for table "guitars".
 *
 * @property integer $id
 * @property string $brand
 * @property string $model
 */
class Guitars extends yiidbActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'guitars';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['brand', 'model'], 'string', 'max' => 64]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'brand' => 'Brand',
            'model' => 'Model',
        ];
    }
}

Awesome! We did not write even one line of code, all we did was tell Gii the name of the table, and now we have a fully functioning Model.

Create A Form With Gii

Gii can now create a view file for you based on the associated Model you just created. Note: When you visit the form generator, if you do not provide the fully qualified namespace for the Model Class field, you will get an error like Class ‘Guitars’ does not exist or has syntax error. So in our case, instead of specifying Guitars as the Model Class, we use appmodelsGuitars and all is well.
yii gii form generator

When this task is completed, you will get the following message:

The form has been generated successfully.

You may add the following code in an appropriate controller class to invoke the view:


<?php

public function actionGuitars()
{
    $model = new appmodelsGuitars();

    if ($model->load(Yii::$app->request->post())) {
        if ($model->validate()) {
            // form inputs are valid, do something here
            return;
        }
    }

    return $this->render('guitars', [
        'model' => $model,
    ]);
}

Fantastic! Not only did Gii create our view for us, it gave us the code that we’ll need for our controller as well. Here is the generated view code:

guitars.php source


<?php

use yiihelpersHtml;
use yiiwidgetsActiveForm;

/* @var $this yiiwebView */
/* @var $model appmodelsGuitars */
/* @var $form ActiveForm */
?>
<div class="guitars">

    <?php $form = ActiveForm::begin(); ?>

        <?= $form->field($model, 'brand') ?>
        <?= $form->field($model, 'model') ?>
    
        <div class="form-group">
            <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
        </div>
    <?php ActiveForm::end(); ?>

</div><!-- guitars -->

Create The Controller

One thing that will throw a few people off no doubt is the conventions of having use statements at the top of the controller file versus referencing the full namespace path then instantiating objects. Note the code we listed above used the second approach, but having use statements is a little more clear. We’ll create our controller as such.

GuitarsController.php source

<?php

namespace appcontrollers;

use Yii;
use yiiwebController;
use appmodelsGuitars;

class GuitarsController extends Controller
{

	public function actionGuitars()
	{
		$model = new Guitars();
	
		// if the post data is set, the user submitted the form
		if ($model->load(Yii::$app->request->post())) {
			
			// in that case, validate the data
			if ($model->validate()) {
				
				// save it to the database
				$model->save();		
				return;
			}
		}
	
		// by default, diplay the form
		return $this->render('guitars', [
			'model' => $model,
		]);
	}
}

Do note that if you get an error such as PHP Fatal Error – yiibaseErrorException Class ‘appcontrollersYii’ not found this just means you forgot to include use Yii; in your namespace declarations, so make sure to include that like you see above. At this point, we should have a functioning model, view and controller. Since this is an instance of ActiveForm, it will also have that super slick client side validation included as well. We can test it out by loading up the controller/view association. We’ll submit several guitars too.

http://localhost/yii/basic/web/index.php?r=guitars/guitars

yii guitar form

After we insert a few guitars, we can check out the results by looking in our database to be sure they took.

mysql> select * from guitars;
+----+-----------+-----------------+
| id | brand     | model           |
+----+-----------+-----------------+
|  1 | Fender    | Stratocaster    |
|  2 | Gibson    | Les Paul        |
|  3 | Music Man | John Petrucci 7 |
+----+-----------+-----------------+
3 rows in set (0.00 sec)

Oh Yeah – It’s working perfectly.


The Gii CRUD Generator

So far we’ve been doing the code generating in a somewhat piecemeal way. With Gii, we can do an entire php CRUD scenario for tables in our database. In this go around, we’ll create a drums table and let Gii create the entire setup for us.

1. Create The Drums Table

mysql> create table drums (
    -> id int not null auto_increment primary key,
    -> brand varchar(64) not null,
    -> model varchar(64) not null
    -> );
Query OK, 0 rows affected (0.03 sec)

2. Create the Model

You must create the Model for your table before you can run the CRUD generator. In this case, proceed exactly as we did with guitars, just use drums instead.

3. Run the CRUD Generator

yii gii crud generator

4. Enjoy Fully Functional CRUD!


Create

http://localhost/yii/basic/web/index.php?r=drums/create

gii create


Read

http://localhost/yii/basic/web/index.php?r=drums/index

gii read


Update

http://localhost/yii/basic/web/index.php?r=drums/update&id=2

gii update


Delete

http://localhost/yii/basic/web/index.php?r=drums/delete&id=2

gii delete


Wow! This should give you an idea of the power contained in Yii and it’s code generation tool Gii. All you need is a properly defined database table, and Gii will generate the entire CRUD infrastructure needed to give you a base functioning application. Super impressive.


The Generated Code

In the prior section, we saw how easy it was to create the full suite of crud functionality with Gii. All we did was create a database table, use Gii to generate a model, then used Gii to generate the entire crud code. Let’s look at the code generated so we understand how it works. This is necessary since the next step in working with and creating Yii applications is to customize the generated code by hand to meet the requirements for your website or application. See if you can understand exactly how these files interact. If you are familiar with the Model View Controller paradigm, it should be fairly straightforward.


Model(s)

models/Drums.php source

<?php

namespace appmodels;

use Yii;

/**
 * This is the model class for table "drums".
 *
 * @property integer $id
 * @property string $brand
 * @property string $model
 */
class Drums extends yiidbActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'drums';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['brand', 'model'], 'required'],
            [['brand', 'model'], 'string', 'max' => 64]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'brand' => 'Brand',
            'model' => 'Model',
        ];
    }
}

models/DrumsSearch.php source

<?php

namespace appmodels;

use Yii;
use yiibaseModel;
use yiidataActiveDataProvider;
use appmodelsDrums;

/**
 * DrumsSearch represents the model behind the search form about `appmodelsDrums`.
 */
class DrumsSearch extends Drums
{
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id'], 'integer'],
            [['brand', 'model'], 'safe'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        // bypass scenarios() implementation in the parent class
        return Model::scenarios();
    }

    /**
     * Creates data provider instance with search query applied
     *
     * @param array $params
     *
     * @return ActiveDataProvider
     */
    public function search($params)
    {
        $query = Drums::find();

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        if (!($this->load($params) && $this->validate())) {
            return $dataProvider;
        }

        $query->andFilterWhere([
            'id' => $this->id,
        ]);

        $query->andFilterWhere(['like', 'brand', $this->brand])
            ->andFilterWhere(['like', 'model', $this->model]);

        return $dataProvider;
    }
}

Controller

controllers/DrumsController.php source

<?php

namespace appcontrollers;

use Yii;
use appmodelsDrums;
use appmodelsDrumsSearch;
use yiiwebController;
use yiiwebNotFoundHttpException;
use yiifiltersVerbFilter;

/**
 * DrumsController implements the CRUD actions for Drums model.
 */
class DrumsController extends Controller
{
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['post'],
                ],
            ],
        ];
    }

    /**
     * Lists all Drums models.
     * @return mixed
     */
    public function actionIndex()
    {
        $searchModel = new DrumsSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

    /**
     * Displays a single Drums model.
     * @param integer $id
     * @return mixed
     */
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    /**
     * Creates a new Drums model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new Drums();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Updates an existing Drums model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Deletes an existing Drums model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();

        return $this->redirect(['index']);
    }

    /**
     * Finds the Drums model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return Drums the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = Drums::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}

View(s)

views/drums/create.php source

<?php

use yiihelpersHtml;


/* @var $this yiiwebView */
/* @var $model appmodelsDrums */

$this->title = 'Create Drums';
$this->params['breadcrumbs'][] = ['label' => 'Drums', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="drums-create">

    <h1><?= Html::encode($this->title) ?></h1>

    <?= $this->render('_form', [
        'model' => $model,
    ]) ?>

</div>

views/drums/_form.php source

use yiihelpersHtml; use yiiwidgetsActiveForm; /* @var $this yiiwebView */ /* @var $model appmodelsDrums */ /* @var $form yiiwidgetsActiveForm */ ?> <div class="drums-form"> <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'brand')->textInput(['maxlength' => 64]) ?> <?= $form->field($model, 'model')->textInput(['maxlength' => 64]) ?> <div class="form-group"> <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?> </div>

views/drums/index.php source

<?php

use yiihelpersHtml;
use yiigridGridView;

/* @var $this yiiwebView */
/* @var $searchModel appmodelsDrumsSearch */
/* @var $dataProvider yiidataActiveDataProvider */

$this->title = 'Drums';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="drums-index">

    <h1><?= Html::encode($this->title) ?></h1>
    <?php 
	// uncomment the following line for a full search form on the index page
	// echo $this->render('_search', ['model' => $searchModel]); 
	?>

    <p>
        <?= Html::a('Create Drums', ['create'], ['class' => 'btn btn-success']) ?>
    </p>

    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yiigridSerialColumn'],

            'id',
            'brand',
            'model',

            ['class' => 'yiigridActionColumn'],
        ],
    ]); ?>

</div>

views/drums/_search.php source

<?php

use yiihelpersHtml;
use yiiwidgetsActiveForm;

/* @var $this yiiwebView */
/* @var $model appmodelsDrumsSearch */
/* @var $form yiiwidgetsActiveForm */
?>

<div class="drums-search">

    <?php $form = ActiveForm::begin([
        'action' => ['index'],
        'method' => 'get',
    ]); ?>

    <?= $form->field($model, 'id') ?>

    <?= $form->field($model, 'brand') ?>

    <?= $form->field($model, 'model') ?>

    <div class="form-group">
        <?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
        <?= Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
    </div>

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

</div>

views/drums/update.php source

<?php

use yiihelpersHtml;

/* @var $this yiiwebView */
/* @var $model appmodelsDrums */

$this->title = 'Update Drums: ' . ' ' . $model->id;
$this->params['breadcrumbs'][] = ['label' => 'Drums', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]];
$this->params['breadcrumbs'][] = 'Update';
?>
<div class="drums-update">

    <h1><?= Html::encode($this->title) ?></h1>

    <?= $this->render('_form', [
        'model' => $model,
    ]) ?>

</div>

views/drums/view.php source

<?php

use yiihelpersHtml;
use yiiwidgetsDetailView;

/* @var $this yiiwebView */
/* @var $model appmodelsDrums */

$this->title = $model->id;
$this->params['breadcrumbs'][] = ['label' => 'Drums', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="drums-view">

    <h1><?= Html::encode($this->title) ?></h1>

    <p>
        <?= Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
        <?= Html::a('Delete', ['delete', 'id' => $model->id], [
            'class' => 'btn btn-danger',
            'data' => [
                'confirm' => 'Are you sure you want to delete this item?',
                'method' => 'post',
            ],
        ]) ?>
    </p>

    <?= DetailView::widget([
        'model' => $model,
        'attributes' => [
            'id',
            'brand',
            'model',
        ],
    ]) ?>

</div>

Conclusion

In this episode we checked out the awesome Gii Code Generation tool which is a part of the great Yii 2 Framework. We learned that by simply providing some basic information to the tool, along with a valid database table, it will create all the code we need to interact with that data. When you’re ready, check out the advanced template in yii for a great way to build out an application shell.

Click to share! ⬇️