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

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

ただいまの
回答率

90.02%

配列の値を複数検索したい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 362

MeB

score 94

 前提・実現したいこと

fromからの値を取って来てそれに対応した項目(配列)を表示させたいのですが、
formの1つの値を value="1,2" のような感じにして複数個取得してヒットしたものを表示させたいです。

現状はvalueが1つであれば動く状態です。valueの中が2つ以上(value="1,2,3")の場合は動かないです。
訂正
現状はvalueが1つであれば正常に検索され該当の配列のみが表示されます。
valueの中が2つ以上(value="1,2,3")の場合は下記のphpに記述しましたが"チェックされてない"が表示されます。

 該当のソースコード

<form id="form" name="search" action="" method="POST">
        <div class="form-list">
          <p>タイプ</p>
          <input type="radio" id="type01" name="type" value="1"><label for="type01">1</label>
          <input type="radio" id="type02" name="type" value="2,3,4"><label for="type02">2以降</label>
        </div>
        <div class="form-list">
          <p>カラー</p>
          <input type="radio" id="color01" name="color" value="red"><label for="color01"></label>
          <input type="radio" id="color02" name="color" value="blue,green"><label for="color02">青または緑</label>
        </div>
        <button class="submit" value="check">検索</button>
      </form>
//ajaxの処理が2回あるのは検索ボタンを押す前に全項目を表示させておきたいからなのですが、
//1回で済む記述があればご教示していただきたいです。ついでの質問ですみません。
$(function () {
  $.ajax({
    url: 'ajax.php',
    type: "POST",
    dataType: "html",
  }).done(function(data){
    $('.result').html(data);
  });

  $('button').on('click',function(event) {
    event.preventDefault();
    var html = '';
    var formdata = new FormData($('#form').get(0));
    $.ajax({
      url: 'ajax.php',
      type: "POST",
      dataType: "html",
      data:formdata,
      cache:false,
      processData: false,
      contentType: false,
    }).done(function(data){
      $('.result').html(data);
    });
  });
});
<?php
header("Content-type: text/html; charset=utf-8");
$type = filter_input( INPUT_POST, "type" );
$type_split = preg_split("/,/", $type); //,で区切って取って見ましたが動きませんでした。追記:配列にカンマ区切りでそれぞれのあたいは入るのですが、正常の検索されまでんでした。
                        //下記のif文のところですと"チェックされてない"が表示されます。
$type_implode = implode($type_split);//区切ったもの文字列にしたのですが"12"となってしまいうまく行きませんでした。追記:結果が"12"となってしまうため同じく"チェックされてない"が表示されます。

$data = [
  "test"=>[
    [
        "type"=>"1",
        "color"=>"red"
    ],
    [
        "type"=>"2"
        "color"=>"red"
    ],
    [
        "type"=>"3"
        "color"=>"blue"
    ],
    [
        "type"=>"4"
        "color"=>"green"
    ]
  ]
];

$result = array_filter($data["test"],function($x) use($type) {
    return (is_null($type) || $x["type"] == $type);
});
if ($result == null) {
    print <<<eof
    <div class="empty">
        <p>チェックされてない</p>
    </div>
eof;
} else {
    array_walk($result,function($x){
    print <<<eof
    <p>{$x["type"]}</p>
eof;
});
}
?>

 試したこと

上記のコメントアウト部分のようにいろいろ試して見たのですが、
そもそも $type がどのような形であれば
複数のtypeがヒットするのでしょうか?
ご教示のほどよろしくお願いします。

追記
質問の趣旨が少し変わってしまうので指摘がありましたら別で質問いたします。

papinianusさんのご回答を元に項目がtype以外にも必要だったため

$result = array_filter($data["test"],function($x) use($type,$color) {
    return (is_null($type) || in_array($x["type"], $type_split, true)) &&
           (is_null($color) || in_array($x["color"], $color_split, true));
});
としましたが、この状態ですと全ての項目に当てはまっているものした表示されませんでした。
例:カラー項目の青または緑のみを押した場合typeでいうと34を表示したいがcolorがチェックされていないため何も表示されない状態です。
※htmlとphpの配列にcolorの項目を追記しています。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • mather

    2018/08/21 10:38

    「動きませんでした」とある部分について、どんな値になるか期待していたのに対して実際にはどんな結果になったのか具体的に書いてください。

    キャンセル

  • MeB

    2018/08/21 10:51

    matherさん 失礼しました。訂正と追記をしました。

    キャンセル

回答 3

+3

仕様としては1,2,3,4のどれか一つでもマッチすればよいということですか?
explodeしてin_arrayでいいかと思いますが、せっかくfilter_inputしているならこれでどうでしょうか?
(とりあえずajaxはおいておいて自分にpostしてあります)

<?PHP
$type = filter_input( INPUT_POST, "type" ,FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/(^|,)[1-4](,|$)/"]]);
if(!is_null($type)){
  if($type===false){
    print "not match";
  }else{
    print $type;
  }
}
?>
<form method="POST">
<label><input type="radio" name="type" value="1">1</label>
<label><input type="radio" name="type" value="2,3,4">2,3,4</label>
<label><input type="radio" name="type" value="4,5,6">4,5,6</label>
<label><input type="radio" name="type" value="5,6,7">5,6,7</label>
<label><input type="radio" name="type" value="20,30,40">20,30,40</label>
<button type="submit" value="check">検索</button>
</form>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/08/21 18:09

    ご回答ありがとうございます。
    上記ですと"2"と"3"と"4"ではなく"2,3,4,"と取れてしましヒットしませんでした。
    おそらく伝え方が悪かったのだと思います。すみません。

    キャンセル

+3

papinianusさんとほぼ同じですが、次のようにすることで判定できます。

$result = array_filter($data["test"],function($x) use($type_split) {
    return in_array($x["type"], $type_split, true);
});

is_null($type) を取り除きましたが、これだけ個別にチェックして $data を全部返すようにして良いと思います。

ちなみに、 $result == null という判定も正確ではないと思います。空配列かどうかチェックしたほうが良いのではないでしょうか? 

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/08/21 18:04

    ご回答ありがとうございます。

    仮にtypeの他にcolorがあった場合は
    true) && in_array...
    などのようにするのでしょうか?

    >is_null($type) を取り除きましたが、これだけ個別にチェック$data を全部返す
    $result =... の後に個別の処理を書くということでしょうか?

    重ねての質問すみません。

    キャンセル

  • 2018/08/22 09:54

    > 仮にtypeの他にcolorがあった場合は
    それはフィルタしたい条件によると思います。 「typeがこの中のどれか」かつ「colorがこの中のどれか」となっている場合は AND条件になると思います。
    しかし、ものすごく中途半端なコードでは認識が同じなのかわからないので僕からは「それで良い」とは言えません。

    > >is_null($type) を取り除きましたが、これだけ個別にチェック$data を全部返す
    > $result =... の後に個別の処理を書くということでしょうか?
    いえ、自分で条件をよく見直してほしいのですが、 $type が指定されていない場合は実際には何もフィルタせずに全件出力してますよね。つまり、 array_filterそのものを実行する必要がないはずです。

    キャンセル

checkベストアンサー

+2

$resultですが、$type_splitを使うときは、こういう書き方ではないかと思います。

$result = array_filter($data["test"],function($x) use($type) {
    return (is_null($type) || in_array($x["type"], $type_split, true));
});

$x["type"] == $type_splitでは文字列と配列を==で比較していることになり、正常に検索できません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/08/21 18:20

    ありがとうございます。
    なん度もすみません。
    いただいたコード部分を && にして記述したのですが
    チェック項目は複数あった場合全てをチェックしないと表示されない状態です。
    理想はチェックした項目が全て当てはまって入れば該当項目を表示、
    またチェックされていない項目があればそこはスルーして表示させたいのですが

    if ($result == null) {...

    の部分を直すべきでしょうか?

    キャンセル

  • 2018/08/21 19:39

    どこのどれを&&になさったのかわかりません。また、全てとはtypeとcolorのどの組み合わせのことを指していますか?
    できれば質問に追記していただけないですか?

    キャンセル

  • 2018/08/22 09:14

    失礼しました。
    追記いたしました。

    キャンセル

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

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