0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【PHP】年月日が配列で渡ってくるときのバリデーション

0
Last updated at Posted at 2018-08-27

目的

入力フォームの都合で次のような配列の形で年月日のデータが渡される。

$date = [
    'year'  => 1990,
    'month' => 1,
    'day'   => 1,
];

このときに

  • 所定の型・形式なのか
  • 妥当な日付なのか

を検証したい。

なお、外部からの入力内容をチェックする想定なので

  • 渡されるデータの型は保証されていない
  • 数値 (int) が入る箇所には、「数値 (int)」「数値 (int) として解釈できる文字列」の両方を許可する

とする。

コード

日付の妥当性検証には PHP 組み込みの checkdate() を使う。

/**
 * @param mixed $value チェック対象のデータ
 * @return bool 所定の形式に従った、妥当な日付の場合に true
 */
function isValidDateArray($value): bool
{
    if (!is_array($value)) {
        return false;
    }

    $expectedKeys = ['year', 'month', 'day'];
    foreach ($expectedKeys as $key) {
        // キーが存在しない、またはそのキーに対する値が整数でなければ false を返す
        if (!isset($value[$key]) || (filter_var($value[$key], FILTER_VALIDATE_INT) === false)) {
            return false;
        }
    }

    return checkdate($value['month'], $value['day'], $value['year']);
}

filter_var() による整数の検証についてはこちらを参照。

用途に合わせて整数の検証ロジックは書き換えるとよい。

動作確認

  • PHP 7.1.18

以下の assertion が全て満たされていることを確認。


$dataSets = [
    '正常系_数値で指定された場合にtrueを返すこと' => [
        'expected' => true,
        'value'    => [
            'year'  => 1990,
            'month' => 1,
            'day'   => 1,
        ],
    ],
    '正常系_文字列で指定された場合にtrueを返すこと' => [
        'expected' => true,
        'value'    => [
            'year'  => '1990',
            'month' => '1',
            'day'   => '1',
        ],
    ],
    '配列が渡されていない場合にfalseを返すこと' => [
        'expected' => false,
        'value'    => 1,
    ],
    'キーが足りていない場合にfalseを返すこと' => [
        'expected' => false,
        'value'    => [
            'year'  => 1990,
            'month' => 1,
        ],
    ],
    '正常系_余分なキーが存在している場合でもtrueを返すこと' => [
        // NOTE: 今回ではこの形は許容している、必要なら余分なキーの存在チェックを足す
        'expected' => true,
        'value'    => [
            'year'  => 1990,
            'month' => 1,
            'day'   => 1,
            'foo'   => 'bar'
        ],
    ],
    '非整数が渡された場合にfalseを返すこと' => [
        'expected' => false,
        'value'    => [
            'year'  => 'a',
            'month' => 1,
            'day'   => 1,
        ],
    ],
    '不正な日付が渡された場合にfalseを返すこと' => [
        'expected' => false,
        'value'    => [
            'year'  => 1990,
            'month' => 2,
            'day'   => 29,
        ],
    ],
    'うるう年の2月29日が渡された場合にtrueを返すこと' => [
        'expected' => true,
        'value'    => [
            'year'  => 1980,
            'month' => 2,
            'day'   => 29,
        ],
    ],
];

foreach ($dataSets as $testCase => $dataSet) {
    assert(isValidDateArray($dataSet['value']) === $dataSet['expected'], $testCase);
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?