どもです。
今回はWordPressに絡まないPHPの話。
複数の候補の中から、ページを読み込む度にランダムで3つ表示する。重複は禁止。
というプログラムをPHPで組むことになったのですが、作ってたら複数種類のループを使うことになって少し面白かったので、ループの復習がてらに載っけとこうと思います。
while 条件を達成する限りループする
whileは、最初に指定した条件にそぐう限りループを続けます。
言い方を変えると、条件を達成するまでループするのがwhile文です。
今回のランダム表示PHPは重複禁止なので、「配列にランダムで数値を入れ、重複があったら数字を入れ直す」必要があります。
言い換えれば、「配列にランダムで数値を入れ、重複がなくなるまでループする」ことになるので、while文が最も相応しいといえます。
$check = 0
while( $check == 0 ){
様々な処理
if(重複がない場合){
$check = 1
}
}
break(ループやswitchの処理を終わらせて抜け出す)を使って脱出することもできますが、それならdo-while文の方が良さそうです。
do{
様々な処理
if(重複がない場合){
break;
}
}while(0)
whileは「チェック→中身→チェック→中身」なのに比べ、
do-whileは「中身→チェック→中身→チェック→中身」と動きます。
この例で行くと、do-whileなら$checkの最初の値が0でなくとも、取り敢えず1回はループすることになります。
で、while(0)とは無条件でループを行うことなので、breakで脱出するまで永遠にループします。
$checkという変数を1つ省略できるので、より理想に近いのはdo-whileでしょうか。
今回の例だと「必ずループをする必要がある」ので、どちらを使っても結果に変わりはないのですが、
「最初から条件が満たされているならループ処理は行わない」のか、
「最初から条件が満ちていても取り敢えず1度ループを行う」のかを見極めて使うと良いでしょう。
まぁぶっちゃけ、whileの方だけ覚えておいても問題ない感じしますね(゚∀゚)
今回もなんだかんだで$checkが省略できなかったので、whileを採用しました。
for 指定の回数だけループする
さて、大本のループにはwhileを使うことにしましたが、whileではやり辛い状況が発生しました。
今回のランダム表示は3つなので、処理の簡略化のためには配列に数値を入れたいところです。
forは指定の回数だけループするので、回数が決まっている処理に最も相応しいでしょう。
$how = 3;
$array = array();
for( $i=0; $i<$how; $i++ ){
$array[$i] = rand(1, 7);
}
forは、( ループする前に行っておく処理 ; ループ条件 ; 回した後に行う処理 )を1行で記載します。
for( $i=0; $i<$how; $i++ ){}をwhileで行おうとすると、
$i = 0;
while( $i<$how; ){
処理
$i++
}
と書くことになります。
可能ですが、見辛い。
ので、回数が決まっている処理は素直にfor使っといた方が良さそうです。
foreach 配列を1つずつ回しながらループする
さて、whileとforのおかげで「配列に重複なしの数を3つ入れる」ことはできました。
が、ゴールはその数に従って表示(echo)を行うことです。
forを使う…でも良いのですが、ここは配列に特化したループを使います。
foreachは、配列の内容をひとつずつ回すループ文です。
今回は普通の配列を使っているので他のループ文でも問題ありませんが、連想配列や、WordPressでよくある数値が飛び飛びの配列等はforでは回せません。
foreachはそういった配列も確実に回します。
foreach( $array as $content ){
switch($content){
case 1: echo '1のときに表示する内容';
break;
case 2: echo '2のときに表示する内容';
break;
}
}
これで、$arrayの中身を1つずつ調べ、その数値に従った内容で出力させることができました。
foreachは、( 配列名 as 中身を収納する変数 )といった感じで宣言します。
$array = ( '0'=>'aaa', '1'=>'bbb', '2'=>'ccc' ) という配列があったとして、
foreach( $array as $content ){} というループを宣言すると、
$contentの内容は一周する度に、「aaa」→「bbb」→「ccc」と変化し、最後の配列を回し終えるとループが終了します。
配列の中身を利用したい際のループは、迷わずこれを選んで良いでしょう。
完成したランダム表示PHP
$how_list= 3 ; // 表示する数を入力
$randList = array(); // 配列を宣言
$check = 0 ; // $checkを0で宣言
while( $check == 0 ){ // $checkが0である限り、ループする
for( $i=0; $i<$how_list; $i++ ){ // $how_listの数だけループする
$randList[$i] = rand(1, 7); // $i番の配列(今回は0~2)に、rand(1, 7)(1~7のランダム数)を入れる
}
$array_value = array_count_values($randList); // 重複チェックのため、チェック用の配列を作成。array_count_values(配列名)で、[内容]->個数 の連想配列を作る。
foreach( $array_value as $array_count ){ // チェック用の連想配列でループ
if( $array_count >= 2 ){ // 配列の中身に、同じものが2つ以上あったなら…
$check = 0 ; // $checkは0のままで…
break; // 連想配列のforeachを脱出
}else{
$check = 1 ; // 中身が1つしかないなら、$checkに1を入れて次の内容でループ(重複が1つでもあれば$checkを0にして即breakするので、最後まで$check=1で配列を終える=重複がないということ)
}
}
} // while( $check == 0 )の終端地点。ここから先頭に戻り、$check==0ならまた処理を行う。0でない(今回は$check==1)なら次へ
foreach( $randList as $randList_li ){ // ランダム数を入れた配列でforeach
switch($randList_li){ // switchを使い、配列の内容ごとの処理を行う。
case 1: echo '1のときに表示する内容';
break;
case 2: echo '2のときに表示する内容';
break;
case 3: echo '3のときに表示する内容';
break;
case 4: echo '4のときに表示する内容';
break;
case 5: echo '5のときに表示する内容';
break;
case 6: echo '6のときに表示する内容';
break;
case 7: echo '7のときに表示する内容';
break;
}
}
こんな感じになりました。
もっと上手な書き方はあるだろうけど、目的は達成できたのでこれで良しです(゚∀゚)