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

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

ただいまの
回答率

88.93%

PHP多次元連想配列を検証したい

解決済

回答 1

投稿 編集

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

mickymouse

score 3

実現したいこと

検証対象$responseに対して、型が$required_infoの指定通りであることを検証する関数を作りたいです。

問題

パターン1やパターン2のように次元の数や構造が異なるのですが、いずれにも対応できるような関数が作れません。

パターン1

// 検証対象
$response = [
    [
         'title'    => 'shortcake'
        ,'tag_list' => ['kids']
        ,'ranking'  => 1
        ,'side' => [
             'url'  => 'http...'
            ,'name' => 'karaage'
            ,'id'   => 10
        ]
    ]
];

// 型を指定
$required_info = [
     'title'    => 'string'
    ,'tag_list' => 'array'
    ,'side' => [
         'url'  => 'string'
        ,'name' => 'string'
        ,'id'   => 'integer'
    ]
];

パターン2

// 検証対象
$response = [
    'titles' => [
          'name'       => 'coconut juice'
         ,'thumbnails' => 'http...'
    ]
    ,'data' => [
        'id' => [
             'a_id' => 10
            ,'b_id' => 20
        ]
    ]
];

// 型を指定
$required_info = [
    'titles' => [
          'name'       => 'string'
         ,'thumbnails' => 'string'
    ]
    ,'data' => [
        'id' => [
            'a_id' => 'integer'
        ]
    ]
];

関数イメージ

作りたい関数のイメージはこちらです。

// 実行
$result = validate_required_in_response( 'cake', $response ); 
var_dump($result);

// $responseのリストそれぞれについて、$required_info で指定した型がおかしければfalseを返す
function validate_required_in_response( $kind, $response ){

    // 引数に応じて型を指定
    if ( $kind === 'cake' ) {
        // 型を指定
        $required_info = [
             'title'    => 'string'
            ,'tag_list' => 'array'
            ,'side' => [
                 'url'  => 'string'
                ,'name' => 'string'
                ,'id'   => 'integer'
            ]
        ];
    }

    elseif ( $kind === 'drink' ) {
        // 型を指定
        $required_info = [
            'titles' => [
                  'name'       => 'string'
                 ,'thumbnails' => 'string'
            ]
            ,'data' => [
                'id' => [
                    'a_id' => 'integer'
                ]
            ]
        ];
    }

    // 検証開始
    $result = true;
    foreach ( $response as $value ) {
         // 検証対象$responseに対して、型が$required_infoの指定通りであることを検証したいです
    }
    return $result; // 型がおかしければfalseを返したい
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

どこまでの仕様かわからないですが

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/08 16:33

    無理やりやってみました。再帰処理も面倒なので冗長にかいてあります
    型があっていればtrue、違えばfalse、なければnullを返します

    キャンセル

  • 2020/07/08 16:33

    $required_info = [
    ['keys'=>['title'] ,'type'=>'string' ],
    ['keys'=>['tag_list'] ,'type'=>'array' ],
    ['keys'=>['ranking'] ,'type'=>'string' ],
    ['keys'=>['side'] ,'type'=>'array' ],
    ['keys'=>['side','url'] ,'type'=>'string' ],
    ['keys'=>['side','name'],'type'=>'string' ],
    ['keys'=>['side','id'] ,'type'=>'integer'],
    ['keys'=>['side','test'],'type'=>'integer'],
    ];

    $result=array_map(function($x) use($response){
    $ret=null;
    if(count($x["keys"])==1){
    if(isset($response[0][$x["keys"][0]])){
    $ret=gettype($response[0][$x["keys"][0]])==$x["type"];
    }
    }
    if(count($x["keys"])==2){
    if(isset($response[0][$x["keys"][0]][$x["keys"][1]])){
    $ret=gettype($response[0][$x["keys"][0]][$x["keys"][1]])==$x["type"];
    }
    }
    return $ret;
    },$required_info);
    var_dump($result);

    キャンセル

  • 2020/07/08 16:52

    なるほど、そちらの指定は思いつきませんでした。
    true、false、nullと3種類で返せるというのも助かります。
    お忙しい中何度もやりとりして下さいまして、誠にありがとうございました。

    キャンセル

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

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

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