2013年6月30日

Float 浮點數型態

Float 浮點數型態

也稱作雙倍精準數(double)或實數(real)。可以用以下任一語法定義
<?php
$a = 1.234; 
$b = 1.2e3; 
$c = 7E-10;
?>

Warning 浮點數的精準度

浮點數的精準度有限,儘管取決於系統,PHP通常使用IEEE 754 雙精準度格式,則由於取整數而導致的最大相對誤差為 1.11e-16。非基本數學運算可能會給出更大誤差,並且要考慮到進行多次運算時的誤差傳遞。

此外,以十進位制能夠精確表示的有理數如0.1或者0.7,無論有多少尾數都不能被內部所使用的二進位制精確表示,因為無法在不丟失一點點精準度的情況下轉換為二進制的格式。這就會造成混亂的結果。

例如,floor((0.1+0.7)*10),通常會得到7而不是預期的8,因為該結果內部的表示其實是類似7.9999999999999991118...。

所以永遠不要相信浮點數結果精確到了最後一位數,也永遠不要比較兩個浮點數是否相等。如果確實需要更高的精準度,應該使用任意精準度數學函數或者是gmp函數


轉換為浮點數型態

如果希望了解有關何時以及如何將字串轉換成浮點數的資訊,請參閱字串轉換為數值的章節。對於其他類型的值,其情況類似於先將值轉換成整數型態,然後再轉換成浮點數型態。
請參閱轉換為整數型態章節獲得更多的資訊。自PHP5起,如果試圖將物件轉換為浮點數,會發出E_NOTICE錯誤訊息。


比較浮點數

如上述警告訊息所述,由於內部機制的原因,比較兩個浮點數是否相等是有問題的。不過還是有迂迴的方式來比較浮點數數值的。

要測試浮點數是否相等,要使用一個儘比該數值大一點的最小誤差值。該值也被稱為機器最小值(epsilon)或者最小單元取整數,是計算中所能接受的最小差別值。

$a 和 $b 在小數點後五位精準度內都是相等的。
<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;
 
if(abs($a-$b) < $epsilon) {
    echo "true";
}
?>


NaN

某些數字運算的結果會回傳一個常數NAN,在浮點數的計算中,這個結果代表一個未定義或者是無法表示的數。任何值對該NAN進行鬆散或嚴謹的比較皆會回傳FALSE。

因為NAN代表著不同的任何數字,NAN不應該拿來與其他的值進行比較,包括它自己。如果你想要檢查請使用is_nan()。

2013年6月24日

Integer 整數型態

語法:可以用十進位、十六進位以及八進位來表示,PHP沒有無號整數。
PHP5.4.0可以使用二進位的方式表是一個整數。


<?php
$a = 1234; // 十進位數
$a = -123; // 負數
$a = 0123; // 八進位數 (等於十進位 83)
$a = 0x1A; // 十六進位數 (等於十進位 26)
$a = 0b111; // 二進位數
?>


八進位的怪事
當輸入的值不符合八進位的要求,則會忽略後面的部分

<?php
var_dump(01090); // 010 octal = 8 decimal
?>


根據作業系統的位元數,整數的最大值有所不同,32位元大約是20億左右,64位元最大值大約為9E18

PHP有預定義的常數 PHP_INT_MAX 跟 PHP_INT_SIZE。

<?php
echo PHP_INT_MAX; // 顯示最大的整數值 2147483647
echo PHP_INT_SIZE; // 顯示儲存整數的空間 4 Bytes
?>


整數溢出

當給訂的數字超過了 integer 的範圍,將會被解釋為 float,如果執行後的結果溢出也是會回傳 float。

絕對不要將未知的分數強制轉換為 integer ,有時候會導致非預期的錯誤

<?php
echo (int) ( (0.1+0.7) * 10 ); // 顯示 7!
?>

2013年6月23日

Boolean 布林型態

語法:要指定一個布林值,可以使用關鍵字 true 或者 false。兩者不分大小寫
例如:$flag = true;

<?php 
$var1 = TRUE; 
$var2 = FALSE; 
 
echo $var1; // 顯示數字1 
 
echo $var2; // 不會顯示任何東西
 
/* 如果你想要它顯示數字0,你必須強制轉型為整數型態 */ 
 
echo (int)$var2; // 顯示數字0
?>


PHP會在需要的時候自動轉換型態,所以在以下第三種情況要特別小心。
<?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的八種原始數據型態

四個純量型態
boolean(布林型態)
integer(整數型態)
float(浮點數型態,也稱作 double)
string(字串型態)

兩個複合型態
array (陣列)
object (物件)

特殊型態
resource (資源)
NULL

如果想要同時查看變數的值跟類型,可以使用 var_dump() 函數。
如果想要知道變數類型並且回傳一個人類方便閱讀的文字字串,可以使用 get_type() 函數。
但是如果是想要檢查是否為某個類型時,使用 is_type 函式會更好
例如: is_array(), is_int(), is_string() 等等

要將變數強制轉型可以使用 set_tyep() 函數或者是直接使用強制轉換寫法。

要注意的是變數的型態通常不是由程式人員來決定,更確切地說,是在執行時由PHP根據變數使用的上下文程式碼而決定。

2013年6月22日

PHP Code Style

程式碼擁有相同的code style,可閱讀性就會提升。如果又使用code formating tool,這樣光是看程式碼的排版就完全分不出來到底是團隊中哪個成員所撰寫。

以下提供兩個比較完整的參考資料

1. Zend Framework Coding Standard for PHP

2. PHP-FIG 所提出的
    2-1. PSR-0 (Autoloading Standard)
    2-2. PSR-1 (Basic Coding Standard)
    2-3. PSR-2 (Coding Style Guide)

2-1. 說明了自動載入類別的標準包含供應商、命名空間以及類別名稱該如何決定,並且寫了一個範例在下方。
2-2. 說明基本編碼標準
2-3. 編碼風格指南

PHP標記、指令分隔符、註解

PHP標記

當解析一份文件時,解析器會尋找開始標籤<?php以及結束標籤?>,這告訴了解析器開始以及停止解析兩者之間的代碼。
因為這樣的解析方式,PHP可以被嵌入在不同的檔案中,兩個標籤之間的文字會被當作PHP代碼解析,其餘則不處理。

可以使用的方式有
1. <?php  ?>
標準且常用的方式

2. <?     ?>
短標籤,簡寫,必須要在 php.ini 內將 short_open_tag 設定為 on,或者在PHP編譯時加上 --enable-short-tags 選項

3. <%     %>
ASP標籤,必須要在 php.ini 內將 asp_tags 設定為 on。

4. <script language="php"> </script>
標籤內的文字不分大小寫

NOTE

另外提到一點是如果該文件是純PHP檔案的話可以省略結尾符號,雖然結尾符號後會刪除一個換行符號,但是如果有兩個換行符號或者是空白符號,則會出現非預期的空白出現。

避免使用短標記,尤其是開發需要更新的程式,或者是你無法控制設定的環境(虛擬主機),為了確保程式碼移植與發行,不要使用短標記

在PHP5.2和之前的版本中,解析器不允許一個文件的內容只有一個開始標記"<?php"。但是在PHP5.3以後就可以,不過在開始標記後面必須要有一個或更多的空白
例如:"<?php "

PHP5.4起,短標記的echo寫法會被識別且是合法,不再管 short_open_tag 的設定如何。
例如: Hello <?=$name ?> 可以被允許
否則你必須寫成 Hello <?php echo $name ?>

單行註解遇到結束符號的情況也要特別注意,下列程式碼並沒有將結尾符號註解。
<?php
// ?>
echo 111;
?>

指令分隔符

跟C還有Perl一樣,PHP需要在每個語句的後面使用分號當作結束。
但是PHP的結束符號包含了一個行結束,下列的寫法是允許的。
<?php 
echo "Hello";
echo "This is a test" 
?>

註解

單行註解可以使用//或者是#
<?php 
//這是註解
#這是註解
?>
要注意的是單行註解後面如果接有?>結束標記,會跳離PHP模式解析。

多行註解 /* */
<?php 
/*
這是註解
這是註解
這是註解
這是註解
*/
?>
要注意的是多行註解中又使用多行註解,註解的開始符號找到第一個結束符號就結束了,所以可能會出現非預期的錯誤
<?php 
/*
這是註解
/*這是註解
這是註解*/
這是註解
*/
?>

有關PHP的小提示

關於換行

換行符號在HTML的實際意義不大,適當的使用可以增加HTML代碼的可閱讀性以及美觀。
PHP的結尾附號"?>"會順帶刪除接在後面的一個換行符號。
如果你希望後面有一個換行符號可以在該結束符號加上一個空白隔開,或者是直接利用PHP echo 輸出一個換行符號。

關於開發工具

編輯PHP檔案必須使用純文字編輯器。
例如:notepad++或者是其他支援PHP的IDE

關於副檔名

將檔案副檔名設定為指定要處理的副檔名,副檔名可以進行設定。
例如:.php, .phtml

在某些開放原始碼的專案中,會使用附檔名.inc,副檔名設定上可能會有安全性的疑慮。
另外一個問題是作業系統預設隱藏檔案的副檔名,所以你改變的可能只是主檔名。
例如:存檔時候設定index.php,實際儲存成index.php.txt

使用utf-8編碼

目前的開發大多使用utf-8編碼,確保你所儲存的檔案已經移除了該檔案的 Byte order mark (BOM,用來識別這個檔案編碼的用途),否則你的PHP執行上可能會有錯誤訊息。
例如:使用 header 或者是 session_start。

簡單的安裝可以運行PHP的環境。

如果是剛開始學習PHP,我建議使用人家直接包裝好的安裝程式。安裝好了以後會直接有網頁伺服器apache、資料庫Mysql、PHP。在Windows環境下,被稱為WAMP。如果作業系統是Linux的話,稱為LAMP。

使用這種方式的好處是你可以直接學習PHP以及PHP如何連接資料庫。專注在學習語言特性上。

1. XAMPP

這是我目前比較常使用的。網站也提供中文解說,雖然不是很完整,但是安裝到好,並且做一些基本的設定都有說明。

2. AppServ

這是我一開始最先使用的。好處是它提供了較多的選擇,因為你必須要安裝Apache、PHP以及Mysql,但是這些都會有自己的版本號,你可以有較多的選擇,使用不同版本的PHP,不同版本的Apache。

PHP能做些什麼?

1. 伺服器端指令稿 (Server-side scripting)
這是PHP最傳統也是最主要使用的領域。你需要PHP解析器(CGI或是伺服器模組)、網頁伺服器以及網頁瀏覽器使之運作。你需要在安裝好PHP的網頁伺服器上運作,並且透過網頁瀏覽器瀏覽PHP頁面去存取網頁伺服器解析PHP輸出的結果。

PS:一般的教學書籍大多是使用第一種方式。

2. 指令列指令稿 (Command line scripting)
你可以不用透過伺服器或者是瀏覽器執行PHP指令稿,你只需要PHP解析器就可以運作。這種用法在linux系統上通常用來跑cron,在win系統用來跑日常工作。通常這樣的用法用來處理一些簡單的文字處理工作。

PS:可以來寫一個交互應答的程序或者是持續運作的程序

3. 用來寫桌面應用程序
對於擁有圖形用戶介面的桌面應用程序,PHP或許不是最好的語言,但是如果你非常了解PHP,並且想要使用PHP接近的功能在你用戶端應用程序,你可以使用PHP-GTK去編寫這類型的程序

PHP可以在大多數主流的作業系統上使用,PHP同時也支援大多數的網頁伺服器,PHP在網頁伺服器上可以是一個模組也可以是一個CGI處理來運作。

你可以自由地選擇作業系統以及網頁伺服器來執行PHP。此外,你可以使用程序導向或者是物件化導向的程式設計,或者是兩者混用。

PHP並沒有限制被用來輸出HTML。你也可以用來輸出圖像、PDF檔案、甚至是FLASH (使用 libswf 或者 Ming),還能夠簡單的輸出文字,例如XHTML或者XML。
PHP可以自動產生這些檔案在伺服器端的快取內,並且將它們儲存在系統內或者是動態地輸出內容

PHP也支援相當多的資料庫,可以透過安裝擴充針對不同的資料庫進行存取。

PHP還支援 LDAP、IMAP、SNMP、NNTP、POP3、HTTP、COM(WINDOWS系統)等協議服務,還支援了WDDX複雜資料交換,也支援對Java的連接。

PHP在處理文字上也非常方便,包括了Perl正規表達式 (PCRE) 以及許多的擴展。對於XML的解析與存取也可以使用基礎的libxml2或者是後來新加入的SimpleXML、XMLReader和XMLWriter。