Heya,
I remember that some people were complaining about the inconsistencies
between normal conversions and the one applied in Andrea's RFC about "Scalar
Type Hinting With Casts".
https://wiki.php.net/rfc/scalar_type_hinting_with_cast
As an example:
$i = (int) "a"; //fine without errors
function foo(int $i){}
foo("a"); //E_RECOVERABLE_ERROR
Personally, I do not like such inconsistencies either but I like that the
conversion rules in Andrea's RFC are more strict. And thus I was asking
myself if it would not make sense to change the current behaviour of
castings and make them more strict in PHP 7.
In the same time we could introduce a cast operator as the "as" operator in
C# which would have the current behaviour.
I believe that we would make PHP applications more robust in this way. At
least I doubt that the majority wants to convert "a" to 0. IMO most people
would prefer that PHP bails out an error in such a case. Sure one could also
write if's and check first if it is numeric etc. but that should be easier
IMO.
Just as an idea. What do you think?
Cheers,
Robert
Personally, I do not like such inconsistencies either but I like that the
conversion rules in Andrea's RFC are more strict. And thus I was asking
myself if it would not make sense to change the current behaviour of
castings and make them more strict in PHP 7.
No, no it would not. PHP’s explicit casts cannot fail, and there is absolutely no good reason to change this. If people want strict casting, we can add new functions or operators for that specifically. But to break explicit casts and make them sometimes fail would cause innumerable bugs and backwards-compatibility ideas.
--
Andrea Faulds
http://ajf.me/
Hi!
No, no it would not. PHP’s explicit casts cannot fail, and there is
absolutely no good reason to change this. If people want strict
casting, we can add new functions or operators for that specifically.
But to break explicit casts and make them sometimes fail would cause
innumerable bugs and backwards-compatibility ideas.
I agree. If the developer explicitly states they want conversion, it
should be conversion. For implicit casts, some tightening may be ok, but
for explicit ones I think it would bring much more headaches than it's
worth.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
Hi!
No, no it would not. PHP’s explicit casts cannot fail, and there is
absolutely no good reason to change this. If people want strict
casting, we can add new functions or operators for that specifically.
But to break explicit casts and make them sometimes fail would cause
innumerable bugs and backwards-compatibility ideas.I agree. If the developer explicitly states they want conversion, it
should be conversion. For implicit casts, some tightening may be ok, but
for explicit ones I think it would bring much more headaches than it's
worth.
Precisely, it would cause a vast amount of headaches for many projects.
Think of user input where you are expecting an integer and it must be a
positive integer (which would ultimately be a string); it is much faster to
do a quick check such as:
$foo = (int) $_GET['foo'];
if ($foo > 0) {
....
}
I'd personally not have to wrap more items around it due to a notice or
warning.
Andrea Faulds wrote (on 09/09/2014):
If people want strict casting, we can add new functions or operators for that specifically.
I think this came up during the previous discussion, and I actually
think it would be quite nice to have some functions both to perform a
"strict"/"safe" cast (and raise E_CATCHABLE_ERROR or perhaps throw
TypeCastException), and to check if a variable can be thus cast
(validating integers is unnecessarily complicated at the moment).
Either:
mixed safe_cast(mixed $var, string $type)
boolean can_safe_cast(mixed $var, string $type)
e.g.
if ( can_safe_cast($_GET['i'], 'int') )
$i = safe_cast($_GET['i'], 'int');
Or, to avoid representing the type with a string arg, a whole set of
functions:
int safe_cast_int(mixed $var)
boolean can_safe_cast_int(mixed $var)
float safe_cast_float(mixed $var)
boolean can_safe_cast_float(mixed $var)
etc
The first avoids creating so many new functions, but perhaps some
constants should be defined for the argument, based on the values
returned by gettype()
:
PHP_TYPE_INT = "integer"
PHP_TYPE_FLOAT = "double"
PHP_TYPE_STRING = "string"
PHP_TYPE_ARRAY = "array"
PHP_TYPE_OBJECT = "object"
PHP_TYPE_RESOURCE = "resource"
PHP_TYPE_NULL = "NULL"
Of course, we'd then need to agree exactly which casts are considered
"safe"...
--
Rowan Collins
[IMSoP]
Andrea Faulds wrote (on 09/09/2014):
If people want strict casting, we can add new functions or operators
for that specifically.I think this came up during the previous discussion, and I actually
think it would be quite nice to have some functions both to perform a
"strict"/"safe" cast (and raise E_CATCHABLE_ERROR or perhaps throw
TypeCastException), and to check if a variable can be thus cast
(validating integers is unnecessarily complicated at the moment).Either:
mixed safe_cast(mixed $var, string $type)
boolean can_safe_cast(mixed $var, string $type)
e.g.
if ( can_safe_cast($_GET['i'], 'int') )
$i = safe_cast($_GET['i'], 'int');Or, to avoid representing the type with a string arg, a whole set of
functions:
int safe_cast_int(mixed $var)
boolean can_safe_cast_int(mixed $var)
float safe_cast_float(mixed $var)
boolean can_safe_cast_float(mixed $var)
etcThe first avoids creating so many new functions, but perhaps some
constants should be defined for the argument, based on the values
returned bygettype()
:PHP_TYPE_INT = "integer"
PHP_TYPE_FLOAT = "double"
PHP_TYPE_STRING = "string"
PHP_TYPE_ARRAY = "array"
PHP_TYPE_OBJECT = "object"
PHP_TYPE_RESOURCE = "resource"
PHP_TYPE_NULL = "NULL"Of course, we'd then need to agree exactly which casts are considered
"safe"...
.oO(ext/filter) ?
--
Regards,
Mike
Michael Wallner wrote (on 10/09/2014):
.oO(ext/filter) ?
Maybe I'm just missing some better documentation, but my main problems
with ext/filter are:
- Many users don't know it exists, or how to use it.
- It's pretty verbose and complex for such a simple task as "is this
thing a valid integer?"
Basically, it's a swiss army knife, but people are looking for a pair of
scissors.
There's a lot of code out there doing things like this:
if ( is_numeric($_GET['user_id']) ) {
display_user($_GET['user_id']);
}
This is definitely the wrong function to use (what kind of a user ID is
'-1.5e-50'?) but it looks like the right function, and it has a really
simple name, so people don't bother looking for anything more complicated...
--
Rowan Collins
[IMSoP]
I think this came up during the previous discussion, and I actually think it would be quite nice to have some functions both to perform a "strict"/"safe" cast (and raise E_CATCHABLE_ERROR or perhaps throw TypeCastException), and to check if a variable can be thus cast (validating integers is unnecessarily complicated at the moment).
Either:
mixed safe_cast(mixed $var, string $type)
boolean can_safe_cast(mixed $var, string $type)
e.g.
if ( can_safe_cast($_GET['i'], 'int') )
$i = safe_cast($_GET['i'], 'int');Or, to avoid representing the type with a string arg, a whole set of functions:
int safe_cast_int(mixed $var)
boolean can_safe_cast_int(mixed $var)
float safe_cast_float(mixed $var)
boolean can_safe_cast_float(mixed $var)
etcThe first avoids creating so many new functions, but perhaps some constants should be defined for the argument, based on the values returned by
gettype()
:PHP_TYPE_INT = "integer"
PHP_TYPE_FLOAT = "double"
PHP_TYPE_STRING = "string"
PHP_TYPE_ARRAY = "array"
PHP_TYPE_OBJECT = "object"
PHP_TYPE_RESOURCE = "resource"
PHP_TYPE_NULL = "NULL"Of course, we'd then need to agree exactly which casts are considered "safe"…
You know, “int”, “float”, “string” etc. aren’t currently reserved words. We could add functions, or even make them reserved words and add internal functions (à la isset), so int(‘2’), float(‘2.0’), string(‘test’) etc.
Or perhaps class-like constructors? $a = new int('2'); ? Would kinda make sense given some people want to add methods to primitive types.
--
Andrea Faulds
http://ajf.me/
You know, “int”, “float”, “string” etc. aren’t currently reserved words. We could add functions, or even make them reserved words and add internal functions (à la isset), so int(‘2’), float(‘2.0’), string(‘test’) etc.
Or perhaps class-like constructors? $a = new int('2'); ? Would kinda make sense given some people want to add methods to primitive types.
+1
$int instanceof Int
$float instanceof Float
$num instanceof Numeric
$bool instanceof Boolean
$str instanceof String
$array instanceof Array
This makes it possible not to use the is_*() functions.
It is desirable to conduct instanceof fully consistent with behavior
hinting casts, it would be logical and correct.
Just wanted to be able to use these classes (or interfaces) to create
their objects, these objects would pass inspection in hinting casts.
You know, “int”, “float”, “string” etc. aren’t currently reserved
words.
Well, they are in the context of casts:
$a = (int)'42';
$a = (string)42;
etc
We could add functions, or even make them reserved words and add
internal functions (à la isset), so int(‘2’), float(‘2.0’),
string(‘test’) etc.
How would this be different from what we already have? For the function version (useful as a callback), we have intval()
, strval()
, etc
Or perhaps class-like constructors? $a = new int('2'); ? Would kinda
make sense given some people want to add methods to primitive types.+1
$int instanceof Int
$float instanceof Float
$num instanceof Numeric
$bool instanceof Boolean
$str instanceof String
$array instanceof ArrayThis makes it possible not to use the is_*() functions.
It is desirable to conduct instanceof fully consistent with behavior
hinting casts, it would be logical and correct.
Just wanted to be able to use these classes (or interfaces) to create
their objects, these objects would pass inspection in hinting casts.
This could cause a lot of confusion. If these "constructors" are just a new syntax for type casting, there's no obvious reason to behave differently in terms of strictness, which is what we were discussing previously. Worse, they would look like objects, but behave as plain variables (no reference-like ability to modify the value in place).
Alternatively, these could be special "boxed types", which were real objects acting almost but not quite the same way as the equivalent basic type. Some languages (e.g. Java) have those, but they're frankly rather confusing, and I'm not sure what the benefit would be.
Regards,
Rowan Collins
[IMSoP]