PHP中強(qiáng)制類(lèi)型轉(zhuǎn)換的示例詳解
前言
學(xué)過(guò)靜態(tài)語(yǔ)言開(kāi)發(fā)的朋友對(duì)類(lèi)型轉(zhuǎn)換不會(huì)陌生,比如Java、C#、C++等。靜態(tài)語(yǔ)言的好處就是變量強(qiáng)制必須指定類(lèi)型,這也是編譯的要求,所以大部分編譯型的語(yǔ)言都會(huì)有強(qiáng)制變量類(lèi)型的要求。而PHP據(jù)說(shuō)也會(huì)在PHP8中加入JIT實(shí)現(xiàn)編譯功能,并且在7.4中就會(huì)引入變量聲明時(shí)的類(lèi)型指定。下面我們先看看目前PHP中的參數(shù)類(lèi)型及返回值類(lèi)型的使用。
1function add(int $a, float $b) : int{ 2 return (int) $a + $b; 3}
上述代碼中,方法參數(shù)中定義了參數(shù)的類(lèi)型,包括一個(gè)int類(lèi)型的a和一個(gè)float類(lèi)型的b。然后在方法后面定義了方法的返回值必須是int類(lèi)型。我們知道,如果計(jì)算表達(dá)式中出現(xiàn)了float類(lèi)型,那么計(jì)算結(jié)果會(huì)變成float類(lèi)型。這個(gè)方法需要返回的是一個(gè)int類(lèi)型。因此我們使用了一個(gè)強(qiáng)制類(lèi)型轉(zhuǎn)換(int)。在定義了參數(shù)類(lèi)型和返回值類(lèi)型后,如果傳遞或者返回的類(lèi)型不一致,就會(huì)報(bào)錯(cuò)。
參數(shù)類(lèi)型和返回值類(lèi)型最好在7以上的版本使用?;绢?lèi)型如int、float等的參數(shù)類(lèi)型聲明都是7以后才支持的,詳情參見(jiàn)文檔:
https://www.php.net/manual/zh/functions.arguments.php
我們通過(guò)(int)、(float)、(bool)等就可以實(shí)現(xiàn)PHP的類(lèi)型強(qiáng)制轉(zhuǎn)換,和C基本上一樣。文檔中關(guān)于可以強(qiáng)制轉(zhuǎn)換的包括如下類(lèi)型:
- (int), (integer) - 轉(zhuǎn)換為整形 integer
- (bool), (boolean) - 轉(zhuǎn)換為布爾類(lèi)型 boolean
- (float), (double), (real) - 轉(zhuǎn)換為浮點(diǎn)型 float
- (string) - 轉(zhuǎn)換為字符串 string
- (array) - 轉(zhuǎn)換為數(shù)組 array
- (object) - 轉(zhuǎn)換為對(duì)象 object
- (unset) - 轉(zhuǎn)換為 NULL (PHP 5)
- (binary) 轉(zhuǎn)換和 b 前綴轉(zhuǎn)換支持為 PHP 5.2.1 新增
(int), (integer)
如果是布爾值,轉(zhuǎn)換結(jié)果為false變成0,true變成1
如果是float,向下取整,如7.99會(huì)轉(zhuǎn)換為7
如果是字符串,字符串從頭開(kāi)始查找,開(kāi)頭第一個(gè)是數(shù)字會(huì)直接變成該轉(zhuǎn)換結(jié)果,如果開(kāi)頭沒(méi)有數(shù)字返回0
其他類(lèi)型轉(zhuǎn)換在文檔中并沒(méi)有定義,文檔提示為“沒(méi)有定義從其它類(lèi)型轉(zhuǎn)換為整型的行為。不要依賴任何現(xiàn)有的行為,因?yàn)樗鼤?huì)未加通知地改變?!?,但我們通過(guò)測(cè)試,可以發(fā)現(xiàn)對(duì)于其他類(lèi)型的轉(zhuǎn)換是通過(guò)多次的類(lèi)型轉(zhuǎn)換達(dá)成的,比如數(shù)組類(lèi)型轉(zhuǎn)換為int類(lèi)型,是根據(jù)數(shù)組是否包含內(nèi)容轉(zhuǎn)換為bool類(lèi)型后再轉(zhuǎn)換為int類(lèi)型
// (int)(integer) var_dump((int) true); // 1 var_dump((int) false); // 0 var_dump((int) 7.99); // 7 var_dump((int) "35 ok"); // 35 var_dump((int) "ok 77"); // 0 var_dump((int) "ok yes"); // 0 var_dump((int) []); // 0 var_dump((int) [3,4,5]); // 1
(bool)(boolean)
當(dāng)轉(zhuǎn)換為 boolean 時(shí),以下值被認(rèn)為是 FALSE:
- 布爾值 FALSE 本身
- 整型值 0(零)
- 浮點(diǎn)型值 0.0(零)
- 空字符串,以及字符串 "0"
- 不包括任何元素的數(shù)組
- 特殊類(lèi)型 NULL(包括尚未賦值的變量)
- 從空標(biāo)記生成的 SimpleXML 對(duì)象
所有其它值都被認(rèn)為是 TRUE(包括任何資源 和 NAN)
這里需要注意的是,負(fù)數(shù)也會(huì)是TRUE,只有0是FASLE
// (bool)(boolean) var_dump((bool) 0); // false var_dump((bool) 1); // true var_dump((bool) -1); // true var_dump((bool) 0.0); // false var_dump((bool) 1.1); // true var_dump((bool) -1.1); // true var_dump((bool) ""); // false var_dump((bool) "0"); // false var_dump((bool) "a"); // true var_dump((bool) []); // false var_dump((bool) ['a']); // true $a; var_dump((bool) $a); // false var_dump((bool) NULL); // false
(string)
- 布爾值,false轉(zhuǎn)換為空字符串"",true轉(zhuǎn)換為"1"
- int或float類(lèi)型,轉(zhuǎn)換為字符串形式的字面量,如1轉(zhuǎn)換為"1"
- 數(shù)組和對(duì)象分別轉(zhuǎn)換為"Array"和"Object"字面量
- 資源類(lèi)型會(huì)被轉(zhuǎn)換為"Resource id #1"形式的字面量
- NULL轉(zhuǎn)換為空字符串""
直接把 array,object 或 resource 轉(zhuǎn)換成 string 不會(huì)得到除了其類(lèi)型之外的任何有用信息??梢允褂煤瘮?shù) print_r() 和 var_dump() 列出這些類(lèi)型的內(nèi)容
注:測(cè)試結(jié)果,對(duì)象類(lèi)型需要實(shí)現(xiàn)__tostring()魔術(shù)函數(shù),否則報(bào)錯(cuò)無(wú)法轉(zhuǎn)換為string類(lèi)型
// (string) var_dump((string) true); // "1" var_dump((string) false); // "" var_dump((string) 55); // "55" var_dump((string) 12.22); // "12.22" var_dump((string) ['a']); // "Array" class S{ function __tostring(){ return "S"; } } var_dump((string) new S()); // "S" var_dump((string) NULL); // ""
(array)
對(duì)于任意 integer,float,string,boolean 和 resource 類(lèi)型,如果將一個(gè)值轉(zhuǎn)換為數(shù)組,將得到一個(gè)僅有一個(gè)元素的數(shù)組,其下標(biāo)為 0,該元素即為此標(biāo)量的值。換句話說(shuō)(array)scalarValue 與 array(scalarValue) 是完全一樣的
如果一個(gè) object 類(lèi)型轉(zhuǎn)換為 array,則結(jié)果為一個(gè)數(shù)組,其單元為該對(duì)象的屬性。鍵名將為成員變量名,不過(guò)有幾點(diǎn)例外:整數(shù)屬性不可訪問(wèn);私有變量前會(huì)加上類(lèi)名作前綴;保護(hù)變量前會(huì)加上一個(gè) '*' 做前綴。這些前綴的前后都各有一個(gè) NULL 字符
將 NULL 轉(zhuǎn)換為 array 會(huì)得到一個(gè)空的數(shù)組
// (array) var_dump((array) 1); var_dump((array) 2.2); var_dump((array) "a"); var_dump((array) true); class Arr { public $a = 1; private $b = 2.2; protected $c = "f"; } class ChildArr extends Arr { public $a = 2; private $d = "g"; private $e = 1; } var_dump((array) new Arr()); var_dump((array) new ChildArr()); var_dump((array) null);
(object)
如果將一個(gè)對(duì)象轉(zhuǎn)換成對(duì)象,它將不會(huì)有任何變化。如果其它任何類(lèi)型的值被轉(zhuǎn)換成對(duì)象,將會(huì)創(chuàng)建一個(gè)內(nèi)置類(lèi) stdClass 的實(shí)例。如果該值為 NULL,則新的實(shí)例為空。array 轉(zhuǎn)換成 object 將使鍵名成為屬性名并具有相對(duì)應(yīng)的值
注意:使用 PHP 7.2.0 之前的版本,數(shù)字鍵只能通過(guò)迭代訪問(wèn)
// (object) var_dump((object) 1); var_dump((object) 1.1); var_dump((object) "string"); var_dump((object) true); var_dump((object) NULL); var_dump((object) [1, 2, 3]); var_dump((object) ["a" => 1, "b" => 2, "c" => 3]);
(unset)
使用 (unset) $var 將一個(gè)變量轉(zhuǎn)換為 null 將不會(huì)刪除該變量或 unset 其值。僅是返回 NULL 值而已
// (unset) var_dump((unset) 1); var_dump((unset) 1.1); var_dump((unset) "string"); var_dump((unset) true); var_dump((unset) null); var_dump((unset) [1, 2, 3]); var_dump((unset) new \stdClass());
(binary)
將所有類(lèi)型轉(zhuǎn)換為二進(jìn)制字符串。二進(jìn)制字符串是區(qū)別于傳統(tǒng)常用的普通php的Unicode字符串。二進(jìn)制字符串是字節(jié)字符串,沒(méi)有字符集。具體的區(qū)別就類(lèi)似于數(shù)據(jù)庫(kù)中的binary和char類(lèi)型及blob和text類(lèi)型
在日常的開(kāi)發(fā)中基本用不到,了解即可
// (binary) var_dump((binary) 1); var_dump((binary) 1.1); var_dump((binary) "string"); var_dump((binary) true); var_dump((binary) null); var_dump((binary) [1, 2, 3]); var_dump((binary) new S());
以上就是我們的強(qiáng)制類(lèi)型轉(zhuǎn)換的所有類(lèi)型,其中有一些類(lèi)型的轉(zhuǎn)換中提到了資源類(lèi)型(Resource),但是并沒(méi)有資源類(lèi)型的強(qiáng)制轉(zhuǎn)換。因?yàn)橘Y源類(lèi)型大多是一些句柄操作,如數(shù)據(jù)庫(kù)鏈接、文件讀寫(xiě)等,將其它類(lèi)型強(qiáng)制轉(zhuǎn)換為資源類(lèi)型沒(méi)有意義。
本文內(nèi)容會(huì)經(jīng)常出現(xiàn)在面試題中,而且在實(shí)際開(kāi)發(fā)中的很多邏輯判斷出現(xiàn)的BUG也常常是由于PHP的自動(dòng)類(lèi)型轉(zhuǎn)換所導(dǎo)致的,所以這篇文章好好收藏多拿出來(lái)看看絕對(duì)會(huì)讓你有意想不到的收獲哦??!
測(cè)試代碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/201910/source/php%E4%B8%AD%E7%9A%84%E5%BC%BA%E5%88%B6%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.php
參考文檔:
https://www.php.net/manual/zh/language.types.type-juggling.php#language.types.typecasting
總結(jié)
到此這篇關(guān)于PHP中強(qiáng)制類(lèi)型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)PHP強(qiáng)制類(lèi)型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP根據(jù)樹(shù)的前序遍歷和中序遍歷構(gòu)造樹(shù)并輸出后序遍歷的方法
這篇文章主要介紹了PHP根據(jù)樹(shù)的前序遍歷和中序遍歷構(gòu)造樹(shù)并輸出后序遍歷的方法,涉及php數(shù)據(jù)結(jié)構(gòu)與算法中關(guān)于數(shù)的遍歷相關(guān)操作技巧,需要的朋友可以參考下2017-11-11PHP獲取163、gmail、126等郵箱聯(lián)系人地址【已測(cè)試2009.10.10】
最近一直忙于項(xiàng)目上的QQ、MSN、郵箱(目前以實(shí)現(xiàn)163、126、gmail、sina、tom、sohu、yahoo等)通訊錄地址獲?。黄渲兴押н€需研究一下!2009-10-10php $_SERVER windows系統(tǒng)與linux系統(tǒng)下的區(qū)別說(shuō)明
本篇文章主要是對(duì)php $_SERVER windows系統(tǒng)與linux系統(tǒng)下的區(qū)別進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-02-02將一維或多維的數(shù)組連接成一個(gè)字符串的php代碼
自定義一個(gè)函數(shù) ,把一個(gè)數(shù)組變成用,(逗號(hào))連接起來(lái)的字符串 (注意:應(yīng)考慮到多維數(shù)組的情況,并以返回值的形式返回)2010-08-08php+jquery編碼方面的一些心得(utf-8 gb2312)
在開(kāi)發(fā)php與jquery的過(guò)程中,需要注意的一些心得,防止亂碼的出現(xiàn)。2010-10-10PHP遞歸實(shí)現(xiàn)無(wú)限級(jí)分類(lèi)的代碼示例
無(wú)限級(jí)分類(lèi)是一種對(duì)商品或信息進(jìn)行分類(lèi)的方式,在這種分類(lèi)方式中,每個(gè)分類(lèi)都可以再次細(xì)分出更多的子分類(lèi),形成無(wú)限的級(jí)別,本文給大家介紹了如何使用PHP遞歸實(shí)現(xiàn)無(wú)限級(jí)分類(lèi),文中有詳細(xì)的代碼示例,需要的朋友可以參考下2023-10-10