- 相關(guān)推薦
PHP中將字符串轉(zhuǎn)化為整數(shù)
早在Sql注入橫行的前幾年,字符串轉(zhuǎn)化為整數(shù)就已經(jīng)被列為每個(gè)web程序必備的操作了。web程序?qū)et或post來的id、整數(shù)等值強(qiáng)制經(jīng)過轉(zhuǎn)化函數(shù)轉(zhuǎn)化為整數(shù),過濾掉危險(xiǎn)字符,盡可能降低系統(tǒng)本身被Sql注入的可能性。
背景、概述
早在Sql注入橫行的前幾年,字符串轉(zhuǎn)化為整數(shù)就已經(jīng)被列為每個(gè)web程序必備的操作了。web程序?qū)et或post來的id、整數(shù)等值強(qiáng)制經(jīng)過轉(zhuǎn)化函數(shù)轉(zhuǎn)化為整數(shù),過濾掉危險(xiǎn)字符,盡可能降低系統(tǒng)本身被Sql注入的可能性。
現(xiàn)如今,雖然Sql注入已經(jīng)逐漸淡出歷史舞臺(tái),但是,為了保證web程序的正常運(yùn)行,減少出錯(cuò)概率,更好的保證用的滿意度,我們同樣需要將用戶的不正確輸入轉(zhuǎn)化為我們所需要的。
轉(zhuǎn)化方式
在PHP中,我們可以使用3種方式將字符串轉(zhuǎn)化為整數(shù)。
1.強(qiáng)制類型轉(zhuǎn)換方式
強(qiáng)制類型轉(zhuǎn)換方式,就是“在要轉(zhuǎn)換的變量之前加上用括號(hào)括起來的目標(biāo)類型”(摘自PHP手冊(cè)“類型戲法”節(jié))的方式。
復(fù)制代碼 代碼如下:
<?php
$foo = "1"; // $foo 是字符串類型
$bar = (int)$foo; // $bar 是整型
?>
對(duì)于整型來說,強(qiáng)制轉(zhuǎn)換類型名稱為int或者integer。
2.內(nèi)置函數(shù)方式
內(nèi)置函數(shù)方式,就是使用PHP的內(nèi)置函數(shù)intval進(jìn)行變量的轉(zhuǎn)換操作。
復(fù)制代碼 代碼如下:
<?php
$foo = "1"; // $foo 是字符串類型
$bar = intval($foo); // $bar 是整型
?>
intval函數(shù)的格式為:
int intval(mixed $var [, int $base]); (摘自PHP手冊(cè))
雖然PHP手冊(cè)中明確指出,intval()不能用于array和object的轉(zhuǎn)換。但是經(jīng)過我測(cè)試,轉(zhuǎn)換array的時(shí)候不會(huì)出任何問題,轉(zhuǎn)換值為1,而不是想象中的0?峙率且?yàn)樵赑HP內(nèi)部,array類型的變量也被認(rèn)為是非零值得緣故吧。轉(zhuǎn)換object的時(shí)候,PHP會(huì)給出如下的 notice:
Object of class xxxx could not be converted to int in xxxxx.php on line xx
轉(zhuǎn)換值同樣為1。
3.格式化字符串方式
格式化字符串方式,是利用sprintf的%d格式化指定的變量,以達(dá)到類型轉(zhuǎn)換的目的。
復(fù)制代碼 代碼如下:
<?php
$foo = "1"; // $foo 是字符串類型
$bar = sprintf("%d", $foo); // $bar 是字符串類型
?>
嚴(yán)格意義上講sprintf的轉(zhuǎn)換結(jié)果還是string型,因此它不應(yīng)該算是字符串轉(zhuǎn)化為整數(shù)的方式。但是經(jīng)過他處理之后的字符串值確實(shí)已經(jīng)成為了“被強(qiáng)制轉(zhuǎn)化為字符串類型的整數(shù)”。
實(shí)際測(cè)試
上面介紹了PHP中,將字符串轉(zhuǎn)化為整數(shù)的3種方式。對(duì)于一般的程序員來說,看到這里就算結(jié)束了,下面的部分是針對(duì)變態(tài)程序員的。
1.基本功能測(cè)試
設(shè)定以下數(shù)組:
復(fù)制代碼 代碼如下:
<?php
$a[] = "1";
$a[] = "a1";
$a[] = "1a";
$a[] = "1a2";
$a[] = "0";
$a[] = array('4',2);
$a[] = "2.3";
$a[] = "-1";
$a[] = new Directory();
?>
使用三種方式依次轉(zhuǎn)化上面給出的數(shù)組中的元素,查看轉(zhuǎn)換情況。程序源代碼如下:
復(fù)制代碼 代碼如下:
<?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 />";
}
?>
程序的最終運(yùn)行結(jié)果如下(已經(jīng)去掉轉(zhuǎn)換object時(shí)出現(xiàn)的notice):
(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"
由此可以看出,三種轉(zhuǎn)換的結(jié)果是完全一樣的。那么從功能上講,3種方式都可以勝任轉(zhuǎn)換工作,那么接下來的工作就是看哪一種效率更高了。
2.性能測(cè)試
被測(cè)試字符串是我們?cè)谧⑷牍ぷ髦锌赡軙?huì)使用到的一種:
復(fù)制代碼 代碼如下:
<?php
$foo = "1';Select * ...";
?>
獲取時(shí)間點(diǎn)的函數(shù)如下(用于獲取測(cè)試起始點(diǎn)和結(jié)束點(diǎn),以計(jì)算消耗時(shí)間):
<?php
**
* Simple function to replicate PHP 5 behaviour
*/
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
?>
。ㄕ訮HP手冊(cè)microtime()函數(shù)節(jié))
測(cè)試過程是使用每種方式轉(zhuǎn)換變量$foo 1000000次(100萬次),并將各自的消耗時(shí)間輸出,總共進(jìn)行三組測(cè)試,盡可能降低誤差。測(cè)試程序如下:
復(fù)制代碼 代碼如下:
<?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 />";
?>
最終的測(cè)試結(jié)果:
(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
雖然這個(gè)測(cè)試有點(diǎn)變態(tài)(誰會(huì)連續(xù)轉(zhuǎn)換100w次的整數(shù)?),但是由此可以看出,使用強(qiáng)制類型轉(zhuǎn)換將字符串轉(zhuǎn)化為整數(shù)速度是最快的。
總結(jié)
使用強(qiáng)制類型轉(zhuǎn)換方式將字符串轉(zhuǎn)化為整數(shù)是最直接的轉(zhuǎn)化方式之一(可以直接獲得整型的變量值)。從代碼可讀性角度上講,sprintf方式代碼比較長(zhǎng),而且其結(jié)果有可能還需要再次進(jìn)行強(qiáng)制類型轉(zhuǎn)換,而intval函數(shù)是典型的面向過程式轉(zhuǎn)換,強(qiáng)制類型轉(zhuǎn)換則比較直接的將“我要轉(zhuǎn)化”這個(gè)思想傳遞給閱讀者。從效率上講,強(qiáng)制類型轉(zhuǎn)換方式也是最快速的轉(zhuǎn)化方式。因此,對(duì)于經(jīng)常進(jìn)行轉(zhuǎn)化工作的程序員,我推薦使用這種方式。
【PHP中將字符串轉(zhuǎn)化為整數(shù)】相關(guān)文章:
PHP的字符串函數(shù)10-06
PHP字符串操作09-29
PHP 中的字符串變量10-05
php字符串截取問題05-02
php的字符串常用函數(shù)06-15
php字符串截取函數(shù)06-10
php字符串與數(shù)組怎么轉(zhuǎn)換10-04
PHP字符串函數(shù)大匯總05-25
PHP字符串常用面試題總結(jié)10-04