1

With modern versions of PHP, we can declare many different types, union types or even mixed. However, I work with Magento 2, and its often impossible to know if you're going to get an ID of 7 or '7' passed to your method

My goal is to validate, using type declaration if possible, whether the input value can be successfully converted to or is already an integer. Because MySQL WHERE conditions treat integers and strings containing only numbers identically, many LAMP applications aren't strict about passing ints vs strings to methods that deal with IDs. However, if I simply declare a union type of int|string, then it would accept the value "example" which isn't numeric and would error once it got to MySQL. So, I can't find a way to validate the input in the declaration.

Is there a clean way to declare a numeric type if I can't control what's sent to my method?

Tyler V.
  • 2,471
  • 21
  • 44
  • 3
    There's float or int. It's a bit unclear what the problem is, exactly – ADyson Mar 30 '22 at 00:57
  • 1
    So validate your inputs. What is your specific issue? https://3v4l.org/bIF5F – Sammitch Mar 30 '22 at 01:03
  • 1
    Most likely you're going to have to create your own validation logic inside of your method/function that raises an error on invalid inputs. Edit: Or use PHP 8: https://stackoverflow.com/a/58826132/61795 or https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.composite.union – Scuzzy Mar 30 '22 at 01:10
  • I'm surprised at the attitude in the these responses. The entire point of declaring type requirements in the structure of the code is that the PHP engine itself, and even one's IDE, can validate method input/output as well as more nuanced things like the signature of child class methods. To "just validate your inputs yourself" misses the point entirely. – Tyler V. Mar 30 '22 at 16:58
  • Well what _is_ the point then, exactly? You asked "can I declare a numeric type", to which the direct answer is "yes, there's float or int". Is that not what you needed? You didn't really explain the precise context or give an example or show a specific issue in some code you were writing, so it's perhaps unsurprising that people are either vague with their responses and/or ask you questions in return. So yes, maybe we missed what exactly you're getting at. Someone's closed it as a duplicate but I'm not entirely sure whether they are relevant links or not, from your post. – ADyson Mar 30 '22 at 17:02
  • My goal is to validate, using type declaration if possible, whether the input value can be successfully converted to or is already an integer. Because MySQL WHERE conditions treat integers and strings containing only numbers identically, many LAMP applications aren't strict about passing ints vs strings to methods that deal with IDs. However, if I simply declare a union type of int|string, then it would accept the value "example" which isn't numeric and would error once it got to MySQL. So, I can't find a way to validate the input *in the declaration*. – Tyler V. Mar 30 '22 at 19:34
  • 1
    That's a much better explanation, thanks, but you need to [edit] that into your question for it to stand any chance of being re-opened for answers. – ADyson Mar 30 '22 at 21:25
  • Anyway you can just declare `int` and PHP will automatically accept a stringified number e.g. `'7'` and turn it into an int, but trying to pass in any other string will cause an exception - demo: https://3v4l.org/LnQvW . Does that help? – ADyson Mar 31 '22 at 14:32
  • @ADyson I had no idea it PHP would try type coercion before validating the input. That's great news. This is the answer I was looking for. – Tyler V. Apr 01 '22 at 19:28

1 Answers1

4

You can just declare int as the type of a function's input parameter and PHP will automatically accept a stringified integer (e.g. '7') and coerce it into an int, but trying to pass in any other string will cause an exception.

Example:

function foo(int $bar) { 
 var_dump($bar); 
}

echo "These ones are all ok:".PHP_EOL;
foo(7);
foo('7');
foo("7345");

echo PHP_EOL."And now for a bad one...".PHP_EOL;
foo("sgjhdfkg");

Outputs:

These ones are all ok:

int(7)

int(7)

int(7345)

And now for a bad one...

Fatal error: Uncaught TypeError: foo(): Argument #1 ($bar) must be of type int, string given

Live demo: https://3v4l.org/LnQvW

ADyson
  • 57,178
  • 14
  • 51
  • 63