Closed xonipatino closed 1 year ago
Hello. I found the solution by changing the following line in the system\Validation\Validation.php file
Line 481:
/** @var IncomingRequest $request */
if (strpos($request->getHeaderLine('Content-Type'), 'application/json') !== false) {
// $this->data = $request->getJSON(true);
$this->data = $request->getJSON(true) ?? [];
return $this;
}
Thank you for reporting.
The error should not be thrown, but if $request->getJSON(true)
returns null
,
it means the JSON string is invalid.
Do you really want the data to be valid?
This was working in CI 4.4.2
It is strange. Because there is no change in Validation except the exact_length
rule.
https://github.com/codeigniter4/framework/commit/a0339851ed3fa122a4a0e7930c62a1463e0cb257#diff-291972258304139308a9538a9fb7abfb92c903481df2a0af105dfdf8515cebd3
@codeigniter4/core-team If we apply the suggested patch, the following test would pass. However, it seems a bit odd that the test would pass. If the result of the validation were to fail, there would be no field to store the error message. Should we throw an exception?
public function testJsonInputInvalid(): void
{
$config = new App();
$json = 'invalid';
$request = new IncomingRequest($config, new URI(), $json, new UserAgent());
$request->setHeader('Content-Type', 'application/json');
$rules = [
'role' => 'if_exist|max_length[5]',
];
$result = $this->validation
->withRequest($request->withMethod('POST'))
->setRules($rules)
->run();
$this->assertTrue($result);
$this->assertSame([], $this->validation->getErrors());
$this->assertSame([], $this->validation->getValidated());
}
Thank you for reporting.
The error should not be thrown, but if
$request->getJSON(true)
returnsnull
, it means the JSON string is invalid. Do you really want the data to be valid?
Hello, I was checking more carefully and I found that if you make a GET request with the header Content-Type = application/json
it generates the error, so I deduced that it is illogical to make a GET request with that header, even though the query parameters they are sent by url.
Hello. I found the solution by changing the following line in the system\Validation\Validation.php file
Line 481:
/** @var IncomingRequest $request */ if (strpos($request->getHeaderLine('Content-Type'), 'application/json') !== false) { // $this->data = $request->getJSON(true); $this->data = $request->getJSON(true) ?? []; return $this; }
It is not necessary to modify the line that I had named, it is just knowing how to put the headings for each case. But they should clarify it in the documentation.
@xonipatino I sent PR #8135
@kenjis does the doc fix make your question above irrelevant? I didn't understand it at first read but I can process to more if it is still relevant.
@MGatner I must say no? It is just a fix to a incorrect sample code that was pointed out by the reporter of this.
The TypeError issue still remains.
Okay I have now fully read and understood the issue. Yes, this is a bug in Validation - IncomingRequest::getJson()
has no need to return an array, but Validation will only work on an array of data.
In my opinion this feature of Validation is assuming too much from the underlying stack and it should be pulled. We cannot assume a particular API schema nor even RESTful protocols. If things a desirable feature it should be moved somewhere appropriate, to IncomingRequest
or even our API trait.
PHP Version
8.2
CodeIgniter4 Version
4.4.3
CodeIgniter4 Installation Method
Composer (using
codeigniter4/appstarter
)Which operating systems have you tested for this bug?
Windows
Which server did you use?
cli-server (PHP built-in webserver)
Database
No response
What happened?
CodeIgniter\\Validation\\DotArrayFilter::run(): Argument #2 ($array) must be of type array, null given, called in ...\\vendor\\codeigniter4\\framework\\system\\Validation\\Validation.php on line 203
Steps to Reproduce
I have the next code:
and returns:
Expected Output
a JSON of data or a JSON with invalid input information
Anything else?
This was working in CI 4.4.2