Edited at

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


はじめに

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


参考文献