php標(biāo)量數(shù)據(jù)類(lèi)型有哪些-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)php的標(biāo)量數(shù)據(jù)類(lèi)型,文章內(nèi)容質(zhì)量較高,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

成都創(chuàng)新互聯(lián)公司長(zhǎng)期為上千客戶(hù)提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為淶水企業(yè)提供專(zhuān)業(yè)的成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè),淶水網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。一、簡(jiǎn)介

該RFC建議添加4種新的標(biāo)量類(lèi)型聲明:int,float,string和bool,這些類(lèi)型聲明將會(huì)和PHP原來(lái)的機(jī)制保持一致的用法。RFC更推薦給每一個(gè)PHP文件,添加一句新的可選指令(declare(strict_type=1);),讓同一個(gè)PHP文件內(nèi)的全部函數(shù)調(diào)用和語(yǔ)句返回,都有一個(gè)“嚴(yán)格約束”的標(biāo)量類(lèi)型聲明檢查。此外,在開(kāi)啟嚴(yán)格類(lèi)型約束后,調(diào)用拓展或者PHP內(nèi)置函數(shù)在參數(shù)解析失敗,將產(chǎn)生一個(gè)E_RECOVERABLE_ERROR級(jí)錯(cuò)誤。通過(guò)這兩個(gè)特性,RFC希望編寫(xiě)PHP能夠變得更準(zhǔn)確和文檔化。

二、細(xì)節(jié)

標(biāo)量類(lèi)型聲明:

沒(méi)有添加新的保留字。int、float、string和bool會(huì)被識(shí)別為類(lèi)型聲明,同時(shí)禁止用作class/interface/trait等的命名。新的用戶(hù)標(biāo)量類(lèi)型聲明,通過(guò)內(nèi)部的Fast Parameter Parsing API實(shí)現(xiàn)。

strict_types/declare()指令

默認(rèn)情況下,所有的PHP文件都處于弱類(lèi)型校驗(yàn)?zāi)J健P碌膁eclare指令,通過(guò)指定strict_types的值(1或者0),1表示嚴(yán)格類(lèi)型校驗(yàn)?zāi)J?,作用于函?shù)調(diào)用和返回語(yǔ)句;0表示弱類(lèi)型校驗(yàn)?zāi)J健?/p>

declare(strict_types=1)必須是文件的第一個(gè)語(yǔ)句。如果這個(gè)語(yǔ)句出現(xiàn)在文件的其他地方,將會(huì)產(chǎn)生一個(gè)編譯錯(cuò)誤,塊模式是被明確禁止的。

類(lèi)似于encoding指令,但不同于ticks指令,strict_types指令只影響指定使用的文件,不會(huì)影響被它包含(通過(guò)include等方式)進(jìn)來(lái)的其他文件。該指令在運(yùn)行時(shí)編譯,不能修改。它的運(yùn)作方式,是在opcode中設(shè)置一個(gè)標(biāo)志位,讓函數(shù)調(diào)用和返回類(lèi)型檢查符合類(lèi)型約束。

參數(shù)類(lèi)型聲明

該指令影響全部的函數(shù)調(diào)用,例如(嚴(yán)格校驗(yàn)?zāi)J剑?/p>

<?php
declare(strict_types=1);
 
foo(); // strictly type-checked function call
 
function foobar() {
    foo(); // strictly type-checked function call
}
 
class baz {
    function foobar() {
        foo(); // strictly type-checked function call
    }
}

對(duì)比(弱校驗(yàn)?zāi)J剑?/p>

<?php
foo(); // weakly type-checked function call
 
function foobar() {
    foo(); // weakly type-checked function call
}
 
class baz {
    function foobar() {
        foo(); // weakly type-checked function call
    }
}

返回類(lèi)型聲明:

指令會(huì)影響同一個(gè)文件下的所有函數(shù)的返回類(lèi)型. 例如(嚴(yán)格校驗(yàn)?zāi)J剑?

<?php
declare(strict_types=1);
 
function foobar(): int {
    return 1.0; // strictly type-checked return
}
 
class baz {
    function foobar(): int {
        return 1.0; // strictly type-checked return
    }
}
<?php
 
function foobar(): int {
    return 1.0; // weakly type-checked return
}
 
class baz {
    function foobar(): int {
        return 1.0; // weakly type-checked return
    }
}

弱類(lèi)型校驗(yàn)行為:

一個(gè)弱類(lèi)型校驗(yàn)的函數(shù)調(diào)用,和PHP7之前的PHP版本是一致的(包括拓展和PHP內(nèi)置函數(shù))。通常,弱類(lèi)型校驗(yàn)規(guī)則對(duì)于新的標(biāo)量類(lèi)型聲明的處理是相同的,但是,唯一的例外是對(duì)NULL的處理。為了和我們現(xiàn)有類(lèi)、調(diào)用、數(shù)組的類(lèi)型聲明保持一致,NULL不是默認(rèn)的,除非它作為一個(gè)參數(shù)并且被顯式賦值為NULL。

為了給不熟悉PHP現(xiàn)有的弱標(biāo)量參數(shù)類(lèi)型規(guī)則的讀者,提供簡(jiǎn)短的總結(jié)。表格展示不同類(lèi)型能夠接受和轉(zhuǎn)換的標(biāo)量類(lèi)型聲明,NULL、arrays和resource不能接受標(biāo)量類(lèi)型聲明,因此不在表格內(nèi)。

*只有范圍在PHP_INT_MIN和PHP_INT_MAX內(nèi)的non-NaN float類(lèi)型可以接受。(PHP7新增,可查看ZPP Failure on Overflow RFC)
?Non-numeric型字符串不被接受,Numeric型字符串跟隨字符串的,也可以被接受,但是會(huì)產(chǎn)生一個(gè)notice。

?僅當(dāng)它有__toString方法時(shí)可以。

嚴(yán)格類(lèi)型校驗(yàn)行為:

嚴(yán)格的類(lèi)型校驗(yàn)調(diào)用拓展或者PHP內(nèi)置函數(shù),會(huì)改變zend_parse_parameters的行為。特別注意,失敗的時(shí)候,它會(huì)產(chǎn)生E_RECOVERABLE_ERROR而不是E_WARNING。它遵循嚴(yán)格類(lèi)型校驗(yàn)規(guī)則,而不是傳統(tǒng)的弱類(lèi)型校驗(yàn)規(guī)則。嚴(yán)格類(lèi)型校驗(yàn)規(guī)則是非常直接的:只有當(dāng)類(lèi)型和指定類(lèi)型聲明匹配,它才會(huì)接受,否則拒絕。

有一個(gè)例外的是,寬泛類(lèi)型轉(zhuǎn)換是允許int變?yōu)閒loat的,也就是說(shuō)參數(shù)如果被聲明為float類(lèi)型,但是它仍然可以接受int參數(shù)。

<?php
declare(strict_types=1);
 
function add(float $a, float $b): float {
    return $a + $b;
}
 
add(1, 2); // float(3)

在這種場(chǎng)景下,我們傳遞一個(gè)int參數(shù)給到定義接受float的函數(shù),這個(gè)參數(shù)將會(huì)被轉(zhuǎn)換為float。除此之外的轉(zhuǎn)換,都是不被允許的。

三、例子:

讓我們創(chuàng)建一個(gè)函數(shù),讓2個(gè)數(shù)相加。

add.php

<?php
function add(int $a, int $b): int {
    return $a + $b;
}

如果在分開(kāi)的文件,我們可以調(diào)用add函數(shù)通過(guò)弱類(lèi)型的方式

<?php
require "add.php";
 
var_dump(add(1, 2)); // int(3)
// floats are truncated by default
var_dump(add(1.5, 2.5)); // int(3)
 
//strings convert if there's a number part
var_dump(add("1", "2")); // int(3)

默認(rèn)情況下,弱類(lèi)型聲明允許使用轉(zhuǎn)換,傳遞進(jìn)去的值會(huì)被轉(zhuǎn)換。

<?php
require "add.php";
 
var_dump(add("1 foo", "2")); // int(3)
// Notice: A non well formed numeric value encountered

但是,通過(guò)可選擇指令declare開(kāi)啟嚴(yán)格類(lèi)型校驗(yàn)后,在這個(gè)場(chǎng)景下,相同的調(diào)用將會(huì)失敗。

<?php
declare(strict_types=1);
 
require "add.php";
 
var_dump(add(1, 2)); // int(3)
 
var_dump(add(1.5, 2.5)); // int(3)
// Catchable fatal error: Argument 1 passed to add() must be of the type integer, float given

指令影響同一個(gè)文件下的所有函數(shù)調(diào)用,不管這個(gè)被調(diào)函數(shù)是否在這個(gè)文件內(nèi)定義的,都會(huì)采用嚴(yán)格類(lèi)型校驗(yàn)?zāi)J健?/p>

<?php
declare(strict_types=1);
 
$foo = substr(52, 1);
// Catchable fatal error: substr() expects parameter 1 to be string, integer given

標(biāo)量類(lèi)型聲明也可以用于返回值的嚴(yán)格類(lèi)型校驗(yàn):

<?php
 
function foobar(): int {
    return 1.0;
}
 
var_dump(foobar()); // int(1)

在弱類(lèi)型模式下,float被轉(zhuǎn)為integer。

<?php
declare(strict_types=1);
 
function foobar(): int {
    return 1.0;
}
 
var_dump(foobar());
// Catchable fatal error: Return value of foobar() must be of the type integer, float returned
四、背景和理論基礎(chǔ)

歷史

PHP從PHP5.0開(kāi)始已經(jīng)有對(duì)支持class和interface參數(shù)類(lèi)型聲明,PHP5.1支持array以及PHP5.4支持callable。這些類(lèi)型聲明讓PHP在執(zhí)行的時(shí)候傳入正確的參數(shù),讓函數(shù)簽名具有更多的信息。

先前曾經(jīng)想添加標(biāo)量類(lèi)型聲明,例如Scalar Type Hints with Casts RFC,因?yàn)楦鞣N原因失敗了:

(1)類(lèi)型轉(zhuǎn)換和校驗(yàn)機(jī)制,對(duì)于拓展和PHP內(nèi)置函數(shù)不匹配。

(2)它遵循一個(gè)弱類(lèi)型方法。

(3)它的“嚴(yán)格”弱類(lèi)型修改嘗試,既沒(méi)有滿(mǎn)足嚴(yán)格類(lèi)型的粉絲期望,也沒(méi)有滿(mǎn)足弱類(lèi)型的粉絲。

這個(gè)RFC嘗試解決全部問(wèn)題。

弱類(lèi)型和強(qiáng)類(lèi)型

在現(xiàn)代編程語(yǔ)言的實(shí)際應(yīng)用中,有三種主要的方法去檢查參數(shù)和返回值的類(lèi)型:

(1)全嚴(yán)格類(lèi)型檢查(也就是不會(huì)有類(lèi)型轉(zhuǎn)換發(fā)生)。例如F#、GO、Haskell、Rust和Facebook的Hack的用法。

(2)廣泛原始類(lèi)型檢查(“安全”的類(lèi)型轉(zhuǎn)換會(huì)發(fā)生)。例如Java、D和Pascal。他們?cè)试S廣泛原始類(lèi)型轉(zhuǎn)換(隱式轉(zhuǎn)換),也就是說(shuō),一個(gè)8-bit的integer可以根據(jù)函數(shù)參數(shù)需要,被隱形轉(zhuǎn)換為一個(gè)16-bit的integer,而且int也可以被轉(zhuǎn)換為float的浮點(diǎn)數(shù)。其他類(lèi)型的隱式轉(zhuǎn)換則不被允許。

(3)弱類(lèi)型檢查(允許所有類(lèi)型轉(zhuǎn)換,可能會(huì)引起警告),它被有限制地使用在C、C#、C++和Visual Basic中。它們嘗試盡可能“不失敗”,完成一次轉(zhuǎn)換。

PHP在zend_parse_parameters的標(biāo)量?jī)?nèi)部處理機(jī)制是采用了弱類(lèi)型模式。PHP的對(duì)象處理機(jī)制采用了廣泛類(lèi)型檢查方式,并不追求精確匹配和轉(zhuǎn)換。

每個(gè)方法各有其優(yōu)缺點(diǎn)。

這個(gè)提案中,默認(rèn)采用弱類(lèi)型校驗(yàn)機(jī)制,同時(shí)追加一個(gè)開(kāi)關(guān),允許轉(zhuǎn)換為廣泛類(lèi)型校驗(yàn)機(jī)制(也就是嚴(yán)格類(lèi)型校驗(yàn)機(jī)制)。

為什么兩者都支持?

目前為止,大部分的標(biāo)量類(lèi)型聲明的擁護(hù)者都要求同時(shí)支持嚴(yán)格類(lèi)型校驗(yàn)和弱類(lèi)型校驗(yàn),并非僅僅支持其中一種。這份RFC,使得弱類(lèi)型校驗(yàn)為默認(rèn)行為,同時(shí),添加一個(gè)可選的指令來(lái)使用嚴(yán)格類(lèi)型校驗(yàn)(同一個(gè)文件中)。在這個(gè)選擇的背后,有很多個(gè)原因。

PHP社區(qū)很大一部分人看起來(lái)很喜歡全靜態(tài)類(lèi)型。但是,添加嚴(yán)格類(lèi)型校驗(yàn)的標(biāo)量類(lèi)型聲明將會(huì)引起一些問(wèn)題:

(1)引起明顯的不一致性:拓展和PHP內(nèi)置函數(shù)對(duì)標(biāo)量類(lèi)型參數(shù)使用弱類(lèi)型校驗(yàn),但是,用戶(hù)的PHP函數(shù)將會(huì)使用嚴(yán)格類(lèi)型校驗(yàn)。

(2)相當(dāng)一部分人更喜歡弱類(lèi)型校驗(yàn),并不贊同這個(gè)提案,他們可能會(huì)阻止它的實(shí)施。

(3)已經(jīng)存在的代碼使用了PHP的弱類(lèi)型,它會(huì)受到影響。如果要求函數(shù)添加標(biāo)量類(lèi)型聲明到參數(shù)上,對(duì)于現(xiàn)有的代碼庫(kù),這將大大增加復(fù)雜性,特別是對(duì)于庫(kù)文件。

這里仍然有相當(dāng)于一部分人是喜歡弱類(lèi)型校驗(yàn)的,但是,添加嚴(yán)格類(lèi)型校驗(yàn)聲明和添加弱類(lèi)型校驗(yàn)聲明都會(huì)引起一些問(wèn)題:

(1)大部分傾向于嚴(yán)格類(lèi)型校驗(yàn)的人將不會(huì)喜歡這個(gè)提案,然后阻止它的實(shí)施。

(2)限制靜態(tài)解析的機(jī)會(huì)。(可能是說(shuō),優(yōu)化的機(jī)會(huì))

(3)它會(huì)隱藏一些在類(lèi)型自動(dòng)轉(zhuǎn)換中數(shù)據(jù)丟失的bug。

第三種方案被提出來(lái)了,就是添加區(qū)分弱類(lèi)型和嚴(yán)格類(lèi)型聲明的語(yǔ)法。它也會(huì)帶來(lái)一些問(wèn)題:

(1)不喜歡弱類(lèi)型和嚴(yán)格類(lèi)型校驗(yàn)的人,會(huì)被強(qiáng)迫分別處理被定義為嚴(yán)格類(lèi)型或者弱類(lèi)型校驗(yàn)的庫(kù)。

(2)像添加嚴(yán)格聲明一樣,這個(gè)也將和原來(lái)弱類(lèi)型實(shí)現(xiàn)的拓展和PHP內(nèi)置函數(shù)無(wú)法保持一致。

為了解決這三種方案帶來(lái)的問(wèn)題,這個(gè)RFC提出了第四種方案:每個(gè)文件各自定義嚴(yán)格或者弱類(lèi)型校驗(yàn)。它帶來(lái)了以下好處:

(1)人們可以選擇適合他們的類(lèi)型校驗(yàn),也就是說(shuō),這個(gè)方案希望同時(shí)滿(mǎn)足嚴(yán)格和弱類(lèi)型校驗(yàn)兩個(gè)陣營(yíng)。

(2)API不會(huì)被強(qiáng)制適應(yīng)某個(gè)類(lèi)型聲明模式。

(3)因?yàn)槲募J(rèn)使用弱類(lèi)型校驗(yàn)方案,已經(jīng)存在的代碼庫(kù),可以在不破壞代碼結(jié)構(gòu)的情況下,添加標(biāo)量類(lèi)型聲明。也可以讓代碼庫(kù)逐步添加類(lèi)型聲明,或者僅部分模塊添加。

(4)只需要一個(gè)單一語(yǔ)法,就可以定義標(biāo)量類(lèi)型聲明。

(5)更喜歡嚴(yán)格類(lèi)型校驗(yàn)的人,通常,不僅將這個(gè)特性使用在用戶(hù)定義的函數(shù),同時(shí)也使用在拓展和PHP內(nèi)置函數(shù)中。也就是說(shuō),PHP使用者會(huì)得到一個(gè)統(tǒng)一機(jī)制,而不會(huì)產(chǎn)生嚴(yán)格標(biāo)量聲明的矛盾。

(6)在嚴(yán)格類(lèi)型校驗(yàn)?zāi)J较?,拓展和PHP內(nèi)置函數(shù)產(chǎn)生的類(lèi)型校驗(yàn)失敗的錯(cuò)誤級(jí)別,和用戶(hù)自定函數(shù)產(chǎn)生的會(huì)保持一致,都是E_RECOVERABLE_ERROR。

(7)它允許嚴(yán)格類(lèi)型和弱類(lèi)型代碼,在一個(gè)單一的代碼庫(kù)中無(wú)縫集成。

以上就是php的標(biāo)量數(shù)據(jù)類(lèi)型,看完之后是否有所收獲呢?如果想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊,感謝各位的閱讀。

當(dāng)前標(biāo)題:php標(biāo)量數(shù)據(jù)類(lèi)型有哪些-創(chuàng)新互聯(lián)
標(biāo)題網(wǎng)址:http://bm7419.com/article12/cecegc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、網(wǎng)站設(shè)計(jì)公司、企業(yè)網(wǎng)站制作、App設(shè)計(jì)、關(guān)鍵詞優(yōu)化、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)