web-dev-qa-db-ja.com

再帰関数:php関数自体を呼び出す

私はそれを正しく行うことを確認したいだけであり、これによって競合が発生することはありません。

自分自身を呼び出す関数がありますが、それがOKかどうかはあなたの承認が必要ですか?

<?php

function determine($the_array){
    foreach ($the_array as $key => $value) {
        switch ($key) {
            case 'in':
                    echo $value;
                break;

            case 'out':
                    echo $value;
                break;

            case 'level':
                    echo '<ul>';
                    determine($value);
                    echo '</ul>';
                break;

        }
    }

}

これは配列です:

$the_array = array(
    'in' => '<li>Simple IN</li>',
    'out' => '<li>Simple OUT</li>',
    'level' => array(
            'in' => '<li>Simple IN 2</li>',
            'out' => '<li>Simple OUT 2</li>',
            'level' => array(
                'in' => '<li>Simple IN 3</li>',
                'out' => '<li>Simple OUT 3</li>'
            ),
        ),
);

そして、これが最後の初期化です:

echo '<ul>';
determine($the_array);
echo '</ul>';

結果は私が望んでいた通りであり、うまく機能しますが、これが良い習慣であるかどうかはわかりません。

15
Andrei Surdu

再帰関数は問題ありませんが、何をしているのかわからない場合は危険です。関数が再帰ループ(それ自体を何度も呼び出し続ける)で終わる可能性がある場合は、タイムアウトするか、メモリが不足するか、ゾンビの黙示録が発生します。

再帰呼び出しは、本当に本当に鋭いナイフだと考えてください。経験豊富なシェフの手で、それは天国で行われた試合であり、食器洗い機の手で、それは起こるのを待っている失われた指です。

PHPはNiceを再生しようとし、デフォルトで再帰的な深さを100に制限します(これは変更できます)が、ほとんどすべての場合、再帰的な深さが100に達すると、事故はすでに発生しており、PHPが反応します追加の歩行者が交通に迷い込むのを防ぐことによって。 :)

35
Fluffeh

Fluffehは、再帰関数に関する限り、十分な答えを提供しました。ただし、大きな配列/オブジェクトなどで再帰を使用する場合は、コードの最適化を監視して、実行に多くのメモリやCPUパワーを必要としないようにする必要があります。

コードを簡単に最適化して、よりクリーンになり、メモリを節約し、予期しないデータに対する耐性を高めることができます。関数の引数リストの&に注意してください(ネストされた関数が呼び出されるたびに配列のコピーを作成する必要がなくなります)。

function determine(& $the_array){
foreach ($the_array as $key => $value) {
    switch ($key) {
        case 'in':
        case 'out':
                echo $value;
            break;

        case 'level':
            if (!is_array($value)) break;
                echo '<ul>';
                determine($value);
                echo '</ul>';
            break;

        }
    }
}
3
Kleskowy

それが良い解決策であるかどうかはわかりませんが、私はこれを使用して内部から関数を呼び出します:

function my_calucar(){
    $arrayy= array('mine' => '1',  'yours' => '24', 'her' => '34');
    foreach ($arrayy as $each=>$value) {
        switch ($each) {
        default:
                my_calucar($value);
        }
    }
}
1
T.Todua

配列の深さを知っているなら、使うのが良いと思います

$list = "";
foreach ($the_array as $array) {
    if(is_array($array)) {
       foreach($array as $sub_array) {
          if(is_array($sub_array)) {
              foreach($sub_array as $sub_array_2) {
                  $list .= "$sub_array_2";
               }
          } else {
             $list .= "$sub_array";
          }
       }
    } else {
        $list .= "$array";
    }
}

echo "<ul>$list</ul>";
0
Salim