Help us understand the problem. What is going on with this article?

CodeIgniter 3.1.10 と Smarty 3.1を連携する開発環境を構築する

More than 1 year has passed since last update.

はじめに

PHP5系でCodeIgniter 2.0.xで開発されたシステムをPHP7系に移植する作業を依頼されました。
腕のいい開発者さんが作ったのでしょう。シンプルな中にも質実剛健のような作りで、見ていて気持ちがいいです。

ですが、この世に産み落とされてから早x年。
時代は、CodeIgniterからLaravelに移り、開発者さん自身もメンテナンスを放棄されてしまったようで、私のところへの依頼となりました。

さて、CodeIgniterの2.0.xから2.2までは問題なくアップデートができたのですが、3系へのアップグレード時に、使われていたSmartyが使えなくなりました。
そこで、CodeIgniter3系でSmartyのインストール方法を探しましたが、ロストテクノロジーなので、メチャメチャ苦労しました。
そのため、ここで導入方法を記録しておきます。

驚いたことに、Smartyの導入さえできれば、開発されたコードは、そのまま使えましたので、まだまだ現役稼働ができる見込みが立ちました。
システムのリフォーム? リストア? 蘇ると嬉しいですね。

今回のサンプルコードをGitHubにあげています。もし、参考になったのでしたら、スターをつけていただくとモチベーションがあがります
https://github.com/idani/CodeIgniter3.1-Smarty3.1-Smaple

環境

CodeIgniterの特徴

さて、私、CodeIgniterって今回、所見でした。なので、自分用のメモとして触った感じをメモ。

applicationとsystemディレクトリに分かれています。
systemの機能を拡張したい場合でも、applicaitonディレクトリの方で、継承、上書きなどを行って独自にカスタマイズできることが可能です。

また、この構成のおかげで、Systemのバージョンアップをする場合にも、systemディレクトリを最新バージョンで上書きするだけで動くという、すっごい楽なメンテナンス性がよいですね。

開発環境構築

まずは、CodeIgniterを動作させるためのPHPの実行・開発環境を用意します。
https://github.com/idani/CodeIgniter3.1-Smarty3.1-Smaple

ディレクトリ構成は、このようになっています。
基本的にSRCの部分を差し替えて、いろいろのPHPの開発で使いまわしています。

2019-08-04_20h51_32.png

このあたり、Dockerの部分がわからない場合は、以下のサンプルコードと記事を見てもらえれば理解できます。

https://github.com/idani/nginx-http2-php-mysql

今回は、SRCに、「codeignter-3.1.10」を展開からスタートしました。

smartyのインストール

docker-compose.ymlの最後の部分でComposerイメージを使ってインストールします。

まずは、以下のようにdocker-compose.ymlを書き換えます。

docker-compose.yaml
  composer:
    image: composer
    volumes: 
      - ./src/application:/app
    command: composer require smarty/smarty

その上で、docker-composeを実行して、インストールを行います。
Smartyのダウンロードを行いますので、終了するまでネットワーク環境によりますが、2,3分かかります。

$ docker-compose up composer
Creating network "codeigniter31-smarty31-smaple_default" with the default driver
Creating codeigniter31-smarty31-smaple_composer_1 ... done
Attaching to codeigniter31-smarty31-smaple_composer_1
Gracefully stopping... (press Ctrl+C again to force)
Stopping codeigniter31-smarty31-smaple_composer_1 ... done

CodeIgniterでのComposerの読み込み設定

「application/config/config.php」で「composer_autoload」をTrusにする。

2019-08-04_19h37_45.png

config.phpに書いてありますが、
「application/vendor/autoload.php」を読み込む場合は、先のように「$config['composer_autoload'] = TRUE;」にするだけでOKです。

CodeIgniterのインストールしたディレクトリを変更する場合は、「$config['composer_autoload'] = '/path/to/vendor/autoload.php';」と設定します。

ディレクトリの作成

Smarty用のテンプレートディレクトリとテンプレートキャッシュ用のディレクトリを作成します。

application/views/templates
application/views/templates_c
の2つのディレクトリをchmod 777で作成しておきます。

Smarty用のライブラリ作成

参考文献記載のライブラリを作成して、CodeIgniterとSmartyの橋渡しをします。

ここで、CodeIgniter側の制限ですが、ファイル名とクラス名は合わせる必要があり、また、すでにSmartyクラスはあるので、「Smartie」としています。

ここは気持ち悪いのですが、後ほど、ライブラリの読み込み時に「Smarty」に補正をかけます。

application/library/Smartie.php
<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Smartie Class
 *
 * @package        CodeIgniter
 * @subpackage     Libraries
 * @category       Smarty
 * @author         Kepler Gelotte
 * @link           http://www.coolphptools.com/codeigniter-smarty
 */

class Smartie extends Smarty {

    var $debug = false;

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

        $this->setTemplateDir(APPPATH . "views/templates");
        $this->setCompileDir(APPPATH . "views/templates_c");
        if ( ! is_writable( $this->compile_dir ) )
        {
            // make sure the compile directory can be written to
            @chmod( $this->compile_dir, 0777 );
        } 

        // Uncomment these 2 lines to change Smarty's delimiters
        // $this->left_delimiter = '{{';
        // $this->right_delimiter = '}}';

        $this->assign( 'FCPATH', FCPATH );     // path to website
        $this->assign( 'APPPATH', APPPATH );   // path to application directory
        $this->assign( 'BASEPATH', BASEPATH ); // path to system directory

        log_message('debug', "Smarty Class Initialized");
    }

    function setDebug( $debug=true )
    {
        $this->debug = $debug;
    }

    /**
     *  Parse a template using the Smarty engine
     *
     * This is a convenience method that combines assign() and
     * display() into one step. 
     *
     * Values to assign are passed in an associative array of
     * name => value pairs.
     *
     * If the output is to be returned as a string to the caller
     * instead of being output, pass true as the third parameter.
     *
     * @access    public
     * @param    string
     * @param    array
     * @param    bool
     * @return    string
     */
    function view($template, $data = array(), $return = FALSE)
    {
        if ( ! $this->debug )
        {
            $this->error_reporting = false;
        }
        $this->error_unassigned = false;

        foreach ($data as $key => $val)
        {
            $this->assign($key, $val);
        }

        if ($return == FALSE)
        {
            $CI =& get_instance();
            if (method_exists( $CI->output, 'set_output' ))
            {
                $CI->output->set_output( $this->fetch($template) );
            }
            else
            {
                $CI->output->final_output = $this->fetch($template);
            }
            return;
        }
        else
        {
            return $this->fetch($template);
        }
    }
}
// END Smartie Class

ライブラリを読み込む

「application/config/autoload.php」の「libraries」の項目を以下のように修正します。

先程の「smartie」という部分を「smarty」に読み替えてロードしています。

application/config/autoload.php
/*
| -------------------------------------------------------------------
|  Auto-load Libraries
| -------------------------------------------------------------------
| These are the classes located in system/libraries/ or your
| application/libraries/ directory, with the addition of the
| 'database' library, which is somewhat of a special case.
|
| Prototype:
|
|   $autoload['libraries'] = array('database', 'email', 'session');
|
| You can also supply an alternative library name to be assigned
| in the controller:
|
|   $autoload['libraries'] = array('user_agent' => 'ua');
*/
$autoload['libraries'] = array('smartie'=>'smarty');

動作確認

デバッグメッセージを出力させるために、Configをいじります。
今回は「4:All Messages」を設定します。

application/config/config.php
/*
|--------------------------------------------------------------------------
| Error Logging Threshold
|--------------------------------------------------------------------------
|
| You can enable error logging by setting a threshold over zero. The
| threshold determines what gets logged. Threshold options are:
|
|   0 = Disables logging, Error logging TURNED OFF
|   1 = Error Messages (including PHP errors)
|   2 = Debug Messages
|   3 = Informational Messages
|   4 = All Messages
|
| You can also pass an array with threshold levels to show individual error types
|
|   array(2) = Debug Messages, without Error Messages
|
| For a live site you'll usually only enable Errors (1) to be logged otherwise
| your log files will fill up very fast.
|
*/
$config['log_threshold'] = 4;

ブラウザで「 http://127.0.0.1:8000/ 」を表示させます。
正常に動作したなら、以下のデフォルトのページが表示されます。

2019-08-04_19h02_16.png

そして、ログにもSmartyライブラリの初期化完了のログ「Smarty Class Initialized」が出力されます。

application/logs/log-.php
・・・
INFO - 2019-08-04 20:07:34 --> Loader Class Initialized
DEBUG - 2019-08-04 20:07:34 --> Smarty Class Initialized
INFO - 2019-08-04 20:07:34 --> Controller Class Initialized
INFO - 2019-08-04 20:07:34 --> File loaded: /src/application/views/welcome_message.php
INFO - 2019-08-04 20:07:34 --> Final output sent to browser
DEBUG - 2019-08-04 20:07:34 --> Total execution time: 0.0578

サンプルを作成する

CodeIgniterが初見なので、サンプルを書いてみます。

application/controllers/HelloWorld.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class HelloWorld extends CI_Controller {

    public function index() {
        $data = [
            'title' => 'Hello World!',
        ];
        $this->smarty->view('HelloWorld.tpl',$data);
    }
}

application/views/template/HelloWorld.tpl
{$title}

ブラウザで、「 http://127.0.0.1:8000/HelloWorld 」にアクセスをすると、以下のように表示されます。

「HelloWorld.php」の$data['title']を変更して、動的に表示が変更されることを確認してみてください。

2019-08-04_20h22_00.png

以上の構築した環境を、以下のGitHubで公開をしています。スターを付けていただけると、誰かの役に立ったんだとわかって、モチベーションがあがります。よろしくお願い致します。

https://github.com/idani/CodeIgniter3.1-Smarty3.1-Smaple

参考文献

idani
井谷(いだに)と申します。 前職では、cakePHPとjQueryとVue.jsを使って、メール配信、SMS配信、セミナー募集システム、かんたんな決済処理、アフィリエイトシステムなどを開発していました。 使える言語は、C、C++、Perl、C#、PHP、JSになります。 昔々、Gentoo Linuxの翻訳作業をしていました。
https://hirotae.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away