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) $var0 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.


Related articles: