这是这个已有 9 年历史的函数的更新版本:
/**
* Converts a form input request field's type to its proper type after values are received stringified.
*
* Function flow:
* 1. Check if it is an array, if yes, return array
* 2. Remove unused spaces
* 3. Check if it is '0', if yes, return 0
* 4. Check if it is empty, if yes, return blank string
* 5. Check if it is 'null', if yes, return null
* 6. Check if it is 'undefined', if yes, return null
* 7. Check if it is '1', if yes, return 1
* 8. Check if it is numeric
* 9. If numeric, this may be a integer or double, must compare this values
* 10. If string, try parse to bool
* 11. If not, this is string
*
* (c) José Moreira - Microdual (www.microdual.com)
* With the help of Svisstack (http://stackoverflow.com/users/283564/svisstack)
*
* Found at: https://stackoverflow.com/questions/2690654/how-to-get-the-real-type-of-a-value-inside-string
*
* @param string $string
* @return mixed
*/
function typeCorrected($string) {
if (gettype($string) === 'array') {
return (array)$string;
}
$string = trim($string);
if ($string === '0') { // we must check this before empty because zero is empty
return 0;
}
if (empty($string)) {
return '';
}
if ($string === 'null') {
return null;
}
if ($string === 'undefined') {
return null;
}
if ($string === '1') {
return 1;
}
if (!preg_match('/[^0-9.]+/', $string)) {
if(preg_match('/[.]+/', $string)) {
return (double)$string;
}else{
return (int)$string;
}
}
if ($string == 'true') {
return true;
}
if ($string == 'false') {
return false;
}
return (string)$string;
}
我在 Laravel 中间件中使用它来将由浏览器 JavaScript 的 FormData.append() 字符串化的表单值转换回正确的 PHP 类型:
public function handle($request, Closure $next)
{
$input = $request->all();
foreach($input as $key => $value) {
$input[$key] = $this->typeCorrected($value);
}
$request->replace($input);
return $next($request);
}
-
要创建它,请在 CLI 中输入 php artisan make:middleware TransformPayloadTypes。
-
然后粘贴上面的handle函数。
-
不要忘记粘贴typeCorrected 函数。我目前建议在您的中间件类中将其设为private function,但我并不声称自己是超级专家。
您可以想象$request->all() 是一个键/值对数组,它包含所有字符串化的值,因此目标是将它们转换回它们的真实类型。 typeCorrected 函数执行此操作。我已经在应用程序中运行了几个星期了,所以边缘情况可能仍然存在,但在实践中,它正在按预期工作。
如果你得到了上面的工作,你应该可以在 Axios 中做这样的事情:
// note: `route()` is from Tightenco Ziggy composer package
const post = await axios.post(route('admin.examples.create', {
...this.example,
category: undefined,
category_id: this.example.category.id,
}));
然后,在您的 Laravel 控制器中,您可以执行 \Log::debug($request->all()); 并看到如下内容:
[2020-10-12 17:52:43] local.DEBUG: array (
'status' => 1,
'slug' => 'asdf',
'name' => 'asdf',
'category_id' => 2,
)
关键事实是您看到的是'status' => 1, 而不是'status' => '1',
所有这些都将允许您通过 Axios 提交 JSON 负载,并在实际负载类型发生变化时在您的 FormRequest 类和控制器中接收非嵌套值。我发现其他解决方案太复杂了。上述解决方案允许您轻松地从纯 JavaScript 提交平面 JSON 有效负载(到目前为止,哈哈)。