Boolean validation does not accept "true" and "false", but accepts "1", "0" #514
Comments
|
Thats odd.. I would just submit your PR anyway. I can't think of a reason why those should not evaluate to their boolean values as PHP even makes the same switch internally. |
|
I did some testing and I think the reasoning behind this may have to do with the way PHP does casting. |
|
I did the PR work around the boolean validation a while ago that added some stuff. So I looked into this at the time. The problem is you cannot accept This means if you did The best option is to change your GET method to use 1/0 instead of "true"/"false". Another option is do some casting on the Request prior to validation. |
|
We could use something like this $bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);described here: https://stackoverflow.com/questions/4775294/parsing-a-string-into-a-boolean-value-in-php |
|
If casting is implemented into validation - then yes. But at the moment Laravel does not cast during validation - so we cannot do this. I think there was some discussion around it on internals somewhere? |
|
I got around this by utilizing the base namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TransformsRequest;
class ConvertStringBooleans extends TransformsRequest
{
protected function transform($key, $value)
{
if($value === 'true' || $value === 'TRUE')
return true;
if($value === 'false' || $value === 'FALSE')
return false;
return $value;
}
} |
|
You might want to consider |
|
Only |
|
I think (for consistency) we should consider whether the boolean validation rule should match the built in boolean validation filter. In my code I had: I think it's just a matter of being consistent with the build in validation rules. As @jfadich suggests I can see how the |
|
The I would also like a rule which allows to validate a checkbox. For now, the workaround is to set the checkbox value to |
|
You can also use the |
Will the |
|
Yes, it won't work. Validation does not change/coerce the input types. So, depending on the "laxness" of the validation, you end up with |
|
I think that the docs should be updated to make the 'boolean' validation rule more clear. The way it's phrased now, it isn't very obvious that boolean strings aren't acceptable to use. While technically the validation rule does work with true/false the Middleware workaround posted by @jfadich is required for the rule to work as you would expect based on the docs. |
Anyone reading this should be very careful using this. Imagine an instance where someone adds a comment simply saying "true" (a common response in a chat room or forum perhaps?) This middleware would convert the comment string to a boolean. |
|
Seems best to make a custom rule using filter_var. Then just... eg. makes it clear what’s happening vs messing with middleware example above which might unintentionally cast a literal ‘true’ string. |
|
Is it possible to overwrite the existing bool method so that |
|
@robjbrain Keep in mind I was posting that as a suggestion, not production ready code. The transforms request middleware provides a means to pass attributes through so you can specify which fields should be converted Then in the middleware: |
|
@jfadich |
|
@iraklisg Looks like it was removed. laravel/framework@a4936b9. You can add it back in yourself in your custom middleware. |
|
For correct parsing you can write helper like this one if (! function_exists('to_bool')) {
/**
* Returns TRUE for TRUE, "1", "true", "t", "on" and "yes". Returns FALSE otherwise.
*
* @param mixed $value
* @return bool
*/
function to_bool($value): bool
{
if (is_bool($value)) {
return $value;
}
if ($value instanceof PotentiallyMissing && $value->isMissing()) {
return false;
}
if (is_string($value) && Str::lower($value) === 't') {
return true;
}
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
} |
|
Since Laravel 6.x: $availableForHire = Request::boolean('available_for_hire'); // true or falseSource: https://www.amitmerchant.com/convert-request-variable-parameters-laravel/ |
because i think, php intrprets "1" or "0" as number..where "true" or "false" is not interpreted as a number. am i right? |
|
Here is a test for those implementing the middleware @jfadich provided. <?php
namespace Tests\Feature;
use Route;
use Tests\TestCase;
class ConverStringBooleansTest extends TestCase
{
/** @test It converts string booleans */
public function it_converts_string_booleans()
{
Route::post('/_tests/booleans', function () {
return request()->all();
});
$this->post('/_tests/booleans', ['val1' => 'true', 'val2' => 'TRUE', 'val3' => 'false', 'val4' => 'FALSE'])
->assertExactJson(['val1' => true, 'val2' => true, 'val3' => false, 'val4' => false]);
}
} |
I ran into a problem where boolean validation for GET parameters (?attribute=true) does not work. I went to write a pull request to allow string versions of "true" and "false" to be accepted but looking at the validator test it appears that this is expected behavior.
Why are string versions of 1 and 0 accepted as valid and not string version of true and false? This makes boolean validation pointless for get parameters since they always come in as strings. Since this appears to be intended behavior I'm wondering what the rational is behind the decision and if it can be changed.
The text was updated successfully, but these errors were encountered: