CodeIgniterのViewで少しだけ工夫した点

CodeIgniter Advent Calendar 2015 - Qiita 5日目に参加しております。

いよいよ年末、お風呂のカビは手強い・掃除に時間がかかるので、早めに対処しましょう!
お風呂のカビ掃除の記録はコチラをどうぞ。

さて、今回はCodeIgniter3のViewを使った際のことを書きます。 Viewはロジックと出力(HTMLなど)を分離する大事な機能です。
デザイナさんとの分業をする場合は気を使う部分ではないでしょうか?
PHPでViewを実現するには、PHP自身をテンプレートエンジンとしたり、TwigやSmartyのようなテンプレートエンジンを使う手法がありますが、今回はCodeIgniter標準のView機能でのPHP自身をテンプレートエンジンにする方法を使っています。

参考

Views — CodeIgniter 3.1.11 documentation

シンプルにできていて使い方は簡単です。

  1. コントローラーで$dataにViewに渡したい値をセットする。
    $this->load->view( 'Viewの名前', $data );
    をコールする。

  2. viewのファイルを用意する。

サンプルとしてはこんな感じです。

  • Controller
<?php
defined( 'BASEPATH' ) OR exit('No direct script access allowed');

/**
 * Class Sazaesan
 */
class Sazaesan extends CI_Controller
{

    public function __construct()
    {
        parent::__construct();
    }


    public function index()
    {

        // ごにょごにょと処理。

        // view用のデータをセット
        $data          = [ ];
        $data['title'] = "こんにちは";

        $data['datanum'] = 3;
        $data['namihei'] = "磯野波平";
        $data['fune']    = "磯野フネ";
        $data['sazae']   = "フグ田サザエ";

        $data['flg_exist_hair'] = true;

        $this->load->view( 'sazaesan_index', $data );
    }
}
  • View
<?php
?><!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title><?= html_escape( $title ); ?></title>
</head>
<body>

<div id="container">
    <h1><?= html_escape( $title ); ?></h1>

    <div id="body">
        <div><?= html_escape( $namihei ); ?>さん
            <?php if( $flg_exist_hair ): ?>
                やったー
            <?php endif; ?>
        </div>

        <div><?= html_escape( $fune ); ?>さん</div>
        <div><?= html_escape( $sazae ); ?>さん</div>
    </div>
</div>

</body>
</html>
  • 出力
    こんにちは

まぁ、シンプルなものです。

Viewで気に入らなかった点

最近の開発環境は賢いです。統合開発環境IDE(PhpStormなど)はView内の変数が未定義だと警告を出してくれます。(赤線がでています。)

Codeigniter_view_in_phpstorm

もちろん間違いではありません。 Viewは別PHPファイルです。
CodeIgniterはdata配列を extract してincludeするのですが、IDEはこんなところまでは知りません。 そのため未定義変数ではないかと警告が出ています。

ちゃんとViewにphpdocコメントを入れれば警告は無くなります。コード補完も効くようになります。

  • View
    /** @var String $title */
    /** @var String $namihei */
    
    
    

もう一点、当たり前ですが、Viewの中で未定義の変数を使ってしまうとエラーが出てしまいます。 たとえば、

  • View
    <div><?= html_escape( $katsuo ); ?>くん</div>

この変数はViewに渡されておらず未定義なので エラーとなってしまいます。

error_view

Viewに渡した変数名を忘れることもあり、確認のためにコントローラーやモデルのソースを往復してしまいます。 ちゃんとコメントを書けば良いのですが、なかなか定着しません。

Viewに少し工夫した!

Viewに渡る変数がわからなければ出力すればよいのです。 今回はViewのPHPの末尾にデバッグ用のコードを入れました。


・(省略)

        <div><?= html_escape( $fune ); ?>さん</div>
        <div><?= html_escape( $sazae ); ?>さん</div>
    </div>
</div>

<?php

    // 変数のPHPdocを出力 
    echo "<pre>";
    foreach( $_ci_vars as $key => $item ){
        $type = gettype( $item );
        echo str_pad( "/** @var $type $".$key, 50 )."*/\n";
    }

    //内容をダンプ
    print_r( $_ci_vars );
    echo "</pre>";

?>
</body>
</html>

すると、こんな感じで表示されます。

dumpvars

print_r は内容確認のためのオマケです。
あとはこれをViewの先頭あたりにコピペすれば、IDEの未定義変数は消え、どんな変数があるかもわかり、存在しない変数はIDEが警告を出してくれます。
リリース時にはちゃんとこのコードを消すことを忘れないで下さい!

  • 改善したView
<?php
/** @var string $title                            */
/** @var integer $datanum                         */
/** @var string $namihei                          */
/** @var string $fune                             */
/** @var string $sazae                            */
/** @var boolean $flg_exist_hair                  */
?><!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title><?= html_escape( $title ); ?></title>
</head>
<body>
・
・
・

(変数の説明も入れたほうがより良いです。)

所感

PHPをテンプレートエンジンとして使うのは、知ってる記法でさっさと書け、パフォーマンスも良いのですが、次のようなデメリットもあります。

  • ちょっとミスるとユーザーにエラー情報を見せてしまう。

  • なんでもできるので、ついついロジックを作成してしまう。

Twigを使うことも考えてみたいと思います。
では皆さま、よいCodeIgniter年末を!