![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
以前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件を表示させたいのです。)
根本的な部分が間違っているような気がするのですが、
どのような考え方で作れば良いのか分かりません。
また皆様のお力をお貸しください。
宜しくお願いします。
No.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に吐き出す~~
}
とても見通しが良くなったっしょ。こげな感じでどうでっしゃろ。
お返事ありがとうございます。
ご説明がとても分かりやすく、理論的に理解は
出来たのですが、初心者のため関数の部分が読めません・・・(涙
下記のように貼り付けてみたのですが、
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;
}
?>
何度もお手数をお掛けし申し訳ありません。
宜しくお願いいたします。
No.2
- 回答日時:
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行以下の出力結果が表示されただけでした・・・。
お手数ですが他のもヒントがありましたらお教えください。宜しくお願いいたします。
No.1
- 回答日時:
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で参照渡しをするのでしょうか?
度々お手数ですが、宜しくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
csvの内容を行単位で削除したい
-
FortranのOPEN文
-
VBAでcsvファイルもシートもあ...
-
xml取得値を文字列と比較
-
別ファイルの構造体の値を読み...
-
行数が30万件ほどあるCSVから、...
-
CSVデータの行数カウントをした...
-
自動で番号を振りたい
-
PHP 別ドメインへのファイル保存法
-
C言語でCSVファイルの行数を読...
-
文字列変換について
-
CSVファイルの最終行のデー...
-
PHPでサーバー上の書き換えたht...
-
配列をループでたくさん宣言し...
-
file_existsでファイル名の部分...
-
array_mapの再帰処理がうまく行...
-
2次元配列CSVのソート
-
foreachで上限回数指定方法また...
-
掲示板のあらし対策
-
Eclipseコンテンツアシストでプ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
PHPからCSVをアップロード後、m...
-
別ファイルの構造体の値を読み...
-
CSVデータの行数カウントをした...
-
Resource id #3 と表示されま...
-
C言語でCSVファイルの行数を読...
-
複数行のデータのPOST処理に関して
-
ヒアドキュメントの中のfor文
-
CSVファイルの最終行のデー...
-
自動で番号を振りたい
-
バイナリファイルの内容を、そ...
-
csvの内容を行単位で削除したい
-
FortranのOPEN文
-
ログファイルが一定行数を超え...
-
行数が30万件ほどあるCSVから、...
-
配列をファイルに書き込む方法
-
テキストデータから指定行の削除
-
stdClass Objectを連想配列のよ...
-
エラーメッセージ(無効な間接...
-
PHPでサーバー上の書き換えたht...
-
PHPでCSVの一部の行を編集したい
おすすめ情報