便利だけど使いどころが難しいPHPの代表的なマジックメソッドと無名関数の使い方:PHPオブジェクト指向プログラミング入門(4)(3/3 ページ)
「PHPで、どのようにオブジェクト指向プログラミングをしていくか」を解説する連載。今回は、マジックメソッドの概要と__get()、__set()、__call()、__callStatic()、__toString()の書き方と使い方に加え、PHP 5.3から使えるようになった無名関数と__invoke()について解説します。
無名関数と、そこで使われている__invoke()
PHP 5.3から使えるようになった「無名関数」とは
PHPでは、5.3から「無名関数」という文法が増えました。英語表記で「Anonymous functions」とされる通り「Anonymous(名前のない)」関数です。リスト11のように書きます。
<?php // $func = function () { echo "Anonymous function\n"; }; // $func();
無名関数は、例えば「関数自体、を関数の戻り値として返す」であるとか、あるいは「関数の引数で『callable』とされているところに直接関数を書く」などの用途で使われることがあります。関数の引数に直接関数を書くのは、JavaScriptだと比較的なじみがあるものかと思います。
比較的よく見掛ける無名関数の使い方としては、例えば「set_error_handler()関数を使って、標準の関数についても、エラーであれば例外をthrowする」というものです。リスト12は、実際に「関数の引数に、直接無名関数を記述している」書き方です。
set_error_handler( function($errno, $errstr, $errfile, $errline) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); });
無名関数は、どう実装されているのか
さて、この「無名関数」ですが、実際にはPHPでどのように実装されているのでしょうか?
まずは、リスト11に少し手を入れて、確認してみましょう。
<?php // $func = function () { echo "Anonymous function\n"; }; // $func(); var_dump($func);
実行すると、下記のようになります。
Anonymous function object(Closure)#1 (0) { }
このように、実際には無名関数はインスタンスになっています。
インスタンスを関数として扱う__invoke()
無名関数は内部的には、「__invoke()」というマジックメソッドを使っています。冒頭で述べた通りマジックメソッドは一定の条件の下に暗黙で呼ばれるメソッドですが、別に明示的に呼んではいけないわけではないので、明示的に呼んでみましょう(リスト14)。
<?php // $func = function () { echo "Anonymous function\n"; }; // $func->__invoke();
動かしてみると分かる通り、結果13と同じ動きをします。
__invokeマジックメソッドはインスタンスを関数としてコールしようとした際に呼ばれるマジックメソッドなので、例えばリスト15のようなコードを書くことができます。
<?php // class hoge { public function __invoke() { echo "call method\n"; } } // $obj = new hoge(); $obj();
普段は無名関数の書式で使うことが多いので、__invoke自体を実際に実装するという機会は少ないかと思いますが、「こんなことができる」というのを知っておくと、ひょんなところで役に立つかもしれません。
__toString()でインスタンスを文字列にする
前述のように__invokeはインスタンスを関数として扱う場合に使いますが、インスタンスを文字列のように扱う場合、__toStringを使います。「toString」というメソッド名自体は、実はJavaやC#など、いくつかの言語にも見られるメソッドです。ログへの出力などの状況で、うまく使っていくと便利です。
実際に、コードを書いて検証してみましょう。まずは、__toStringがない場合です。
<?php // class hoge { } // $obj = new hoge(); $s = 'data is ' . $obj; echo "{$s}\n";
実行すると、「Catchable fatal error: Object of class hoge could not be converted to string」というエラーになります。
続いて、__toStringを実装してみましょう。
<?php // class hoge { public function __toString() { return "hoge to string"; } } // $obj = new hoge(); $s = 'data is ' . $obj; echo "{$s}\n";
実行すると、下記のようになります。
data is hoge to string
なお、「インスタンスの保存」という意味では、連載第6回で説明を予定している「シリアライズ」の方が便利なので、そちらも参照してもらえればと思います。
次回は、interface、抽象メソッド、traitなどについて
今回は、比較的PHPに固有な仕様である「マジックメソッド」のいくつかについて説明しました。
次回は、オブジェクト指向系の言語で割と広く見られる「interface」、抽象メソッド、多重継承の系列の一つである「trait」などについて解説します。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- 初心者がPHPプログラミングを始めるための基礎知識とXAMPPのインストール
オープンソースのWeb開発向けスクリプト言語「PHP」の文法を一から学ぶための入門連載。初回は、PHPの概要や特徴を紹介し、環境構築や「Hello World!」までの手順などを解説します【PHP 7.1含め2017年の情報に合うように対応、XAMPP環境構築を追記】。 - PHP編に突入! まずはソースをダウンロード
今回からPHPのビルドとインストールに入ります。まずはPHPという言語の概要と、ソースコードの入手法を解説します(編集部) - 理論編:PHPについて知ろう
スクリプトを記述するだけの簡単なプログラミングで、Web対応の高速なデータベースアプリケーションを実現する手法としてPHPが急速に注目を集めている。しかもデータベースはオープンソースのPostgreSQLだけでなく、Oracleなどの商用データベースも扱える。ここでは、5月にバージョンアップしたばかりのPHP4によるWeb-DBシステム構築法を紹介しよう。 - Mac OS X+PHPでオールインワン環境(インストール編):Mac内にPHP4、5、6を同居させるコツ
PHP4の開発は終了したが、移行の問題は残されている。異なるバージョンのPHPをスムーズに切り替えるには? - @IT自分戦略研究所 資格辞典:PHP技術者認定試験
- 自分をプログラミング言語に例えると何?
2013年1月16日、エンジニアたちが集うトークライブイベント「TechLION vol.11」が開催された。今回のレポートでは、「自分をプログラミング言語に例える」というお題に答えた5人の技術者の回答をみていく。