Smarty3 + CakePHP3 でらくらくファイル出力


やりたいこと

テンプレートファイルを用意して、ユーザーがフォームから入力した値を埋め込みたい!
そして値を埋め込んだ結果をファイル出力したい!

環境

CakePHP: 3.5.6
CentOS: 7.4
Smarty: 3.1

Smartyを触ったことがなかったので、触ってみることに。

手順

Smartyのセットアップ

composerにてインストール

composer require smarty/smarty:~3.1

ディレクトリ作成

smarty-sample/  ・・・CakeのROOTディレクトリ
  smarty/
    templates/  ・・・テンプレートファイル(.tpl)の設置先
    templates_c/  ・・・コンパイル結果出力先
    cache/ ・・・キャッシュファイル出力先
  files/  ・・・テンプレート埋め込み後のファイル保存先

apacheユーザーが書き込めるようにします。

chmod 0777 smarty/templates_c smarty/cache/
chmod 0777 files

PATHの設定

利用しやすいようにpaths.phpに書いちゃいましょう。

// config/paths.phpに追記
# Smarty用ディレクトリ
define('SMARTY_TEMPLATE_DIR', ROOT . DS . 'smarty' . DS . 'templates' . DS);
define('SMARTY_COMPILE_DIR', ROOT . DS . 'smarty' . DS . 'templates_c' . DS);
define('SMARTY_CACHE_DIR', ROOT . DS . 'smarty' . DS . 'cache' . DS);
define('SMARTY_CONFIG_DIR', ROOT . DS . 'smarty' . DS . 'config' . DS);

# ファイル出力用ディレクトリ
define('FILE_DIR', ROOT . DS . 'files' . DS);

クラスの拡張

<?php
namespace App\Lib;

use Smarty;

class AppSmarty extends Smarty
{

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

        // paths.phpに書いた値を使って初期化
        $this->template_dir = SMARTY_TEMPLATE_DIR;
        $this->compile_dir = SMARTY_COMPILE_DIR;
        $this->config_dir = SMARTY_CONFIG_DIR;
        $this->cache_dir = SMARTY_CACHE_DIR;
    }

}

?>

これでAppSmartyをuseしてあげれば利用可能です!

サンプル

えいやっとサンプルを作りました。

tplファイル

smarty/templates/hello.tpl

私の名前は {$name} です!

{$comment}

◯ 食べたいもの
{foreach $favorites as $key => $val}
・{$val}
{/foreach}

smarty/templates/hello2.tpl

名前: {$name}
コメント: {$comment}
好きな食べ物:
{foreach $favorites as $key => $val}
    ・{$val}
{/foreach}

配列を渡すこともできます。

Controller

TutorialController.php

<?php
namespace App\Controller;

use App\Controller\AppController;

// AppSmartyの読み込み
use App\Lib\AppSmarty;
use Cake\Filesystem\File;

class TutorialController extends AppController
{
    public function add()
    {

        if ($this->request->is('post')) {
            // 1. インスタンスを作成
            $smarty = new AppSmarty();

            // 2. リクエストデータを変数を割り当て
            // $this->assign(template内変数, 割り当てる値)
            foreach ($this->request->getData() as $key => $val) {
                $smarty->assign($key, $val);
            }

            // 3. fetch('template file')で変数の割当後の値を取得
            // assignした値を使って複数のtemplateを利用することができる
            $hello1 = $smarty->fetch('hello1.tpl');
            $hello2 = $smarty->fetch('hello2.tpl');

            // 4. Fileユーティリティを利用して結果を出力
            (new File(FILE_DIR . 'hello1.txt'))->write($hello1);
            (new File(FILE_DIR . 'hello2.txt'))->write($hello2);
        }

    }
}

View

add.ctp

<fieldset>
    <?= $this->Form->create(
        null,
        [
            'url' => [
                'controller' => 'Tutorial',
                'action' => 'add'
            ]
        ]) ?>
    <?= $this->Form->input('name') ?>
    <?= $this->Form->input('comment') ?>

    <?= $this->Form->select(
        'favorites',
        [
            ['text' => 'カレー', 'value' => 'カレー'],
            ['text' => 'カツ丼', 'value' => 'カツ丼'],
            ['text' => '焼肉', 'value' => '焼肉'],
        ],
        [
            'multiple' => 'checkbox'
        ]
    ) ?>

    <?= $this->Form->button(__('submit')) ?>
    <?= $this->Form->end() ?>
</fieldset>

現在21:30。食欲がctpファイルに如実に現れています。

postしてみる

Let's post!!

結果

[fusic@localhost smarty-sample]$ cat files/hello1.txt
私の名前は koga です!

お腹すいた。。

◯ 食べたいもの
・カレー
・焼肉

[fusic@localhost smarty-sample]$ cat files/hello2.txt
名前: koga
コメント: お腹すいた。。
好きな食べ物:
 ・カレー
 ・焼肉

値が埋め込まれた結果がちゃんと出力されました!!

まとめ

  • SmartyとFileユーティリティで簡単にファイル出力できました!
  • templateの工夫次第で色々できるかも?

参考リンク

Smarty3 マニュアル
Folder & File