Search code examples
laravelphpstan

Issues with PHPStan Validation for Array Conversion to Integers


I'm new to using PHPStan/Larastan and configured it based on their documentation. When I run PHPStan at level 8, it passes without errors However, when I set PHPStan to the maximum level, it generates the following error:

I have an array of input data that I retrieve with the following code:

$num = $request->input('num', []);

I want to convert each element of $num from a string to an integer, so I use a foreach loop like this:

foreach ($num as $key => $value) { $num[$key] = (int) $value; }

When I run PHPStan, it fails with the following message:

Line Controllers\CalculationController.php
------ ---------------------------------------------------------------------------------------
:25    Argument of an invalid type mixed supplied for foreach, only iterables are supported.
:26    Cannot access offset mixed on mixed.
:26    Cannot cast mixed to int.
:29    Only iterables can be unpacked, mixed given in argument #1.

How can I resolve these issues and ensure PHPStan does not report these errors?

my goal is to convert array of string to int i try 3 possible way

  1. forloop
$num = $request->input('num', []);

foreach ($num as $key => $value) {
    $num[$key] = (int) $value;
}

error:

 ------ ---------------------------------------------------------------------------------------
  Line   Controllers\CalculationController.php
 ------ ---------------------------------------------------------------------------------------
  :25    Argument of an invalid type mixed supplied for foreach, only iterables are supported.
  :26    Cannot access offset mixed on mixed.
  :26    Cannot cast mixed to int.
  :29    Only iterables can be unpacked, mixed given in argument #1.
 ------ ---------------------------------------------------------------------------------------
  1. forloop with pointer
 $num = $request->input('num', []);

 foreach ($num as &$value) {
    $value = (int) $value;
 }

error:

 ------ ---------------------------------------------------------------------------------------
  Line   Controllers\CalculationController.php
 ------ ---------------------------------------------------------------------------------------
  :25    Argument of an invalid type mixed supplied for foreach, only iterables are supported.
  :26    Cannot cast mixed to int.
  :29    Only iterables can be unpacked, mixed given in argument #1.
 ------ ---------------------------------------------------------------------------------------
  1. array_map
 $num = array_map('intval', $request->input('num', []));

error:

 ------ ------------------------------------------------------------------------------------------------------    
  Line   Controllers\CalculationController.php
 ------ ------------------------------------------------------------------------------------------------------    
  :23    Parameter #1 $callback of function array_map expects (callable(mixed): mixed)|null, 'intval' given.      
         💡 Type array|bool|float|int|resource|string|null of parameter #1 $value of passed callable needs to     
            be same or wider than parameter type mixed of accepting callable.
  :23    Parameter #2 $array of function array_map expects array, mixed given.
 ------ ------------------------------------------------------------------------------------------------------    
  1. array_map with closer
$num = array_map(function (string $value): int {
            return intval($value);
        }, $request->input('num', []));

error:

 ------ ------------------------------------------------------------------------------------------------------    
  Line   Controllers\CalculationController.php
 ------ ------------------------------------------------------------------------------------------------------ 
  :23    Parameter #1 $callback of function array_map expects (callable(mixed): mixed)|null, Closure(string):  
         int given.
         💡 Type string of parameter #1 $value of passed callable needs to be same or wider than parameter     
            type mixed of accepting callable.
  :25    Parameter #2 $array of function array_map expects array, mixed given.
 ------ ------------------------------------------------------------------------------------------------------ 


Solution

  • Request::input returns mixed. It has no way of knowing whats inside your request body, you're going to have to define the type yourself.

    /**
     * @var array<string, string> $num
     */
    $num = $request->input('num', []);
    
    foreach ($num as $key => $value) {
        $num[$key] = (int) $value;
    }