おぎろぐはてブロ

なんだかんだエンジニアになって10年以上

可変長引数を受けて、可変長引数の関数に渡す

可変長引数を受けて、可変長引数の関数に渡すような関数を書きたいことがあります。例として、[http://php.net/trigger_error:title=trigger_error][http://php.net/sprintf:title=sprintf]なフォーマット文字列を設定できるwrapper関数を作ってみることにします。
I/Fはこんな感じ。都合上エラータイプを先頭に持ってきてます。

bool trigger_errorf(     int $error_type, 
                      string $error_format 
                    [, mixed $args [, mixed $...]])

これを、実装するとこういう感じ。

<?php
function trigger_errorf()
{
    $args  = func_get_args();
    $level = array_shift($args);
    return trigger_error(call_user_func_array('sprintf', $args), $level);
}

trigger_errorf(E_USER_WARNING, "error test: %d", rand()); 
?>

そういえば、こういうことをCマクロで書こうとして、__VA_ARGS__(可変個引数マクロ)を使おうとしたら、自分とこの標準のビルド環境では使えなくて泣いたことを思い出した。
こんな感じで、[http://php.net/call_user_func_array:title=call_user_func_array]を使います。可変個でない場合は、引数が配列でない[http://php.net/call_user_func:title=call_user_func]です。
というか、その場合、上のようなコードであれば、普通に関数を呼べばよいわけで、用途としては、呼び出す関数名が不定の場合に使うという感じで、_arrayの方よりも使う機会が少ないのかなと思います。
あと、

<?php
$funcname = "trigger_error";
$funcname("hey");
?>

可変関数もOKですね。(但し、includeのように関数ではなく言語構造と書かれているものは、これでは呼べない)

途中までしか書いてないので続く。ほんとは、こういうことを書こうと思ったんじゃない。