這篇文章將為大家詳細講解有關php的標量數(shù)據(jù)類型,文章內(nèi)容質(zhì)量較高,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
成都創(chuàng)新互聯(lián)公司長期為上千客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為淶水企業(yè)提供專業(yè)的成都網(wǎng)站設計、成都網(wǎng)站建設,淶水網(wǎng)站改版等技術服務。擁有10年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。一、簡介該RFC建議添加4種新的標量類型聲明:int,float,string和bool,這些類型聲明將會和PHP原來的機制保持一致的用法。RFC更推薦給每一個PHP文件,添加一句新的可選指令(declare(strict_type=1);),讓同一個PHP文件內(nèi)的全部函數(shù)調(diào)用和語句返回,都有一個“嚴格約束”的標量類型聲明檢查。此外,在開啟嚴格類型約束后,調(diào)用拓展或者PHP內(nèi)置函數(shù)在參數(shù)解析失敗,將產(chǎn)生一個E_RECOVERABLE_ERROR級錯誤。通過這兩個特性,RFC希望編寫PHP能夠變得更準確和文檔化。
二、細節(jié)標量類型聲明:
沒有添加新的保留字。int、float、string和bool會被識別為類型聲明,同時禁止用作class/interface/trait等的命名。新的用戶標量類型聲明,通過內(nèi)部的Fast Parameter Parsing API實現(xiàn)。
strict_types/declare()指令
默認情況下,所有的PHP文件都處于弱類型校驗模式。新的declare指令,通過指定strict_types的值(1或者0),1表示嚴格類型校驗模式,作用于函數(shù)調(diào)用和返回語句;0表示弱類型校驗模式。
declare(strict_types=1)必須是文件的第一個語句。如果這個語句出現(xiàn)在文件的其他地方,將會產(chǎn)生一個編譯錯誤,塊模式是被明確禁止的。
類似于encoding指令,但不同于ticks指令,strict_types指令只影響指定使用的文件,不會影響被它包含(通過include等方式)進來的其他文件。該指令在運行時編譯,不能修改。它的運作方式,是在opcode中設置一個標志位,讓函數(shù)調(diào)用和返回類型檢查符合類型約束。
參數(shù)類型聲明
該指令影響全部的函數(shù)調(diào)用,例如(嚴格校驗模式):
對比(弱校驗模式)
返回類型聲明:
指令會影響同一個文件下的所有函數(shù)的返回類型. 例如(嚴格校驗模式):
弱類型校驗行為:
一個弱類型校驗的函數(shù)調(diào)用,和PHP7之前的PHP版本是一致的(包括拓展和PHP內(nèi)置函數(shù))。通常,弱類型校驗規(guī)則對于新的標量類型聲明的處理是相同的,但是,唯一的例外是對NULL的處理。為了和我們現(xiàn)有類、調(diào)用、數(shù)組的類型聲明保持一致,NULL不是默認的,除非它作為一個參數(shù)并且被顯式賦值為NULL。
為了給不熟悉PHP現(xiàn)有的弱標量參數(shù)類型規(guī)則的讀者,提供簡短的總結。表格展示不同類型能夠接受和轉換的標量類型聲明,NULL、arrays和resource不能接受標量類型聲明,因此不在表格內(nèi)。
*只有范圍在PHP_INT_MIN和PHP_INT_MAX內(nèi)的non-NaN float類型可以接受。(PHP7新增,可查看ZPP Failure on Overflow RFC)
?Non-numeric型字符串不被接受,Numeric型字符串跟隨字符串的,也可以被接受,但是會產(chǎn)生一個notice。?僅當它有__toString方法時可以。
嚴格類型校驗行為:
嚴格的類型校驗調(diào)用拓展或者PHP內(nèi)置函數(shù),會改變zend_parse_parameters的行為。特別注意,失敗的時候,它會產(chǎn)生E_RECOVERABLE_ERROR而不是E_WARNING。它遵循嚴格類型校驗規(guī)則,而不是傳統(tǒng)的弱類型校驗規(guī)則。嚴格類型校驗規(guī)則是非常直接的:只有當類型和指定類型聲明匹配,它才會接受,否則拒絕。
有一個例外的是,寬泛類型轉換是允許int變?yōu)閒loat的,也就是說參數(shù)如果被聲明為float類型,但是它仍然可以接受int參數(shù)。
在這種場景下,我們傳遞一個int參數(shù)給到定義接受float的函數(shù),這個參數(shù)將會被轉換為float。除此之外的轉換,都是不被允許的。
三、例子:讓我們創(chuàng)建一個函數(shù),讓2個數(shù)相加。
add.php
如果在分開的文件,我們可以調(diào)用add函數(shù)通過弱類型的方式
默認情況下,弱類型聲明允許使用轉換,傳遞進去的值會被轉換。
但是,通過可選擇指令declare開啟嚴格類型校驗后,在這個場景下,相同的調(diào)用將會失敗。
指令影響同一個文件下的所有函數(shù)調(diào)用,不管這個被調(diào)函數(shù)是否在這個文件內(nèi)定義的,都會采用嚴格類型校驗模式。
標量類型聲明也可以用于返回值的嚴格類型校驗:
在弱類型模式下,float被轉為integer。
四、背景和理論基礎歷史
PHP從PHP5.0開始已經(jīng)有對支持class和interface參數(shù)類型聲明,PHP5.1支持array以及PHP5.4支持callable。這些類型聲明讓PHP在執(zhí)行的時候傳入正確的參數(shù),讓函數(shù)簽名具有更多的信息。
先前曾經(jīng)想添加標量類型聲明,例如Scalar Type Hints with Casts RFC,因為各種原因失敗了:
(1)類型轉換和校驗機制,對于拓展和PHP內(nèi)置函數(shù)不匹配。
(2)它遵循一個弱類型方法。
(3)它的“嚴格”弱類型修改嘗試,既沒有滿足嚴格類型的粉絲期望,也沒有滿足弱類型的粉絲。
這個RFC嘗試解決全部問題。
弱類型和強類型
在現(xiàn)代編程語言的實際應用中,有三種主要的方法去檢查參數(shù)和返回值的類型:
(1)全嚴格類型檢查(也就是不會有類型轉換發(fā)生)。例如F#、GO、Haskell、Rust和Facebook的Hack的用法。
(2)廣泛原始類型檢查(“安全”的類型轉換會發(fā)生)。例如Java、D和Pascal。他們允許廣泛原始類型轉換(隱式轉換),也就是說,一個8-bit的integer可以根據(jù)函數(shù)參數(shù)需要,被隱形轉換為一個16-bit的integer,而且int也可以被轉換為float的浮點數(shù)。其他類型的隱式轉換則不被允許。
(3)弱類型檢查(允許所有類型轉換,可能會引起警告),它被有限制地使用在C、C#、C++和Visual Basic中。它們嘗試盡可能“不失敗”,完成一次轉換。
PHP在zend_parse_parameters的標量內(nèi)部處理機制是采用了弱類型模式。PHP的對象處理機制采用了廣泛類型檢查方式,并不追求精確匹配和轉換。
每個方法各有其優(yōu)缺點。
這個提案中,默認采用弱類型校驗機制,同時追加一個開關,允許轉換為廣泛類型校驗機制(也就是嚴格類型校驗機制)。
為什么兩者都支持?
目前為止,大部分的標量類型聲明的擁護者都要求同時支持嚴格類型校驗和弱類型校驗,并非僅僅支持其中一種。這份RFC,使得弱類型校驗為默認行為,同時,添加一個可選的指令來使用嚴格類型校驗(同一個文件中)。在這個選擇的背后,有很多個原因。
PHP社區(qū)很大一部分人看起來很喜歡全靜態(tài)類型。但是,添加嚴格類型校驗的標量類型聲明將會引起一些問題:
(1)引起明顯的不一致性:拓展和PHP內(nèi)置函數(shù)對標量類型參數(shù)使用弱類型校驗,但是,用戶的PHP函數(shù)將會使用嚴格類型校驗。
(2)相當一部分人更喜歡弱類型校驗,并不贊同這個提案,他們可能會阻止它的實施。
(3)已經(jīng)存在的代碼使用了PHP的弱類型,它會受到影響。如果要求函數(shù)添加標量類型聲明到參數(shù)上,對于現(xiàn)有的代碼庫,這將大大增加復雜性,特別是對于庫文件。
這里仍然有相當于一部分人是喜歡弱類型校驗的,但是,添加嚴格類型校驗聲明和添加弱類型校驗聲明都會引起一些問題:
(1)大部分傾向于嚴格類型校驗的人將不會喜歡這個提案,然后阻止它的實施。
(2)限制靜態(tài)解析的機會。(可能是說,優(yōu)化的機會)
(3)它會隱藏一些在類型自動轉換中數(shù)據(jù)丟失的bug。
第三種方案被提出來了,就是添加區(qū)分弱類型和嚴格類型聲明的語法。它也會帶來一些問題:
(1)不喜歡弱類型和嚴格類型校驗的人,會被強迫分別處理被定義為嚴格類型或者弱類型校驗的庫。
(2)像添加嚴格聲明一樣,這個也將和原來弱類型實現(xiàn)的拓展和PHP內(nèi)置函數(shù)無法保持一致。
為了解決這三種方案帶來的問題,這個RFC提出了第四種方案:每個文件各自定義嚴格或者弱類型校驗。它帶來了以下好處:
(1)人們可以選擇適合他們的類型校驗,也就是說,這個方案希望同時滿足嚴格和弱類型校驗兩個陣營。
(2)API不會被強制適應某個類型聲明模式。
(3)因為文件默認使用弱類型校驗方案,已經(jīng)存在的代碼庫,可以在不破壞代碼結構的情況下,添加標量類型聲明。也可以讓代碼庫逐步添加類型聲明,或者僅部分模塊添加。
(4)只需要一個單一語法,就可以定義標量類型聲明。
(5)更喜歡嚴格類型校驗的人,通常,不僅將這個特性使用在用戶定義的函數(shù),同時也使用在拓展和PHP內(nèi)置函數(shù)中。也就是說,PHP使用者會得到一個統(tǒng)一機制,而不會產(chǎn)生嚴格標量聲明的矛盾。
(6)在嚴格類型校驗模式下,拓展和PHP內(nèi)置函數(shù)產(chǎn)生的類型校驗失敗的錯誤級別,和用戶自定函數(shù)產(chǎn)生的會保持一致,都是E_RECOVERABLE_ERROR。
(7)它允許嚴格類型和弱類型代碼,在一個單一的代碼庫中無縫集成。
以上就是php的標量數(shù)據(jù)類型,看完之后是否有所收獲呢?如果想了解更多相關內(nèi)容,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊,感謝各位的閱讀。
新聞名稱:php標量數(shù)據(jù)類型有哪些-創(chuàng)新互聯(lián)
鏈接地址:http://weahome.cn/article/cecegc.html