當(dāng)整數(shù)超過平臺(tái)的最大值時(shí),會(huì)導(dǎo)致php中的整數(shù)溢出,從而使其被施加到浮點(diǎn),這可能導(dǎo)致精確損失和意外行為。在32位系統(tǒng)上,最大整數(shù)為2,147,483,647,而在64位系統(tǒng)上,它為9,223,372,036,854,775,807。當(dāng)溢出發(fā)生時(shí),PHP會(huì)默默地將整數(shù)轉(zhuǎn)換為浮動(dòng),而不會(huì)出錯(cuò),導(dǎo)致諸如平等檢查失敗,錯(cuò)誤的位操作,JSON PECISION損失和損壞的數(shù)據(jù)庫(kù)ID等問題。當(dāng)處理大型自動(dòng)收入ID,未來的時(shí)間戳或在32位服務(wù)器上運(yùn)行時(shí),這尤其有問題。例如,3,000,000的用戶ID成為32位系統(tǒng)上的浮動(dòng),當(dāng)降回整數(shù)時(shí),可能會(huì)被截?cái)嘀?,147,483,647,從而導(dǎo)致數(shù)據(jù)庫(kù)查詢不正確。為了防止這些問題:1)永遠(yuǎn)不要假設(shè)整數(shù)仍然是整數(shù);始終使用is_int()驗(yàn)證; 2)將字符串用於大量,尤其是數(shù)據(jù)庫(kù)ID來保留精度; 3)使用SafeInt()函數(shù)驗(yàn)證和夾具輸入值和php_int_max和php_int_max; 4)使用BCMATH或GMP進(jìn)行大量的任意精確算術(shù); 5)在32位和64位環(huán)境中測(cè)試應(yīng)用程序,尤其是在CI/CD管道中進(jìn)行遺留系統(tǒng)支持。 PHP中的整數(shù)溢出不會(huì)導(dǎo)致崩潰,而是引入無聲,難以檢測(cè)的錯(cuò)誤,因此開發(fā)人員必須驗(yàn)證類型並仔細(xì)處理大量數(shù)字,以確??缙脚_(tái)的正確性。
PHP Integer溢出並不是大多數(shù)開發(fā)人員考慮的事情,直到某些系統(tǒng)悄悄地破裂。雖然PHP大量摘要,但基本體系結(jié)構(gòu)(32位與64位)可以大大改變整數(shù)的行為方式,這可能導(dǎo)致微妙,難以捕獲的錯(cuò)誤。

PHP中的整數(shù)溢出是什麼?
在PHP中, integer
類型具有由平臺(tái)確定的最大值:
- 32位系統(tǒng):最大整數(shù)為
2,147,483,647
(2^31-1) - 64位系統(tǒng):最大整數(shù)為
9,223,372,036,854,775,807
(2^63 - 1)
當(dāng)操作產(chǎn)生大於最大值的數(shù)字時(shí),它會(huì)溢出並鑄成float
。一旦發(fā)生這種情況,精度就會(huì)丟失(因?yàn)楦∽硬皇蔷_的),並且比較或計(jì)算可能會(huì)出現(xiàn)干擾。

var_dump(php_int_max); // 2147483647在32位上,64位更大
為什麼這是一個(gè)沉默的威脅
危險(xiǎn)在於PHP的自動(dòng)類型雜耍。當(dāng)PHP超過PHP_INT_MAX
時(shí),PHP沒有丟下錯(cuò)誤,而是將整數(shù)默默地轉(zhuǎn)換為浮點(diǎn)。
$ big = php_int_max; $ big; //溢出! var_dump($ big); // float(2147483648)在32位上 var_dump(is_int($ big)); //布爾(false)
現(xiàn)在您正在處理浮標(biāo),突然:

- 平等檢查失?。?
$big == (int)$big
可能是錯(cuò)誤的) - 鑽頭操作出乎意料的行為
- JSON編碼可能會(huì)失去精度
- 數(shù)據(jù)庫(kù)ID(例如自動(dòng)插入主鍵)可能會(huì)損壞
當(dāng):
- 您正在使用數(shù)據(jù)庫(kù)中的大型自動(dòng)收入ID(例如MySQL
BIGINT
) - 將來用時(shí)間戳進(jìn)行數(shù)學(xué)
- 處理32位服務(wù)器上的數(shù)據(jù)(在較舊的託管或嵌入式環(huán)境中常見)
現(xiàn)實(shí)世界示例:破損的用戶ID
想像您的應(yīng)用程序?qū)⒂脩鬒D作為整數(shù)存儲(chǔ)。在64位系統(tǒng)上,您可以插入具有ID 3000000000
的用戶 - 纖維,它適合64位,但不適合32位。
在32位系統(tǒng)上:
$ id = 3000000000; var_dump($ id); // float(3000000000) var_dump(((int)$ id); // 2147483647(或可能為-1,具體取決於系統(tǒng))
現(xiàn)在,您的用戶ID已被困擾。如果將其傳遞給查詢:
“從id =”的用戶中選擇 *。 (int)$ id;
您不是在獲取合適的用戶。
如何安全處理
這是避免被燒毀的方法:
永遠(yuǎn)不要假設(shè)整數(shù)保持整數(shù)
如果類型很重要,請(qǐng)始終使用is_int()
檢查。使用大量字符串
特別是數(shù)據(jù)庫(kù)中的ID。存放並通過將它們作為字符串傳遞以保持精度。$ userId =(string)$ row ['id']; //跨平臺(tái)安全
驗(yàn)證和夾具輸入
如果您期望整數(shù),請(qǐng)確認(rèn)它們?cè)?code>PHP_INT_MAX及以上的PHP_INT_MIN
範(fàn)圍內(nèi)。功能safeint($ value){ if($ value> php_int_max || $ value <php_int_min){ 投擲新的OverFlowException(“檢測(cè)到整數(shù)溢出”); } 返回(int)$ value; }
使用BCMATH或GMP進(jìn)行大數(shù)學(xué)
對(duì)於超出整數(shù)限制的計(jì)算,請(qǐng)使用任意的精確庫(kù)。$ sum = bcadd('9223372036854775800','10');
在32位和64位環(huán)境上測(cè)試
如果您支持舊系統(tǒng),則CI/CD管道應(yīng)包括32位PHP構(gòu)建。
基本上,PHP中的整數(shù)溢出不會(huì)使您的應(yīng)用程序崩潰,這只是使它安靜地錯(cuò)誤。這要危險(xiǎn)得多。了解您的平臺(tái),驗(yàn)證您的類型,並謹(jǐn)慎對(duì)待大量。
以上是PHP整數(shù)溢出:32位與64位系統(tǒng)的無聲威脅的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版
神級(jí)程式碼編輯軟體(SublimeText3)

UseIntl.NumberFormatwithuser-specificlocalesforcorrectdigitgroupinganddecimalseparators.2.Formatcurrencyusingstyle:'currency'withISO4217codesandlocale-specificsymbolplacement.3.ApplycompactnotationforlargenumberstoenhancereadabilitywithunitslikeMor??

使用BCMath擴(kuò)展是解決PHP金融計(jì)算精度問題的關(guān)鍵,因?yàn)樗ㄟ^字符串進(jìn)行任意精度的十進(jìn)制運(yùn)算,避免了浮點(diǎn)數(shù)的捨入誤差;2.必須始終以字符串形式傳入數(shù)值並設(shè)置scale參數(shù)(如bcadd('0.1','0.2',2)),以確保結(jié)果精確到所需的小數(shù)位;3.避免將浮點(diǎn)數(shù)直接傳給BCMath函數(shù),因其在傳參前已丟失精度;4.可通過bcscale(2)設(shè)置全局小數(shù)位數(shù),確保財(cái)務(wù)計(jì)算統(tǒng)一保留兩位小數(shù);5.BCMath默認(rèn)截?cái)喽撬膾挝迦耄枳孕袑?shí)現(xiàn)四捨五入邏輯(如通過bcround函數(shù));6.輸入值需驗(yàn)

mt_rand()isNotsecureCryptographicposePoseSitusEsthemerSennetWisterAlgorithm,whtroducesProdiCesProdiCtableOutput,Maybepoorlyseeded,andisnotdesignedforsecurity.2.2.forsecurererandomnumnumnumnumnumnumnumnumnumnumnumnumnumnumbergeneration,UsserandSty,inserandsyterstranseftsfors

PHP的鬆散類型系統(tǒng)在數(shù)字類型轉(zhuǎn)換中既強(qiáng)大又危險(xiǎn)。 1.使用鬆散比較(==)時(shí),PHP會(huì)將非數(shù)字字符串轉(zhuǎn)為0,導(dǎo)致'hello'==0為true,可能引發(fā)安全漏洞,應(yīng)始終在需要時(shí)使用嚴(yán)格比較(===)。 2.算術(shù)運(yùn)算中,PHP會(huì)靜默轉(zhuǎn)換字符串,如'10apples'變?yōu)?0,而'apples10'變?yōu)?,可能導(dǎo)致計(jì)算錯(cuò)誤,應(yīng)使用is_numeric()或filter_var()驗(yàn)證輸入。 3.數(shù)組鍵中,數(shù)字字符串如'123'會(huì)被轉(zhuǎn)為整數(shù),導(dǎo)致'007'變?yōu)?,丟失格式,可通過添加前綴避免。 4.函數(shù)參數(shù)

當(dāng)需要處理超過PHP_INT_MAX(如9223372036854775807)的整數(shù)時(shí),1.應(yīng)使用GMP擴(kuò)展或brick/math等任意精度數(shù)學(xué)庫(kù);2.GMP基於C庫(kù),性能高但需服務(wù)器支持;3.brick/math為純PHP實(shí)現(xiàn),便於移植但速度較慢;4.初始化大數(shù)時(shí)必須用字符串防止精度丟失;5.所有操作應(yīng)避免浮點(diǎn)數(shù)參與以確保精度。最終選擇取決於環(huán)境控製程度、性能需求與代碼風(fēng)格偏好,但都需以字符串方式安全初始化大整數(shù)。

is_numeric()checksifavaluecanbeinterpretedasanumber,acceptingformatslikehex,scientificnotation,andwhitespace,butonlyreturnsabooleanwithouttypecasting.2.filter_var()withFILTER_VALIDATE_INTorFILTER_VALIDATE_FLOATvalidatesandsanitizesbyreturningtheactua

浮點(diǎn)數(shù)不準(zhǔn)確的問題在PHP中常見,尤其是在金融計(jì)算或精確比較時(shí),根本原因是十進(jìn)制小數(shù)無法在二進(jìn)制浮點(diǎn)表示法(IEEE754標(biāo)準(zhǔn))中精確存儲(chǔ),導(dǎo)致如0.1 0.2≠0.3的結(jié)果;1.進(jìn)行浮點(diǎn)數(shù)相等比較時(shí)應(yīng)使用容差值(epsilon)而非直接用==;2.金融計(jì)算應(yīng)避免使用浮點(diǎn)數(shù),改用整數(shù)(如以分為單位)或BCMath擴(kuò)展;3.BCMath通過字符串進(jìn)行任意精度計(jì)算,適用於高精度場(chǎng)景,但性能較低;4.應(yīng)注意PHP的類型轉(zhuǎn)換可能將字符串或整數(shù)隱式轉(zhuǎn)為浮點(diǎn)數(shù)引入誤差;總之,浮點(diǎn)數(shù)不精確是通用計(jì)算問題,但在

intdiv()performstrueintegerdivisionandissaferforwholenumbers,whilecasting(int)afterdivisionrisksfloating-pointprecisionerrors.2.Bothtruncatetowardzero,butcastingcanyieldincorrectresultswithnegativeorimprecisevaluesduetofloatrepresentationissues.3.int
