質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

1回答

1641閲覧

【php】複合検索のページ送りに関して

nakamura03

総合スコア25

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2015/09/15 02:39

こんにちは。この度も、宜しくお願いします。
http_build_queryの使い方の理解が及ばず、ページ送りをうまく実装できません。
以下のような、詳細検索ページを作りたいと考えています。
イメージ説明
キーワードandスタイルand(メディアorメディア)のような検索方法です。
色々なサイトさまを参考に、検索まではできるようになったのですが、
ページ送りを実装して、次のページへ行くと、チェックボックスやラジオボックスの検索内容を維持できません。
以下のままですと、チェックボックスはurlに「&m[0]=anime&m[1]=comic」と記されてしまいます。
どうしたら「&m=anime&m=comic」のようにできますでしょうか。
または、ページ送りをきちんとできるようになりますでしょうか。
よろしくご指導ください。お忙しい中、大変恐縮ではございますが、お願いします。

<?php /* htmlspecialchars のラッパーを定義 */ function h($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); } /* 設定 */ $config = [ 'pdo' => [ // SQL_CALC_FOUND_ROWS を利用するのでMySQL前提 'dsn' => 'mysql:dbname=****;host=localhost;charset=utf8', 'username' => '****', 'password' => '****', ], 'pagenation' => [ 'per_page' => 3, ], ]; $mediaform = array('anime' => 'アニメ','comic' => 'コミック','novel' => '小説','game' => 'ゲーム','cinema' => '映画'); $word_styleform = array('word' =>'セリフ','style' => '地の文'); /* GETパラメータを変数にセット(ページ表示時に再利用してもよい) */ $request = [ 'page' => max((int)filter_input(INPUT_GET, 'page'), 1), // 1以上の整数を保証 'q' => (string)filter_input(INPUT_GET, 'q'), // 文字列を保証 'm' => filter_input ( INPUT_GET,'media', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY), ]; /* データベースに接続 */ try { // PDOインスタンスを準備 $c = $config['pdo']; $pdo = new PDO($c['dsn'], $c['username'], $c['password']); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); // 全角スペースなども含めて全てを「1バイト以上の文字列」に分割する $words = preg_split( "/[\\x0-\x20\x7f\xc2\xa0\xe3\x80\x80]++/u", $request['q'], -1, PREG_SPLIT_NO_EMPTY ); $media = filter_input ( INPUT_GET,'media', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY); $word_style = (string)filter_input(INPUT_GET, 'word_style'); $test = ""; if (!empty($media)){ foreach($media as $check){ $ttt[] = "Find_IN_SET('$check',media)"; } $test = implode(' or ', $ttt); $test2 = " ( ".$test . ")"; } $radio = ""; if (!empty($word_style)){ $radio = sprintf (' word_style = \'%s\'', $word_style); } if(!empty($word_style)){ if(!empty($media)){ $msw = " AND ".$radio." AND ".$test2; } else { $msw = " AND ".$radio; } } elseif(!empty($test2)) { $msw = " AND ".$test2; } else { $msw = ""; } // 検索を実行 $conds = ['1']; $values = []; foreach ($words as $word) { $conds[] = 'keyword LIKE ? ESCAPE "!"'; $values[] = '%' . preg_replace('/(?=[!_%])/', '!', $word) . '%'; } $format = 'SELECT SQL_CALC_FOUND_ROWS id,word,keyword FROM ttables WHERE %s %s ORDER BY id DESC LIMIT %d, %d'; $stmt = $pdo->prepare(sprintf( $format, implode(' AND ', $conds), $msw, $config['pagenation']['per_page'] * ($request['page'] - 1), $config['pagenation']['per_page'] )); $stmt->execute($values); // 結果とページネーションのための情報を取得 $rows = $stmt->fetchAll(); $page_count = ceil( (int)$pdo->query('SELECT FOUND_ROWS()')->fetchColumn() / $config['pagenation']['per_page'] ); } catch (PDOException $e) { $error = $e->getMessage(); } /* UTF-8のHTML文書であることをブラウザに明示する */ header('Content-Type: text/html; charset=UTF-8'); ?> </body> </html><body> <h2>詳細検索</h2> <div> <form action="" method="get"> <div> <label for="q">キーワード:</label> <input type="text" name="q" size="25" value="<?=h($request['q'])?>"> </div> <div> <label for="word_style">スタイル:</label> <input type="radio" name="word_style" value="word" />セリフ <input type="radio" name="word_style" value="style" />地の文 </div> <div> <label for="media">メディア:</label> <?php foreach($mediaform as $key =>$val){ if(!empty($media)){ $kekka = array_search($key, $media); if($kekka === false){ $chk = ""; } else { $chk = "checked"; } } echo "<input type=\"checkbox\" name=\"media[]\" value=\""; echo $key. "\""; if(!empty($chk)){echo $chk;} echo ">"; echo $val; }

?>
</div>
<div>
<input value="検索開始" type="submit" />
</div>

</form> </div> <!-- エラーがあれば出力 --> <?php if (isset($error)): ?> <p><?=h($error)?></p> <?php endif; ?> <!-- 結果があれば出力 --> <?php if (!empty($rows)): ?> <table> <tr> <th>作品タイトル</th> <th>キーワード</th> <th>編集</th> </tr> <?php foreach ($rows as $row): ?> <tr> <td><?=sprintf('<a href="data.php?id=%d">%s</a>', $row['id'], h($row['word'])) ?></td> <td><?=h($row['keyword'])?></td> <td><?=sprintf('<a href="edit.php?id=%d">◆</a>', $row['id'])?></td> </tr> <?php endforeach; ?> </table> <?php endif; ?> <!-- ページネーション --> <?php if (isset($page_count)) { // 表示内容を配列に格納する $items = []; // 2ページ目以降であれば「前へ」をセット if ($request['page'] >= 2) { $items[] = sprintf('<a href="?%s">前へ</a>', http_build_query([ 'page' => $request['page'] - 1, 'q' => $request['q'], 'm' => $request['m'] ], '', '&amp;')); } // ページ番号をセット for ($i = 1; $i <= $page_count; ++$i) { if ($i === $request['page']) { $items[] = "$i"; } else { $items[] = sprintf('<a href="?%s">%d</a>', http_build_query([ 'page' => $i, 'q' => $request['q'], 'm' => $request['m'] ], '', '&amp;'), $i); } } // 次のページがあれば「次へ」をセット if ($request['page'] <= $page_count - 1) { $items[] = sprintf('<a href="?%s">次へ</a>', http_build_query([ 'page' => $request['page'] + 1, 'q' => $request['q'], 'm' => $request['m'] ], '', '&amp;')); } // 表示 echo '<div>' . implode(' | ', $items) . '</div>'; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

すいません、自己解決しました。
お目汚しなコードですが……
if (!empty($media)){
$_SESSION['media'] = $media;
foreach($_SESSION['media'] as $check){
$ttt[] = "Find_IN_SET('$check',media)";
}
としてから、
'media' => $_SESSION['media'],をsprintfで代入してできました。

投稿2015/09/15 05:16

nakamura03

総合スコア25

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問