最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Codeigniter 4 validation of keys within an associative array - Stack Overflow

programmeradmin7浏览0评论

I would like to validate the following json in CI4:

{
    "field1": "some value",
    "array1": {
        "2876": "4358",
        "9904": "17"
    }
}

Array 1 can reasonably contain up to 50 key value pairs.

I have validation rules for both the keys and values in array1, for the purposes of this question lets require them both to be numeric.

The code I have so far is:

        $validation = \Config\Services::validation();

        $validation->setRules([
            'field1'   => 'required|max_length[20]',
            'array1.*'   => 'required|numeric',
        ]);

        if (! $validation->withRequest($this->request)->run()) {
            return $this->failValidationErrors($validation->getErrors());
        }

Alternatively based on an answer I've seen elsewhere:

        $validation = \Config\Services::validation();

        $validation->setRules([
            'field1'   => 'required|max_length[20]'
        ]);

        $to_validate = $this->request->getPost();
        foreach ($to_validate['array1'] as $key => $value) {
            $validation->setRule('array1.' . $key , null, 'required|numeric');
        }

        if (! $validation->withRequest($this->request)->run()) {
            return $this->failValidationErrors($validation->getErrors());
        }

This code successfully rejects a value of "abcd" but how do I reject a string key?

I could pre-process by putting the keys into their own array which can be validated with an array2.* rule but this seems like a simple use case which should work out of the box.

Also how should I implement the array size limit check?

I would like to validate the following json in CI4:

{
    "field1": "some value",
    "array1": {
        "2876": "4358",
        "9904": "17"
    }
}

Array 1 can reasonably contain up to 50 key value pairs.

I have validation rules for both the keys and values in array1, for the purposes of this question lets require them both to be numeric.

The code I have so far is:

        $validation = \Config\Services::validation();

        $validation->setRules([
            'field1'   => 'required|max_length[20]',
            'array1.*'   => 'required|numeric',
        ]);

        if (! $validation->withRequest($this->request)->run()) {
            return $this->failValidationErrors($validation->getErrors());
        }

Alternatively based on an answer I've seen elsewhere:

        $validation = \Config\Services::validation();

        $validation->setRules([
            'field1'   => 'required|max_length[20]'
        ]);

        $to_validate = $this->request->getPost();
        foreach ($to_validate['array1'] as $key => $value) {
            $validation->setRule('array1.' . $key , null, 'required|numeric');
        }

        if (! $validation->withRequest($this->request)->run()) {
            return $this->failValidationErrors($validation->getErrors());
        }

This code successfully rejects a value of "abcd" but how do I reject a string key?

I could pre-process by putting the keys into their own array which can be validated with an array2.* rule but this seems like a simple use case which should work out of the box.

Also how should I implement the array size limit check?

Share Improve this question asked 10 hours ago ChrisGChrisG 739 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

array1.* validates the values of array1 and indeed not the keys.

The idea you had to provide the keys upfront is not bad at all, as it would turn the keys into values and you then would be able to validate them with the standard rules:

$to_validate = $this->request->getPost();
$to_validate['array1_keys'] = array_keys($to_validate['array1'] ?? []);
...

Then it is possible to use array1_keys.* next to array1.*.

I would start with that as you can find out how far you get with the standard rules.

Furthermore if you would like to dig deeper towards custom rules, I'd suggest to look into rules for file uploads as they refer to array fields. Their implementation (read the source code of them) should show how you can access array data including keys (IIRC). You can then experiment creating your own rules.

This works:

        $validation = \Config\Services::validation();

        $validation->setRules([
            'field1'           => 'required|max_length[20]',
            'array1'           => 'required',
            'array1.*'         => 'required|numeric',
            'array1_keys.*'    => 'required|numeric',
            'array1_count'     => 'required|numeric|greater_than_equal_to[1]|less_than_equal_to[50]'
        ]);

        $to_validate                 = $this->request->getPost();
        $to_validate["array1_keys"]  = array_keys($to_validate['array1'] ?? []);
        $to_validate["array1_count"] = count($to_validate["array1_keys"]);

        if (! $validation->run($to_validate)) {
            return $this->failValidationErrors($validation->getErrors());
        }

That said it is hardly elegant so I will happily upvote a more concise alternative.

发布评论

评论列表(0)

  1. 暂无评论