您好,登錄后才能下訂單哦!
這篇文章主要介紹了PHP7類型的案例分析,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
當PHP7出現(xiàn)了強類型,我看到了光明。我終于有信心不會再因為PHP弱類型看見bug或者不一致的情況。
我記著讀過一些代碼,對其中的變量該是的類型沒什么想法。這個方法我該使用int類型作為返回值?boolen類型?這樣將會產(chǎn)生一些隱藏的bug或者不可預見的行為?
嚴格類型很有用,返回值類型提示也很有用。你很了解你正處理的數(shù)據(jù)是什么。你再也不用靠猜了。
但是,PHP7并不是我這篇文章努力的結束。你仍可以寫易混淆的代碼,即使PHP7努力去修復這個問題。你需要遵守一些規(guī)則來使你的代碼保持規(guī)范。
我會使用PHP7.1.1-dev的命令行模式運行本文的每個例子。
PHP7引入了兩個合適類型:標量類型和返回值類型。我在這不會解釋它們的不同以及如何去使用它們。PHP意見征求稿會比我做得更好:
*https://wiki.php.net/rfc/scalar_type_hints_v5
*https://wiki.php.net/rfc/return_types
直截了當些:PHP7編程可能會有一些不可預期的結果。
對此懷疑?以下一些例子:
function mySuperFunction(): int{ return "hello world"; } mySuperFunction();
這段代碼沒問題。類型聲明指出這個方法應該返回int類型。然而,它返回字符串類型。毋庸置疑,PHP會拋出了一個錯誤:
Fatal error: Uncaught TypeError: Return value of mySuperFunction() must be of the type integer, string returned. 致命錯誤:未捕捉的類型錯誤:mySuper函數(shù)返回類型必須是int類型,返回了字符串。
讓我們看另一個例子:
function mySuperFunction():int{ return "hello world1"; } mySuperFunction();
和上邊相同的結果:類型錯誤。好!返回類型有什么問題嗎?我沒騙到你吧?
function mySuperFunction():int{ return "1hello world"; } mySuperFunction();
這不是應該拋出異常嗎?我們很明確地定義了返回類型為int,但返回的卻是一個字符串。
翻譯作者補充:PHP7.2.4會拋出注意型錯誤:
Notice: A non well formed numeric value encountered 出現(xiàn)一個不好的格式化數(shù)字類型值
錯。函數(shù)返回1。
function mySuperFunction():int{ return 1.1456415; } mySuperFunction();
定義返回int類型,很明顯,實際返回的是float類型。但是這段代碼不拋出異常。
它返回1.
還不服氣?
function mySuperFunction():bool{ return "1hello world"; } mySuperFunction();
PHP會把'1hello world'視作是布爾類型并返回1。
function mySuperFunction():bool{ return "abcde"; } mySuperFunction();
在奇怪的的PHP世界中,'abcde'是布爾類型。的確,這個方法會返回true!
如你所見,這些編碼規(guī)則仍舊把你搞得暈頭轉向。簡而言之,即使代碼交代清楚也不一定是真的!
PHP習慣弱類型。
我不愿意。
事實上PHP會在運行時默默地把字符串類型轉換成布爾類型,轉換成int類型。就把你的代碼搞混了!本該簡單明了的東西搞亂了。
讓我們明確下。我們是開發(fā)者。因此我們應該在代碼中控制數(shù)據(jù)的類型。
如果我們不這樣,我們將打開bug之門,在開發(fā)者間傳播怪行為和誤解。代碼將會改變。bug將會出現(xiàn),老板將會解雇了你,妻子將會對你失望,你將會墜入深淵。在自責中難過、孤獨。
還有補救的機會!所有事情都可能。PHP有解決方法!
注意嚴格類型模式:
declare(strict_types=1);function mySuperFunction(): bool{ return 'abcde'; }echo mySuperFunction();
運行這段代碼,你將會得到一個致命的錯誤:
Fatal error: Uncaught TypeError: Return value of mySuperFunction() must be of the type boolean, string returned!
未捕獲的類型錯誤:mySuperFunction()返回值必須是布爾類型,返回了字符串!
我十分高興看到這個錯誤在屏幕彈出。通常遇到錯誤都不是很爽,但是這次沒什么。當然是字符串類型而不是布爾類型!
我的建議是:把這個嚴格類型的聲明放到的每一段代碼中。任何地方!為你的IDE創(chuàng)建一個代碼片段。每次創(chuàng)建一個PHP文件時,你應該把嚴格類型的聲明放到頂部。
不幸的是你不能全局地設置嚴格模式。你需要在每個PHP文件中執(zhí)行。理由很簡單:你應用中的任何包或者其他類型的資源,即使不需要執(zhí)行強類型模式。
我知道有人會不認同。我知道一些人正準備毀掉代碼一致性,然后單純地為了可能的「靈活性」。
我知道爭論:「一種觀點認為布爾類型需要被展示為字符串類型是很容易的」。
我會回復他們:修復你的結構和/或你的實現(xiàn)。如果代碼是弱類型,就會有一些問題。如果你確實需要,請修復真實存在的問題,不用再徘徊于把布爾值作為一個字符串或者int類型。
你是開發(fā)者。你不是黑客。你要解決問題,而不是與問題為伍。
五個字概括:強類型驕傲!PHP7是強類型類型語言了!
PHP7.1中Nullable類型 請小心nullable類型的笑里藏刀!它是猛獸!
nullabla類型詳見PHP意見征求稿
你怎么會用錯?
declare(strict_types=1);class User{ //Value object}class UserRepository{ private $database; public function construct(Database $database){ $this->database = $database; } public function getUserById(int $id):?User { //If user is not in the database, return null $user = $this->database->fetchUser($id); return $user; } }class EmailSender{ public function sendEmailToUser(int $userId) { $userRepository = new UserRepository(new Database()); $user = $userRepository->getUserById($userId); //Can send email to... null! $this->sendEmail($user); } } $emailSender = new EmailSender(); $emailSender->sendEmailToUser(12345);
這段代碼將會崩潰,因為我們試圖獲取數(shù)據(jù)庫中不存在的User模型。我們怎么能給null發(fā)郵件?
很明顯你應該用如下方法修正:
...class EmailSender{ public function sendEmailToUser($userId) { $userRepository = new UserRepository(new Database()); $user = $userRepository->getUserById($userId); if ($user !== null) { $this->sendEmail($user); } } }
但是這個方法有兩個問題:
對nullable的處理將導致判斷是否為null的判斷到處都是(if ($methodReturn !== null))。無用且聒噪。
如果用戶不存在以上代碼將會靜靜地失敗。「為什么用戶沒收到郵件?」將會是你的噩夢。你需要明白:
用戶模型不存在(可能是一個錯誤的用戶id被傳入了getUserByid())
用戶模型為null,可能因為nullable類型
加上null的條件判斷,導致應用什么都沒做
這是另一種方式:
...class UserRepository{ private $database; public function construct($database){ $this->database = $database; } public function getUserById($id):User { $user = $this->database->fetchUser($id); //If user is not in the database, an error will be thrown! return $user; } } ...
在這個例子中沒必要使用nullalble類型。代碼將會拋出一個異常。如果User模型不存在,應用的執(zhí)行將會終止。
那時你僅需要去處理這個錯誤。簡單、清晰、高效,毋庸置疑。
nullable類型有一些其他的意外。
declare(strict_types=1);interface MySuperInterface{ public function superFunction():?int; }class SuperClass implements mySuperInterface{ public function superFunction():int { return 42; } } $superClass = new SuperClass();echo $superClass->superFunction();
Super類實現(xiàn)了接口MySubper,但不會實現(xiàn)接口約定。接口要求返回nullable的類型,實際將返回int類型。
然而,這段代碼在PHP7.1中不會拋出錯誤。
等等。。。我們需要如接口中表示的那樣無論如何都要返回null?
讓我們嘗試一下:
declare(strict_types=1);interface MySuperInterface{ public function superFunction():?int; }class SuperClass implements mySuperInterface{ public function superFunction():int { return null; } } $superClass = new SuperClass();echo $superClass->superFunction();
結果如下:
Fatal error: Uncaught TypeError: Return value of SuperClass::superFunction() must be of the type integer, null returned 致命錯誤:未捕獲的類型錯誤:Super類的super方法的返回值必須得是int類型,返回了null
現(xiàn)在我應該理解了在某場景下很有用,比如不能在數(shù)據(jù)庫中存null值時。
我強烈建議你謹慎使用。我很少在代碼中使用這個類型,因為我通常有更好的解決辦法。
我更喜歡在大多場景下使用null對象代替null。為什么?簡而言之,因為我討厭在任何時候檢測變量是否為null!
我喜歡PHP。尤其當它引入了強類型??赡苓€不完美,但是將會越來越好。
不過當你在PHP中操作類型時,一定要多加小心。我還是要強調:
需要使用嚴格類型。
需要控制應用中數(shù)據(jù)。
如果仍使用弱類型,將會是個問題。因此:修復它!
不應該猜測變量的類型到底是什么。
盡可能避免使用nullable類型
為了每個使用我們的代碼的開發(fā)人員,我們需要保持一致性。對我來說,意味著很專業(yè)。
很明顯在留言中閱讀你們的建議使我很開心。
看完了這篇文章,相信你對PHP7類型的案例分析有了一定的了解,想了解更多相關知識,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!
感謝你能夠認真閱讀完這篇文章,希望小編分享PHP7類型的案例分析內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。