學過靜態語言開發的朋友對型別轉換不會陌生,比如Java、C#、C++等,靜態語言的好處就是變數強制必須指定型別,這也是編譯的要求,所以大部分編譯型的語言都會有強制變數型別的要求,而PHP據說也會在PHP8中加入JIT實作編譯功能,并且在7.4中就會引入變數宣告時的型別指定,下面我們先看看目前PHP中的引數型別及回傳值型別的使用,
function add(int $a, float $b) : int{
return (int) $a + $b;
}
上述代碼中,方法引數中定義了引數的型別,包括一個int型別的$a和一個float型別的$b,然后在方法后面定義了方法的回傳值必須是int型別,我們知道,如果計算運算式中出現了float型別,那么計算結果會變成float型別,這個方法需要回傳的是一個int型別,因此我們使用了一個強制型別轉換(int),在定義了引數型別和回傳值型別后,如果傳遞或者回傳的型別不一致,就會報錯,
引數型別和回傳值型別最好在7以上的版本使用,基本型別如int、float等的引數型別宣告都是7以后才支持的,詳情參見檔案:https://www.php.net/manual/zh/functions.arguments.php
我們通過(int)、(float)、(bool)等就可以實作PHP的型別強制轉換,和C基本上一樣,檔案中關于可以強制轉換的包括如下型別:
- (int), (integer) - 轉換為整形 integer
- (bool), (boolean) - 轉換為布爾型別 boolean
- (float), (double), (real) - 轉換為浮點型 float
- (string) - 轉換為字串 string
- (array) - 轉換為陣列 array
- (object) - 轉換為物件 object
- (unset) - 轉換為 NULL (PHP 5)
- (binary) 轉換和 b 前綴轉換支持為 PHP 5.2.1 新增
(int), (integer)
- 如果是布林值,轉換結果為false變成0,true變成1
- 如果是float,向下取整,如7.99會轉換為7
- 如果是字串,字串從頭開始查找,開頭第一個是數字會直接變成該轉換結果,如果開頭沒有數字回傳0
- 其他型別轉換在檔案中并沒有定義,檔案提示為“沒有定義從其它型別轉換為整型的行為,不要依賴任何現有的行為,因為它會未加通知地改變,”,但我們通過測驗,可以發現對于其他型別的轉換是通過多次的型別轉換達成的,比如陣列型別轉換為int型別,是根據陣列是否包含內容轉換為bool型別后再轉換為int型別
// (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)
當轉換為 boolean 時,以下值被認為是 FALSE:
- 布林值 FALSE 本身
- 整型值 0(零)
- 浮點型值 0.0(零)
- 空字串,以及字串 "0"
- 不包括任何元素的陣列
- 特殊型別 NULL(包括尚未賦值的變數)
- 從空標記生成的 SimpleXML 物件
所有其它值都被認為是 TRUE(包括任何資源 和 NAN)
這里需要注意的是,負數也會是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轉換為空字串"",true轉換為"1"
- int或float型別,轉換為字串形式的字面量,如1轉換為"1"
- 陣列和物件分別轉換為"Array"和"Object"字面量
- 資源型別會被轉換為"Resource id #1"形式的字面量
- NULL轉換為空字串""
直接把 array,object 或 resource 轉換成 string 不會得到除了其型別之外的任何有用資訊,可以使用函式 print_r() 和 var_dump() 列出這些型別的內容
注:測驗結果,物件型別需要實作__tostring()魔術函式,否則報錯無法轉換為string型別
// (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)
對于任意 integer,float,string,boolean 和 resource 型別,如果將一個值轉換為陣列,將得到一個僅有一個元素的陣列,其下標為 0,該元素即為此標量的值,換句話說,(array)$scalarValue 與 array($scalarValue) 完全一樣
如果一個 object 型別轉換為 array,則結果為一個陣列,其單元為該物件的屬性,鍵名將為成員變數名,不過有幾點例外:整數屬性不可訪問;私有變數前會加上類名作前綴;保護變數前會加上一個 '*' 做前綴,這些前綴的前后都各有一個 NULL 字符
將 NULL 轉換為 array 會得到一個空的陣列
// (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)
如果將一個物件轉換成物件,它將不會有任何變化,如果其它任何型別的值被轉換成物件,將會創建一個內置類 stdClass 的實體,如果該值為 NULL,則新的實體為空, array 轉換成 object 將使鍵名成為屬性名并具有相對應的值
注意:使用 PHP 7.2.0 之前的版本,數字鍵只能通過迭代訪問
// (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 將一個變數轉換為 null 將不會洗掉該變數或 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)
將所有型別轉換為二進制字串,二進制字串是區別于傳統常用的普通php的Unicode字串,二進制字串是位元組字串,沒有字符集,具體的區別就類似于資料庫中的binary和char型別及blob和text型別
在日常的開發中基本用不到,了解即可
// (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());
以上就是我們的強制型別轉換的所有型別,其中有一些型別的轉換中提到了資源型別(Resource),但是并沒有資源型別的強制轉換,因為資源型別大多是一些句柄操作,如資料庫鏈接、檔案讀寫等,將其它型別強制轉換為資源型別沒有意義,
本文內容會經常出現在面試題中,而且在實際開發中的很多邏輯判斷出現的BUG也常常是由于PHP的自動型別轉換所導致的,所以這篇文章好好收藏多拿出來看看絕對會讓你有意想不到的識訓哦!!
測驗代碼:
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
===============
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/247056.html
標籤:PHP
上一篇:laravel郵件發送
