Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision |
rfc:strict_operators:faq [2020/07/06 11:50] – jasny | rfc:strict_operators:faq [2020/07/06 14:58] – jasny |
---|
* Variable parsing in strings specified in double quotes and with heredoc, is also affected. | * Variable parsing in strings specified in double quotes and with heredoc, is also affected. |
* Concatenation operation (using ''%%.%%'') on ''%%null%%'' does not throw a ''%%TypeError%%'', but will cast ''%%null%%'' to an empty string. | * Concatenation operation (using ''%%.%%'') on ''%%null%%'' does not throw a ''%%TypeError%%'', but will cast ''%%null%%'' to an empty string. |
| * ''switch'' is not affected by this directive. |
| |
==== Why use a directive instead of applying this behavior as default? ==== | ==== Why use a directive instead of applying this behavior as default? ==== |
Both the concatenation operator and arithmetic operators throw a ''%%TypeError%%'' for arrays, resources, and objects. Casting these to a string or int/float doesn't give a proper representation of the value of the operand. | Both the concatenation operator and arithmetic operators throw a ''%%TypeError%%'' for arrays, resources, and objects. Casting these to a string or int/float doesn't give a proper representation of the value of the operand. |
| |
Using a boolean or null as operand for both concatenation and arithmetic operators also throws a ''%%TypeError%%''. In most cases, the use of a boolean or null indicates an error as many functions return ''%%false%%'' or ''%%null%%'' in case of an error or when no result can be returned. This is different from the function returning an empty string or ''%%0%%''. [[https://php.net/strpos|''%%strpos%%'']] is a well-known example. | Using a boolean or null as operand for both concatenation and arithmetic operators also throws a ''%%TypeError%%''. In most cases, the use of a boolean or null indicates an error as many functions return ''%%false%%'' or ''%%null%%'' in case of an error or when no result can be returned. This is different from the function returning an empty string or ''%%0%%''. [[https://php.net/strpos|strpos]] is a well-known example. |
| |
==== Will comparing a number to a numeric string work with strict_operators? ==== | ==== Will comparing a number to a numeric string work with strict_operators? ==== |
Strict comparison of arrays as unsorted hashmaps currently isn't possible and requires sorting the array, prior to comparison. | Strict comparison of arrays as unsorted hashmaps currently isn't possible and requires sorting the array, prior to comparison. |
| |
With ''%%==%%'' unavailable when using strict_operators, sorting the array would be the only option available. | With ''%%==%%'' unavailable when using strict_operators, sorting the array is the only option available. |
| |
| <code php> |
| ksort($array1); |
| ksort($array2); |
| |
| $array1 === $array2; |
| </code> |
| |
Array functions might be added to compare arrays in different ways. But that's outside the scope of this RFC. | Array functions might be added to compare arrays in different ways. But that's outside the scope of this RFC. |
| |
| ==== How can objects be compared by property? ==== |
| |
| With the ''=='' operator, two object instances are equal if they have the same attributes and values, and are instances of the same class. Values are compared with ''=='', applying type juggling. Using ''==='' will check if the objects are the same instance. |
| |
| When using strict_operators, ''=='' with objects will always throw a ''TypeError''. With ''%%==%%'' unavailable, ''get_object_vars'' needs to be used. |
| |
| |
| <code php> |
| get_class($object1) === get_class($object2) && get_object_vars($object1) === get_object_vars($object2); |
| </code> |
| |
| |
==== Why isn't is allowed to increment strings with strict_operators? ==== | ==== Why isn't is allowed to increment strings with strict_operators? ==== |
Throwing a ''%%TypeError%%'' only if the keys of the arrays don't match is not in line with this RFC. The behavior of an operator should not depend on the value of the operand, only on the type. Furthermore, a ''%%TypeError%%'' would be misplaced here, as some arrays would be accepted but others not, whereas a ''%%TypeError%%'' indicates no values of that type are accepted. | Throwing a ''%%TypeError%%'' only if the keys of the arrays don't match is not in line with this RFC. The behavior of an operator should not depend on the value of the operand, only on the type. Furthermore, a ''%%TypeError%%'' would be misplaced here, as some arrays would be accepted but others not, whereas a ''%%TypeError%%'' indicates no values of that type are accepted. |
| |
==== Why is switch affected? It's not an operator. ==== | ==== Why is switch not affected? ==== |
| |
Internally the ''%%case%%'' of a switch is handled as a comparison operator. The issues with ''%%case%%'' are therefore similar to those of comparison operators. The audience that strict_operators caters to, may want to get rid of this behavior completely. | Using strict_operators will apply only result in cases where a ''TypeError'' is thrown. It will not affect the behavior, giving a different result. |
| |
This is determined by a secondary vote. | Changing ''switch'' to compare using ''==='' would change the behavior based on the directive. |
| |
==== Are there cases where a statement doesn't throw a TypeError but yields a different result? ==== | To use strict comparison, most ''switch'' statements can be rewritten to [[https://wiki.php.net/rfc/match_expression_v2|''match'' statements]. |
| |
No, not for operators. | ==== Are there cases where a statement doesn't throw a TypeError but yields a different result? ==== |
| |
If the secondary vote for strict comparison with ''%%switch%%'' is accepted, ''%%switch%%'' can give a different result. | No. |
| |
==== Will this directive disable type juggling altogether? ==== | ==== Will this directive disable type juggling altogether? ==== |
No. Operators can still typecast under the given conditions. For instance, the concatenation (''%%.%%'') operator will cast an integer or float to a string, and boolean operators will cast any type of operand to a boolean. | No. Operators can still typecast under the given conditions. For instance, the concatenation (''%%.%%'') operator will cast an integer or float to a string, and boolean operators will cast any type of operand to a boolean. |
| |
Typecasting is also done in other places: ''%%if%%'' and ''%%while%%'' statements interpret expressions as boolean, and booleans and floats are cast to an integer when used as array keys. | Type juggling is also done in other places: ''%%if%%'' and ''%%while%%'' statements interpret expressions as boolean, and booleans and floats are cast to an integer when used as array keys. The ''switch'' statement will still use loose comparison (''==''). |
| |
This RFC is limited to the scope of operators. | This RFC is limited to the scope of operators. |
| |