風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

PHPは手強い…

仕事の都合上やむを得ずPHPを使わざるを得なくなって、いろいろ混乱中。

配列のループ時によくやるミス

たとえば、

$list = array(array('a' => 1), array('a' => 2), array('a' => 3));

$list = array(array('a' => 11), array('a' => 12), array('a' => 13));

のように、リストになっている連想配列それぞれに同様の操作を施したいような場合。

NGパターン
foreach ($list as $item) $item['a'] += 10;
OKパターン
foreach ($list as &$item) $item['a'] += 10;

ついつい“&”を付け忘れてはまる…。


追記(2014/09/25)

リファレンス(&)を使った場合はいろいろとはまる要素が多いので、十分注意のこと…というか、極力使わない方向で。

PHPのリファレンス(参照)について、自分なりにかみくだいてみる - 風柳メモ

とりあえず、foreach の後は、unset($item) しとけ>過去の自分…というか、以前のプログラムにこういう不具合をいっぱい含めていそうで怖い(汗)。



Smarty3になって良かったこと

以前、

{$foo['bar']}

と書けなくていらいらした経験があるのだけれど、Smarty3からは書けるようになっているのはうれしい。
上記の場合はまだしも、

{$foo.bar}

でよいとして、hoge[':fuga']とかだとどう書けばいいのかで悩まされるので。
$fuga=':fuga'にしておいて$hoge.$fugaとか、方法はあるにしてもまだるっこしい。

イベントと関数の結びつけ

$func_map = array(
    'event1' => <関数1>
,   'event2' => <関数2>
,   'event3' => <関数3>
);

のように連想配列でイベントと関数をマッピングして、

$result = $func_map[$event]();

みたいに呼び出す、というのはよく使われる手だと思うけれど、PHPに不慣れなので、関数の登録方法に迷う。

通常の関数
function test(){
    echo 'TEST';
}
$test = 'test';
$test(); // 'TEST'

のように関数名を文字列として登録した変数はそのまま呼び出し可能みたい。
この場合だとそのまま登録すればよいけれど、

class Test {
    // : 中略
    public function test(){ // これを登録したい
        echo 'TEST';
    }
};

のような場合はどうするか。

call_user_func() を使えばよいかも
$obj = new Test();
$test = array($obj, 'test');
call_user_func($test); // 'TEST'

で、一応可能のようだ。

実用的には、コンストラクタで登録しておいて、イベント処理関数で呼び出すとか、か。
オブジェクトを生成せずに登録する方法は不明なのが惜しい。

class Test {
    private $func_map;
    // :中略
    public function __construct() {
        // : 中略
        $this->func_map = array(
            'event1' => array($this, 'func1')
        ,   'event2' => array($this, 'func2')
        ,   'event3' => array($this, 'func3')
        // : 中略
        );
    }
    private function func1(){
        // : 中略
    }
    //  : 中略
    public function main($event) {
        $result = call_user_func($this->func_map[$event]);
        // : 後略
    }
    // :後略
}

実際には例外処理で後数行程度は要るだろうけれど、switch($event)やif($event...)よりはすっきりと書けそう。