PHP の型検査を模倣する。

今日も常用している関数を晒してみる。

bool cast_arg(mixed &$given, int $expect[, int $offset]) 値の型を検査する。
http://xif.jp/php/cast_arg.phps

利用方法。

<?php

require 'cast_arg.php';

/**
 * 模倣するのは
 *
 * function() expects parameter 1 to be long, array given
 * Object of class ClassName could not be converted to string
 * function() supplied resource is not a valid stream resource
 * function() parameter 1 must be a valid callback
 * +
 *  in <b>/path/to/callee.php</b> on line <b>#</b><br />\n
 *
 * Array to string conversion は出ない。
 * (function() expects ... になる)
 */

function foo($arg)
{
    echo 'gettype(): ', gettype($arg), "\n";
    if (!cast_arg($arg, TYPE_LONG, 1)) {
        echo '$arg is not int', "\n";
        echo 'var_dump(): ';
        var_dump($arg);
        return false;
    }
    echo '$arg is int', "\n";
    echo 'var_dump(): ';
    var_dump($arg);
    return true;
}

foo(1); // returns true
// gettype(): integer
// $arg is int
// var_dump(): int(1)

foo('1'); // returns true
// gettype(): string
// $arg is int
// var_dump(): int(1)

foo('bar'); // returns false
// gettype(): string
// Warning: foo() expects parameter 1 to be long, string given in ...
// $arg is not int
// var_dump(): int(0)


開発中は

<?php

error_reporting(E_ALL | E_STRICT);
// PHP 4 なら error_reporting(E_ALL);
ini_set('display_errors', 'Off');

set_error_handler('my_error_handler');
function my_error_handler(/* 略 */)
{
    // @ でエラーが抑制されていれば何もしない。
    if (!error_reporting()) {
        return true;
    }

    $message = ''; // 略。ログ用エラーメッセージを生成する。
    error_log($message);

    // header() するのでバッファを全てクリア。
    $level = (int)@ob_get_level();
    if ($level > 0) {
        while (@ob_end_clean() && --$level) {}
    }

    if ($level < 1) {
        @header('HTTP/1.1 500 Internal Server Error');
    }
    echo 'Internal Server Error';
    exit(1);
}

ob_start();

// プログラム本体の実行。

みたいなことしてます。
お陰でエラーに敏感になりました。
ついでに is_a() が本気で嫌になりました。 (PHP4/5 両用で書けねえ!)
PHP 5.3 で is_a() から E_STRICT なくなったから良いけどね。


え?
debug_backtrace() のコスト?
計ってないよ。