PHP知識點總結(二)

數組


PHP數組之索引數組初始化

PHP有兩種數組:索引數組、關聯數組。

索引和關聯兩個詞都是針對數組的鍵而言的。

先介紹下索引數組,索引數組是指數組的鍵是整數的數組,並且鍵的整數順序是從0開始,依次類推。

下面使用圖來說明一下:

可以使用下面代碼實現:

$fruit = array("蘋果","香蕉","菠蘿"); 注意數組的鍵是從0開始的。可以使用print_r($fruit);語句輸出數組鍵及對應的值。

[php] view plain copy
  1. <?php  
  2. //創建一個索引數組,索引數組的鍵是“0”,值是“蘋果”  
  3. $fruit = array("蘋果",'香蕉','菠蘿');  
  4. echo '<pre>';  
  5. print_r( $fruit );  
  6. echo '</pre>';  
  7. ?>  
  8.   
  9. 輸出  
  10. <pre>Array  
  11. (  
  12.     [0] => 蘋果  
  13.     [1] => 香蕉  
  14.     [2] => 菠蘿  
  15. )  

PHP數組之索引數組賦值

索引數組賦值有三種方式:

第一種:用數組變量的名字後面跟一箇中括號的方式賦值,當然,索引數組中,中括號內的鍵一定是整數。比如,$arr[0]='蘋果';

第二種:用array()創建一個空數組,使用=>符號來分隔鍵和值,左側表示鍵,右側表示值。當然,索引數組中,鍵一定是整數。比如,array('0'=>'蘋果');

第三種:用array()創建一個空數組,直接在數組裏用英文的單引號'或者英文的雙引號"賦值,數組會默認建立從0開始的整數的鍵。比如array('蘋果');這個數組相當於array('0'=>'蘋果');

[php] view plain copy
  1. <?php  
  2. $arr=array('0'=>'蘋果','1'=>'西瓜');  
  3. $arr1 = array("蘋果",'香蕉','菠蘿');  
  4. $arr2=array();  
  5. $arr2[0]="蘋果";  
  6. $arr2[1]="香蕉";  
  7. $arr2[2]="菠蘿";  
  8. print_r($arr);  
  9. echo '<pre>';  
  10. print_r( $arr1 );  
  11. echo '</pre>';  
  12. echo '<pre>';  
  13. print_r( $arr2 );  
  14. echo '</pre>';  
  15. ?>  
  16. //////  
  17.   
  18. (  
  19.     [0] => 蘋果  
  20.     [1] => 香蕉  
  21.     [2] => 菠蘿  
  22. )  
Array
(
    [0] => 蘋果
    [1] => 香蕉
    [2] => 菠蘿
)

PHP數組之訪問索引數組內容

有的時候我們需要把數組中的內容也就是值取出來該怎麼辦呢?用數組變量的名字後跟的中括號中的鍵,來訪問數組中的值。
[php] view plain copy
  1. <?php  
  2. //從數組變量$arr中,讀取鍵爲0的值  
  3. $arr = array('蘋果','香蕉');  
  4. $arr0 = $arr['0'];  
  5. if( isset($arr0) ) {print_r($arr0);}  
  6. ?>  
  7. //////  
  8. <pre>蘋果  
  9. isset()在php中用來檢測變量是否設置,該函數返回的是否布爾值,即true/false。  

PHP數組之for循環訪問索引數組裏的值

for循環可以將數組裏的所有值都訪問到,用for循環訪問索引數組裏的值。
[php] view plain copy
  1. <?php  
  2. $fruit=array('蘋果','香蕉','菠蘿');  
  3. for($index=0; $index<3; $index++){  
  4.     echo '數組第'.$index.'值是:'.$fruit[$index]."<br/>";  
  5. }  
  6. ?>  
  7. //////  
  8. 數組第0值是:蘋果  
  9. 數組第1值是:香蕉  
  10. 數組第2值是:菠蘿  

PHP數組之foreach循環訪問索引數組裏的值

foreach循環可以將數組裏的所有值都訪問到,用foreach循環訪問索引數組裏的值。
[php] view plain copy
  1. <?php  
  2.     $fruit=array('蘋果','香蕉','菠蘿');  
  3.     foreach($fruit as $key=>$value){  
  4.         echo '第'.$key.'值是:'.$value.'<br/>';  
  5.     }  
  6.     foreach($fruit as $value){  
  7.         echo $value.'<br/>';  
  8.     }  
  9. ?>  
  10. //////  
  11. 第0值是:蘋果  
  12. 第1值是:香蕉  
  13. 第2值是:菠蘿  
  14. 蘋果  
  15. 香蕉  
  16. 菠蘿  

PHP數組之關聯數組初始化

PHP有兩種數組:索引數組、關聯數組。

索引和關聯兩個詞都是針對數組的鍵而言的。

先介紹下,關聯數組是指數組的鍵是字符串的數組。

[php] view plain copy
  1. <?php  
  2.     $fruit = array(  
  3.         'apple'=>"蘋果",  
  4.         'banana'=>"香蕉",  
  5.         'pineapple'=>"菠蘿"  
  6.     );   
  7.     print_r($fruit)  
  8. ?>  
  9. //////  
  10. Array ( [apple] => 蘋果 [banana] => 香蕉 [pineapple] => 菠蘿 )  

PHP數組之關聯數組賦值

關聯數組賦值有兩種方式:

第一種:用數組變量的名字後面跟一箇中括號的方式賦值,當然,關聯數組中,中括號內的鍵一定是字符串。比如,$arr['apple']='蘋果';

第二種:用array()創建一個空數組,使用=>符號來分隔鍵和值,左側表示鍵,右側表示值。當然,關聯數組中,鍵一定是字符串。比如,array('apple'=>'蘋果');

[php] view plain copy
  1. <?php  
  2.     $arr = array('apple'=>'蘋果','pineapple'=>'菠蘿');  
  3.     if( isset($arr)){  
  4.         print_r($arr);  
  5.     }  
  6. ?>  
  7. //////  
  8. Array ( [apple] => 蘋果 [pineapple] => 菠蘿 )  

PHP數組之訪問關聯數組內容

用數組變量的名字後跟中括號+鍵的方式來訪問數組中的值,鍵使用單引號或者雙引號括起來。

[php] view plain copy
  1. <?php  
  2.     $fruit = array('apple'=>"蘋果",'banana'=>"香蕉",'pineapple'=>"菠蘿");   
  3.     $fruit0 = $fruit['banana'];  
  4.     print_r($fruit0);  
  5. ?>  
  6. //////  
  7. 香蕉  

PHP數組之foreach循環訪問關聯數組裏的值

foreach循環可以將數組裏的所有值都訪問到,用foreach循環訪問關聯數組裏的值。
[php] view plain copy
  1. <?php  
  2.     $fruit=array('apple'=>"蘋果",'banana'=>"香蕉",'pineapple'=>"菠蘿");  
  3.     foreach($fruit as $k=>$v){  
  4.         echo '水果的英文鍵名:'.$k.',對應的值是:'.$v.'<br/>';  
  5.     }  
  6. ?>  
  7. //////  
  8. 水果的英文鍵名:apple,對應的值是:蘋果  
  9. 水果的英文鍵名:banana,對應的值是:香蕉  
  10. 水果的英文鍵名:pineapple,對應的值是:菠蘿  

函數

PHP自定義函數

PHP內置了超過1000個函數,因此函數使得PHP成爲一門非常強大的語言。大多數時候我們使用系統的內置函數就可以滿足需求,但是自定義函數通過將一組代碼封裝起來,使代碼進行復用,程序結構與邏輯更加清晰。
PHP函數的定義方式:
    1.使用關鍵字“function”開始
    2.函數名可以是字母或下劃線開頭:function name()

    3.在大括號中編寫函數體:

[php] view plain copy
  1. <?php  
  2.     function say()  
  3.     {  
  4.         echo 'hello world';  
  5.     }  
  6.     say();  
  7.     //在這裏調用函數  
  8. ?>  
  9. //////  
  10. hello world  

PHP函數的參數

PHP的函數可以沒有參數,也可以有若干個參數,多個參數稱之爲參數列表,採用逗號進行分割,參數類似於一個變量,調用時用來傳遞數據到函數體中。通過傳遞參數可以使函數實現對參數的運算,得到我們想要的結果。

參數的變量名可以自由指定,但最好能夠表達相關的意思
[php] view plain copy
  1. <?php  
  2.     function sum($a$b) {  
  3.         echo $a + $b;  
  4.     }  
  5.     sum(2,5);  
  6.     //在這裏調用函數計算1+2的值  
  7. ?>  
  8. //////  
  9. 7  

PHP函數之返回值

使用return關鍵字可以使函數返回值,可以返回包括數組和對象的任意類型,如果省略了 return,則默認返回值爲 NULL。
[php] view plain copy
  1. <?php  
  2.     function add($a) {  
  3.         return $a+1;  
  4.     }  
  5.     $b = add(1);  
  6.     echo $b;  
  7. ?>  
  8. //////  
  9. 2  
返回語句會立即中止函數的運行,並且將控制權交回調用該函數的代碼行
[php] view plain copy
  1. <?php  
  2.     function add($a) {  
  3.         return $a+1;  
  4.         $a = 10;  
  5.         return $a+20;  
  6.     }  
  7.     $b = add(1);  
  8.     echo $b;  
  9. ?>  
  10. //////  
  11. 2  

函數不能返回多個值,但可以通過返回一個數組來得到類似的效果

[php] view plain copy
  1. <?php  
  2.     function numbers() {  
  3.         return array(1, 2, 3);  
  4.     }  
  5.     list ($one$two$three) = numbers();  
  6.     echo $one;  
  7.     echo $two;  
  8.     echo $three;  
  9. ?>  
  10. //////  
  11. 123  
  12. 函數不能返回多個值,但可以通過返回一個數組來得到類似的效果  
[php] view plain copy
  1. array(3) {  
  2.   [0]=>  
  3.   int(1)  
  4.   [1]=>  
  5.   int(2)  
  6.   [2]=>  
  7.   int(3)  
  8. }  
  9. 這是numbers()返回的值  
list()只是舉個例子而已,重點是函數函數不能返回多個值。
[php] view plain copy
  1. <?php  
  2.     function numbers() {  
  3.         return array(1, 2, 3);  
  4.     }  
  5.     $hh=numbers();  
  6.     print_r ($hh);  
  7. ?>  
  8. //////  
  9. Array ( [0] => 1 [1] => 2 [2] => 3 )  

PHP函數之可變函數

所謂可變函數,即通過變量的值來調用函數,因爲變量的值是可變的,所以可以通過改變一個變量的值來實現調用不同的函數。經常會用在回調函數、函數列表,或者根據動態參數來調用不同的函數。可變函數的調用方法爲變量名加括號。
[php] view plain copy
  1. <?php  
  2.     function name() {  
  3.         echo 'jobs';  
  4.     }  
  5.     $func = 'name';  
  6.     $func(); //調用可變函數  
  7. ?>  
  8. //////  
  9. jobs  
可變函數也可以用在對象的方法調用上。
[php] view plain copy
  1. <?php  
  2.     class book {  
  3.         function getName() {  
  4.             return 'bookname';  
  5.         }  
  6.     }  
  7.     $func = 'getName';  
  8.     $book = new book();  
  9.     echo $book->$func();  
  10. ?>  
  11. //////  
  12. bookname  

PHP函數之內置函數

內置函數指的是PHP默認支持的函數,PHP內置了很多標準的常用的處理函數,包括字符串處理、數組函數、文件處理、session與cookie處理等。

通過內置函數str_replace可以實現字符串的替換。下面的例子將“jobs”替換成“steven jobs”:

[php] view plain copy
  1. <?php  
  2.     $str = 'i am jobs.';  
  3.     $str = str_replace('jobs''steven jobs'$str);  
  4.     echo $str//結果爲“i am steven jobs”  
  5. ?>  

PHP函數之判斷函數是否存在

當我們創建了自定義函數,並且瞭解了可變函數的用法,爲了確保程序調用的函數是存在的,經常會先使用function_exists判斷一下函數是否存在。同樣的method_exists可以用來檢測類的方法是否存在。
[php] view plain copy
  1. <?php  
  2.     function func() {  
  3.     }  
  4.     if (function_exists('func')){  
  5.         echo 'exists';  
  6.     }  
  7. ?>  

類是否定義可以使用class_exists。
[php] view plain copy
  1. <?php  
  2.     class MyClass{  
  3.     }  
  4.     // 使用前檢查類是否存在  
  5.     if (class_exists('MyClass')) {  
  6.         $myclass = new MyClass();  
  7.     }  
  8. ?>  

PHP中有很多這類的檢查方法,例如文件是否存在file_exists等。
[php] view plain copy
  1. <?php  
  2.     $filename = 'test.txt';  
  3.     if (!file_exists($filename)) {  
  4.         echo $filename . ' not exists.';  
  5.     }  
  6. ?>  

判斷函數func是否存在,如果存在的話就調用他。
[php] view plain copy
  1. <?php  
  2.     function func() {  
  3.         echo 'exists';  
  4.     }  
  5.     $name = 'func';  
  6.     if (function_exists($name)) { //判斷函數是否存在  
  7.         $name();  
  8.     }  
  9. ?>  

類與面向對象

PHP類和對象

類是面向對象程序設計的基本概念,通俗的理解類就是對現實中某一個種類的東西的抽象, 比如汽車可以抽象爲一個類,汽車擁有名字、輪胎、速度、重量等屬性,可以有換擋、前進、後退等操作方法。

通常定義一個汽車類的方法爲:

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         $name = '汽車';  
  4.         function getName() {  
  5.             return $this->name;  
  6.         }  
  7.     }  
  8. ?>  

類是一類東西的結構描述,而對象則是一類東西的一個具體實例,例如汽車這個名詞可以理解爲汽車的總類,但這輛汽車則是一個具體的汽車對象。

對象通過new關鍵字進行實例化:

[php] view plain copy
  1. $car = new Car();  
  2. ar->getName();  
類與對象看起來比較相似,但實際上有本質的區別,類是抽象的概念,對象是具體的實例。類可以使程序具有可重用性。
[php] view plain copy
  1. <?php  
  2.     class car{  
  3.         public function rec(){  
  4.             echo "你好";  
  5.         }  
  6.         public function caa(){  
  7.             $this->rec();  
  8.         }  
  9.     }  
  10.     $cat=new car();  
  11.     $cat->caa();  
  12. ?>  
  13. //////  
  14. 你好  
定義類的屬性爲公共,
var跟public一個意思,var是php舊版的用法。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         var $name = '汽車';  
  4.         function getName() {  
  5.             return $this->name;  
  6.         }  
  7.     }  
  8.   
  9.     //實例化一個car對象  
  10.     $car = new Car();  
  11.     echo $car->getName();  //調用對象的方法 輸出對象的名字  
  12.     echo $car->name;  
  13. ?>  
  14. //////  
  15. 汽車汽車  
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         public $name = '汽車';  
  4.         function getName() {  
  5.             return $this->name;  
  6.         }  
  7.     }  
  8.   
  9.     //實例化一個car對象  
  10.     $car = new Car();  
  11.     echo $car->getName();  //調用對象的方法 輸出對象的名字  
  12.     echo $car->name;  
  13. ?>  
  14. //////  
  15. 汽車汽車  
[php] view plain copy
  1. <?php  
  2.     //定義一個類  
  3.     class Car {  
  4.         var $name = '汽車';  
  5.         function getName() {  
  6.             return $this->name;  
  7.         }  
  8.     }  
  9.   
  10.     //實例化一個car對象  
  11.     $car = new Car();  
  12.     $car->name = '奧迪A6'//設置對象的屬性值  
  13.     echo $car->getName();  //調用對象的方法 輸出對象的名字  
  14. ?>  
  15. //////  
  16. 奧迪A6  

PHP類和對象之創建一個對象

類通過關鍵字class開頭,然後是類名與花括號,在花括號中定義類的屬性與方法。類名必須是字母或下劃線開頭,後面緊跟若干個字母、數字或下劃線,類名最好能夠表意,可以採用名詞或者英文單詞。

[php] view plain copy
  1. <?php  
  2.     //定義一個類  
  3.     class Car {  
  4.         //定義屬性  
  5.         public $name = '汽車';  
  6.   
  7.         //定義方法  
  8.         public function getName() {  
  9.             //方法內部可以使用$this僞變量調用對象的屬性或者方法  
  10.             return $this->name;  
  11.         }  
  12.     }  
  13.     $car = new Car();  
  14.     echo $car->getName();  //調用對象的方法 輸出對象的名字  
  15. ?>  
  16. //////  
  17. 汽車  

也可以採用變量來創建
[php] view plain copy
  1. <?php  
  2.     //定義一個類  
  3.     class Car {  
  4.         //定義屬性  
  5.         public $name = '汽車';  
  6.   
  7.         //定義方法  
  8.         public function getName() {  
  9.             //方法內部可以使用$this僞變量調用對象的屬性或者方法  
  10.             return $this->name;  
  11.         }  
  12.     }  
  13.     $className = 'Car';  
  14.     $car = new $className();  
  15.     echo $car->getName();  
  16. ?>  
  17. <pre name="code" class="php">//////  
  18. 汽車  

PHP類和對象之類的屬性

在類中定義的變量稱之爲屬性,通常屬性跟數據庫中的字段有一定的關聯,因此也可以稱作“字段”。屬性聲明是由關鍵字 public,protected 或者 private 開頭,後面跟一個普通的變量聲明來組成。屬性的變量可以設置初始化的默認值,默認值必須是常量。

訪問控制的關鍵字代表的意義爲:

public:公開的protected:受保護的private:私有的

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         //定義公共屬性  
  4.         public $name = '汽車';  
  5.   
  6.         //定義受保護的屬性  
  7.         protected $corlor = '白色';  
  8.   
  9.         //定義私有屬性  
  10.         private $price = '100000';  
  11.     }  
  12.     $car = new Car();  
  13.     echo $car->name;    //調用對象的屬性  
  14.     echo $car->color;  //錯誤 受保護的屬性不允許外部調用  
  15.     echo $car->price;  //錯誤 私有屬性不允許外部調用    
  16. ?>  

默認都爲public,外部可以訪問。一般通過->對象操作符來訪問對象的屬性或者方法,對於靜態屬性則使用::雙冒號進行訪問。當在類成員方法內部調用的時候,可以使用$this僞變量調用當前對象的屬性。

受保護的屬性與私有屬性不允許外部調用,在類的成員方法內部是可以調用的。

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private $name = '汽車';  
  4.         public function getName() {  
  5.             return $this->name;  
  6.         }  
  7.     }  
  8.   
  9.     $carnew Car();    //new一個新的類  
  10.     echo $car->getName();  
  11. ?>  
  12. //////  
  13. 汽車  

PHP類和對象之定義類的方法

方法就是在類中的function,很多時候我們分不清方法與函數有什麼差別,在面向過程的程序設計中function叫做函數,在面向對象中function則被稱之爲方法。

同屬性一樣,類的方法也具有public,protected 以及 private 的訪問控制。

訪問控制的關鍵字代表的意義爲:
public:公開的
protected:受保護的
private:私有的

[php] view plain copy
  1. <?php   
  2.     class hup {  
  3.         public function but() {  
  4.             return 100;  
  5.         }  
  6.     }  
  7.     $hu=new hup();  
  8.     echo $hu->but();  
  9. ?>  
  10. //////  
  11. 100  

使用關鍵字static修飾的,稱之爲靜態方法,靜態方法不需要實例化對象,可以通過類名直接調用,操作符爲雙冒號::。

[php] view plain copy
  1. <?php   
  2.     class hup {  
  3.         public function but() {  
  4.             return 100;  
  5.         }  
  6.     }  
  7.     echo hup::but(); //結果爲“100”  
  8. ?>  

PHP類和對象之構造函數和析構函數

PHP5可以在類中使用__construct()定義一個構造函數,具有構造函數的類,會在每次對象創建的時候調用該函數,因此常用來在對象創建的時候進行一些初始化工作。
[php] view plain copy
  1. <?php   
  2.     class Car {  
  3.        function __construct() {  
  4.            print "構造函數被調用\n";  
  5.        }  
  6.     }  
  7.     $car = new Car(); //實例化的時候 會自動調用構造函數__construct,這裏會輸出一個字符串  
  8. ?>  


在子類中如果定義了__construct則不會調用父類的__construct,如果需要同時調用父類的構造函數,需要使用parent::__construct()顯式的調用。

[php] view plain copy
  1. <?php   
  2.     class Car {  
  3.        function __construct() {  
  4.            print "父類構造函數被調用\n";  
  5.        }  
  6.     }  
  7.     class Truck extends Car {  
  8.        function __construct() {  
  9.            print "子類構造函數被調用\n";  
  10.            parent::__construct();  
  11.        }  
  12.     }  
  13.     $car = new Truck();  
  14. ?>  
  15. //////  
  16. 子類構造函數被調用 父類構造函數被調用  
PHP5支持析構函數,使用__destruct()進行定義,析構函數指的是當某個對象的所有引用被刪除,或者對象被顯式的銷燬時會執行的函數。
[php] view plain copy
  1. <?php   
  2.     class Car {  
  3.        function __construct() {  
  4.            print "構造函數被調用 \n";  
  5.        }  
  6.        function __destruct() {  
  7.            print "析構函數被調用 \n";  
  8.        }  
  9.     }  
  10.     $car = new Car(); //實例化時會調用構造函數  
  11.     echo '使用後,準備銷燬car對象 \n';  
  12.     unset($car); //銷燬時會調用析構函數  
  13. ?>  

當PHP代碼執行完畢以後,會自動回收與銷燬對象,因此一般情況下不需要顯式的去銷燬對象。

PHP類和對象之Static靜態關鍵字

靜態屬性與方法可以在不實例化類的情況下調用,直接使用類名::方法名的方式進行調用。靜態屬性不允許對象使用->操作符調用。

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private static $speed = 10;  
  4.         public static function getSpeed() {  
  5.             return self::$speed;  
  6.         }  
  7.     }  
  8.     echo Car::getSpeed();  //調用靜態方法  
  9. ?>  
  10. //////  
  11. 10  
靜態方法也可以通過變量來進行動態調用
[php] view plain copy
  1. $func = 'getSpeed';  
  2. $className = 'Car';  
  3. echo $className::$func();  //動態調用靜態方法  

靜態方法中,$this僞變量不允許使用。可以使用self,parent,static在內部調用靜態方法與屬性。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private static $speed = 10;  
  4.   
  5.         public static function getSpeed() {  
  6.             return self::$speed;  
  7.         }  
  8.   
  9.         public static function speedUp() {  
  10.             return self::$speed+=10;  
  11.         }  
  12.     }  
  13.     class BigCar extends Car {  
  14.         public static function start() {  
  15.             parent::speedUp();  
  16.         }  
  17.     }  
  18.   
  19.     BigCar::start();  
  20.     echo BigCar::getSpeed();  
  21. ?>  
  22. //////  
  23. 20  

PHP類和對象之訪問控制

訪問控制通過關鍵字public,protected和private來實現。被定義爲公有的類成員可以在任何地方被訪問。被定義爲受保護的類成員則可以被其自身以及其子類和父類訪問。被定義爲私有的類成員則只能被其定義所在的類訪問。

類屬性必須定義爲公有受保護私有之一。爲兼容PHP5以前的版本,如果採用 var 定義,則被視爲公有。

[php] view plain copy
  1. class Car {  
  2.     $speed = 10; //錯誤 屬性必須定義訪問控制  
  3.     public $name;   //定義共有屬性  
  4. }  

類中的方法可以被定義爲公有私有受保護。如果沒有設置這些關鍵字,則該方法默認爲公有
[php] view plain copy
  1. class Car {  
  2. ​    //默認爲共有方法  
  3.     function turnLeft() {  
  4.     }  
  5. }  

如果構造函數定義成了私有方法,則不允許直接實例化對象了,這時候一般通過靜態方法進行實例化,在設計模式中會經常使用這樣的方法來控制對象的創建,比如單例模式只允許有一個全局唯一的對象。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private function __construct() {  
  4.             echo 'object create';  
  5.         }  
  6.   
  7.         private static $_object = null;  
  8.         public static function getInstance() {  
  9.             if (empty(self::$_object)) {  
  10.                 self::$_object = new Car(); //內部方法可以調用私有方法,因此這裏可以創建對象  
  11.             }  
  12.             return self::$_object;  
  13.         }  
  14.     }  
  15.     //$car = new Car(); //這裏不允許直接實例化對象  
  16.     $car = Car::getInstance(); //通過靜態方法來獲得一個實例  
  17. ?>  

PHP類和對象之對象繼承

繼承是面向對象程序設計中常用的一個特性,汽車是一個比較大的類,我們也可以稱之爲基類,除此之外,汽車還分爲卡車、轎車、東風、寶馬等,因爲這些子類具有很多相同的屬性和方法,可以採用繼承汽車類來共享這些屬性與方法,實現代碼的複用。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         public $speed = 0; //汽車的起始速度是0  
  4.   
  5.         public function speedUp() {  
  6.             $this->speed += 10;  
  7.             return $this->speed;  
  8.         }  
  9.     }  
  10.     //定義繼承於Car的Truck類  
  11.      class Truck extends Car {  
  12.         public function speedUp() {  
  13.             $this->speed = parent::speedUp() + 50;  
  14.         }  
  15.     }  
  16.   
  17.     $car = new Truck();  
  18.     $car->speedUp();  
  19.     echo $car->speed;  
  20. ?>  
  21. //////  
  22. 60  

PHP類和對象之重載

PHP中的重載指的是動態的創建屬性與方法,是通過魔術方法來實現的。屬性的重載通過__set,__get,__isset,__unset來分別實現對不存在屬性的賦值、讀取、判斷屬性是否設置、銷燬屬性。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private $ary = array();  
  4.   
  5.         public function __set($key$val) {  
  6.             $this->ary[$key] = $val;  
  7.         }  
  8.   
  9.         public function __get($key) {  
  10.             if (isset($this->ary[$key])) {  
  11.                 return $this->ary[$key];  
  12.             }  
  13.             return null;  
  14.         }  
  15.   
  16.         public function __isset($key) {  
  17.             if (isset($this->ary[$key])) {  
  18.                 return true;  
  19.             }  
  20.             return false;  
  21.         }  
  22.   
  23.         public function __unset($key) {  
  24.             unset($this->ary[$key]);  
  25.         }  
  26.     }  
  27.     $car = new Car();  
  28.     $car->name = '汽車';  //name屬性動態創建並賦值  
  29.     echo $car->name;  
  30. ?>  

方法的重載通過__call來實現,當調用不存在的方法的時候,將會轉爲參數調用__call方法,當調用不存在的靜態方法時會使用__callStatic重載。
[php] view plain copy
  1. class Car {  
  2.     public $speed = 0;  
  3.       
  4.     public function __call($name$args) {  
  5.         if ($name == 'speedUp') {  
  6.             $this->speed += 10;  
  7.         }  
  8.     }  
  9. }  
  10. $car = new Car();  
  11. $car->speedUp(); //調用不存在的方法會使用重載  
  12. echo $car->speed;  

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         public $speed = 10;  
  4.   
  5.         //在這裏使用重載實現speedDown方法  
  6.         public function __call($name,$args){  
  7.             if ($name=='speedDown'){  
  8.                 $this->speed-=10;  
  9.             }  
  10.         }  
  11.     }  
  12.     $car = new Car();  
  13.     $car->speedDown(); //調用不存在的speedDown方法  
  14.     echo $car->speed;  
  15. ?>  
  16. //////  
  17. 0  

PHP類和對象之對象的高級特性

對象比較,當同一個類的兩個實例的所有屬性都相等時,可以使用比較運算符==進行判斷,當需要判斷兩個變量是否爲同一個對象的引用時,可以使用全等運算符===進行判斷。
[php] view plain copy
  1. class Car {  
  2. }  
  3. $a = new Car();  
  4. $b = new Car();  
  5. if ($a == $becho '==';   //true  
  6. if ($a === $becho '==='//false  

對象複製,在一些特殊情況下,可以通過關鍵字clone來複制一個對象,這時__clone方法會被調用,通過這個魔術方法來設置屬性的值。
[php] view plain copy
  1. class Car {  
  2.     public $name = 'car';  
  3.       
  4.     public function __clone() {  
  5.         $obj = new Car();  
  6.         $obj->name = $this->name;  
  7.     }  
  8. }  
  9. $a = new Car();  
  10. $a->name = 'new car';  
  11. $b = clone $a;  
  12. var_dump($b);  

對象序列化,可以通過serialize方法將對象序列化爲字符串,用於存儲或者傳遞數據,然後在需要的時候通過unserialize將字符串反序列化成對象進行使用。
[php] view plain copy
  1. class Car {  
  2.     public $name = 'car';  
  3. }  
  4. $a = new Car();  
  5. $str = serialize($a); //對象序列化成字符串  
  6. echo $str.'<br>';  
  7. $b = unserialize($str); //反序列化爲對象  
  8. var_dump($b);  

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         public $name = 'car';  
  4.   
  5.         public function __clone() {  
  6.             $obj = new Car();  
  7.             $obj->name = $this->name;  
  8.         }  
  9.     }  
  10.     $a = new Car();  
  11.     $a->name = 'new car';  
  12.     $b = clone $a;  
  13.     if ($a == $becho '==';   //true  
  14.     if ($a === $becho '==='//false  
  15.   
  16.     $str = serialize($a); //對象序列化成字符串  
  17.     echo $str.'<br>';  
  18.     $c = unserialize($str); //反序列化爲對象  
  19.     var_dump($c);  
  20. ?>  

字符串操作

PHP字符串介紹

PHP開發中,我們遇到最多的可能就是字符串。

字符串變量用於包含字符串的值。

一個字符串 通過下面的3種方法來定義:

1、單引號
2、雙引號
3、heredoc語法結構

基本用法如下,後面的節還會詳細進行介紹使用技巧,這裏只介紹用法:

單引號定義的字符串:$hello = 'hello world';

雙引號定義的字符串:$hello = "hello world";

heredoc語法結構定義的字符串:

[php] view plain copy
  1. $hello = <<<TAG  
  2. hello world  
  3. TAG;  

PHP字符串之單引號和雙引號的區別

在PHP中,字符串的定義可以使用英文單引號' ',也可以使用英文雙引號" "

但是必須使用同一種單或雙引號來定義字符串,如:'Hello World""Hello World'爲非法的字符串定義。

單引號和雙引號到底有啥區別呢?

PHP允許我們在雙引號串中直接包含字串變量

而單引號串中的內容總被認爲是普通字符。

[php] view plain copy
  1. $str='hello';  
  2. echo "str is $str"//運行結果: str is hello  
  3. echo 'str is $str'//運行結果: str is $str  

PHP字符串之字符串的連接

PHP中兩個字符串如何連接呢,比如我有個字符串$hello='hello',還有一個字符串$world=' world',我想將這兩個字符串連接在一起,跟世界打個招呼。

PHP中用英文的點號.來連接兩個字符串。

[php] view plain copy
  1. $hello='hello';  
  2.   
  3. $world=' world';  
  4.   
  5. $hi = $hello.$world;  
  6.   
  7. echo $hi;//我們可以用echo函數輸出一下這個字符串連接。  

[php] view plain copy
  1. <?php  
  2.     $i='I';  
  3.     $love=' Love';  
  4.     $you=' You';  
  5.     //連接一下三個字符串  
  6.     $str = $i.$love.$you;  
  7.     echo $str;  
  8. ?>  
  9. //////  
  10. I Love You  

PHP字符串之去除字符串首尾的空格

PHP中有三個函數可以去掉字符串的空格

trim去除一個字符串兩端空格。
rtrim是去除一個字符串右部空格,其中的r是right的縮寫。
ltrim是去除一個字符串左部空格,其中的l是left的縮寫。

[php] view plain copy
  1. echo trim(" 空格 ")."<br>";  
  2. echo rtrim(" 空格 ")."<br>";  
  3. echo ltrim(" 空格 ")."<br>";  
[php] view plain copy
  1. <?php  
  2.     $str="      左側空格要去掉";  
  3.     echo trim($str);  
  4. ?>  

PHP字符串之獲取字符串的長度

php中有一個神奇的函數,可以直接獲取字符串的長度,這個函數就是strlen()。

[php] view plain copy
  1. $str = 'hello';  
  2. $len = strlen($str);  
  3. echo $len;//輸出結果是5  

strlen函數對於計算英文字符是非常的擅長,但是如果有中文漢字,要計算長度該怎麼辦?

可以使用mb_strlen()函數獲取字符串中中文長度。

[php] view plain copy
  1. $str = "我愛你";  
  2. echo mb_strlen($str,"UTF8");//結果:3,此處的UTF8表示中文編碼是UTF8格式,中文一般採用UTF8編碼  

PHP字符串之字符串的截取

php中有非常多的字符串處理函數,其中就有字符串截取函數。

1、英文字符串的截取函數substr()

函數說明:substr(字符串變量,開始截取的位置,截取個數)

[php] view plain copy
  1. $str='i love you';  
  2. //截取love這幾個字母  
  3. echo substr($str, 2, 4);//爲什麼開始位置是2呢,因爲substr函數計算字符串位置是從0開始的,也就是0的位置是i,1的位置是空格,l的位置是2。從位置2開始取4個字  
  4. 符,就是love。  

2、中文字符串的截取函數mb_substr()

函數說明:mb_substr(字符串變量,開始截取的位置,截取個數, 網頁編碼)

[php] view plain copy
  1. $str='我愛你,中國';  
  2.   
  3. //截取中國兩個字  
  4.   
  5. echo mb_substr($str, 4, 2, 'utf8');//爲什麼開始位置是4呢,和上一個例子一樣,因爲mb_substr函數計算漢字位置是從0開始的,也就是0的位置是我,1的位置是愛,4的位置是中。從位置4開始取2個漢字,就是中國。中文編碼一般是utf8格式  

PHP字符串之查找字符串

如果有一個字符串$str = 'I want to study at imooc';,怎麼樣找到其中的imooc在哪個位置呢?

查找字符串,我們需要用到PHP的查找字符串函數strpos();

函數說明:strpos(要處理的字符串, 要定位的字符串, 定位的起始位置[可選])

[php] view plain copy
  1. $str = 'I want to study at imooc';  
  2. $pos = strpos($str'imooc');  
  3. echo $pos;//結果顯示19,表示從位置0開始,imooc在第19個位置開始出現  

PHP字符串之替換字符串

如果有一個字符串$str = 'I want to learn js';,怎麼樣將js字符替換成你想學的php字符呢?

替換字符串,我們需要用到PHP的替換函數str_replace()

函數說明:str_replace(要查找的字符串, 要替換的字符串, 被搜索的字符串, 替換進行計數[可選])

[php] view plain copy
  1. $str = 'I want to learn js';  
  2. $replace = str_replace('js''php'$str);  
  3. echo $replace;//結果顯示I want to learn php  

[php] view plain copy
  1. <?php  
  2.     //替換字符串  
  3.     $str = 'I Love Chian';  
  4.     $replace=str_replace('Chian','China',$str);  
  5.     echo $replace;  
  6. ?>  

PHP字符串之格式化字符串

如果有一個字符串$str = '99.9';,怎麼樣使這個字符串變成99.90呢?

我們需要用到PHP的格式化字符串函數sprintf()

函數說明:sprintf(格式, 要轉化的字符串)

返回:格式化好的字符串

例子:

$str = '99.9';
$result = sprintf('%01.2f', $str);
echo $result;//結果顯示99.90

解釋下,上面例子中的格式

這個 %01.2f 是什麼意思呢?

1、這個 % 符號是開始的意思,寫在最前面表示指定格式開始了。 也就是 "起始字符", 直到出現 "轉換字符" 爲止,就算格式終止。
2、跟在 % 符號後面的是 0, 是 "填空字元" ,表示如果位置空着就用0來填滿。
3、在 0 後面的是1,這個 1 是規定整個所有的字符串佔位要有1位以上(小數點也算一個佔位)。
    如果把 1 改成 6,則 $result的值將爲 099.90
    因爲,在小數點後面必須是兩位,99.90一共5個佔位,現在需要6個佔位,所以用0來填滿。
4、在 %01 後面的 .2 (點2) 就很好理解了,它的意思是,小數點後的數字必須佔2位。 如果這時候,$str 的值爲9.234,則 $result的值將爲9.23.
    爲什麼4 不見了呢? 因爲在小數點後面,按照上面的規定,必須且僅能佔2位。 可是 $str 的值中,小數點後面佔了3位,所以,尾數4被去掉了,只剩下 23。
5、最後,以 f "轉換字符" 結尾。

[php] view plain copy
  1. <?php  
  2.     //格式化字符串  
  3.     $str = '100.1';  
  4.     $spr = sprintf('%01.3f',$str);  
  5.     echo $spr;  
  6. ?>  

PHP字符串之字符串的合併與分割

1、php字符串合併函數implode()

函數說明:implode(分隔符[可選], 數組)

返回值:把數組元素組合爲一個字符串

例子:

$arr = array('Hello', 'World!');
$result = implode('', $arr);
print_r($result);//結果顯示Hello World!

2、php字符串分隔函數explode()

函數說明:explode(分隔符[可選], 字符串)

返回值:函數返回由字符串組成的數組

例子:

$str = 'apple,banana';
$result = explode(',', $str);
print_r($result);//結果顯示array('apple','banana')

[php] view plain copy
  1. <?php  
  2.     //分隔字符串  
  3.     $str = 'sun-moon-star';  
  4.     $rro=explode('-',$str);  
  5.     print_r($rro);  
  6. ?>  
  7. //////  
  8. Array  
  9. (  
  10.     [0] => sun  
  11.     [1] => moon  
  12.     [2] => star  
  13. )  

PHP字符串之字符串的轉義

php字符串轉義函數addslashes()

函數說明:用於對特殊字符加上轉義字符,返回一個字符串

返回值:一個經過轉義後的字符串

例子:

$str = "what's your name?";
echo addslashes($str);//輸出:what\'s your name?

正則表達式

什麼叫正則表達式

正則表達式是對字符串進行操作的一種邏輯公式,就是用一些特定的字符組合成一個規則字符串,稱之爲正則匹配模式。
[php] view plain copy
  1. $p = '/apple/';  
  2. $str = "apple banna";  
  3. if (preg_match($p$str)) {  
  4.     echo 'matched';  
  5. }  

其中字符串'/apple/'就是一個正則表達式,他用來匹配源字符串中是否存在apple字符串。

PHP中使用PCRE庫函數進行正則匹配,比如上例中的preg_match用於執行一個正則匹配,常用來判斷一類字符模式是否存在。

[php] view plain copy
  1. <?php  
  2.     //請修改變量p的正則表達式,使他能夠匹配蘋果  
  3.     $p = '/蘋果/';  
  4.   
  5.     $str = "我喜歡吃蘋果";  
  6.     if (preg_match($p$str)) {  
  7.         echo '匹配成功';  
  8.     }  
  9. ?>  

正則表達式的基本語法

PCRE庫函數中,正則匹配模式使用分隔符與元字符組成,分隔符可以是非數字、非反斜線、非空格的任意字符。經常使用的分隔符是正斜線(/)、hash符號(#) 以及取反符號(~),例如:

/foo bar/
#^[^0-9]$#
~php~

如果模式中包含分隔符,則分隔符需要使用反斜槓(\)進行轉義。

/http:\/\//

如果模式中包含較多的分割字符,建議更換其他的字符作爲分隔符,也可以採用preg_quote進行轉義。

$p = 'http://';
$p = '/'.preg_quote($p, '/').'/';
echo $p;

分隔符後面可以使用模式修飾符,模式修飾符包括:i, m, s, x等,例如使用i修飾符可以忽略大小寫匹配:

$str = "Http://www.imooc.com/";
if (preg_match('/http/i', $str)) {
    echo '匹配成功';
}

元字符與轉義

正則表達式中具有特殊含義的字符稱之爲元字符,常用的元字符有:

\ 一般用於轉義字符
^ 斷言目標的開始位置(或在多行模式下是行首)
$ 斷言目標的結束位置(或在多行模式下是行尾)
. 匹配除換行符外的任何字符(默認)
[ 開始字符類定義
] 結束字符類定義
| 開始一個可選分支
( 子組的開始標記
) 子組的結束標記
? 作爲量詞,表示 0 次或 1 次匹配。位於量詞後面用於改變量詞的貪婪特性。 (查閱量詞)
* 量詞,0 次或多次匹配
+ 量詞,1 次或多次匹配
{ 自定義量詞開始標記
} 自定義量詞結束標記

//下面的\s匹配任意的空白符,包括空格,製表符,換行符。[^\s]代表非空白符。[^\s]+表示一次或多次匹配非空白符。
$p = '/^我[^\s]+(蘋果|香蕉)$/';
$str = "我喜歡吃蘋果";
if (preg_match($p, $str)) {
    echo '匹配成功';
}

元字符具有兩種使用場景,一種是可以在任何地方都能使用,另一種是只能在方括號內使用,在方括號內使用的有:

\ 轉義字符
^ 僅在作爲第一個字符(方括號內)時,表明字符類取反
- 標記字符範圍

其中^在反括號外面,表示斷言目標的開始位置,但在方括號內部則代表字符類取反,方括號內的減號-可以標記字符範圍,例如0-9表示0到9之間的所有數字。

//下面的\w匹配字母或數字或下劃線。
$p = '/[\w\.\-]+@[a-z0-9\-]+\.(com|cn)/';
$str = "我的郵箱是[email protected]";
preg_match($p, $str, $match);
echo $match[0];
[php] view plain copy
  1. <?php  
  2.     //請修改變量p的正則表達式,使他能夠匹配str中的電話  
  3.     $p = '/[\d]{3,4}\-[\d]{8,9}/';  
  4.     $str = "我的電話是010-12345678";  
  5.     preg_match($p$str$match);  
  6.     echo $match[0];  
  7. ?>  

貪婪模式與懶惰模式

貪婪模式:在可匹配與可不匹配的時候,優先匹配

//下面的\d表示匹配數字
$p = '/\d+\-\d+/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結果爲:010-12345678

懶惰模式:在可匹配與可不匹配的時候,優先不匹配

$p = '/\d?\-\d?/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0];  //結果爲:0-1

當我們確切的知道所匹配的字符長度的時候,可以使用{}指定匹配字符數

$p = '/\d{3}\-\d{8}/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結果爲:010-12345678
[php] view plain copy
  1. <?php  
  2. //請修改變量p的正則表達式,使他能夠匹配str中的姓名  
  3. $p = '/(\w+\s\w+)/';  
  4. $str = "name:steven jobs";  
  5. preg_match($p$str$match);  
  6. echo $match[1];  

使用正則表達式進行匹配

使用正則表達式的目的是爲了實現比字符串處理函數更加靈活的處理方式,因此跟字符串處理函數一樣,其主要用來判斷子字符串是否存在、字符串替換、分割字符串、獲取模式子串等。

PHP使用PCRE庫函數來進行正則處理,通過設定好模式,然後調用相關的處理函數來取得匹配結果。

preg_match用來執行一個匹配,可以簡單的用來判斷模式是否匹配成功,或者取得一個匹配結果,他的返回值是匹配成功的次數0或者1,在匹配到1次以後就會停止搜索。

$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches);
print_r($matches); //結果爲:Array ( [0] => def )

上面的代碼簡單的執行了一個匹配,簡單的判斷def是否能匹配成功,但是正則表達式的強大的地方是進行模式匹配,因此更多的時候,會使用模式:

$subject = "abcdef";
$pattern = '/a(.*?)d/';
preg_match($pattern, $subject, $matches);
print_r($matches); //結果爲:Array ( [0] => abcd [1] => bc )

通過正則表達式可以匹配一個模式,得到更多的有用的數據。

[php] view plain copy
  1. <?php  
  2. $subject = "my email is [email protected]";  
  3. $pattern = "/[0-9a-z]+@[0-9a-z]+.com/";  
  4. //$pattern = '/\w+@(\w+\.)+\w+/';  
  5. preg_match($pattern$subject$matches);  
  6. //在這裏補充代碼,實現正則匹配,並輸出郵箱地址  
  7.   
  8. print_r($matches[0]);//   

查找所有匹配結果

preg_match只能匹配一次結果,但很多時候我們需要匹配所有的結果,preg_match_all可以循環獲取一個列表的匹配結果數組。

$p = "|<[^>]+>(.*?)</[^>]+>|i";
$str = "<b>example: </b><div align=left>this is a test</div>";
preg_match_all($p, $str, $matches);
print_r($matches);

可以使用preg_match_all匹配一個表格中的數據:

$p = "/<tr><td>(.*?)<\/td>\s*<td>(.*?)<\/td>\s*<\/tr>/i";
$str = "<table> <tr><td>Eric</td><td>25</td></tr> <tr><td>John</td><td>26</td></tr> </table>";
preg_match_all($p, $str, $matches);
print_r($matches);

$matches結果排序爲$matches[0]保存完整模式的所有匹配, $matches[1] 保存第一個子組的所有匹配,以此類推。

[php] view plain copy
  1. <?php  
  2. $str = "<ul>  
  3.             <li>item 1</li>  
  4.             <li>item 2</li>  
  5.         </ul>";  
  6. //在這裏補充代碼,實現正則匹配所有li中的數據  
  7. $p = "/<li>(.*)<\/li>/i";  
  8. $p = "/<li>(.*)<\/li>/i";//解釋下這個正則://後面的i表示不區分大小寫,<li>(.*?)<\/li>表示li標籤內的匹配的()內的值有多少,括號內的.表示所有單字符,*表示數量爲0個或者多個。也就是li標籤內有字符就顯示出來  
  9. preg_match_all($p,$str,$matches);  
  10. print_r($matches[1]);  
  11.   
  12. // $p = "|<[^>]+>(.*?)</[^>]+>|i";  
  13. // $str = "<b>example: </b><div align=left>this is a test</div>";  
  14. // preg_match_all($p, $str, $matches);  
  15. // print_r($matches);  
  16.   
  17. // // 可以使用preg_match_all匹配一個表格中的數據:  
  18. // $p = "/<tr><td>(.*?)<\/td>\s*<td>(.*?)<\/td>\s*<\/tr>/i";  
  19. // $str = "<table> <tr><td>Eric</td><td>25</td></tr> <tr><td>John</td><td>26</td></tr> </table>";  
  20. // preg_match_all($p, $str, $matches);  
  21. // print_r($matches);  
  22. // // echo $matches[1];  
  23. ?>  

正則表達式的搜索和替換

正則表達式的搜索與替換在某些方面具有重要用途,比如調整目標字符串的格式,改變目標字符串中匹配字符串的順序等。

例如我們可以簡單的調整字符串的日期格式:

$string = 'April 15, 2014';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '$3, ${1} $2';
echo preg_replace($pattern, $replacement, $string); //結果爲:2014, April 15

其中${1}與$1的寫法是等效的,表示第一個匹配的字串,$2代表第二個匹配的。

通過複雜的模式,我們可以更加精確的替換目標字符串的內容。

$patterns = array ('/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/',
                   '/^\s*{(\w+)}\s*=/');
$replace = array ('\3/\4/\1\2', '$\1 =');//\3等效於$3,\4等效於$4,依次類推
echo preg_replace($patterns, $replace, '{startDate} = 1999-5-27'); //結果爲:$startDate = 5/27/1999
//詳細解釋下結果:(19|20)表示取19或者20中任意一個數字,(\d{2})表示兩個數字,(\d{1,2})表示1個或2個數字,(\d{1,2})表示1個或2個數字。^\s*{(\w+)\s*=}表示以任意空格開頭的,並且包含在{}中的字符,並且以任意空格結尾的,最後有個=號的。

用正則替換來去掉多餘的空格與字符:

$str = 'one     two';
$str = preg_replace('/\s+/', ' ', $str);
echo $str; // 結果改變爲'one two'
[php] view plain copy
  1. <?php  
  2. $str = '主要有以下幾個文件:index.php, style.css, common.js';  
  3. //將目標字符串$str中的文件名替換後增加em標籤  
  4. $p = '/\w+\.\w+/i';  
  5. $str = preg_replace($p'<em>$0</em>'$str);  
  6. echo $str;  

正則匹配常用案例

[php] view plain copy
  1. <?php  
  2. $user = array(  
  3.     'name' => 'spark1985',  
  4.     'email' => '[email protected]',  
  5.     'mobile' => '13312345678'  
  6. );  
  7. //進行一般性驗證  
  8. if (empty($user)) {  
  9.     die('用戶信息不能爲空');  
  10. }  
  11. if (strlen($user['name']) < 6) {  
  12.     die('用戶名長度最少爲6位');  
  13. }  
  14. //用戶名必須爲字母、數字與下劃線  
  15. if (!preg_match('/^\w+$/i'$user['name'])) {  
  16.     die('用戶名不合法');  
  17. }  
  18. //驗證郵箱格式是否正確  
  19. if (!preg_match('/^[\w\.]+@\w+\.\w+$/i'$user['email'])) {  
  20.     die('郵箱不合法');  
  21. }  
  22. //手機號必須爲11位數字,且爲1開頭  
  23. if (!preg_match('/^1\d{10}$/i'$user['mobile'])) {  
  24.     die('手機號不合法');  
  25. }  
  26. echo '用戶信息驗證成功';  


會話控制(session與cookie) 

cookie簡介

Cookie是存儲在客戶端瀏覽器中的數據,我們通過Cookie來跟蹤與存儲用戶數據。一般情況下,Cookie通過HTTP headers從服務端返回到客戶端。多數web程序都支持Cookie的操作,因爲Cookie是存在於HTTP的標頭之中,所以必須在其他信息輸出以前進行設置,類似於header函數的使用限制。

PHP通過setcookie函數進行Cookie的設置,任何從瀏覽器發回的Cookie,PHP都會自動的將他存儲在$_COOKIE的全局變量之中,因此我們可以通過$_COOKIE['key']的形式來讀取某個Cookie值。

PHP中的Cookie具有非常廣泛的使用,經常用來存儲用戶的登錄信息,購物車等,且在使用會話Session時通常使用Cookie來存儲會話id來識別用戶,Cookie具備有效期,當有效期結束之後,Cookie會自動的從客戶端刪除。同時爲了進行安全控制,Cookie還可以設置域跟路徑,我們會在稍後的章節中詳細的講解他們。

[php] view plain copy
  1. <?php  
  2.     setcookie('test', time());  
  3.     ob_start();  
  4.     print_r($_COOKIE);   
  5.     $content = ob_get_contents();  
  6.     $content = str_replace(" "' '$content);  
  7.     ob_clean();  
  8.     header("content-type:text/html; charset=utf-8");  
  9.     echo '當前的Cookie爲:<br>';  
  10.     echo nl2br($content);  
  11. ?>  

設置cookie

PHP設置Cookie最常用的方法就是使用setcookie函數,setcookie具有7個可選參數,我們常用到的爲前5個:

name( Cookie名)可以通過$_COOKIE['name'] 進行訪問
value(Cookie的值)
expire(過期時間)Unix時間戳格式,默認爲0,表示瀏覽器關閉即失效
path(有效路徑)如果路徑設置爲'/',則整個網站都有效
domain(有效域)默認整個域名都有效,如果設置了'www.imooc.com',則只在www子域中有效

$value = 'test';
setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600);  //有效期一小時
setcookie("TestCookie", $value, time()+3600, "/path/", "http://localhost/.com"); //設置路徑與域

PHP中還有一個設置Cookie的函數setrawcookie,setrawcookie跟setcookie基本一樣,唯一的不同就是value值不會自動的進行urlencode,因此在需要的時候要手動的進行urlencode。

setrawcookie('cookie_name', rawurlencode($value), time()+60*60*24*365); 

因爲Cookie是通過HTTP標頭進行設置的,所以也可以直接使用header方法進行設置。

header("Set-Cookie:cookie_name=value");

[php] view plain copy
  1. <?php  
  2. $value = time();  
  3. //在這裏設置一個名爲test的Cookie  
  4. setcookie("test",$value);  
  5. if (isset($_COOKIE['test'])) {  
  6.     echo 'success';  
  7. }  
[php] view plain copy
  1. <?php  
  2.     setcookie('test', time());  
  3.   
  4.     //在這裏試着刪除test的cookie值  
  5.   
  6.   
  7.     var_dump($_COOKIE);  
  8. ?>  


cookie的刪除與過期時間

我們瞭解了設置cookie的函數,但是我們卻發現php中沒有刪除Cookie的函數,在PHP中刪除cookie也是採用setcookie函數來實現。
setcookie('test', '', time()-1); 

可以看到將cookie的過期時間設置到當前時間之前,則該cookie會自動失效,也就達到了刪除cookie的目的。之所以這麼設計是因爲cookie是通過HTTP的標頭來傳遞的,客戶端根據服務端返回的Set-Cookie段來進行cookie的設置,如果刪除cookie需要使用新的Del-Cookie來實現,則HTTP頭就會變得複雜,實際上僅通過Set-Cookie就可以簡單明瞭的實現Cookie的設置、更新與刪除。

瞭解原理以後,我們也可以直接通過header來刪除cookie。

header("Set-Cookie:test=1393832059; expires=".gmdate('D, d M Y H:i:s \G\M\T', time()-1));

這裏用到了gmdate,用來生成格林威治標準時間,以便排除時差的影響。


[php] view plain copy
  1. <?php  
  2.     setcookie('test', time()-1);  
  3.     setcookie('test''', time()-1);  
  4.     //在這裏試着刪除test的cookie值  
  5.     var_dump($_COOKIE);  
  6. ?>  

cookie的有效路徑

cookie中的路徑用來控制設置的cookie在哪個路徑下有效,默認爲'/',在所有路徑下都有,當設定了其他路徑之後,則只在設定的路徑以及子路徑下有效,例如:

setcookie('test', time(), 0, '/path');

上面的設置會使test在/path以及子路徑/path/abc下都有效,但是在根目錄下就讀取不到test的cookie值。

一般情況下,大多是使用所有路徑的,只有在極少數有特殊需求的時候,會設置路徑,這種情況下只在指定的路徑中才會傳遞cookie值,可以節省數據的傳輸,增強安全性以及提高性能。

當我們設置了有效路徑的時候,不在當前路徑的時候則看不到當前cookie。

setcookie('test', '1',0, '/path');  
var_dump($_COOKIE['test']);  

[php] view plain copy
  1. <?php  
  2.     setcookie('test''1', 0, '/path');  
  3.     var_dump($_COOKIE['test']);  
  4. ?>  

setcookie('test', '1', 0,'/path');記得前面又說,忘了,現在記錄下,0表示有效期,瀏覽器關閉,cookie也就到期了

setcookie(名稱 , 值 , 有效期 , 路徑 , 域 , 是否通過安全傳輸);其中名稱和值是必需的,後面的可選。

session與cookie的異同

cookie將數據存儲在客戶端,建立起用戶與服務器之間的聯繫,通常可以解決很多問題,但是cookie仍然具有一些侷限:

cookie相對不是太安全,容易被盜用導致cookie欺騙
單個cookie的值最大隻能存儲4k
每次請求都要進行網絡傳輸,佔用帶寬

session是將用戶的會話數據存儲在服務端,沒有大小限制,通過一個session_id進行用戶識別,PHP默認情況下session id是通過cookie來保存的,因此從某種程度上來說,seesion依賴於cookie。但這不是絕對的,session id也可以通過參數來實現,只要能將session id傳遞到服務端進行識別的機制都可以使用session。

[php] view plain copy
  1. <?php  
  2.     //開始使用session  
  3.     session_start();  
  4.     //設置一個session  
  5.     $_SESSION['test'] = time();  
  6.     //顯示當前的session_id  
  7.     echo "session_id:".session_id();  
  8.     echo "<br>";  
  9.   
  10.     //讀取session值  
  11.     echo $_SESSION['test'];  
  12.   
  13.     //銷燬一個session  
  14.     unset($_SESSION['test']);  
  15.     echo "<br>";  
  16.     var_dump($_SESSION);  
  17. ?>  

使用session

在PHP中使用session非常簡單,先執行session_start方法開啓session,然後通過全局變量$_SESSION進行session的讀寫。

session_start();
$_SESSION['test'] = time();
var_dump($_SESSION);

session會自動的對要設置的值進行encode與decode,因此session可以支持任意數據類型,包括數據與對象等。

session_start();
$_SESSION['ary'] = array('name' => 'jobs');
$_SESSION['obj'] = new stdClass();
var_dump($_SESSION);
默認情況下,session是以文件形式存儲在服務器上的,因此當一個頁面開啓了session之後,會獨佔這個session文件,這樣會導致當前用戶的其他併發訪問無法執行而等待。可以採用緩存或者數據庫的形式存儲來解決這個問題
[php] view plain copy
  1. <?php  
  2.     session_start();  
  3.     $_SESSION['name'] = 'jobs';  
  4.     echo $_SESSION['name'];  
  5. ?>  

刪除與銷燬session

刪除某個session值可以使用PHP的unset函數,刪除後就會從全局變量$_SESSION中去除,無法訪問。

session_start();
$_SESSION['name'] = 'jobs';
unset($_SESSION['name']);
echo $_SESSION['name']; //提示name不存在

如果要刪除所有的session,可以使用session_destroy函數銷燬當前session,session_destroy會刪除所有數據,但是session_id仍然存在。

session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
session_destroy();

值得注意的是,session_destroy並不會立即的銷燬全局變量$_SESSION中的值,只有當下次再訪問的時候,$_SESSION才爲空,因此如果需要立即銷燬$_SESSION,可以使用unset函數。

session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
unset($_SESSION);
session_destroy(); 
var_dump($_SESSION); //此時已爲空

如果需要同時銷燬cookie中的session_id,通常在用戶退出的時候可能會用到,則還需要顯式的調用setcookie方法刪除session_id的cookie值。

[php] view plain copy
  1. <?php  
  2.     session_start();  
  3.     $_SESSION['name'] = 'jobs';  
  4.     //在這裏刪除name的session值  
  5.     unset($_SESSION['name']);  
  6.     if (isset($_SESSION['name'])) {  
  7.         echo $_SESSION['name'];  
  8.     }  
  9. ?>  

使用session來存儲用戶的登錄信息

session可以用來存儲多種類型的數據,因此具有很多的用途,常用來存儲用戶的登錄信息,購物車數據,或者一些臨時使用的暫存數據等。

用戶在登錄成功以後,通常可以將用戶的信息存儲在session中,一般的會單獨的將一些重要的字段單獨存儲,然後所有的用戶信息獨立存儲。

$_SESSION['uid'] = $userinfo['uid'];
$_SESSION['userinfo'] = $userinfo;

一般來說,登錄信息既可以存儲在sessioin中,也可以存儲在cookie中,他們之間的差別在於session可以方便的存取多種數據類型,而cookie只支持字符串類型,同時對於一些安全性比較高的數據,cookie需要進行格式化與加密存儲,而session存儲在服務端則安全性較高。

[php] view plain copy
  1. <!DOCTYPE html>  
  2. <html lang="en">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>Document</title>  
  6. </head>  
  7. <body>  
  8. <?php  
  9.     session_start();  
  10.     //假設用戶登錄成功獲得了以下用戶數據  
  11.     $userinfo = array(  
  12.         'uid'  => 10000,  
  13.         'name' => 'spark',  
  14.         'email' => '[email protected]',  
  15.         'sex'  => 'man',  
  16.         'age'  => '18'  
  17.     );  
  18.     header("content-type:text/html; charset=utf-8");  
  19.   
  20.     /* 將用戶信息保存到session中 */  
  21.     $_SESSION['uid'] = $userinfo['uid'];  
  22.     $_SESSION['name'] = $userinfo['name'];  
  23.     $_SESSION['userinfo'] = $userinfo;  
  24.   
  25.     //* 將用戶數據保存到cookie中的一個簡單方法 */  
  26.     $secureKey = 'imooc'//加密密鑰  
  27.     $str = serialize($userinfo); //將用戶信息序列化  
  28.     //用戶信息加密前  
  29.     $str = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($secureKey), $str, MCRYPT_MODE_ECB));  
  30.     //用戶信息加密後  
  31.     //將加密後的用戶數據存儲到cookie中  
  32.     setcookie('userinfo'$str);  
  33.   
  34.     //當需要使用時進行解密  
  35.     $str = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($secureKey), base64_decode($str), MCRYPT_MODE_ECB);  
  36.     $uinfo = unserialize($str);  
  37.     echo "解密後的用戶信息:<br>";  
  38.     print_r($uinfo);  
  39. ?>  
  40. </body>  
  41. </html>  


文件系統

PHP文件系統之讀取文件內容

PHP具有豐富的文件操作函數,最簡單的讀取文件的函數爲file_get_contents,可以將整個文件全部讀取到一個字符串中。

[php] view plain copy
  1. <?php  
  2.     $content = file_get_contents('text.txt');  
  3.     echo $content;  
  4. ?>  

file_get_contents也可以通過參數控制讀取內容的開始點以及長度。

$content = file_get_contents('./test.txt', null, null, 100, 500);

PHP也提供類似於C語言操作文件的方法,使用fopen,fgets,fread等方法,fgets可以從文件指針中讀取一行,freads可以讀取指定長度的字符串。

$fp = fopen('./text.txt', 'rb');
while(!feof($fp)) {
    echo fgets($fp); //讀取一行
}
fclose($fp);

 

$fp = fopen('./text.txt', 'rb');
$contents = '';
while(!feof($fp)) {
    $contents .= fread($fp, 4096); //一次讀取4096個字符
}
fclose($fp);

使用fopen打開的文件,最好使用fclose關閉文件指針,以避免文件句柄被佔用。

[php] view plain copy
  1. <?php  
  2.     $filename = 'text.txt';  
  3.     //編寫代碼讀取$filename的文件內容  
  4.     $content = file_get_contents($filename);  
  5.     echo $content;  
  6. ?>  
  7. //////  
  8. this is a test file.  

PHP文件系統之判斷文件是否存在

一般情況下在對文件進行操作的時候需要先判斷文件是否存在,PHP中常用來判斷文件存在的函數有兩個is_file與file_exists.

$filename = './test.txt';
if (file_exists($filename)) {
    echo file_get_contents($filename);
}

如果只是判斷文件存在,使用file_exists就行,file_exists不僅可以判斷文件是否存在,同時也可以判斷目錄是否存在,從函數名可以看出,is_file是確切的判斷給定的路徑是否是一個文件。

$filename = './test.txt';
if (is_file($filename)) {
    echo file_get_contents($filename);
}

更加精確的可以使用is_readable與is_writeable在文件是否存在的基礎上,判斷文件是否可讀與可寫。

$filename = './test.txt';
if (is_writeable($filename)) {
    file_put_contents($filename, 'test');
}
if (is_readable($filename)) {
    echo file_get_contents($filename);
}


[php] view plain copy
  1. <?php  
  2.     $filename = 'text.txt';  
  3.     if (file_exists($filename)) {  
  4.         echo '文件存在';  
  5.     }else{  
  6.        echo '文件不存在';  
  7.     }  
  8. ?>  

PHP文件系統之取得文件的修改時間

文件有很多元屬性,包括:文件的所有者、創建時間、修改時間、最後的訪問時間等。

fileowner:獲得文件的所有者
filectime:獲取文件的創建時間
filemtime:獲取文件的修改時間
fileatime:獲取文件的訪問時間

其中最常用的是文件的修改時間,通過文件的修改時間,可以判斷文件的時效性,經常用在靜態文件或者緩存數據的更新。

$mtime = filemtime($filename);
echo '修改時間:'.date('Y-m-d H:i:s', filemtime($filename));
[php] view plain copy
  1. <?php  
  2.     $filename = 'text.txt';  
  3.     echo '所有者:'.fileowner($filename).'<br>';  
  4.     echo '創建時間:'.filectime($filename).'<br>';  
  5.     echo '修改時間:'.filemtime($filename).'<br>';  
  6.     echo '最後訪問時間:'.fileatime($filename).'<br>';  
  7.   
  8.     //給$mtime賦值爲文件的修改時間  
  9.     $mtime = filemtime($filename);  
  10.     //通過計算時間差 來判斷文件內容是否有效  
  11.     if (time() - $mtime > 3600) {  
  12.         echo '<br>緩存已過期';  
  13.     } else {  
  14.         echo file_get_contents($filename);  
  15.     }  
  16. ?>  

PHP文件系統之取得文件的大小

通過filesize函數可以取得文件的大小,文件大小是以字節數表示的。
[php] view plain copy
  1. <?php  
  2.     $filename = 'text.txt';  
  3.     $size = filesize($filename);  
  4.     echo $size;  
  5. ?>  

如果要轉換文件大小的單位,可以自己定義函數來實現。
[php] view plain copy
  1. <?php  
  2.     function getsize($size$format = 'kb') {  
  3.         $p = 0;  
  4.         if ($format == 'kb') {  
  5.             $p = 1;  
  6.         } elseif ($format == 'mb') {  
  7.             $p = 2;  
  8.         } elseif ($format == 'gb') {  
  9.             $p = 3;  
  10.         }  
  11.         $size /= pow(1024, $p);  
  12.         return number_format($size, 3);  
  13.     }  
  14.   
  15.     $filename = 'text.txt';  
  16.     $size = filesize($filename);  
  17.   
  18.     $size = getsize($size'kb'); //進行單位轉換  
  19.     echo $size.'kb';  
  20. ?>  

值得注意的是,沒法通過簡單的函數來取得目錄的大小,目錄的大小是該目錄下所有子目錄以及文件大小的總和,因此需要通過遞歸的方法來循環計算目錄的大小。


日期和時間

PHP日期和時間之取得當前的Unix時間戳

[php] view plain copy
  1. UNIX 時間戳(英文叫做:timestamp)是 PHP 中關於時間與日期的一個很重要的概念,它表示從 1970年1月1日 00:00:00 到當前時間的秒數之和。  
  2.   
  3. PHP提供了內置函數 time() 來取得服務器當前時間的時間戳。那麼獲取當前的UNIX時間戳就很簡單了。  
  4.   
  5. <?php  
  6.     $time = time();  
  7.     echo $time;  
  8. ?>  
  9. //1478270126,這個數字表示從1970年1月1日 00:00:00 到我輸出這個腳本時經歷了1478270126秒  

PHP日期和時間之取得當前的日期

php內置了date()函數,來取得當前的日期。

函數說明:date(時間戳的格式, 規定時間戳【默認是當前的日期和時間,可選】)

返回值:函數日期和時間

例子:

//date函數,第二個參數取默認值的情況
echo date("Y-m-d");//2014-03-30

//date函數,第二個參數有值的情況
echo date("Y-m-d",'1396193923');//2014-03-30,1396193923表示2014-03-30的unix時間戳

[php] view plain copy
  1. <?php  
  2.     //date函數,第二個參數取默認值的情況  
  3.     echo date("Y-m-d")."<br/>";//2014-03-30  
  4.   
  5.     //date函數,第二個參數有值的情況  
  6.     echo date("Y-m-d",'1396193923');//2014-03-30,1396193923表示2014-03-30的unix時間戳  
  7. ?>  

[php] view plain copy
  1. <?php  
  2. //設置默認的時區  
  3. date_default_timezone_set('Asia/Shanghai');  
  4. //輸出1396193923對應的日期  
  5. echo date("Y-m-d",'1396193923');  
  6. ?>  

PHP日期和時間之取得日期的Unix時間戳

UNIX 時間戳(英文叫做:timestamp)是 PHP 中關於時間與日期的一個很重要的概念,它表示從 1970年1月1日 00:00:00 到當前時間的秒數之和。

PHP提供了內置函數strtotime實現功能:獲取某個日期的時間戳,或獲取某個時間的時間戳。例如:

echo strtotime('2014-04-29');//1398700800,這個數字表示從1970年1月1日 00:00:00 到2014年4月29號經歷了1398700800秒

echo strtotime('2014-04-29 00:00:01');//1398700801,這個數字表示從1970年1月1日 00:00:00 到2014-04-29 00:00:01時經歷了1398700801秒

大家發現上面的規律了嗎,其實strtotime('2014-04-29')相當於strtotime('2014-04-29 00:00:00')
[php] view plain copy
  1. <?php  
  2. //設置默認時區是中國  
  3. date_default_timezone_set("Asia/Shanghai");  
  4. //獲取2014-05-01的unix時間戳  
  5. echo strtotime('2014-05-01');  
  6. ?>  

PHP日期和時間之將格式化的日期字符串轉換爲Unix時間戳

strtotime函數預期接受一個包含美國英語日期格式的字符串並嘗試將其解析爲 Unix 時間戳。

函數說明:strtotime(要解析的時間字符串, 計算返回值的時間戳【默認是當前的時間,可選】)
返回值:成功則返回時間戳,否則返回 FALSE

比如

echo strtotime("now");//相當於將英文單詞now直接等於現在的日期和時間,並把這個日期時間轉化爲unix時間戳。這個效果跟echo time();一樣。
echo strtotime("+1 seconds");//相當於將現在的日期和時間加上了1秒,並把這個日期時間轉化爲unix時間戳。這個效果跟echo time()+1;一樣。
echo strtotime("+1 day");//相當於將現在的日期和時間加上了1天。
echo strtotime("+1 week");//相當於將現在的日期和時間加上了1周。
echo strtotime("+1 week 3 days 7 hours 5 seconds");//相當於將現在的日期和時間加上了1周3天7小時5秒。
[php] view plain copy
  1. <?php  
  2. //設置默認時區是中國  
  3. date_default_timezone_set("Asia/Shanghai");  
  4. //返回現在時間過5秒後的unix時間戳  
  5. echo strtotime("+5 seconds");  
  6. ?>  

PHP日期和時間之格式化格林威治(GMT)標準時間

gmdate 函數能格式化一個GMT的日期和時間,返回的是格林威治標準時(GMT)。

舉個例子,我們現在所在的中國時區是東八區,領先格林威治時間8個小時,有時候也叫GMT+8,那麼服務器運行以下腳本返回的時間應該是這樣的:
當前時間假定是2014-05-01 15:15:22
echo date('Y-m-d H:i:s', time()); //輸出爲:2014-05-01 15:15:22 
echo gmdate('Y-m-d H:i:s', time()); //輸出爲:2014-05-01 07:15:22 因爲格林威治時間是現在中國時區的時間減去8個小時,所以相對於現在時間要少8個小時


[php] view plain copy
  1. <?php  
  2.     //設置默認時區是中國  
  3.     date_default_timezone_set("Asia/Shanghai");  
  4.     //返回2014-05-01 12:00:01的格林威治標準時間  
  5.     echo gmdate('Y-m-d H:i:s'strtotime('2014-05-01 12:00:01'));  
  6. ?>  



圖形圖像操作 

PHP圖形操作之GD庫簡介

header("content-type: image/png");
$img=imagecreatetruecolor(100, 100);創建一個真彩色的空白圖片:
$red=imagecolorallocate($img, 0xFF, 0x00, 0x00);進行分配畫筆顏色
imagefill($img, 0, 0, $red);進行線條的繪製,通過指定起點跟終點來最終得到線條。
imagepng($img);得到一個圖片文件,指定文件名將繪製後的圖像保存到文件中。
imagedestroy($img);銷燬圖片

[php] view plain copy
  1. GD指的是Graphic Device,PHP的GD庫是用來處理圖形的擴展庫,通過GD庫提供的一系列API,可以對圖像進行處理或者直接生成新的圖片。  
  2.   
  3. PHP除了能進行文本處理以外,通過GD庫,可以對JPG、PNG、GIF、SWF等圖片進行處理。GD庫常用在圖片加水印,驗證碼生成等方面。  
  4.   
  5. PHP默認已經集成了GD庫,只需要在安裝的時候開啓就行。  
  6.   
  7. header("content-type: image/png");  
  8. $img=imagecreatetruecolor(100, 100);  
  9. $red=imagecolorallocate($img, 0xFF, 0x00, 0x00);  
  10. imagefill($img, 0, 0, $red);  
  11. imagepng($img);  
  12. imagedestroy($img);  

[php] view plain copy
  1. <?php  
  2.     header("content-type: image/png");  
  3.     $img=imagecreatetruecolor(200, 100);  
  4.     $red=imagecolorallocate($img, 0, 0, 0);  
  5.     imagefill($img, 0, 0, $red);  
  6.     imagepng($img);  
  7.     imagedestroy($img);  
  8. ?>  

PHP圖形操作之繪製線條


要對圖形進行操作,首先要新建一個畫布,通過imagecreatetruecolor函數可以創建一個真彩色的空白圖片:

$img = imagecreatetruecolor(100, 100);

GD庫中對於畫筆所用的顏色,需要通過imagecolorallocate函數進行分配,通過參數設定RGB的顏色值來確定畫筆的顏色:

$red = imagecolorallocate($img, 0xFF, 0x00, 0x00);

然後我們通過調用繪製線段函數imageline進行線條的繪製,通過指定起點跟終點來最終得到線條。

imageline($img, 0, 0, 100, 100, $red);

線條繪製好以後,通過header與imagepng進行圖像的輸出。

header("content-type: image/png");
imagepng($img);

最後可以調用imagedestroy釋放該圖片佔用的內存。

imagedestroy($img);

通過上面的步驟,可以發現PHP繪製圖形非常的簡單,但很多時候我們不只是需要輸出圖片,可能我們還需要得到一個圖片文件,可以通過imagepng函數指定文件名將繪製後的圖像保存到文件中。

imagepng($img, 'img.png');

[php] view plain copy
  1. <?php  
  2.     $img = imagecreatetruecolor(70, 20);  
  3.     $red = imagecolorallocate($img, 0xFF, 0x00, 0x00);  
  4.     //在這裏繪製文字  
  5.     $str ="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";  
  6.     $str1 = " ";  
  7.     for($i=0;$i<6;$i++)//循環6次  
  8.     {  
  9.         $str1 .= $str[rand(0,(strlen($str)-1))];//連接隨機字符  
  10.     }  
  11.     imagestring($img,5,0,0,$str1,$red);  
  12.     header("content-type: image/png");  
  13.     imagepng($img);  
  14.     imagedestroy($img);  


PHP圖形操作之輸出圖像文件

通過imagepng可以直接輸出圖像到瀏覽器,但是很多時候,我們希望將處理好的圖像保存到文件,以便可以多次使用。通過指定路徑參數將圖像保存到文件中。
$filename = 'img.png';
imagepng($img, $filename);

使用imagepng可以將圖像保存成png格式,如果要保存成其他格式需要使用不同的函數,使用imagejpeg將圖片保存成jpeg格式,imagegif將圖片保存成gif格式,需要說明的是,imagejpeg會對圖片進行壓縮,因此還可以設置一個質量參數。

$filename = 'img.jpg';
​imagejpeg($img, $filename, 80);
[php] view plain copy
  1. <?php  
  2.     $img = imagecreatetruecolor(100, 100);  
  3.     $red = imagecolorallocate($img, 0xFF, 0x00, 0x00);  
  4.     imagestring($img, 5, 0, 0, "Hello world"$red);  
  5.     $filename = 'img.png';  
  6.     //在這裏將圖片保存到$filename文件中  
  7.     imagepng($img$filename);  
  8.   
  9.     imagedestroy($img);  
  10.     if (file_exists($filename)) {  
  11.         echo '文件保存成功';  
  12.     }  

PHP圖形操作之生成圖像驗證碼

簡單的驗證碼其實就是在圖片中輸出了幾個字符,通過我們前面章節講到的imagestring函數就能實現。

但是在處理上,爲了使驗證碼更加的安全,防止其他程序自動識別,因此常常需要對驗證碼進行一些干擾處理,通常會採用繪製一些噪點,干擾線段,對輸出的字符進行傾斜、扭曲等操作。

可以使用imagesetpixel繪製點來實現噪點干擾,但是隻繪製一個點的作用不大,因此這裏常常會使用循環進行隨機繪製。

for($i=0;$i<50;$i++) {
  imagesetpixel($im, rand(0, 100) , rand(0, 100) , $black); 
  imagesetpixel($im, rand(0, 100) , rand(0, 100) , $green);
} 
[php] view plain copy
  1. <?php  
  2.     $img = imagecreatetruecolor(100, 40);  
  3.     $black = imagecolorallocate($img, 0x00, 0x00, 0x00);  
  4.     $green = imagecolorallocate($img, 0x00, 0xFF, 0x00);  
  5.     $white = imagecolorallocate($img, 0xFF, 0xFF, 0xFF);  
  6.     imagefill($img,0,0,$white);  
  7.     //生成隨機的驗證碼  
  8.     $code = '';  
  9.     for($i = 0; $i < 4; $i++) {  
  10.         $code .= rand(0, 9);  
  11.     }  
  12.     imagestring($img, 5, 10, 10, $code$black);  
  13.     //加入噪點干擾  
  14.     for($i=0;$i<400;$i++) {  
  15.       imagesetpixel($img, rand(0, 100) , rand(0, 100) , $black);   
  16.       imagesetpixel($img, rand(0, 100) , rand(0, 100) , $green);  
  17.     }  
  18.     //輸出驗證碼  
  19.     header("content-type: image/png");  
  20.     imagepng($img);  
  21.     imagedestroy($img);  


PHP圖形操作之給圖片添加水印

給圖片添加水印的方法一般有兩種,一種是在圖片上面加上一個字符串,另一種是在圖片上加上一個logo或者其他的圖片。

因爲這裏處理的是已經存在的圖片,所以可以直接從已存在的圖片建立畫布,通過imagecreatefromjpeg可以直接從圖片文件創建圖像。

$im = imagecreatefromjpeg($filename);

創建圖像對象以後,我們就可以通過前面的GD函數,繪製字符串到圖像上。如果要加的水印是一個logo圖片,那麼就需要再建立一個圖像對象,然後通過GD函數imagecopy將logo的圖像複製到源圖像中。

$logo = imagecreatefrompng($filename);
imagecopy($im, $logo, 15, 15, 0, 0, $width, $height);

當將logo圖片複製到原圖片上以後,將加水印後的圖片輸出保存就完成了加水印處理。

imagejpeg($im, $filename);
[php] view plain copy
  1. <?php  
  2.     //這裏僅僅是爲了案例需要準備一些素材圖片  
  3.     $url = 'http://www.iyi8.com/uploadfile/2014/0521/20140521105216901.jpg';  
  4.     $content = file_get_contents($url);  
  5.     $filename = 'tmp.jpg';  
  6.     file_put_contents($filename$content);  
  7.     $url = 'http://wiki.ubuntu.org.cn/images/3/3b/Qref_Edubuntu_Logo.png';  
  8.     file_put_contents('logo.png'file_get_contents($url));  
  9.     //開始添加水印操作  
  10.     $im = imagecreatefromjpeg($filename);  
  11.     $logo = imagecreatefrompng('logo.png');  
  12.     $size = getimagesize('logo.png');  
  13.     imagecopy($im$logo, 15, 15, 0, 0, $size[0], $size[1]);   
  14.        
  15.     header("content-type: image/jpeg");  
  16.     imagejpeg($im);  


PHP異常處理

PHP異常處理之拋出一個異常

從PHP5開始,PHP支持異常處理,異常處理是面向對象一個重要特性,PHP代碼中的異常通過throw拋出,異常拋出之後,後面的代碼將不會再被執行。

既然拋出異常會中斷程序執行,那麼爲什麼還需要使用異常處理?

異常拋出被用於在遇到未知錯誤,或者不符合預先設定的條件時,通知客戶程序,以便進行其他相關處理,不至於使程序直接報錯中斷。

當代碼中使用了try catch的時候,拋出的異常會在catch中捕獲,否則會直接中斷。

 

1、基本語法
        try{
            //可能出現錯誤或異常的代碼
            //catch表示捕獲,Exception是php已定義好的異常類
        } catch(Exception $e){
            //對異常處理,方法:
                //1、自己處理
                //2、不處理,將其再次拋出
        }
2、處理處理程序應當包括:
Try - 使用異常的函數應該位於 "try"  代碼塊內。如果沒有觸發異常,則代碼將照常繼續執行。但是如果異常被觸發,會拋出一個異常。
Throw - 這裏規定如何觸發異常。注意:每一個 "throw" 必須對應至少一個 "catch",當然可以對應多個"catch"
Catch - "catch" 代碼塊會捕獲異常,並創建一個包含異常信息的對象。

//創建可拋出一個異常的函數
function checkNum($number){
     if($number>1){
         throw new Exception("異常提示-數字必須小於等於1");
     }
     return true;
 }
 
//在 "try" 代碼塊中觸發異常
 try{
     checkNum(2);
     //如果異常被拋出,那麼下面一行代碼將不會被輸出
     echo '如果能看到這個提示,說明你的數字小於等於1';
 }catch(Exception $e){
     //捕獲異常
     echo '捕獲異常: ' .$e->getMessage();
 }

上面代碼將獲得類似這樣一個錯誤:

捕獲異常:: 異常提示-數字必須小於等於1

例子解釋:

上面的代碼拋出了一個異常,並捕獲了它:

創建 checkNum() 函數。它檢測數字是否大於 1。如果是,則拋出一個異常。
在 "try" 代碼塊中調用 checkNum() 函數。
checkNum() 函數中的異常被拋出
"catch" 代碼塊接收到該異常,並創建一個包含異常信息的對象 ($e)。
通過從這個 exception 對象調用 $e->getMessage(),輸出來自該異常的錯誤消息

[php] view plain copy
  1. <?php  
  2. $filename = 'test.txt';  
  3. try {  
  4.     if (!file_exists($filename)) {  
  5.       throw new Exception('文件不存在');  
  6.     }  
  7. } catch(Exception $e) {  
  8.     echo $e->getMessage();  
  9. }  

PHP異常處理之異常處理類

PHP具有很多異常處理類,其中Exception是所有異常處理的基類。

Exception具有幾個基本屬性與方法,其中包括了:

message 異常消息內容
code 異常代碼
file 拋出異常的文件名
line 拋出異常在該文件的行數

其中常用的方法有:

getTrace 獲取異常追蹤信息
getTraceAsString 獲取異常追蹤信息的字符串
getMessage 獲取出錯信息

如果必要的話,可以通過繼承Exception類來建立自定義的異常處理類。

//自定義的異常類,繼承了PHP的異常基類Exception
class MyException extends Exception {
    function getInfo() {
        return '自定義錯誤信息';
    }
}

try {
    //使用異常的函數應該位於 "try"  代碼塊內。如果沒有觸發異常,則代碼將照常繼續執行。但是如果異常被觸發,會拋出一個異常。
    throw new MyException('error');//這裏規定如何觸發異常。注意:每一個 "throw" 必須對應至少一個 "catch",當然可以對應多個"catch"
} catch(Exception $e) {//"catch" 代碼塊會捕獲異常,並創建一個包含異常信息的對象
    echo $e->getInfo();//獲取自定義的異常信息
    echo $e->getMessage();//獲取繼承自基類的getMessage信息
}
[php] view plain copy
  1. <?php  
  2. class MyException extends Exception {  
  3.     function getInfo() {  
  4.         return '自定義錯誤信息';  
  5.     }  
  6. }  
  7.   
  8. try {  
  9.     throw new MyException('error');  
  10. } catch(Exception $e) {  
  11.     echo $e->getInfo();  
  12. }  
  13. ?>  

PHP異常處理之捕獲異常信息

我們可以通過try catch來捕獲異常,我們將執行的代碼放在try代碼塊中,一旦其中的代碼拋出異常,就能在catch中捕獲。

這裏我們只是通過案例來了解try catch的機制以及異常捕獲的方法,在實際應用中,不會輕易的拋出異常,只有在極端情況或者非常重要的情況下,纔會拋出異常,拋出異常,可以保障程序的正確性與安全,避免導致不可預知的bug。

一般的異常處理流程代碼爲:

try {
    throw new Exception('wrong');
} catch(Exception $ex) {
    echo 'Error:'.$ex->getMessage().'<br>';
    echo $ex->getTraceAsString().'<br>';
}
echo '異常處理後,繼續執行其他代碼';
[php] view plain copy
  1. <?php  
  2. try {  
  3.     throw new Exception('wrong');  
  4. } catch(Exception $ex) {  
  5.     echo 'Error:'.$ex->getMessage().'<br>';  
  6.     echo $ex->getTraceAsString().'<br>';  
  7. }  
  8. echo '異常處理後,繼續執行其他代碼';  

PHP異常處理之獲取錯誤發生的所在行

在異常被捕獲之後,我們可以通過異常處理對象獲取其中的異常信息,前面我們已經瞭解捕獲方式,以及獲取基本的錯誤信息。

在實際應用中,我們通常會獲取足夠多的異常信息,然後寫入到錯誤日誌中。

通過我們需要將報錯的文件名、行號、錯誤信息、異常追蹤信息等記錄到日誌中,以便調試與修復問題。

[php] view plain copy
  1. <?php  
  2. try {  
  3.     throw new Exception('wrong');  
  4. } catch(Exception $ex) {  
  5.     $msg = 'Error:'.$ex->getMessage()."\n";  
  6.     $msg.= $ex->getTraceAsString()."\n";  
  7.     $msg.= '異常行號:'.$ex->getLine()."\n";  
  8.     $msg.= '所在文件:'.$ex->getFile()."\n";  
  9.     //將異常信息記錄到日誌中  
  10.     file_put_contents('error.log'$msg);  
  11. }  


數據庫操作

PHP支持哪些數據庫

PHP通過安裝相應的擴展來實現數據庫操作,現代應用程序的設計離不開數據庫的應用,當前主流的數據庫有MsSQL,MySQL,Sybase,Db2,Oracle,PostgreSQL,Access等,這些數據庫PHP都能夠安裝擴展來支持,一般情況下常說的LAMP架構指的是:Linux、Apache、Mysql、PHP,因此Mysql數據庫在PHP中的應用非常廣泛
[php] view plain copy
  1. <?php  
  2. if (function_exists('mysql_connect')) {  
  3.     echo 'Mysql擴展已經安裝';  
  4. }  
  5. ?>  

PHP數據庫擴展

HP中一個數據庫可能有一個或者多個擴展,其中既有官方的,也有第三方提供的。像Mysql常用的擴展有原生的mysql庫,也可以使用增強版的mysqli擴展,還可以使用PDO進行連接與操作。

不同的擴展提供基本相近的操作方法,不同的是可能具備一些新特性,以及操作性能可能會有所不同。

MySQL擴展進行數據庫連接的方法:

$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');

mysqli擴展:

$link = mysqli_connect('mysql_host', 'mysql_user', 'mysql_password');

PDO擴展

$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
[php] view plain copy
  1. <?php  
  2. $link = mysql_connect('127.0.0.1''code1'''or die('數據庫連接失敗');  
  3. mysql_select_db('code1');  
  4. mysql_query("set names 'utf8'");  
  5. $result = mysql_query('select * from user limit 1');  
  6. $row = mysql_fetch_assoc($result);  
  7. print_r($row);  

PHP數據庫操作之連接MySQL數據庫

PHP要對數據庫進行操作,首先要做的是與數據庫建立連接,通常我們使用mysql_connect函數進行數據庫連接,該函數需要指定數據庫的地址,用戶名及密碼。

$host = 'localhost';
$user = 'code1';
$pass = '';
$link = mysql_connect($host, $user, $pass);

PHP連接數據庫的方式類似於直接在命令行下通過進行連接,類似:mysql -hlocalhost -ucode1 -p,當連接成功以後,我們需要選擇一個操作的數據庫,通過mysql_select_db函數來選擇數據庫。

mysql_select_db('code1');

通常我們會先設置一下當前連接使用的字符編碼,一般的我們會使用utf8編碼。

mysql_query("set names 'utf8'");

通過上面的步驟,我們就與數據庫建立了連接,可以進行數據操作了。

[php] view plain copy
  1. <?php  
  2. $host = '127.0.0.1';  
  3. $user = 'code1';  
  4. $pass = '';  
  5. //在這裏編寫數據庫連接代碼  
  6. $link = mysql_connect($host$user$pass);  
  7. mysql_select_db('code1');  
  8. mysql_query("set names 'utf8'");  

PHP數據庫操作之執行MySQL查詢

在數據庫建立連接以後就可以進行查詢,採用mysql_query加sql語句的形式向數據庫發送查詢指令。

$res = mysql_query('select * from user limit 1');

對於查詢類的語句會返回一個資源句柄(resource),可以通過該資源獲取查詢結果集中的數據。

$row = mysql_fetch_array($res);
var_dump($row);

默認的,PHP使用最近的數據庫連接執行查詢,但如果存在多個連接的情況,則可以通過參數指令從那個連接中進行查詢。

$link1 = mysql_connect('127.0.0.1', 'code1', '');
$link2 = mysql_connect('127.0.0.1', 'code1', '', true); //開啓一個新的連接
$res = mysql_query('select * from user limit 1', $link1); //從第一個連接中查詢數據
[php] view plain copy
  1. <?php  
  2. //連接數據庫  
  3. error_reporting(0);  
  4. mysql_connect('127.0.0.1''code1''');  
  5. mysql_select_db('code1');  
  6. mysql_query("set names 'utf8'");  
  7. //在這裏進行數據查詢  
  8. $res=mysql_query('select * from user limit 1');  
  9. $row=mysql_fetch_array($res);  
  10. var_dump($row);  

PHP數據庫操作之插入新數據到MySQL中

當我們瞭解瞭如何使用mysql_query進行數據查詢以後,那麼類似的,插入數據其實也是通過執行一個sql語句來實現,例如:

$sql = "insert into user(name, age, class) values('李四', 18, '高三一班')";
mysql_query($sql); //執行插入語句

通常數據都是存儲在變量或者數組中,因此sql語句需要先進行字符串拼接得到。

$name = '李四';
$age = 18;
$class = '高三一班';
$sql = "insert into user(name, age, class) values('$name', '$age', '$class')";
mysql_query($sql); //執行插入語句

在mysql中,執行插入語句以後,可以得到自增的主鍵id,通過PHP的mysql_insert_id函數可以獲取該id。

$uid = mysql_insert_id();

這個id的作用非常大,通常可以用來判斷是否插入成功,或者作爲關聯ID進行其他的數據操作。

[php] view plain copy
  1. <?php  
  2. //連接數據庫  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //已知的數據變量有  
  7. $name = '李四';  
  8. $age = 18;  
  9. $class = '高三一班';  
  10. //在這裏進行數據查詢  
  11.   
  12. //首先查看有什麼數據表  
  13. print_r(mysql_fetch_array(mysql_query('SHOW TABLES')));  
  14. //查看錶的結構,可以看到5個字段  
  15. $sql = mysql_query('DESC test');  
  16. var_dump(mysql_fetch_array($sql));  
  17. //查看錶的數據  
  18. $sql = mysql_query('SELECT * FROM test');  
  19. var_dump(mysql_fetch_array($sql));  
  20. //插入數據  
  21. $sql = mysql_query("INSERT test('name','age','class') VALUES('$name','$age','$class')");  
  22. var_dump(mysql_insert_id());  

PHP數據庫操作之取得數據查詢結果

通過前面的章節,我們發現PHP操作數據庫跟MySql客戶端上操作極爲相似,先進行連接,然後執行sql語句,再然後獲取我們想要的結果集。

PHP有多個函數可以獲取數據集中的一行數據,最常用的是mysql_fetch_array,可以通過設定參數來更改行數據的下標,默認的會包含數字索引的下標以及字段名的關聯索引下標。

$sql = "select * from user limit 1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

可以通過設定參數MYSQL_NUM只獲取數字索引數組,等同於mysql_fetch_row函數,如果設定參數爲MYSQL_ASSOC則只獲取關聯索引數組,等同於mysql_fetch_assoc函數。

$row = mysql_fetch_row($result);
$row = mysql_fetch_array($result, MYSQL_NUM); //這兩個方法獲取的數據是一樣的
$row = mysql_fetch_assoc($result);
$row = mysql_fetch_array($result, MYSQL_ASSOC);

如果要獲取數據集中的所有數據,我們通過循環來遍歷整個結果集。

$data = array();
while ($row = mysql_fetch_array($result)) {
    $data[] = $row;
}
[php] view plain copy
  1. <?php  
  2. //連接數據庫  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //數據預處理 防止查詢不到數據  
  7. mysql_query("insert into user(name, age, class) values('王二', 19, '高三五班')");  
  8. //進行數據查詢  
  9. $sql = "select * from user limit 1";  
  10. $result = mysql_query($sql);  
  11.   
  12. //在這裏獲取一行數據  
  13. // $row=mysql_fetch_row($result);  
  14. $row=mysql_fetch_row($result);  
  15.   
  16. echo '<pre>';  
  17. print_r($row);  
  18. echo '</pre>';  

PHP數據庫操作之查詢分頁數據

上一節中,我們瞭解到通過循環可以獲取一個查詢的所有數據,在實際應用中,我們並不希望一次性獲取數據表中的所有數據,那樣性能會非常的低,因此會使用翻頁功能,每頁僅顯示10條或者20條數據。

通過mysql的limit可以很容易的實現分頁,limit m,n表示從m行後取n行數據,在PHP中我們需要構造m與n來實現獲取某一頁的所有數據。

假定當前頁爲$page,每頁顯示$n條數據,那麼m爲當前頁前面所有的數據,既$m = ($page-1) * $n,在知道了翻頁原理以後,那麼我們很容易通過構造SQL語句在PHP中實現數據翻頁。

$page = 2;
$n = 2;
$m = ($page - 1) * $n;
$sql = "select * from user limit $m, $n";
$result = mysql_query($sql);
//循環獲取當前頁的數據
$data = array();
while ($row = mysql_fetch_assoc($result)) {
    $data[] = $row;
}

在上面的例子中,我們使用了$m與$n變量來表示偏移量與每頁數據條數,但我們推薦使用更有意義的變量名來表示,比如$pagesize, $start, $offset等,這樣更容易理解,有助於團隊協作開發。

[php] view plain copy
  1. <?php  
  2. //連接數據庫  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //預設翻頁參數  
  7. $page = 2;  
  8. $pagesize = 2;  
  9. //在這裏構建分頁查詢  
  10. $offset = ($page - 1) * $pagesize;  
  11. $sql = "select * from user limit $offset, $pagesize";  
  12.   
  13. //獲取翻頁數據  
  14. $result = mysql_query($sql);  
  15. $data = array();  
  16. while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {  
  17.     $data[] = $row;  
  18. }  
  19. echo '<pre>';  
  20. print_r($data);  
  21. echo '</pre>';  

[php] view plain copy
  1. <?php  
  2. //連接數據庫  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //預設數據以便進行更新操作  
  7. mysql_query("insert into user(name, age, class) values('王二', 19, '高三五班')");  
  8. $id = mysql_insert_id();  
  9. //在這裏更新id爲$id的行的名字爲李白  
  10. $sql = "update user set name='李白' where id=$id";  
  11. mysql_query($sql);  
  12. //輸出更新數據條數  
  13. echo '數據更新行數:'.mysql_affected_rows();  
  14. mysql_query("delete from user where id='$id'");  

PHP數據庫操作之關閉MySQL連接

當數據庫操作完成以後,可以使用mysql_close關閉數據庫連接,默認的,當PHP執行完畢以後,會自動的關閉數據庫連接。

mysql_close();

雖然PHP會自動關閉數據庫連接,一般情況下已經滿足需求,但是在對性能要求比較高的情況下,可以在進行完數據庫操作之後儘快關閉數據庫連接,以節省資源,提高性能。

在存在多個數據庫連接的情況下,可以設定連接資源參數來關閉指定的數據庫連接。

$link = mysql_connect($host, $user, $pass);
mysql_close($link);
[php] view plain copy
  1. <?php  
  2. //連接數據庫  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //在這裏關閉數據庫連接  
  7. mysql_close();  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章