php易錯筆記-類型

Boolean

當轉換爲 boolean 時,如下值被認爲是 FALSE:
布爾值 FALSE 自己
整型值 0(零)
浮點型值 0.0(零)
空字符串'',以及字符串 "0"
不包括任何元素的數組[]
特殊類型 NULL(包括還沒有賦值的變量)
空標記生成的 SimpleXML 對象php

全部其它值都被認爲是 TRUE(包括任何資源 和 NAN)。正則表達式

<?php
// Consider that the 0 could by any parameters including itself
var_dump(0 == 1); // false
var_dump(0 == (bool)'all'); // false
var_dump(0 == 'all'); // TRUE, take care
var_dump(0 === 'all'); // false

// To avoid this behavior, you need to cast your parameter as string like that :
var_dump((string)0 == 'all'); // false
?>

整數

<?php
$a = 1234; // 十進制數
$a = -123; // 負數
$a = 0123; // 八進制數 (等於十進制 83)
$a = 0x1A; // 十六進制數 (等於十進制 26)
$a = 0b11111111; // 二進制數字 (等於十進制 255)//php5.4開始
?>

注意類型轉換:api

<?php 
//當從浮點數轉換成整數時,將向下取整。
$w = (int)1.7;// 1
//字符串轉換
$x = 0123;// 83
$y = "0123" + 0;// 123
$z = '0x12' + 0;//0
$aa = '0b101' + 0;//0
$bb = (int)'0123';//123
$cc = (int)'0x123';//0
$dd = (int)'0b1011';//0
 ?>
若是給定的一個數超出了 integer 的範圍,將會被解釋爲 float。一樣若是執行的運算結果超出了 integer 範圍,也會返回 float。

Example #2 32 位系統下的整數溢出數組

<?php
$large_number = 2147483647;
var_dump($large_number);                     // int(2147483647)

$large_number = 2147483648;
var_dump($large_number);                     // float(2147483648)

$million = 1000000;
$large_number =  50000 * $million;
var_dump($large_number);                     // float(50000000000)
?>

Example #3 64 位系統下的整數溢出安全

<?php
$large_number = 9223372036854775807;
var_dump($large_number);                     // int(9223372036854775807)

$large_number = 9223372036854775808;
var_dump($large_number);                     // float(9.2233720368548E+18)

$million = 1000000;
$large_number =  50000000000000 * $million;
var_dump($large_number);                     // float(5.0E+19)
?>

浮點型

(也叫浮點數 float,雙精度數 double 或實數 real)能夠用如下任一語法定義:app

<?php
$a = 1.234; 
$b = 1.2e3; 
$c = 7E-10;
?>
浮點數的精度有限。
floor((0.1+0.7)*10) 一般會返回 7 而不是預期中的 8,由於該結果內部的表示實際上是相似
7.9999999999999991118...。
因此永遠不要相信浮點數結果精確到了最後一位,也永遠不要比較兩個浮點數是否相等

$a 和 $b 在小數點後五位精度內都是相等的。ide

<?php
$a = 8 - 6.4;  // which is equal to 1.6
$b = 1.6;
var_dump($a == $b); // is not true
//This happens probably because $a is not really 1.6, but 1.599999..

$epsilon = 0.00001;    
if(abs($a-$b) < $epsilon) {
    echo "true";
}
?>

字符串

單引號

只轉義\函數

<?php
// 輸出: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';

// 輸出: You deleted C:\*.*?
echo 'You deleted C:\\*.*?';
?>

雙引號

正則用雙引號優化

\n    換行(ASCII 字符集中的 LF 或 0x0A (10))
\r    回車(ASCII 字符集中的 CR 或 0x0D (13))
\t    水平製表符(ASCII 字符集中的 HT 或 0x09 (9))
\v    垂直製表符(ASCII 字符集中的 VT 或 0x0B (11))(自 PHP 5.2.5 起)
\e    Escape(ASCII 字符集中的 ESC 或 0x1B (27))(自 PHP 5.4.0 起)
\f    換頁(ASCII 字符集中的 FF 或 0x0C (12))(自 PHP 5.2.5 起)
\\    反斜線
\$    美圓標記
\"    雙引號\\"
\[0-7]{1,3}    符合該正則表達式序列的是一個以八進制方式來表達的字符
\x[0-9A-Fa-f]{1,2}    符合該正則表達式序列的是一個以十六進制方式來表達的字符

雙引號示例:this

<?php
$great = 'fantastic';
//輸出: This is {$great}
echo "This is {\$great}";
// 無效,輸出: This is { fantastic}
echo "This is { $great}";

// 有效,輸出: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
echo "This is the value of the var named $name: {${$name}}";
echo "This is the value of the var named by the return value of getName(): {${getName()}}";
echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";

// 有效,輸出: I'd like an A & W
echo "I'd like an {${beers::softdrink}}\n";

// 也有效,輸出: I'd like an Alexander Keith's
echo "I'd like an {${beers::$ale}}\n";
?>

Heredoc 結構

沒有使用雙引號的雙引號字符串

Warning
要注意的是結束標識符這行除了可能有一個分號(;)外,絕對不能包含其它字符。這意味着 標識符不能縮進,分號的先後也不能有任何空白或製表符。更重要的是結束標識符的前面必須是個被本地 操做系統承認的換行,好比在 UNIX 和 Mac OS X 系統中是 n,而結束定界符(可能其後有個分號)以後也必須緊跟一個換行。

若是不遵照該規則致使結束標識不「乾淨」,PHP 將認爲它不是結束標識符而繼續尋找。若是在文件結束前也沒有找到一個正確的結束標識符,PHP 將會在最後一行產生一個解析錯誤。

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

<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;

This does not:
foo(<<<END
abcd
END;
);
// syntax error, unexpected ';'

//Without semicolon, it works fine:
foo(<<<END
abcd
END
);
?>

Nowdoc 結構

單引號字符串

<?php
//不能使用hereDoc
class foo {
    public $bar = <<<'EOT'
bar
EOT;
}
?>

存取和修改

超出字符串長度的下標寫入將會拉長該字符串並以空格填充。 非整數類型下標會被轉換成整數。 非法下標類型會產生一個 E_NOTICE 級別錯誤。用 負數下標寫入字符串時會產生一個 E_NOTICE
級別錯誤,用 負數下標讀取字符串時返回空字符串。寫入時只用到了賦值字符串的第一個字符。用 空字符串賦值則賦給的值是 NULL 字符。

PHP 的字符串在內部是字節組成的數組。所以用花括號訪問或修改字符串對多字節字符集很不安全。僅應對單字節編碼例如 ISO-8859-1 的字符串進行此類操做。

<?php
// 取得字符串的第一個字符
$str = 'This is a test.';
$first = $str[0];
$first = $str{2};
//錯誤Fatal Error:Cannot create references to/from string offsets nor overloaded objects
$first = &$str[0];

// 取得字符串的最後一個字符
$str = 'This is still a test.';
$last = $str[strlen($str)-1]; 

// 修改字符串的最後一個字符
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';

?>
Note:
自 PHP 5.4 起字符串下標必須爲 整數或可轉換爲整數的字符串,不然會發出警告。以前例如 "foo" 的下標會無聲地轉換成 0。
PHP 5.5 增長了直接在字符串原型中用 [] 或 {} 訪問字符的支持。

轉換

1.一個值能夠經過在其前面加上 (string) 或用 strval() 函數來轉變成字符串
2.一個布爾值 boolean 的 TRUE 被轉換成 string 的 "1"。Boolean 的 FALSE 被轉換成 ""(空字符串)
3.數組 array 老是轉換成字符串 "Array"
4.在 PHP 4 中對象 object 老是被轉換成字符串 "Object",PHP 5 起,適當時能夠用 __toString 方法。
5.資源 resource 總會被轉變成 "Resource id #1" 這種結構的字符串,其中的 1 是 PHP 在運行時分配給該 resource 的惟一值
6.NULL 老是被轉變成空字符串

字符串的開始部分決定了它的值。若是該字符串以合法的數值開始,則使用該數值。不然其值爲 0(零)。
<?php
$foo = 1 + "10.5";                // $foo is float (11.5)
$foo = 1 + "-1.3e3";              // $foo is float (-1299)
$foo = 1 + "bob-1.3e3";           // $foo is integer (1)
$foo = 1 + "bob3";                // $foo is integer (1)
$foo = 1 + "10 Small Pigs";       // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1;          // $foo is float (11)
$foo = "10.0 pigs " + 1.0;        // $foo is float (11)     
?>

數組

PHP 中的數組其實是一個有序映射。映射是一種把 values 關聯到 keys 的類型。此類型在不少方面作了優化,所以能夠把它當成真正的數組,或列表(向量),散列表(是映射的一種實現),字典,集合,棧,隊列以及更多可能性。

PHP 數組能夠 同時含有 integer 和 string 類型的鍵名,由於 PHP 實際並不區分索引數組和關聯數組。

Key

key 會有以下的強制轉換
1.包含有合法整型值的字符串會被轉換爲整型。例如鍵名 "8" 實際會被儲存爲 8。可是 "08" 則不會強制轉換,由於其不是一個合法的十進制數值。
2.浮點數也會被轉換爲整型,意味着其小數部分會被捨去。例如鍵名 8.7 實際會被儲存爲 8
3.布爾值也會被轉換成整型。即鍵名 true 實際會被儲存爲 1 而鍵名 false 會被儲存爲 0
4.Null 會被轉換爲空字符串,即鍵名 null 實際會被儲存爲 ""
5.數組和對象不能被用爲鍵名。堅持這麼作會致使警告:Illegal offset type。

Example #2 類型強制與覆蓋示例

<?php
$array = array(
    1    => "a",
    "1"  => "b",
    1.5  => "c",
    true => "d",
);
var_dump($array);
?>

以上例程會輸出:

array(1) {
  [1]=>
  string(1) "d"
}

Example #3 混合 integer 和 string 鍵名

<?php
$array = array(
    "foo" => "bar",
    "bar" => "foo",
    100   => -100,
    -100  => 100,
);
var_dump($array);
?>

以上例程會輸出:

array(4) {
  ["foo"]=>
  string(3) "bar"
  ["bar"]=>
  string(3) "foo"
  [100]=>
  int(-100)
  [-100]=>
  int(100)
}

Example #5 僅對部分單元指定鍵名

<?php
$array = array(
         "a",
         "b",
    6 => "c",
         "d",
);
var_dump($array);
?>

以上例程會輸出:

array(4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
}

轉換

integer,float,string,boolean 和 resource 類型轉換爲數組,將獲得一個僅有一個元素的數組,其下標爲 0,該元素即爲此標量的值。換句話說,(array)$scalarValue 與 array($scalarValue) 徹底同樣

若是一個 object 類型轉換爲 array,則結果爲一個數組,其單元爲該對象的屬性。鍵名將爲成員變量名,不過有幾點例外:整數屬性不可訪問;私有變量前會加上類名做前綴;保護變量前會加上一個 '*' 作前綴。這些前綴的先後都各有一個 NULL 字符。這會致使一些不可預知的行爲:

<?php

class A {
    private $A; // This will become '\0A\0A'
}

class B extends A {
    private $A; // This will become '\0B\0A'
    public $AA; // This will become 'AA'
}

var_dump((array) new B());
?>

上例會有兩個鍵名爲 'AA',不過其中一個其實是 '0A0A'。

將 NULL 轉換爲 array 會獲得一個空的數組。

Callback / Callable 類型

<?php
class foo {
    static function callIt(callable $callback) {
        $callback();
    }
    
    static function doStuff() {
        echo "Hello World!";
    }
}

foo::callIt('foo::doStuff');
//The code would work fine, if we replaced the '$callback()' with 'call_user_func($callback)' or if we used the array ['foo', 'doStuff'] as the callback instead.
?>
The callable type hint, like is_callable(), will trigger an autoload of the class if the value looks like a static method callback
<?php 

// An example callback function
function my_callback_function() {
    echo 'hello world!';
}

// An example callback method
class MyClass {
    static function myCallbackMethod() {
        echo 'Hello World!';
    }
}

// Type 1: Simple callback
call_user_func('my_callback_function'); 

// Type 2: Static class method call
call_user_func(array('MyClass', 'myCallbackMethod')); 

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');

// Type 5: Relative static class method call (As of PHP 5.3.0)
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')); // A

// Type 6: Objects implementing __invoke can be used as callables (since PHP 5.3)
class C {
    public function __invoke($name) {
        echo 'Hello ', $name, "\n";
    }
}

$c = new C();
call_user_func($c, 'PHP!');
?>

Example #2 使用 Closure 的示例

<?php
// Our closure
$double = function($a) {
    return $a * 2;
};

// This is our range of numbers
$numbers = range(1, 5);

// Use the closure as a callback here to 
// double the size of each element in our 
// range
$new_numbers = array_map($double, $numbers);

print implode(' ', $new_numbers);
?>

以上例程會輸出:

2 4 6 8 10

文檔中使用的僞類型與變量

mixed

mixed 說明一個參數能夠接受多種不一樣的(但不必定是全部的)類型。
例如 gettype() 能夠接受全部的 PHP 類型,str_replace() 能夠接受字符串和數組。

number

number 說明一個參數能夠是 integer 或者 float。

callback

本文檔中在 PHP 5.4 引入 callable 類型以前使用 了 callback 僞類型。兩者含義徹底相同。

array|object

array|object 意思是參數既能夠是 array 也能夠是 object。

void

void 做爲返回類型意味着函數的返回值是無用的。void 做爲參數列表意味着函數不接受任何參數。

...

在函數原型中,$... 表示等等的意思。當一個函數能夠接受任意個參數時使用此變量名。

強制轉換

(int), (integer) - 轉換爲整形 integer
(bool), (boolean) - 轉換爲布爾類型 boolean
(float), (double), (real) - 轉換爲浮點型 float
(string) - 轉換爲字符串 string
(array) - 轉換爲數組 array
(object) - 轉換爲對象 object
(unset) - 轉換爲 NULL (PHP 5)
(binary) 轉換和 b 前綴轉換支持爲 PHP 5.2.1 新增。

注意在括號內容許有空格和製表符,因此下面兩個例子功能相同:

<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>

將字符串文字和變量轉換爲二進制字符串:

<?php
$binary = (binary)$string;
$binary = b"binary string";
?>

實例:

<?php 
$a = TRUE; 
echo ($a++) . $a;  // prints "11"
?>
相關文章
相關標籤/搜索