溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP7類型的案例分析

發(fā)布時間:2020-11-02 11:13:33 來源:億速云 閱讀:166 作者:小新 欄目:編程語言

這篇文章主要介紹了PHP7類型的案例分析,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。


當PHP7出現(xiàn)了強類型,我看到了光明。我終于有信心不會再因為PHP弱類型看見bug或者不一致的情況。

我記著讀過一些代碼,對其中的變量該是的類型沒什么想法。這個方法我該使用int類型作為返回值?boolen類型?這樣將會產(chǎn)生一些隱藏的bug或者不可預見的行為?

嚴格類型很有用,返回值類型提示也很有用。你很了解你正處理的數(shù)據(jù)是什么。你再也不用靠猜了。

但是,PHP7并不是我這篇文章努力的結束。你仍可以寫易混淆的代碼,即使PHP7努力去修復這個問題。你需要遵守一些規(guī)則來使你的代碼保持規(guī)范。

我會使用PHP7.1.1-dev的命令行模式運行本文的每個例子。

PHP類型聲明

PHP7引入了兩個合適類型:標量類型和返回值類型。我在這不會解釋它們的不同以及如何去使用它們。PHP意見征求稿會比我做得更好:

*https://wiki.php.net/rfc/scalar_type_hints_v5

*https://wiki.php.net/rfc/return_types

PHP7有強類型...還是很奇怪?

直截了當些: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習慣弱類型。

我不愿意。

事實上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í)行將會終止。

那時你僅需要去處理這個錯誤。簡單、清晰、高效,毋庸置疑。

PHP中nullable類型和接口

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è)資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI