PHPTypeSafeで目から鱗が落ちた
PHP5から導入されたタイプヒンティングを、とある方法で拡張してstringやint、boolなどのスカラー値に対しても使えるようにしたライブラリです。
Today I released the first public version of my new library PHPTypeSafe. It provides the ability to use PHPs Type Hinting feature for scalar values.
PHP5.3以降対応で、phar形式で提供されています。つーか、PHP本体に入れば楽なんだけどなぁ。。。
どのように書けるかというと、こんな感じ。barメソッドに注目。
<?php require 'com.maxhorvath.phptypesafe.phar'; class Foo { public static function bar(string $msg, int $counter) { echo $counter . '. run: ' . $msg . "\n\n"; } } $obj = new Foo(); $obj->bar('test', 1); Foo::bar(false, 2); // 引数の型が合っていない
PHP5.3.0α2で実行すると。。。なんかechoの部分がうまく出なかったんですが、
$ php -n sample.php ???????????????????????????????????????????????????????????????????????????????????? Fatal error: Uncaught exception 'ErrorException' with message 'Argument 1 passed to Foo::bar must be of type string, boolean given, called in ... $
な感じで例外(ErrorException)が投げられます。ちゃんと「Argument 1 passed to Foo::bar must be of type string, boolean given」となっているのが分かりますかね。
で、このライブラリが面白いのは、pharで提供されているところじゃなくて、これを実現している方法。PHP5で上記のFooクラスのように書くと「string」や「int」がオブジェクト型として認識されるので、
Catchable fatal error: Argument 1 passed to Foo::bar() must be an instance of string, string given, called in ...
となりますが、PHPTypeSafeではこのCatchable fatal error(E_RECOVERABLE_ERROR)を独自のエラー処理関数で処理しています。この部分の大まかな流れを抜き出すとこんな感じ。
<?php set_error_handler('errorHandler'); function errorHandler($code, $message, $file = '', $line = 0, array $context = array()) { if ($code === E_RECOVERABLE_ERROR) { printf("message:%s\n", $message); } return call_user_func(...) }
詳細は、ErrorHandlerクラスを参照。これに気づいたときは目から鱗。感動しました。
また、
- PHP5.3から導入される名前空間
- PHP5.3から標準になるphar
- cruisecontrol+phpUnderControl+PHPUnit+phpt
をガッツリ使っているので、非常に良いサンプルになりそうです。
ちなみに、com.maxhorvath.phptypesafe.pharを
<?php try { $p = new Phar(dirname(__FILE__) . '/com.maxhorvath.phptypesafe.phar'); } catch (Exception $e) { die($e->getMessage() . PHP_EOL); }
な感じで読み込もうとしたんですが、
$ php -v PHP 5.3.0alpha2 (cli) (built: Sep 2 2008 11:52:39) Copyright (c) 1997-2008 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2008 Zend Technologies with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans $ cat -n construct.php 1 <?php 2 try { 3 $p = new Phar(dirname(__FILE__) . '/com.maxhorvath.phptypesafe.phar'); 4 } catch (Exception $e) { 5 die($e->getMessage() . PHP_EOL); 6 } $ ls com.maxhorvath.phptypesafe.phar com.maxhorvath.phptypesafe.phar $ php -n construct.php phar "/path/to/com.maxhorvath.phptypesafe.phar" SHA1 signature could not be verified: broken signature $
と怒られてしまいました。。。むーん。