Facebook Twitter Google Maps RSS
Home 開発言語 PHPで無名関数
formats

PHPで無名関数

Published on 2014年7月31日, by in 開発言語.

こんにちは、陽気なシステム屋です。

今さらですが、PHP5.3で無名関数(Closureクラス)が実装されました。

個人的にJavaScriptなどで馴染み深い無名関数ですが
PHPではどんなふうに使えるのか試したことがなかったので
ちょっとやってみたいと思います。

▼クロージャ(Closureクラス)とは?
(PHPでは)無名関数を表すために使うクラスです。

▼無名関数とは?
関数名を指定せずに関数を作成できるようにするものです。

↓↓では使ってみます

①無名関数をコールバックに使う
array_walk()のコールバックに無名関数を指定してみます。

// 配列の全ての要素のうち空文字をNULLに置換する
$hoge = array(‘aaa’, ”, ‘ccc’, ‘ddd’, ”);
array_walk($hoge, function(&$val) { if($val === ”) $val = null; });
var_dump($hoge);

▼出力結果
array(5) {
  [0]=>
  string(3) “aaa”
  [1]=>
  NULL
  [2]=>
  string(3) “ccc”
  [3]=>
  string(3) “ddd”
  [4]=>
  NULL
}

②無名関数を変数にセットする
無名関数を生成して変数に入れておくことができます。

// 引数を返すだけの無名関数
$hoge = function($arg) { return $arg; };
echo ‘hoge1 => ‘.$hoge(‘fuga’);

// 外部変数(値渡し)を返す無名関数
$fuga = ‘fuga’;
$hoge = function() use($fuga) { return $fuga; };
echo ‘hoge2 => ‘.$hoge();

// 外部変数(参照渡し)を変更して返す無名関数
$fuga = ‘fuga’;
$hoge = function() use(&$fuga) { return $fuga.=’!?’; };
echo ‘hoge3 => ‘.$hoge();
echo ‘fuga => ‘.$fuga;

▼出力結果
hoge1 => fuga
hoge2 => fuga
hoge3 => fuga!?
fuga => fuga!?

// 無名関数をセットした変数を見るとClosureクラスになってます
var_dump($hoge);

▼出力結果
object(Closure)#1 (1) {
  [“static”]=>
  array(1) {
    [“fuga”]=>
    &string(6) “fuga!?”
  }
}

③無名関数にオブジェクトをバインドする(PHP5.4~)
PHP5.4以降、Closureクラスにメソッドが追加され
無名関数に別オブジェクトをバインドできるようになりました。

// Piyoクラスオブジェクト生成
class Piyo {
  public $pub_val = ‘public_value’;
  private $pri_val = ‘private_value’;
}
$piyo = new Piyo();

// Piyoクラスオブジェクトをバインドした無名関数を生成
// (第1引数に無名関数、第2引数にバインドするオブジェクト、第3引数にスコープ(省略するとstatic))
$hoge = Closure::bind(function() { return $this->pub_val.=’!!’; }, $piyo);

// private変数を操作する場合はスコープをPiyoクラスにする
$fuga = Closure::bind(function() { return $this->pri_val.=’!?’; }, $piyo, ‘Piyo’);

// いったん無名関数を生成し、bindTo()で複製という書き方もできます
// 無名関数を生成
$fu = function() { return $this->pri_val.=’!?’; };

// Piyoクラスオブジェクトをバインドして無名関数を複製
// (第1引数にバインドするオブジェクト、第2引数にスコープ)
$fuga = $fu->bindTo($piyo, ‘Piyo’);

// 無名関数内で $this が $piyo を参照します
echo ‘hoge => ‘.$hoge();
echo ‘fuga => ‘.$fuga();

▼出力結果
hoge => public_value!!
fuga => private_value!?

// Piyoクラスオブジェクト($piyo)の値を変えてみる
$piyo->pub_val.= ‘ Hooooo’;
echo ‘hoge2 => ‘.$hoge();

▼出力結果
hoge2 => public_value!! Hooooo!!

// Piyoクラスオブジェクト($piyo)がどうなったか見てみる
var_dump($piyo);

▼出力結果
object(Piyo)#1 (2) {
  [“pub_val”]=>
  string(23) “public_value!! Hooooo!!”
  [“pri_val”:”Piyo”:private]=>
  string(15) “private_value!?”
}

こんな感じでした。

コールバックはよく使いますが、変数やバインドは今のところ実務で使ったことないです。
どんな有用性があるかは今後みつけていきたいと思います。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*