LoginSignup
6

More than 5 years have passed since last update.

Smartyで配列のキーにハイフンが使えない理由

Posted at

【Smarty】配列のキーにハイフンを使ったらアウトらしい
http://qiita.com/seihowlow24/items/713e12c459fa47df7eb1

こういう記事がありました。
Smartyでは連想配列のキーに-を使用できないという問題です。

では何故使えないのかというのを少し調べてみたので記載。
使用したバージョンはSmarty3.1.19。

まあ言ってしまうとマイナスと区別が付かないからです。

index.php
<?php
    $hoge = [
        'a'=>10,
        'a-1'=>5,
    ];
    $smarty->assign('hoge', $hoge);
    $smarty->display('index.html');
index.html
    {$hoge.a-1}

{$hoge.a-1}$hoge['a-1']ではなく$hoge['a']-1と解釈され、結果は「9」になります。

実際コンパイル後のファイルは

<?php echo $_smarty_tpl->tpl_vars['hoge']->value['a']-1;?>`

となっています。
これはSmartyが演算をサポートするかぎりどうしようもないですね。

PHPの配列キーには他の演算子や記号や日本語なども大概入れられますが、Smartyテンプレートでは大半が使用できません。
$など使っただけでFatal errorが発生します。

index.php
<?php
    $hoge = [ 'some-key'=>'val' ];
    $smarty->assign('hoge', $hoge);
    $smarty->display('index.html');
index.html
    {$hoge.some-key}

コンパイル後。

<?php echo $_smarty_tpl->tpl_vars['hoge']->value['some']-'key';?>

$_smarty_tpl->tpl_vars['hoge']->value['some']は未定義なのでNULL - 'key'というよくわからない演算となり、結果は「0」となります。
当然Undefined indexのNoticeも発生します。

おっと、参考サイトと何故か結果が違ってますね。
参考サイトは『{$hoge['some-key']}と書けない』とか言ってるので、古いバージョンだと思われます。
最近のバージョンでは{$hoge['some-key']}と問題なく書くことが可能です。
こちらであれば記号や日本語などの配列キーもそのまま使えるので、常にこちらの記法で書くとか決めてしまってもいいかもしれません。

ちなみに構文解析の実体はSMARTY_SYSPLUGINS_DIR.smarty_internal_templatelexer.phpあたりにありますが、

preg_match('/\G(\{\})|\G(\{\*([\S\s]*?)\*\})|\G(\{\s*strip\s*\})|\G(\{\s*\/strip\s*\})|\G(\{\s*literal\s*\})|\G(\{\s*(if|elseif|else if|while)\s+)|\G(\{\s*for\s+)|\G(\{\s*foreach(?![^\s]))|\G(\{\s*setfilter\s+)|\G(\{\s*\/)|\G(\{\s*)|\G(<\?(?:php\w+|=|[a-zA-Z]+)?)|\G(\?>)|\G(\s*\})|\G(<%)|\G(%>)|\G([\S\s])/iS', $contents);

うん、これ読むの無理。
これとかSmarty_Internal_Templateparserはいったい何なのか誰か教えて下さい。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6