I have this validation rules in request class:
public function rules(): array
{
$countries = getCountriesForValidation();
return [
'total_capital_cost' => 'required|integer|in:' . implode(',', CapitalCosts::getCases()),
'investment_amount_id' => 'required|integer|in:' . implode(',', InvestmentAmounts::getCases()),
'other_income' => 'array',
'other_income.other_income_sources' => 'required_with:other_income|integer|in:' . implode(',', IncomeSources::getCases()),
'other_income.income_frequency' => 'required_with:other_income|integer|in:' . implode(',', IncomeFrequencies::getCases()),
'overseas_transfers_last_year' => 'array',
'overseas_transfers_last_year.funds_transfer_country' => 'required_with:overseas_transfers_last_year|integer|in:' . $countries,
'incoming_funds_last_year' => 'array',
'incoming_funds_last_year.funds_origin_country' => 'required_with:incoming_funds_last_year|integer|in:' . $countries
];
}
As you can see, several fields are required to be integer
. However, when I call $request->validated()
in the controller, it returns all validated values as strings, even though they were specified as integers.
I’m converting the validated data to JSON to store it in the database. I also have another API that returns this submitted data.
The issue is that even if I send integer values, I receive them as strings in the response due to Laravel's request handling. This makes it difficult for the front-end to handle the response consistently, as the data types can vary between integer and string.
Found global solution for this issue
I have overridden the validated()
method of the FormRequest
class to cast fields specified by integer rules to integers.
public function validated($key = null, $default = null)
{
// Call the parent validated method to get the initial validated data
$validatedData = parent::validated($key, $default);
// Get the validation rules
$rules = $this->rules();
// Loop through each rule
foreach ($rules as $field => $rule)
{
// Split the field into parts for nested arrays
$fieldParts = explode('.', $field);
// Start with the root of the validated data
$currentData = &$validatedData;
// Traverse the nested structure based on the field parts
foreach ($fieldParts as $part)
{
// Check if currentData is an array and contains the part
if (is_array($currentData) && array_key_exists($part, $currentData))
{
// Move deeper into the nested array
$currentData = &$currentData[$part];
}
else
{
// If part is not found, skip to the next field
continue 2;
}
}
// If the data at the current field is null, skip integer conversion
if ($currentData === null)
{
continue;
}
// If the rule requires integer conversion, cast the data to integer
if ($this->hasIntegerRule($rule))
{
$currentData = (int) $currentData;
}
}
// Return the modified validated data
return $validatedData;
}
private function hasIntegerRule($rule): bool
{
// Check if the rule is an array and contains 'integer'
if (is_array($rule))
{
return in_array('integer', $rule);
}
// Check if the rule string contains 'integer'
return str_contains($rule, 'integer');
}