/**
* 関数の再帰処理クラス
* $typeがstring以外の場合はあまり使うことがないかもしれない
*/
class FuncRecursive {
var $type = 'string';
var $func = '';
var $data = array();
var $args = array();
var $map = array();
function __construct() {}
/**
* 再帰処理実行
*/
function execute() {
//データのセット
$args = func_get_args();
$this->_setParams($args);
//配列じゃない場合
if(!is_array($this->data)) {
$params = array_merge(array($this->data), $this->args);
return call_user_func_array($this->func, $params);
}
// switch($this->type) {
// case 'string':
// return $this->_exeString($this->data);
// case 'array':
// return $this->_exeArray($this->data);
// case 'map':
// return $this->_exeMap($this->data);
// }
//実行
$execute = '_exe'.ucfirst($this->type);
return $this->{$execute}($this->data);
}
/**
* 処理対象が文字列の場合
* mb_convert_encodingなど
*/
function _exeString($data) {
foreach($data as &$val) {
if(is_array($val)) {
$val = $this->_exeString($val);
} else {
$params = array_merge(array($val), $this->args);
$val = call_user_func_array($this->func, $params);
}
}
return $data;
}
/**
* 処理対象が配列の場合
* implodeなど
*/
function _exeArray($data) {
foreach($data as &$val) {
if(is_array($val)) {
$val = $this->_exeArray($val);
}
}
$params = array_merge(array($data), $this->args);
return call_user_func_array($this->func, $params);
}
/**
* array_mapっぽい処理を行なう場合
*/
function _exeMap($data) {
foreach($data as &$val) {
//対応するパラメータを取得
$array = !empty($this->map) ? 'map' : 'args';
$map = array();
foreach($this->{$array} as &$a) {
$map[] = is_array($a) ? array_shift($a) : $a;
}
if(is_array($val)) {
//使用するパラメータを変数に保持しておく
$this->map = $map;
$val = $this->_exeMap($val);
} else {
array_unshift($map, $val);
$val = call_user_func_array($this->func, $map);
}
}
$this->map = array();
return $data;
}
/**
* 引数を実行可能な形で取得
*/
function _setParams($args) {
//使用する関数と参照するデータ
$this->func = array_shift($args);
$this->data = array_shift($args);
//残りの引数
$this->args = $args;
return;
}
}