元のデータは前と同じ 2to3nen.txt です。3年の名簿をソートして出るようにします。
3年の選択ボタンの部分はselect2.phpと同じですが、今回はselect3.phpというページにするのでactionの先も忘れずにselect3.phpに直します。その他は同じ。
<form action="select3.php#koko" method="post" id="koko" <p> <input type="submit" name="hr" value="2A"> <input type="submit" name="hr" value="2B"> <input type="submit" name="hr" value="2C"> <input type="submit" name="hr" value="2D"> <input type="submit" name="hr" value="2E"> <input type="submit" name="hr" value="2F"> <input type="submit" name="hr" value="2G"> <input type="submit" name="hr" value="2H"> </p> <p> <input type="submit" name="newhr" value="3A"> <input type="submit" name="newhr" value="3B"> <input type="submit" name="newhr" value="3C"> <input type="submit" name="newhr" value="3D"> <input type="submit" name="newhr" value="3E"> <input type="submit" name="newhr" value="3F"> <input type="submit" name="newhr" value="3G"> <input type="submit" name="newhr" value="3H"> </p> </form>
PHPプログラムはこちら。
まず、3年の時だけソートが必要なので、newhrに値が入っているかhrに値が入っているかで作業を分けます。 isset($_POST["hr"]) が hr に値が入っているかどうか調べる関数です。
newhrに値が入っているときには、sort.php でやった手法で、key,valを登録しています。今回のkeyはnewnoです。newhrで先に該当するデータだけに絞っているのがif ($newhr === $snewhr){の部分です。newhrで絞っているのでnewnoだけで順番が決まります。
$fp = fopen("2to3nen.txt","r");        
$shr="2Z";
if( isset($_POST["hr"]) ){ 
    $shr =$_POST["hr"];
    while(!feof($fp)){
       $line = fgets($fp);
        if (trim($line) != null){
            list($hr,$no,$sei,$mei,$seib,$ysei,$ymei,$newhr,$newno) = explode("\t",$line);
            if ($hr === $shr){
                print "<tr>\n";
                print "<td>$hr</td><td>$no</td><td>$sei</td><td>$mei</td>";
                print "<td>$seib</td><td>$ysei</td><td>$ymei</td>\n";
                print "<td>$newhr</td><td>$newno</td>\n";
                print "</tr>\n";
            }
        }
    }
}
$snewhr="3Z";
if( isset($_POST["newhr"]) ){
    $snewhr =$_POST["newhr"];
    while(!feof($fp)){
        $line = fgets($fp);
        if (trim($line) != null){
            list($hr,$no,$sei,$mei,$seib,$ysei,$ymei,$newhr,$newno) = explode("\t",$line);
            if ($newhr === $snewhr){
                $key = $newno;
                $val = $line;
                $gotoarray[$key]=$val;
            }
        }
    }
    ksort($gotoarray);
    foreach ($gotoarray as $key => $val) {
        list($hr,$no,$sei,$mei,$seib,$ysei,$ymei,$newhr,$newno) = explode("\t",$val);
        print "<tr>\n";
        print "<td>$hr</td><td>$no</td><td>$sei</td><td>$mei</td>";
        print "<td>$seib</td><td>$ysei</td><td>$ymei</td>\n";
        print "<td>$newhr</td><td>$newno</td>\n";
        print "</tr>\n";
    }
}
fclose($fp);
残念ながら、上記のソートでは次のようになります。
これはksort($gotoarray);の並べ替えがデータを文字列として扱っている為です。
| 2E | 2 | 梅村 | 千草 | 女 | うめむら | ちぐさ | 3A | 1 | 
| 2E | 11 | 諏訪 | 亜由香 | 女 | すわ | あゆか | 3A | 10 | 
| 2D | 11 | 相馬 | 美和 | 女 | そうま | みわ | 3A | 11 | 
| 2D | 12 | 竹浪 | 千秋 | 女 | たけなみ | ちあき | 3A | 12 | 
| 2A | 14 | 鳴海 | 麻美 | 女 | なるみ | あさみ | 3A | 13 | 
| 2F | 14 | 野呂 | 春菜 | 女 | のろ | はるな | 3A | 14 | 
| 2C | 16 | 福田 | 初美 | 女 | ふくだ | はつみ | 3A | 15 | 
| 2A | 15 | 蒔苗 | 菜摘 | 女 | まかなえ | なつみ | 3A | 16 | 
| 2H | 16 | 山内 | 志保 | 女 | やまうち | しほ | 3A | 17 | 
| 2C | 18 | 幸田 | 奈々子 | 女 | ゆきた | ななこ | 3A | 18 | 
| 2D | 19 | 浅利 | 和哉 | 男 | あさり | かずや | 3A | 19 | 
| 2A | 3 | 岡本 | 愛 | 女 | おかもと | あい | 3A | 2 | 
| 2D | 21 | 石川 | 和茂 | 男 | いしかわ | かずしげ | 3A | 20 | 
| 2B | 20 | 一戸 | 聡 | 男 | いちのへ | さとし | 3A | 21 | 
| .. | .. | .............. | .. | .. | ||||
これはksortにSORT_NUMERICの指示を加えることで回避できます。ksort($gotoarray)をksort($gotoarray,SORT_NUMERIC)にしてください。
3年のクラスと番号を行の先頭に表示させるのは簡単です。print "<td>$hr</td><td>$no</td>...の部分を変更するだけです。
sort.php でksort()を紹介した関係で上記の方法が先になりましたが、今回の条件なら配列に代入するだけでソートを使うことなく実現できます。
c言語やjavaなど「整数の添字で記憶場所を指定する配列」に慣れているとわかりやすい手法です。しかし注意すべき問題もあります。以下3年の部分だけ示します。
$snewhr="3Z";
if( isset($_POST["newhr"]) ){
    $snewhr =$_POST["newhr"];
    while(!feof($fp)){
        $line = fgets($fp);
        if (trim($line) != null){
            list($hr,$no,$sei,$mei,$seib,$ysei,$ymei,$newhr,$newno) = explode("\t",$line);
            if ($newhr === $snewhr){
                $gotoarray[(int)$newno]=$line;
            }
        }
    }
    $count = count($gotoarray);
    for ($i = 1;  $count>=$i; $i++) {
        print "<tr>\n";
        list($hr,$no,$sei,$mei,$seib,$ysei,$ymei,$newhr,$newno)
                       = explode("\t",$gotoarray[$i]);
        print "<td>$hr</td><td>$no</td><td>$sei</td><td>$mei</td>";
        print "<td>$seib</td><td>$ysei</td><td>$ymei</td>\n";
        print "<td>$newhr</td><td>$newno</td>\n";
        print "</tr>\n";
    }
}
(int)はキャストと呼ばれ、$newnoを文字列から整数に変換します。$newnoは$lineから切り取られたので文字列になっています。このままでは$newnoは文字列のままkeyになってしまいます。
forはc言語やjavaなどでよく使われる構文なのでforeachよりよく知られていますが、慣れていない人がforeachより分かりやすいかというと疑問です。
要素数を調べる count($gotoarray)は毎回データ数を数えるのであらかじめ別の変数に覚えさせます。これが添え字の最大値と必ずしも一致しないので問題があります。
たとえば、3Aの2番がデータから抜けていたとします。
| 2E | 2 | 梅村 | 千草 | 女 | うめむら | ちぐさ | 3A | 1 | 
| 2B | 5 | 小野寺 | のぞみ | 女 | おのでら | のぞみ | 3A | 3 | 
| 2G | 4 | 葛西 | 由佳 | 女 | かさい | ゆか | 3A | 4 | 
| 2D | 5 | 樺沢 | 郁乃 | 女 | かばさわ | いくの | 3A | 5 | 
| .. | .. | .............. | .. | .. | ||||
| 2G | 34 | 福原 | 史学 | 男 | ふくはら | ふみのり | 3A | 34 | 
| 2A | 31 | 藤田 | 健一 | 男 | ふじた | けんいち | 3A | 35 | 
3Aの36番があるのですが、2番が抜けて35人分しかデータが無いので35までしか表示しません。2番のデータが無いので2番の所は空欄になっています。空欄になるのは好ましい場合もありますが、入っているデータが表示されないのは厄介です。
phpの配列の基本が「keyとvalueを関係付けるmap」であるため、key,valueを用いてforeachを使うほうがお勧めです。
上の説明は前回の課題2の解答になっています。
前回の課題2 select3.php を完成させなさい。index.htmlに「phpで選択3」という名前のリンクを作りましたか。