型別 - PHP手冊筆記

weixin_33858249發表於2015-06-19
原文:型別 - PHP手冊筆記

型別簡介

PHP 支援 8 種原始資料型別。

  • 四種標量型別:

    • boolean(布林型,不區分大小寫)
    • integer(整型)
    • float(浮點型,也稱作double)
    • string(字串)
  • 兩種複合型別:

    • array(陣列)
    • object(物件)
  • 最後是兩種特殊型別:

    • resource(資源)
    • NULL(無型別)

如果想檢視某個表示式的值和型別,用var_dump()函式。

<?php 
$a = array(1, 2, array("a", "b", "c"));
var_dump($a);

$b = 3.1;
$c = true;
var_dump($b, $c);

上面的程式碼通過var_dump()列印變數的相關資訊,輸出結果如下所示(PHP版本5.5.12)。

array (size=3)
  0 => int 1
  1 => int 2
  2 => 
    array (size=3)
      0 => string 'a' (length=1)
      1 => string 'b' (length=1)
      2 => string 'c' (length=1)

float 3.1

boolean true

如果只是想得到一個易讀懂的型別的表達方式用於除錯,用gettype()函式。要檢視某個型別,不要用gettype(),而用is_type函式。使用is_type可以對引數進行過濾。

如果要將一個變數強制轉換為某型別,可以對其使用強制轉換或者settype()函式。注意變數根據其當時的型別在特定場合下會表現出不同的值。

boolean布林型別

特別注意,當轉換為boolean時,以下值被認為是FALSE:

  • 空字串,以及字串 "0"
  • 不包括任何元素的陣列

只要是物件,返回值均為TRUE。

下面這段程式能加深對boolean型別轉換的理解。

<?php 
var_dump((bool) array());  // boolean false
var_dump((bool) "");  // boolean false
var_dump((bool) "0");  // boolean false
var_dump((bool) "00");  // boolean true
var_dump((bool) "false");  // boolean true
var_dump((bool) (new stdClass()));  // boolean true
var_dump((bool) ((object) array()));  // boolean true

integer整型

要使用八進位制表達,數字前必須加上0(零)。
要使用十六進位制表達,數字前必須加上0x。
要使用二進位制表達,數字前必須加上0b。
二進位制表達的integer自PHP 5.4.0起可用。

integer值的字長可以用常量PHP_INT_SIZE來表示,最大值可以用常量PHP_INT_MAX來表示。

<?php 
var_dump(PHP_INT_SIZE);  // int 4
var_dump(PHP_INT_MAX);  // int 2147483647
var_dump(01090);  // int 8  八進位制 010 = 十進位制 8

上面程式最後一條語句,處理八進位制時發生一件怪事。那是因為,如果向八進位制數傳遞了一個非法數字(即8或9),則後面其餘數字會被忽略。

如果給定的一個數超出了integer的範圍,將會被解釋為float。同樣如果執行的運算結果超出了integer範圍,也會返回float。

PHP中沒有整除的運算子。1/2產生出float 0.5。值可以捨棄小數部分強制轉換為integer,或者使用round()函式可以更好地進行四捨五入。

手冊中說,決不要將未知的分數強制轉換為integer,這樣有時會導致不可預料的結果。

<?php 
echo (int)((0.1 + 0.7) * 10);

這段程式的輸出結果為7,永遠不要相信浮點數!

float浮點型

某些數學運算會產生一個由常量NAN所代表的結果。此結果代表著一個在浮點數運算中未定義或不可表述的值。任何拿此值與其它任何值進行的鬆散或嚴格比較的結果都是FALSE。

string字串

一個字串string就是由一系列的字元組成,其中每個字元等同於一個位元組。實現方式是一個由位元組組成的陣列再加上一個整數指明緩衝區長度。這意味著PHP只能支援256的字符集,因此不支援Unicode。那中文是怎樣顯示的呢?先把疑問記錄下來。

字串有4中語法表達方式:

  • 單引號
  • 雙引號
  • heredoc
  • nowdoc

單引號

要表達一個單引號自身,需在它的前面加個反斜線(\)來轉義。
要表達一個反斜線自身,則用兩個反斜線(\)。
其它任何方式的反斜線都會被當成反斜線本身。

但是,如果單引號包裹的字串中只有一個反斜線,反斜線也會輸出,這是為什麼呢?

雙引號

可以對轉義字元進行解析,最重要的特徵是變數會被解析。

單引號、雙引號都支援字串多行錄入。

heredoc結構

這種結構在以往的程式設計中使用的較少,這裡詳細學習一下。

結構大致如下:
運算子<<<之後提供識別符號,然後換行。
接下來是字串本身。
最後用前面定義的識別符號作為結束標誌。

結束時所引用的識別符號必須在該行的第一列,這意味著識別符號不能縮排,這行除了可能有一個分號(;)外,絕對不能包含其它字元。

Heredocs結構不能用來初始化類的屬性。自PHP 5.3起,此限制僅對heredoc包含變數時有效。

Heredoc 結構就象是沒有使用雙引號的雙引號字串,轉義規則同雙引號。

nowdoc結構

nowdoc結構與heredoc相似,只是跟在運算子<<<後面的識別符號要用單引號括起來。

就象heredoc結構類似於雙引號字串,nowdoc結構是類似於單引號字串的。nowdoc中不進行解析操作。這種結構很適合用於嵌入PHP程式碼或其它大段文字而無需對其中的特殊字元進行轉義。nowdoc結構可以用在任意的靜態資料環境中,最典型的示例是用來初始化類的屬性或常量。

變數解析

變數解析有兩種語法規則,一種是簡單規則,一種是複雜規則。簡單規則最常用、最方便,這裡詳細學習一下複雜語法規則。複雜規則語法的顯著標記是用花括號包圍的表示式。

複雜語法不是因為其語法複雜而得名,而是因為它可以使用複雜的表示式。 由於{無法被轉義,只有$緊挨著{時才會被識別。

存取和修改

可以以陣列形式訪問字串,用超出字串長度的下標寫入將會拉長該字串並以空格填充。非整數型別下標會被轉換成整數。寫入時只用到了賦值字串的第一個字元。用空字串賦值則賦給的值是NULL字元。PHP的字串在內部是位元組組成的陣列。因此用花括號訪問或修改字串對多位元組字符集很不安全。

字串可以用 '.'(點)運算子連線起來,注意 '+'(加號)運算子沒有這個功能。

一個布林值boolean的TRUE被轉換成string的"1"。boolean的FALSE被轉換成""(空字串)。字串轉換為數值,該字串的開始部分決定了它的值。如果該字串以合法的數值開始,則使用該數值。否則其值為 0(零)。

PHP的優勢就體現在字串處理的方便上,對於string的操作有很多有用的函式,可以運用各種函式,還有正規表示式。

PHP 並不特別指明字串的編碼,字串會被按照該指令碼檔案相同的編碼方式來編碼。因此,操作文字的函式必須假定字串是如何編碼的。不幸的是,PHP關於此的函式有很多變種,關於PHP的字串處理函式還需多加學習。

array陣列

PHP中的陣列實際上是一個有序對映,對映是一種把values關聯到keys的型別。

可以用array()語言結構來新建一個陣列。它接受任意數量用逗號分隔的“鍵(key)=>值(value)對”。自5.4起可以使用短陣列定義語法,用[]替代array()。key可以是integer或者string,value可以是任意型別。

key會有如下的強制轉換和規則:

  • 包含有合法整型值的字串會被轉換為整型。
  • 浮點數也會被轉換為整型,意味著其小數部分會被捨去。
  • 布林值也會被轉換成整型。
  • null會被轉換為空字串,即鍵名null實際會被儲存為""。
  • 陣列和物件不能被用為鍵名。
  • 如果在陣列定義中多個單元都使用了同一個鍵名,則只使用了最後一個,之前的都被覆蓋了。
  • 如果對給出的值沒有指定鍵名,則取當前最大的整數索引值,而新的鍵名將是該值加一。
<?php 
$a = array('20' => 'a', '02' => 'b');
var_dump($a);

通過上面的規則可知,這段程式碼的輸出結果如下:

array (size=2)
  20 => string 'a' (length=1)
  '02' => string 'b' (length=1)

如果給出方括號但沒有指定鍵名,則取當前最大整數索引值,新的鍵名將是該值加上1(但是最小為0)。要刪除某鍵值對,對其呼叫unset()函式,該函式允許刪除陣列中的某個鍵,但要注意陣列將不會重建索引。

<?php 
$a = array('a', 'b' => 'b');
$a[] = 'c';
var_dump($a);
unset($a[1]);
var_dump($a);

對於上面這段程式,輸出為:

array (size=3)
  0 => string 'a' (length=1)
  'b' => string 'b' (length=1)
  1 => string 'c' (length=1)

array (size=2)
  0 => string 'a' (length=1)
  'b' => string 'b' (length=1)

應該始終在用字串表示的陣列索引上加上引號。例如用$foo['bar']而不是$foo[bar]。此程式碼中有一個未定義的常量(bar)而不是字串('bar'-注意引號),而 PHP 可能會在以後定義此常量。

foreach控制結構是專門用於陣列的。它提供了一個簡單的方法來遍歷陣列。

下面的示例程式,通過讀取目錄填充陣列,這裡涉及到幾個函式的使用。

<?php 
$handle = opendir('.');
while(false !== ($file = readdir($handle))) {
	$files[] = $file;
}
closedir($handle);
var_dump($files);

對於任意integer,float,string,boolean和resource型別,如果將一個值轉換為陣列,將得到一個僅有一個元素的陣列,其下標為 0,該元素即為此標量的值。

object物件

要建立一個新的物件 object,使用 new 語句例項化一個類。

如果將一個物件轉換成物件,它將不會有任何變化。如果其它任何型別的值被轉換成物件,將會建立一個內建類 stdClass 的例項。如果該值為 NULL,則新的例項為空。陣列轉換成物件將使鍵名成為屬性名並具有相對應的值。對於任何其它的值,名為 scalar 的成員變數將包含該值。

<?php 
class foo {
	function do_foo() {
		echo 'Doint foo.';
	}
}
$bar = new foo;
$bar->do_foo();
var_dump($bar);

$obj = (object) 'hello';
var_dump($obj);

上面的示例程式輸出結果為:

Doint foo.object(foo)[1]

object(stdClass)[2]
  public 'scalar' => string 'hello' (length=5)

resource資源型別

資源resource是一種特殊變數,儲存了到外部資源的一個引用。資源使用的所有外部資源都會被垃圾回收系統釋放,很少需要手工釋放記憶體。但是,持久資料庫連線比較特殊,它們不會被垃圾回收系統銷燬。

NULL

NULL型別只有一個值,就是不區分大小寫的常量NULL。

callback回撥型別

第一次接觸到這個概念,有點陌生。

自PHP 5.4起可用callable型別指定回撥型別callback。

手冊示例程式中使用了很多call_user_func函式,先把這函式理一下。call_user_func第一個引數作為回撥函式(callback),並且將其餘的引數作為回撥函式的引數。返回回撥函式的返回值,如果錯誤則返回FALSE。

回撥函式可以是簡單函式、物件方法、靜態類方法,回撥函式的幾種使用方法如下所示:

  1. 呼叫使用者自定義的簡單函式,以string型別傳遞其名稱。
<?php 
function my_callback_function() {
	echo 'hello, world.';
}
call_user_func('my_callback_function');
  1. 呼叫類的靜態成員方法,類及方法被作為陣列傳遞,下標0包含該物件,下標1包含方法名。
<?php 
class MyClass {
	static function myCallbackMethod() {
		echo 'Hello, world.';
	}
}
call_user_func(array('MyClass', 'myCallbackMethod'));
  1. 呼叫已例項化的物件方法。
<?php 
class MyClass {
	static function myCallbackMethod() {
		echo 'Hello, world.';
	}
}
$obj = new MyClass;
call_user_func(array($obj, 'myCallbackMethod'));
  1. 呼叫靜態類方法。
<?php 
class MyClass {
	static function myCallbackMethod() {
		echo 'Hello, world.';
	}
}
call_user_func('MyClass::myCallbackMethod');
  1. 呼叫父類靜態成員方法。
<?php 
class A {
	public static function who() {
		echo "A\n";
	}
}
class B extends A {
	public static function who() {
		echo "B\n";
	}
}
call_user_func(array('B', 'parent::who'));

除了普通的使用者自定義函式外,create_function()可以用來建立一個匿名回撥函式。

型別轉換

PHP是弱型別語言,變數型別根據使用該變數的上下文所決定的。

(全文完)

相關文章