最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PHP中將字符串轉(zhuǎn)化為整數(shù)(int) intval() printf() 性能測(cè)試

 更新時(shí)間:2020年03月20日 21:27:33   投稿:mdxy-dxy  
早在Sql注入橫行的前幾年,字符串轉(zhuǎn)化為整數(shù)就已經(jīng)被列為每個(gè)web程序必備的操作了。web程序?qū)et或post來(lái)的id、整數(shù)等值強(qiáng)制經(jīng)過(guò)轉(zhuǎn)化函數(shù)轉(zhuǎn)化為整數(shù),過(guò)濾掉危險(xiǎn)字符,盡可能降低系統(tǒng)本身被Sql注入的可能性

背景、概述

  早在Sql注入橫行的前幾年,字符串轉(zhuǎn)化為整數(shù)就已經(jīng)被列為每個(gè)web程序必備的操作了。web程序?qū)et或post來(lái)的id、整數(shù)等值強(qiáng)制經(jīng)過(guò)轉(zhuǎn)化函數(shù)轉(zhuǎn)化為整數(shù),過(guò)濾掉危險(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)括起來(lái)的目標(biāo)類型”(摘自PHP手冊(cè)“類型戲法”節(jié))的方式。

<?php 
$foo = "1"; // $foo 是字符串類型 
$bar = (int)$foo; // $bar 是整型 
?>

  對(duì)于整型來(lái)說(shuō),強(qiáng)制轉(zhuǎn)換類型名稱為int或者integer。

2.內(nèi)置函數(shù)方式

  內(nèi)置函數(shù)方式,就是使用PHP的內(nèi)置函數(shù)intval進(jìn)行變量的轉(zhuǎn)換操作。

<?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)過(guò)我測(cè)試,轉(zhuǎn)換array的時(shí)候不會(huì)出任何問(wèn)題,轉(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)換的目的。

<?php 
$foo = "1"; // $foo 是字符串類型 
$bar = sprintf("%d", $foo); // $bar 是字符串類型 
?> 

  嚴(yán)格意義上講sprintf的轉(zhuǎn)換結(jié)果還是string型,因此它不應(yīng)該算是字符串轉(zhuǎn)化為整數(shù)的方式。但是經(jīng)過(guò)他處理之后的字符串值確實(shí)已經(jīng)成為了“被強(qiáng)制轉(zhuǎn)化為字符串類型的整數(shù)”。

實(shí)際測(cè)試

  上面介紹了PHP中,將字符串轉(zhuǎn)化為整數(shù)的3種方式。對(duì)于一般的程序員來(lái)說(shuō),看到這里就算結(jié)束了,下面的部分是針對(duì)變態(tài)程序員的。

1.基本功能測(cè)試

  設(shè)定以下數(shù)組:

<?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)換情況。程序源代碼如下:

<?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)換工作,那么接下來(lái)的工作就是看哪一種效率更高了。

2.性能測(cè)試

  被測(cè)試字符串是我們?cè)谧⑷牍ぷ髦锌赡軙?huì)使用到的一種:

<?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); 
} 
?> 

  (摘自PHP手冊(cè)microtime()函數(shù)節(jié))
  測(cè)試過(guò)程是使用每種方式轉(zhuǎn)換變量$foo 1000000次(100萬(wàn)次),并將各自的消耗時(shí)間輸出,總共進(jìn)行三組測(cè)試,盡可能降低誤差。測(cè)試程序如下:

<?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)(誰(shuí)會(huì)連續(xù)轉(zhuǎn)換100w次的整數(shù)?),但是由此可以看出,使用強(qiáng)制類型轉(zhuǎn)換將字符串轉(zhuǎn)化為整數(shù)速度是最快的。

PHP中將字符串轉(zhuǎn)換為整數(shù)的最快方法

起步

這是個(gè)舊貼,在 SO 上偶然看到的:https://stackoverflow.com/questions/239136/fastest-way-to-convert-string-to-integer-in-php

對(duì)于 "123" => 123 最快的方法是什么,如果是 "hello" => ? 轉(zhuǎn)為整型又會(huì)有什么問(wèn)題。

intval vs int

我以前是混著用的,有時(shí)用 intval($var) 有時(shí)用 (int) $var ,純看哪個(gè)順手??戳?SO 上才知道,顯式的類型轉(zhuǎn)換的性能大約是 intval 4 倍。這就可以是性能調(diào)優(yōu)的小 Tip 了。

我測(cè)了不同的 $val 值,發(fā)現(xiàn)兩者得到的結(jié)果完全一樣,發(fā)出的警告也是相同的。

因此在不考慮 intval 需要第二個(gè)參數(shù)的情況下,就可以放心的使用 int 來(lái)做轉(zhuǎn)換了。

深層原因

網(wǎng)友 Joseph Scott 對(duì) OPCODE 進(jìn)行了分析,解釋了其深層原因

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_VARDO_FCALL 操作,是導(dǎo)致 int intval() 快很多的原因。

ps: 還有另一個(gè)類型轉(zhuǎn)換的 settype 就不用試了,它的性能比 intval int 都差。

總結(jié)

使用強(qiáng)制類型轉(zhuǎn)換方式將字符串轉(zhuǎn)化為整數(shù)是最直接的轉(zhuǎn)化方式之一(可以直接獲得整型的變量值)。從代碼可讀性角度上講,sprintf方式代碼比較長(zhǎng),而且其結(jié)果有可能還需要再次進(jìn)行強(qiáng)制類型轉(zhuǎn)換,而intval函數(shù)是典型的面向過(guò)程式轉(zhuǎn)換,強(qiáng)制類型轉(zhuǎn)換則比較直接的將“我要轉(zhuǎn)化”這個(gè)思想傳遞給閱讀者。從效率上講,強(qiáng)制類型轉(zhuǎn)換方式也是最快速的轉(zhuǎn)化方式。因此,對(duì)于經(jīng)常進(jìn)行轉(zhuǎn)化工作的程序員,我推薦使用這種方式。

相關(guān)文章

  • PHP采集相關(guān)教程之一 CURL函數(shù)庫(kù)

    PHP采集相關(guān)教程之一 CURL函數(shù)庫(kù)

    目前為目最全的CURL中文說(shuō)明了,學(xué)PHP的要好好掌握。有很多的參數(shù)。大部份都很有用。真正掌握了它和正則,一定就是個(gè)采集高手了。
    2010-02-02
  • php中intval()的實(shí)例用法

    php中intval()的實(shí)例用法

    在本篇文章里小編給大家整理了一篇關(guān)于php中intval()的實(shí)例用法及相關(guān)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-09-09
  • PHP的命令行擴(kuò)展Readline相關(guān)函數(shù)的使用

    PHP的命令行擴(kuò)展Readline相關(guān)函數(shù)的使用

    PHP 作為一個(gè) Web 開(kāi)發(fā)語(yǔ)言,相對(duì)來(lái)說(shuō),命令行程序并不是它的主戰(zhàn)場(chǎng)。所以很多年輕的 PHP 開(kāi)發(fā)者可能連命令行腳本都沒(méi)有寫過(guò),更別提交互式的命令操作了。而今天,我們帶來(lái)的這個(gè)擴(kuò)展就是針對(duì) PHP 的交互式命令行操作的
    2021-05-05
  • PHP實(shí)現(xiàn)基于回溯法求解迷宮問(wèn)題的方法詳解

    PHP實(shí)現(xiàn)基于回溯法求解迷宮問(wèn)題的方法詳解

    這篇文章主要介紹了PHP實(shí)現(xiàn)基于回溯法求解迷宮問(wèn)題的方法,結(jié)合實(shí)例形式詳細(xì)分析了回溯法的原理、實(shí)現(xiàn)步驟與解決迷宮問(wèn)題的相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • ecshop 訂單確認(rèn)中顯示省市地址信息的方法

    ecshop 訂單確認(rèn)中顯示省市地址信息的方法

    ecshop的購(gòu)物流程中最后的訂單確認(rèn)信息,其中關(guān)于用戶訂單配送地址信息,沒(méi)有包含用戶選擇的省市縣區(qū)信息。
    2010-03-03
  • 詳解PHP實(shí)現(xiàn)異步調(diào)用的4種方法

    詳解PHP實(shí)現(xiàn)異步調(diào)用的4種方法

    這篇文章主要為大家詳細(xì)介紹PHP實(shí)現(xiàn)異步調(diào)用的4種方法,感興趣的小伙伴們可以參考一下
    2016-03-03
  • PHP獲取用戶的瀏覽器與操作系統(tǒng)信息的代碼

    PHP獲取用戶的瀏覽器與操作系統(tǒng)信息的代碼

    PHP為了準(zhǔn)確獲得訪問(wèn)用戶的瀏覽器 操作系統(tǒng)信息,以便返回給不同的用戶不同的需求,比如不同的IE用戶,分別加載不同的CSS文件
    2012-09-09
  • PHP獲取中英混合字符串長(zhǎng)度的方法

    PHP獲取中英混合字符串長(zhǎng)度的方法

    這篇文章主要介紹了PHP獲取中英混合字符串長(zhǎng)度的方法,需要的朋友可以參考下
    2014-06-06
  • Apache中php.ini的設(shè)置方法

    Apache中php.ini的設(shè)置方法

    無(wú)論是IIS 還是 Apache, 在啟動(dòng)PHP的時(shí)候,默認(rèn)都從系統(tǒng)變量"C:\Windows"這個(gè)目錄中尋找。 如果要在系統(tǒng)中同時(shí)使用IIS和Apache來(lái)運(yùn)行PHP,而且PHP的版本又不一樣,那么需要為Apache指定自己的PHP環(huán)境。
    2013-02-02
  • php addslashes及其他清除空格的方法是不安全的

    php addslashes及其他清除空格的方法是不安全的

    清除空格的方法是不安全的,部分原因是因?yàn)樽址械目崭穹浅6?例如 addslashes的問(wèn)題在 于黑客 可以用0xbf27來(lái)代替單引號(hào)
    2012-01-01

最新評(píng)論

黄龙县| 金华市| 皮山县| 根河市| 西畴县| 南平市| 丹东市| 南城县| 屏东市| 丹棱县| 儋州市| 城口县| 白玉县| 金昌市| 韩城市| 松潘县| 楚雄市| 西盟| 长泰县| 嘉祥县| 垫江县| 当阳市| 郯城县| 松原市| 乌拉特中旗| 新宾| 松原市| 闸北区| 卢湾区| 宁强县| 长乐市| 邳州市| 民丰县| 扶沟县| 石泉县| 通江县| 辽宁省| 武定县| 巨鹿县| 紫阳县| 锡林郭勒盟|