- ベストアンサー
DBを使用しないで条件にマッチしたもののみページング
以前DBを使用しないページングについてお教えいただいた者です。 少し改良して降順ソートを出来るようになったのですが、 リスト表示の際にある条件に一致したもののみを表示する場合の やり方が分かりません。。。 現在は以下のようになっています。 ■sample.csv no0001,あああああ,20050101,ON no0002,いいいいい,20050102,OFF 略) no0020,ととととと,20050120,OFF ■index.php (800字オーバーしてしまうので、省略しています。) //ファイルを配列に格納 $rec = file("sample.csv"); //レコード数を取得して、最後尾の行番号を取得 $rec_number = sizeof($rec) -1; //ページ範囲を出力 for ( $i = $rec_number-$page*$max; $i > $rec_number-$page*$max-$max; $i -- ) { $data = explode(",","$rec[$i]"); if ($data[3]==("ON") && $data[2]<=date("Ymd")) { print $data[0].("<br>"); print $data[1].("<br>"); print $data[2].("<br><br>\n"); } } print "<a href=\"?page=".($page+1)."\">次のページへ</a>\n"; ?> CSVの各行の[3]が 「ON」となっていれば表示し、 「OFF」となっていれば表示しないようにし、 また、[2]が 今日以降の日付であれば表示しないようにしたいのですが、 for文の中に上記のようなif文を使ってしまうとオカシナことに なってしまいます。 (no0020が抜けただけで1ページ目に9件しか表示されません。本当は no0020が抜けたので、no0010までの10件を表示させたいのです。) 根本的な部分が間違っているような気がするのですが、 どのような考え方で作れば良いのか分かりません。 また皆様のお力をお貸しください。 宜しくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> 次のページへ渡していないからだと思うのですが、 > これはPOSTなりGETで参照渡しをするのでしょうか? 今ページ番号って渡してる? おそらくそれが最終的に$pageになるのだと思うのだが。 今、「有効な行を数えて」10行分きちんと出す事ができた。ここでちょっと考えて欲しい。2ページ目に表示するのは「CSVの11行目から」だろうか? 否、「CSVを先頭から全部舐めていって、有効な行を10行分(←1ページ目の分)捨てた後に、最初に出てきた有効な行」だ。これが、前回の回答で私が「頭出し」と言った部分だ。 という訳で、次の関数を作りましょう。クラスにしても良いだろう。 class MyRecords { var recnum; // int var recmax; // int var records; // array int initCsvData(array recs); // file関数で読み込んだ行データを引数に、現在行などを初期化。 array getNextLine(); // 次の有効な行を返す。 } このような下請けルーチンを作ることで、メインルーチンはこんなに簡単になる。 $recs = new MyRecords(); $recs->initCsvData($rec); // CSVデータをセット for($i = 0; $i < $page * $max; $i++) { // 「ページ数×ページあたりの行数」分だけ $recs->getNextLine(); // 捨てる。 } for($i = 0; $i < $max; $i++) { // 「ページあたりの行数」分だけ if(!$arr = $recs->getNextLine()) break; // もうデータが無ければループ終了(最後のページとなる) // ~~行をHTMLに吐き出す~~ } とても見通しが良くなったっしょ。こげな感じでどうでっしゃろ。
その他の回答 (2)
- riaf
- ベストアンサー率0% (0/1)
continueしてやるのはどうでしょうか? for ( $i = $rec_number-$page*$max; $i > $rec_number-$page*$max-$max; $i -- ) { $data = explode(",","$rec[$i]"); if ($data[3]==("ON") && $data[2]<=date("Ymd")) { print $data[0].("<br>"); print $data[1].("<br>"); print $data[2].("<br><br>\n"); }else{ continue; } }
お礼
お返事ありがとうございます。 しかし、continue を使っても、結果は同じで、 OFFの部分と本日の日付を越えた部分を抜いた 10行以下の出力結果が表示されただけでした・・・。 お手数ですが他のもヒントがありましたらお教えください。宜しくお願いいたします。
- anmochi
- ベストアンサー率65% (1332/2045)
for ( $i = $rec_number-$page*$max; $i > $rec_number-$page*$max-$max; $i -- ) { ここが問題だね。中をよく見てみると、「出力しようがしまいが$max回ループする」事になる。 という訳で、「$max行出力するまでループ」という方法に変えてあげましょう。 そうだなぁ。あまりごちゃごちゃ変えるのもあれなので、こんなのはどうだろう。 $outputline = 0; $i = $rec_number-$page*$max; // ここもおかしいよね。$rec[$i]を先頭から1行ずつ舐めていって、条件に合致する行数を数えていって頭だしをしないといけない。 while($outputline < max || $i <= $rec_number) { $data = explode(",", $rec[$i++]); if ($data[3]==("ON") && $data[2]<=date("Ymd")) { print $data[0].("<br>"); print $data[1].("<br>"); print $data[2].("<br><br>\n"); outputline++; // 行を出力したので1行増やす。これが$maxまで到達すると1ページ分。 } }
お礼
お返事ありがとうございます。 しかしお教えいただいたやり方を とりあえず昇順ソートで試してみたのですが、 出力結果が ●1ページ目 no0001,あああああ,20050101,ON no0003,ううううう,20050103,ON no0004,えええええ,20050104,ON no0005,おおおおお,20050105,ON no0006,かかかかか,20050106,ON no0007,ききききき,20050107,ON no0008,くくくくく,20050108,ON no0009,けけけけけ,20050109,ON no0010,こここここ,20050110,ON no0011,さささささ,20050111,ON と10行分表示されるのですが、 ●2ページ目 no0011,さささささ,20050111,ON no0012,ししししし,20050112,ON 略) とCSVデータの10行目から読み込みを 始めてしまいます。 恐らく、お教えいただいた > $i = $rec_number-$page*$max; // ここもおかしいよね。 > $rec[$i]を先頭から1行ずつ舐めていって、条件に合致する行数を > 数えていって頭だしをしないといけない。 ココを次のページへ渡していないからだと思うのですが、 これはPOSTなりGETで参照渡しをするのでしょうか? 度々お手数ですが、宜しくお願いいたします。
お礼
お返事ありがとうございます。 ご説明がとても分かりやすく、理論的に理解は 出来たのですが、初心者のため関数の部分が読めません・・・(涙 下記のように貼り付けてみたのですが、 13行目にエラーが出てしまいます。 「Parse error: parse error, expecting `T_VARIABLE'」 <?php // 1ページに表示する最大数 $max = 10; // 現在のページ数を取得 $page=$_GET['page']; if ( $page == "" ) { $page = 0; } //ファイルを配列に格納 $rec = file("sample.csv"); class MyRecords { var recnum; // int var recmax; // int var records; // array int initCsvData(array recs); // file関数で読み込んだ行データを引数に、現在行などを初期化。 array getNextLine(); // 次の有効な行を返す。 } $recs = new MyRecords(); $recs->initCsvData($rec); // CSVデータをセット for($i = 0; $i < $page * $max; $i++) { // 「ページ数×ページあたりの行数」分だけ $recs->getNextLine(); // 捨てる。 } for($i = 0; $i < $max; $i++) { // 「ページあたりの行数」分だけ if(!$arr = $recs->getNextLine()) break; // もうデータが無ければループ終了(最後のページとなる) // ~~行をHTMLに吐き出す~~ print <<<HTML $recs[0].("<br>"); $recs[1].("<br>"); $recs[2].("<br><br>"); HTML; } ?> 何度もお手数をお掛けし申し訳ありません。 宜しくお願いいたします。