5 ms·
>there's still no reasonable int parsing function What's wrong with (int)$val ?
by baisq 4y ago
>there's still no reasonable int parsing function
What's wrong with (int)$val ?
- dvdkon 4y agoThere's no error handling, (int)"x" === 0.
- RedShift1 4y agoYou should use the filter functions for that
- Y-bar 4y agoWhy should that be an error? First we are explicitly forcing a string to an integer and then comparing it with type sensitivity to another integer.
- dvdkon 4y agoWe could debate that for a long time, but my point was different: There's no sane function in today's PHP that parses ints and handles errors (defaulting to 0 doesn't count).
- Y-bar 4y ago> defaulting to 0 doesn't count Why this arbitrary restriction? A forced cast of a string to integer is always guaranteed to produce an integer.
- dvdkon 4y agoAnd a forced cast is therefore a bad way to generally parse a user-provided string to int.
- samus 4y agoAnd how are we supposed to distinguish that from a legit 0?
- Y-bar 4y agois_numeric() has been available since forever, and is intended for exactly the thing you appear to want to do. https://www.php.net/manual/en/function.is-numeric.php https://www.php.net/manual/en/function.is-numeric.php
- deathanatos 4y agoAt this point you're writing the parser that ships in most language's standard libraries. And, if you naïvely use the suggested function for the purpose you've suggested it for, e.g., like, if(!is_numeric($input)) { error(); } else { return (int)$input; } …you'll parse a lot of strings that still aren't valid integers. (E.g., "2e-2" is "numeric" and would thus parse.)
- nucleardog 4y ago/** * Cast to int, fail if not a valid integer * @throws \UnexpectedValueException * @param mixed $thing * @return int */ function as_int($thing): int { if (!filter_var($thing, \FILTER_VALIDATE_INT)) throw new \UnexpectedValueException("Value is not an integer."); return (int)$thing; } While, yeah, it'd be nice if there were something like this built in... it's a couple lines of code. If that's your major complaint, I'd be happy to whip up a whole suite of proper functions to cast to primitives while throwing errors on invalid values since it's just swapping FILTER_VALIDATE_INT for the various types.
- dvdkon 4y agoI think this illustrates my problem with PHP well: There are ways to do common tasks properly, but they're often hidden, obscure or basically require creating your own "stdlib extension", as seen here (I only heard about filter_var from this discussion, and I specifically searched for string conversion functions). Your function proves my point: It looks correct, but actually breaks for as_int("0"), since filter_var with FILTER_VALIDATE_INT doesn't acutally validate the int, but parse it, and zero is falsy.
- tored 4y agoAbove usage of filter_var is wrong, there is no need to cast $thing to int, filter_var already returns the filtered int or false on failure. The correct usage is therefore /** * Cast to int, fail if not a valid integer * @throws \UnexpectedValueException * @param mixed $thing * @return int */ function as_int($thing): int { $int = filter_var($thing, \FILTER_VALIDATE_INT); if ($int === false) { throw new \UnexpectedValueException("Value is not an integer."); } return $int; } Thus the critique against PHP that is lacks a proper integer parsing function is simply not true, filter_var has been part of PHP since 5.2 released in 2006, over 16 years ago. filter_var works as advertised, because I use it almost every time i write PHP and that is to mostly to parse integers but sometimes also for other types. And I don't even wrap it with my own as_int function, using it inline with an simple if-check afterwards is actually cleaner. And if you prefer that filter_var returns null on failure instead of false you can simply add FILTER_NULL_ON_FAILURE as the third argument to filter_var. And this is the recurring thing with PHP critique, vast majority of the time it just in imagination because nobody bothers to look it up. https://www.php.net/manual/en/function.filter-var.php https://www.php.net/manual/en/function.filter-var.php
- baisq 4y agoI think that in that case it should return false instead of 0 so (int)$val === false means that the variable is not a number. Right now I guess that the alternative is using is_numeric and then casting to int if possible.
- Y-bar 4y agoBut the forced cast to integer is always guaranteed to result in an integer. So why would it make more sense to explicitly force cast a variable's type to an integer and get a boolean as the functions return value? Edit: > (int)$val === false Would always be false because comparing two types, an integer and boolean would always be false.
- zerocrates 4y agoYou can kind of get this to happen in 8 and up: Doing math on a non numeric string is then a catchable TypeError so you can do 'x' + 0 in a try. Doesn't avoid other PHP numeric-string stuff like scientific notation and floats being accepted, though. Passing to a int-typehinted function param in 8.1 gets you closer (will complain about float strings) but is currently just a annoying-to-work-with deprecation notice. Presumably it will eventually also be a TypeError.
- deleted 4y ago[deleted]