strcmp equivelant for integers (intcmp) in PHP
Sort your data with:
function sortScripts($a, $b)
{
return $a['order'] - $b['order'];
}
Use $b-$a if you want the reversed order.
If the numbers in question exceed PHP's integer range, return ($a < $b) ? -1 : (($a > $b) ? 1 : 0)
is more robust.
PHP and proper way of using the strcmp function
The "===" and "!==" comparison operators assert two things:
- The values are equal, and
- The values are of the same type
The short answer to your question "what is the point of using !== with the strcmp function" is simply "it's good practice". That's really the only reason regarding strcmp specifically, and != would give you the exact same result when it comes to that function.
The long answer is as follows:
PHP is traditionally a loosely typed language. That is, datatypes were not all that important and PHP implicitly cast types for you automatically. It still does this by default (although lots of stuff has been added to improve the situation over recent years). For example, if you add the string "1" to the integer 1, PHP will cast the string to an integer automatically and return the integer value 2. Strongly typed languages would return an error if you tried to do that. Another example is that PHP will cast 0 to boolean false and any other non-zero value to boolean true.
It's that second example that causes problems with some of PHP's built-in functions. For example, the strpos() function. If you check the documentation page for strpos you'll see a big "Warning" in the "Return Values" section stating "This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE". For that reason it advises you to use the "===" operator to make sure you are getting the exact value and type that you expect. So "=== 0" means the string was found at the beginning of the input, and "=== false" means the string was not found. If you just used "== false" you won't be distinguishing between the string being found at the beginning of the input and the string not being found at all (because 0 will be implicitly cast to boolean false for the "if" statement).
So, developers got into the habit of testing for equality and type by using "===" and "!==". It's a good habit.
Since strcmp always return an integer, and you are always comparing it to an integer, there is no implicit casting and so comparing types as well as equality is not neccessary.
PHP: Strcmp returns value -58 even though the 2 strings seem identical?
Credits to @CBroe who introduced var_dump to me! :)
I added the following lines of code
var_dump($current_file_name, $scriptname);
var_dump(basename($_SERVER['SCRIPT_NAME'],".php"));
into my function echoActiveClassIfPageIsActive
.
function echoActiveClassIfPageIsActive($scriptname)
{
$current_file_name = $_SERVER['SCRIPT_NAME'];
var_dump($current_file_name, $scriptname);
var_dump(basename($_SERVER['SCRIPT_NAME'],".php"));
if (strcmp($current_file_name, $scriptname) == 0)
echo 'class="active"';
}
Turns out,
$current_file_name
wasstring(10)=" index.php"
$scriptname
wasstring(9)="index.php"
Hence, strcmp($current_file_name, $scriptname
) did not return a value of 0. The 2 strings were not identical, unlike what I thought. basename($current_file_name)
and $scriptname
are the identical strings.
This is how I realised my error. Just thought I might share this thought process.
PHP strcmp not giving correct output
1 is less than 2, strcmp is defined as returning:
Returns < 0 if str1 is less than str2; > 0 if str1 is greater than
str2, and 0 if they are equal.
Thus the behaviour is expected.
Note the following caveat:
If you rely on strcmp for safe string comparisons, both parameters
must be strings, the result is otherwise extremely unpredictable. For
instance you may get an unexpected 0, or return values of NULL, -2, 2,
3 and -3.
From a comment on the documentation page for strcmp
.
PHP is full of this sort of unexpected behaviour. In your situation, I would ensure both arguments were cast as strings to avoid any confusion:
$first = 1;
$second = 2;
echo strcmp((string)$first, (string)$second);
String comparison using '==' or '===' vs. 'strcmp()'
The reason to use it is because strcmp
returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.
===
only returns true
or false
, it doesn't tell you which is the "greater" string.
php usort() results in strange result
function sortScripts($a, $b)
{
return $a['order'] - $b['order'];
}
Use $b-$a
if you want the reversed order.
If the numbers in question exceed PHP's integer range, return ($a < $b) ? -1 : (($a > $b) ? 1 : 0)
is more robust.
You can check this link for more understanding strcmp equivelant for integers (intcmp) in PHP
Comparing strings, containing space with == in PHP
It all seems to go back to this is_numeric_string_ex
C function.
To start at the implementation of ==
:
ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2) {
...
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
...
case TYPE_PAIR(IS_STRING, IS_STRING):
...
ZVAL_LONG(result, zendi_smart_strcmp(op1, op2));
If both operands are a string, it ends up calling zendi_smart_strcmp
...
ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zval *s1, zval *s2) {
...
if ((ret1 = is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
(ret2 = is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) ...
Which calls is_numeric_string_ex
...
/* Skip any whitespace
* This is much faster than the isspace() function */
while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
str++;
length--;
}
ptr = str;
Which has explicit code to skip whitespace at the beginning, but not at the end.
Related Topics
Check Whether an Array Is Empty
Difference Between Var_Dump,Var_Export & Print_R
PHP - Extracting a Property from an Array of Objects
How to Convert Pascalcase to Snake_Case
Codeigniter Check for User Session in Every Controller
Get Div Content from External Website
Calculate Total Seconds in PHP Dateinterval
How to Remove the Leading Character from a String
Fastest Hash for Non-Cryptographic Uses
Check to See If a String Is Serialized
How to Run a Cronjob Every X Minutes
Composer Update Failed -- Out of Memory
Design Patterns: How to Create Database Object/Connection Only When Needed
Laravel Advanced Wheres How to Pass Variable into Function
Explode() into $Key=>$Value Pair
PHP Get Request, Sending Headers
Looping Through Query Results Multiple Times with MySQLi_Fetch_Array
How to Add Square Braces Around Subarray Data Inside of a JSON Encoded String