PHP converts the string to the integer of int intval of printf of performance test
- 2020-05-16 06:30:46
- OfStack
Background and overview
In the years before Sql injection ramps, converting strings to integers was a required operation for every web program. The web program enforces the id and integer equivalents from get or post to be converted to integers through the conversion function, filtering out dangerous characters, and minimizing the possibility that the system itself will be injected by Sql.
Nowadays, although the injection of Sql has gradually faded from the stage of history, in order to ensure the normal operation of web program, reduce the probability of error, and better guarantee the satisfaction of use, we also need to convert users' incorrect input into what we need.
Transformation way
In PHP, we can convert a string to an integer in three ways.
1. Cast type conversion mode
Casting is the way you put the target type in parentheses before the variable you want to convert (from the "type tricks" section of the PHP manual).
<?php
$foo = "1"; // $foo It's a string
$bar = (int)$foo; // $bar Is the integer
?>
For integers, cast the type name int or integer.
2. Built-in function mode
The built-in function mode is to use PHP's built-in function intval for variable conversion.
<?php
$foo = "1"; // $foo It's a string
$bar = intval($foo); // $bar Is the integer
?>
The format of intval function is:
int intval(mixed $var [, int $base]); (from PHP manual)
Although the PHP manual makes it clear that intval() cannot be used for conversion between array and object. However, in my tests, there is no problem when converting array, and the conversion value is 1 instead of the imaginary 0. I'm afraid it's worth noting that within PHP, variables of type array are also considered non-zero. When converting object, PHP gives notice as follows:
[Object of class could not be converted int int xxxxx php on line xx
]The conversion value is also 1.
3. Format the string
Format string method, which USES %d of sprintf to format specified variables for type conversion purposes.
<?php
$foo = "1"; // $foo It's a string
$bar = sprintf("%d", $foo); // $bar It's a string
?>
Strictly speaking, sprintf's conversion results in string, so it should not be considered a way to convert a string to an integer. However, the string value after his processing does become "forced to be converted to an integer of string type".
The actual test
The three ways to convert a string to an integer in PHP are described above. For 1-like programmers, this is the end of the story. The following section is for creepy programmers.
1. Basic functional test
Set the following array:
<?php
$a[] = "1";
$a[] = "a1";
$a[] = "1a";
$a[] = "1a2";
$a[] = "0";
$a[] = array('4',2);
$a[] = "2.3";
$a[] = "-1";
$a[] = new Directory();
?>
To see the conversion, convert the elements of the array given above one by one in three ways. Program source code is as follows:
<?php
$a[] = "1";
$a[] = "a1";
$a[] = "1a";
$a[] = "1a2";
$a[] = "0";
$a[] = array('4',2);
$a[] = "2.3";
$a[] = "-1";
$a[] = new Directory();
// int
print "(int)<br />";
foreach($a as $v)
{
var_dump((int)$v);
print "<br />";
}
// intval
print "intval();<br />";
foreach($a as $v)
{
var_dump(intval($v));
print "<br />";
}
// sprintf
print "sprintf();<br />";
foreach($a as $v)
{
var_dump(sprintf("%d", $v));
print "<br />";
}
?>
The final running result of the program is as follows (notice appeared when object was removed) :
[
(int)
int(1)
int(0)
int(1)
int(1)
int(0)
int(1)
int(2)
int(-1)
int(1)
intval();
int(1)
int(0)
int(1)
int(1)
int(0)
int(1)
int(2)
int(-1)
int(1)
sprintf();
string(1) "1"
string(1) "0"
string(1) "1"
string(1) "1"
string(1) "0"
string(1) "1"
string(1) "2"
string(2) "-1"
string(1) "1"
It can be seen that the results of the three transformations are exactly the same. So functionally speaking, all three methods can be competent for the transformation work, so the next task is to see which one is more efficient.
2. Performance testing
The string under test is one of the types we might use in our injection work:
<?php
$foo = "1';Select * ...";
?>
The function to get the time point is as follows (used to get the test start point and end point to calculate the elapsed time) :
<?php
**
* Simple function to replicate PHP 5 behaviour
*/
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
?>
(from PHP manual microtime() function section)
The test process USES each method to convert the variable $foo 1,000,000 times (1,000,000 times), and outputs the respective elapsed time. Three tests are conducted in total to minimize errors. The test procedure is as follows:
<?php
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$foo = "1';Select * ...";
// (int)
$fStart = microtime_float();
for($i=0;$i<1000000;$i++)
{
$bar = (int)$foo;
}
$fEnd = microtime_float();
print "(int):" . ($fEnd - $fStart) . "s<br />";
// intval()
$fStart = microtime_float();
for($i=0;$i<1000000;$i++)
{
$bar = intval($foo);
}
$fEnd = microtime_float();
print "intval():" . ($fEnd - $fStart) . "s<br />";
// sprintf()
$fStart = microtime_float();
for($i=0;$i<1000000;$i++)
{
$bar = sprintf("%d", $foo);
}
$fEnd = microtime_float();
print "sprintf():" . ($fEnd - $fStart) . "s<br />";
?>
Final test results:
[
(int):0.67205619812012s
intval():1.1603000164032s
sprintf():2.1068270206451s
(int):0.66051411628723s
intval():1.1493890285492s
sprintf():2.1008238792419s
(int):0.66878795623779s
intval():1.1613430976868s
sprintf():2.0976209640503s
Although this test is a bit perverted (who would convert the integer of 100w consecutive times?) , but as you can see, converting a string to an integer using casts is the fastest.
PHP is the fastest way to convert a string to an integer
start
This is a JiuTie, came across on SO: https: / / stackoverflow com/questions / 239136 / fastest - way - to - convert - string - to - integer - in - php
For "123" = > What is the fastest way for 123, if "hello" = > The & # 63; What's wrong with going to integer.
intval vs int
I used to mix them up, sometimes
intval($var)
Sometimes used
(int) $var
, which is more convenient. Looking at SO, the performance of an explicit type conversion is approximately
intval
4 times. This can be a performance-tuned small Tip.
I tested different values of $val, and found that they gave exactly the same results and the same warnings.
So don't think about it
intval
If the second parameter is needed, it can be safely used
int
Let's do the transformation.
The deep reason
Joseph Scott analyzes OPCODE and explains its underlying causes
intval()
0 ASSIGN
1 SEND_VAR
2 DO_FCALL
3 ASSIGN
4 RETURN
5* ZEND_HANDLE_EXCEPTION
int
0 ASSIGN
1 CAST
2 ASSIGN
3 RETURN
4* ZEND_HANDLE_EXCEPTION
SEND_VAR
and
DO_FCALL
The action is to cause
int
than
intval()
A lot faster.
ps: there is another type conversion
settype
You don't have to try it, the performance ratio
(int) $var
0
and
int
Are poor.
conclusion
Converting a string to an integer using casts is the most direct way to convert 1 (you can get the value of an integer directly). From the point of view of code readability, sprintf code is relatively long, and the result may need to be cast again, while intval function is a typical process-oriented cast, and casts directly convey the idea of "I want to transform" to the reader. In terms of efficiency, casting is also the fastest way to convert. Therefore, I recommend this approach for programmers who do a lot of transformation work.