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

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

ただいまの
回答率

88.34%

PHPとajaxによる検索について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 4
  • VIEW 2,611

melon910

score 35

検索機能の作り方で困ったので質問させていただきます。

現在、PHPとMySQLとajaxで検索機能を作っています。

仕様としましては、リアルタイムに検索結果を出したかったので、検索項目を用意しチェックなどをしたらその場で結果が出るような造りになっています。

リアルタイムなので、ajaxを複数使い、そして、その複数のajax間でデータのやり取りをしたかったので、PHPのSESSIONを使いデータの受け渡しをしています。
ある条件を満たす(例えば、GETで「Search=on」を取得する)と検索プログラムが起動し、各項目を取得します。

if ($_GET["Search"] == "on") {
    // 条件が満たされた場合
}


そして、その項目を取得した場合、SESSIONと検索結果を残したかったのでGETパラメータを保存し、その取得した条件でデータベース内を検索し、ヒットしたデータを返しページに反映し、URLにパラメータを反映するような流れとなっています。

if ($_GET["Search"] == "on") {
    //GETで取得した場合
    if ($_GET["検索項目1"]) {
        //セッションとパラメータに保存
        $_SESSION["検索項目1"] = $param["検索項目1"] = $_GET["検索項目1"];
    //SESSIONにデータが保存されている、且つ検索ボタンが押されなかった場合
    } else if (!$_GET["検索ボタン"] and $_SESSION["検索項目1"]) {
        //パラメータに保存
        $param["検索項目1"] = $_SESSION["検索項目1"];
    //ボタンは押されたがGETが空の場合
    } else {
        //SESSION初期化
        $_SESSION["検索項目1"] = "";
    }
}
//この後、MySQLで検索、URLにパラメータ反映


また、上記の条件を満たさない(「Search=on」を取得しなかった)場合は、検索結果のSESSIONを初期化し、次に検索条件を満たした場合に引き継がないような仕様にしています。

しかし、この仕様だとページは違うページだが、検索条件を満たしてしまう場合は条件が引き継がれてしまい、本当は初期化しないといけないのにその引き継いだ条件で検索してしまいます。

ページ①:Search=on//移動
ページ②:Search=on //初期化されず引き継いでしまう

各ajax間に検索した項目を引き継ぎ、URLに前の結果も引き継がれるようにしたかったのでSESSIONを使っています。

この機能を止めればいいのですが、理想の検索がこの仕様なので、どうかできないか悩んでいます。
何か良い方法はないでしょうか。

また、この仕様だと何か他に問題が出てくるでしょうか。

皆様のご意見をお聞かせください。

■追記(2016/06/02)
ajax側のプログラムは、項目ごとに設定したボタンを押すとそれに応じたチェックボックスが起動します。
(例えば、都道府県の項目で選択を押した際には、都道府県を選択できるようなajaxが起動)

ボタンを押した初期起動は、関東や関西など大エリアを選ぶことのできるチェックボックスを生成し返します。

//ajax内(例:都道府県)
//初期起動
if ($_GET["Area"] == 1) {
    //関東や関西などの大エリアチェックボックスを返す
}

次に、任意の大エリアを選択すると、それに応じた都道府県を返します。

//ajax内(例:都道府県)
//初期起動
if ($_GET["Area"] == 1) {
    //関東や関西などの大エリアチェックボックスを返す
} else if ($_GET["Area"] == 2) {
    //大エリアに応じた都道府県のチェックボックスを返す
}


次に、都道府県を選択すると、それに応じた市区町村を生成し、返します。

//ajax内(例:都道府県)
//初期起動
if ($_GET["Area"] == 1) {
    //関東や関西などの大エリアチェックボックスを返す
} else if ($_GET["Area"] == 2) {
    //大エリアに応じた都道府県のチェックボックスを返す
} else if ($_GET["Area"] == 3) {
    //都道府県に応じた市区町村のチェックボックスを返す
}


複数あるajaxは上記のような造りになっており、一度検索し、再度検索する際に以前の情報を保存するために、取得した情報をSESSIONで保存しています。
そして、その情報があった際は初期起動の際に処理を行っています。

//ajax内(例:都道府県)
//初期起動
if ($_GET["Area"] == 1) {
    //再検索の際に以前の情報があった場合はそれを再構築する
    if ($_SESSION["エリア①"]) {
        //以前の情報を再構築
    } else if ($_SESSION["エリア②"]) {
        //以前の情報を再構築
    } else if ($_SESSION["エリア③"]) {
        //以前の情報を再構築
    }
    //関東や関西などの大エリアチェックボックスを返す
    //検索条件を保存
    $_SESSION["エリア①"] = $_GET["エリア①"];
} else if ($_GET["Area"] == 2) {
    //大エリアに応じた都道府県のチェックボックスを返す
    //検索条件を保存
    $_SESSION["エリア②"] = $_GET["エリア②"];
} else if ($_GET["Area"] == 3) {
    //都道府県に応じた市区町村のチェックボックスを返す
    //検索条件を保存
    $_SESSION["エリア③"] = $_GET["エリア③"];
}


あとは、任意のチェックボックスにチェックし検索ボタンが押されると上記で説明したプログラムにデータが受け渡され検索を開始します。

よろしくお願いします。

■再追記(2016/06/02)
すみません、ajax側のコードを追加しておりませんでした。

ますは、初期起動のコードです。

//初期起動ajax
$("エリア選択ボタン").on("click", function() {
    $.ajax({
        url : "hoge.php",
        type : "get",
        dataType : "json",
        scriptCharset: 'utf-8',
        data: {
            Area: 1
        },
        success : function(data){
            $("#チェックボックス表示ボックス").remove();
            $("#チェックボックス表示ボックス").append(data["tmp"]);
        },
        error: function(XMLHttpRequest, textStatus, errorThrown){
            //エラー処理
           }
    });
});


次にチェックボックスにチェックした際のコードです。

$("エリア①").live("change", function() {
    var Area1 = $('["エリア①"]:checked').map(function(){
        return $(this).val()
    }).get().join(',');
    var Area2 = $('["エリア②"]:checked').map(function(){
        return $(this).val()
    }).get().join(',');
    var Area3 = $('["エリア③"]:checked').map(function(){
        return $(this).val()
    }).get().join(',');

    $.ajax({
        url : "hoge.php",
        type : "get",
        dataType : "json",
        scriptCharset: 'utf-8',
        data: {
            Area : 1,
            Area1: Area1,
            Area2: Area2,
            Area3: Area3
        },
        success : function(data){
            $("#大エリアボックス").remove();
            $("#大エリアボックス").append(data["エリア①"]);
            if (data["エリア②"]) {
                $("都道府県ボックス").remove();
                $("都道府県ボックス").append(data["エリア②"]);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown){
            //エラー処理
           }
    });
});
//都道府県、市区町村も同じようなコード


この後に、検索ボタンを押すと、上記のようにエリアデータを収集し、検索プログラムへデータを渡します。

よろしくお願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2016/06/01 18:50

    ajax側のコードを提示することは可能でしょうか?

    キャンセル

  • kei344

    2016/06/02 11:46

    JavaScript に $_GET変数 $_SESSION変数 は無いと思うのですが、出力されたHTMLとJavaScriptを提示いただくことは可能でしょうか。

    キャンセル

  • melon910

    2016/06/02 12:19

    >>kei344 様
    すみません、PHPコードと勘違いしておりました。追加が完了致しました。よろしくお願い致します。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2016/06/02 12:33

    目的がよく読み取れません。最終的にどのような画面(インターフェイス)を作りたいのでしょうか?

    キャンセル

回答 2

checkベストアンサー

0

大区分、都道府県と市町村を順に絞り込んだ上で、キーワードなどでの検索が有り、絞り込み状態を保存したまま再検索する、というような挙動でしょうか。

ex) 1回目の検索
大区分 ⇒ 北海道, 九州
都道府県 ⇒ 北海道, 沖縄
市区町村 ⇒ 稚内市, 石垣市
検索キーワード ⇒ 最南端

ex) 2回目の検索
大区分 ⇒ 北海道, 九州        // ここをセッションで保存
都道府県 ⇒ 北海道, 沖縄    // ここをセッションで保存
市区町村 ⇒ 稚内市, 石垣市    // ここをセッションで保存
検索キーワード ⇒ 最北端

セッションをどういう意図で使っているのかがいまいちわかりませんが、書かれている内容であればセッションを使う必要性は低いと思います。ajaxで画面遷移なしで検索を行っているのだから、ページ内に変数を保持するか毎回取得し、全キーワードを送ったほうが手早い気がします。

※ 下記コードは「こういう方向性」くらいな気分で書いているのでこのまま動作するわけでは有りません。

$( 'form' ).on( 'click', 'select, input', function() {
    var form_data = {}
      , $_this = $( this )
      , id = $_this.attr( 'data-flag' )
      ;

    // クリックした要素がどれか
    if ( id === '大区分' ) {
        // 大区分なら都道府県を消しておく
    } else if ( id === '.都道府県' ) {
        // 都道府県なら市区町村を消しておく
    } else if ( id === '市区町村' ) {

    } else if ( id === '検索キーワード' ) {

    } else {

    };
    var $a = $( 'form' ).find( '#大区分:checked' )
      , $b = $( 'form' ).find( '.都道府県:checked' )
      , $c = $( 'form' ).find( '.市区町村:checked' )
      , $d = $( 'form' ).find( '#検索キーワード' )
      ;
    if ( $a.length ) { form_data[ '大区分'   ] = $a.val(); }; // 選択されていないとnullが入るはず。
    if ( $b.length ) { form_data[ '都道府県' ] = $b.map( function() { return $(this).val(); } ).get().join( ',' ); };
    if ( $c.length ) { form_data[ '市区町村' ] = $c.map( function() { return $(this).val(); } ).get().join( ',' ); };
    if ( $d.length ) { form_data[ '検索キーワード' ] = $d.val(); };
    /* { // ex)
          '大区分' : '北海道, 九州'
        , '都道府県' : '北海道, 沖縄'
        , '市区町村' : '稚内市, 石垣市'
        , '検索キーワード' : '最南端'
    }; */

    $.ajax( {
          url : 'hoge.php'    // '大区分' だけ入っていたら都道府県のデータを返し、それ以降が入っていたらそれぞれ返すものを変えるようにhoge.phpを構成する
        , type : 'get'
        , dataType : 'json'
        , scriptCharset : 'utf-8'
        , data : form_data
        , success : function( data ){
            if ( data[ 'type' ] === '大区分' ) {
                // 都道府県部分を書き換え
            } else if ( data[ 'type' ] === '都道府県' ) {
                // 市区町村部分を書き換え
            } else if ( data[ 'type' ] === '市区町村' ) {
                // 処理
            } else if ( data[ 'type' ] === '検索キーワード' ) {
                // 処理
            } else {
                // 処理
            };
          }
        , error: function( XMLHttpRequest, textStatus, errorThrown ) {
            //エラー処理
          }
    } );
} );
<form action="" method="post">

    <label for="area">大区分:</label>
    <select name="大区分" id="大区分" multiple="multiple">
        <option value=""></option>
        <option value="北海道">北海道</option>
        <option value="九州">九州</option>
    </select>

    <label>都道府県:</label>
    <div id="都道府県">
        <label><input type="checkbox" class="都道府県" value="01">北海道</label>
        <label><input type="checkbox" class="都道府県" value="47">沖縄</label>
    </div>

    <label>市区町村:</label>
    <div id="市区町村">
        <label><input type="checkbox" class="市区町村" value="01214">稚内市</label>
        <label><input type="checkbox" class="市区町村" value="47207">石垣市</label>
    </div>

    <label>検索キーワード:</label>
    <div id="検索キーワード">
        <label><input type="text" id="検索キーワード" value=""></label>
    </div>
</form>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

セッションはとりあえずDBアクセスを減らすのが目的なんでしょうかね…。

例にあるような、取得する内容が「地域」「都道府県」ならセッションを利用するのはちょっと違うかな。
アクセスしたユーザーによって返す値が変わるわけじゃないので。
どういうことかというと、「どんなユーザーが利用しても、選んだ地域が同じなら返す値も同じ」はずだからです。

<?php
$arrArea = ["---- 地域 ----", "北海道", "東北"];
$selected_area = filter_input(INPUT_POST, 'area');
$selected_pref = filter_input(INPUT_POST, 'pref');
?><!DOCTYPE HTML>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form action="" method="post">

            <label for="area">地域:</label>
            <select name="area" id="area">
                <?php foreach ($arrArea as $key => $area): ?>
                    <?php
                    printf('<option value="%d"%s>%s</option>'
                        , $key
                        , ($selected_area == $key) ? ' selected' : ''
                        , $area
                    );
                    ?>
                <?php endforeach; ?>
            </select>

            <label for="pref">都道府県:</label>
            <select name="pref" id="pref">
                <option value="">---- 都道府県 ----</option>
            </select>

            <div id="checkboxes_pref">

            </div>
        </form>
        <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
        <script type="text/javascript">
            $(function () {
                $("#area").on('change', function () {
                    var url = 'get_pref.php';
                    var params = {
                        area: $(this).val()
                    };

                    // selectbox
                    $("#pref").empty()
                            .append($("<option>").val('0').text('---- 地域 ----'));

                    // checkboxes
                    $("#checkboxes_pref").empty();

                    if (0 < $(this).val()) {
                        $.getJSON(url, params, function (json) {
                            $.each(json, function (i, res) {

                                // selectbox
                                $('<option>').val(i).text(res)
                                        .appendTo($("#pref"));

                                // checkboxes
                                var label = $('<label>');
                                $('<input>').prop('type', 'checkbox').val(i)
                                        .appendTo(label);
                                label.append(res).appendTo($("#checkboxes_pref"));
                            });
                        });
                    }
                });
            });
        </script>
    </body>
</html>

get_pref.php

<?php

/**
 * get_pref.php
 */
$arrPref = [
    0 => []
    , 1 => ['01' => '北海道']
    , 2 => ['02' => '青森', '03' => '岩手', '04' => '秋田', '05' => '宮城', '06' => '山形', '07' => '福島']
];

$area = filter_input(INPUT_GET, 'area');
echo json_encode($arrPref[$area]);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る