重複使用程式碼與編寫函式:減少成本,增加可靠性,一致性。 使用require()與include(): 兩者幾乎相同,引入失敗時會對結構產生嚴重錯誤使用require(),不會產生嚴重錯誤時使用include()。 為了避免檔案被重複加入,使用require_one()與include_one()可確保檔案只被加入一次。 如果你夠細心使用require()與include()會讓程式執行更快。 使用auto_prepend_file與auto_append_file 可讓網頁自動使用它。Apache web可搭配.htaccess來自動載入一些網頁,例如頁手頁尾。 使用PHP函式 使用function_name();可呼叫函式。 特定函式通常需要使用特定的資料型態以下是fopen()函式原型: resource fopen(string filename,string mode[, bool use_include_path=false [, resource context]]); 學會正確地解讀這些規則對使用來說非常重要。 fopen( string $filename, string $mode, bool $use_include_path = false, ?resource $context = null ): resource|false 呼叫未定義函式將報錯。 函式名稱不區分大小寫。 命名規則: 函式名稱不能與既有的函式相同。 函式名稱只能使用字母、數字與底線。 函式名稱的第一個字不能使用數字。 變數函式? 這啥玩意$name();類似指標或參照? 預設參數function_name($data = '') 使用參數: $name = 變數 此為參數,可搭配函數達到指定效果。 刪除變數:unset($name); 暸解範圍: 函式範圍內宣告的變數,為區域變數。 在函式外宣告的變數,為全域變數,作用範圍為宣告後到檔案結尾為止。 如果你想要在函式內使用全域變數可在函示開始時宣告global $name;讓name變數擁有全域函數值。 以址傳遞&以值傳遞: 匯入參數時,會建立一個新的變數,原本變數的值不會被函數改變。 如果要修改一個值,就該使用以址傳遞。 function increment(&$value,$amount = 1){ $value = $value + $amount; } 使用return關鍵字: 可在函示得到預期結果時終止函式。 return $name; 實作遞迴: 遞回函式會呼叫他自己的韓式,這函式特別適合用來巡覽動態資料結構,例如連接的串列與樹狀結構。 快速排序有看到此函式。 實作匿名函式:(或closure) 這種函式沒有名稱。他們通常會被當成回呼來使用。也就是被傳遞給其他函式的函式...三小? 一般例子: bool array_walk(array arr, callable func[, mixed userdata]) function my_print($value){ echo "$value<br/>"; } array($array,'my_print'); 匿名函式: array_walk($array, function($value){ echo "$value <br/>";}); 也可用變數保存closure函式: $printer = function($value){ echo "$value <br/>";}; 如何使用: $printer('Hello'); 使用這做法可以將array_walk()呼叫精簡成: array_walk($array, $printer);
物件導向PHP: 物件導向軟體以一堆獨立的物件來設計與建構,這些物件具備屬性與動作,並彼此互動來符合你的需求。 屬性=變數、動作=方法 封裝特性:具有封裝特性,只靠介面來操作存取物件。 較易維護:可以輕鬆修改物件的實作細節來改善效能,加新功能或修改錯誤,而不需要修改介面。 相較程序或函式導向作法,較新。但許多web應用程式仍然是匆促安排的做法以及函式導向方法來設計與編寫的。 多型特性:行為特徵而非物件的特徵。 繼承特性:利用繼承讓相似的物件獲得相同功能。 開發思維: 物件導向程式設計就是在設計系統時將系統的架構建構在每一個系統或子系統所要操作的『物件』上(而不是建構在系統所要完成的『功能』上的設計方式。 不要先問系統要作到什麼功能;先問有哪些東西可以讓系統做到這些功能! 細說: 物件導向系統所需要處理的「物件」或是「資料」作為考慮系統架構的出發點。 先從抽象的層面來分析要處理『類別』(class)的資料? 各種類別的資料會以哪些『方法』(method)來操作? 整個系統是以各個封裝良好的物件模組架構起來的,每一個物件模組就是一個類別定義,它包含有一組私有的資料結構,以及開放給外界用來操作這組資料的一群方法。 程序導向PHP:與程序導向差異在於,程序導向思考方向是完成該行為要採取哪些動作,這些動作需要哪些程序,系統的架構是建立在所要處理的功能上,根據功能來劃分系統裡的各個模組。 相比程序導向開發較花時間,但維護及修改較便捷。 用PHP來建立類別、屬性與動作: 類別的結構:物件的設計圖 class name{ public $apple; public function myMath($count = 0;){ return $count * $apple; } } 建構式:new物件時會自動執行的函示,一般用來初始化這個物件。 class name{ function __construct(){ //初始化的行為 } } 解構式:物件結束行為,被摧毀之前執行的一些動作。(解構式不能接收參數) class name{ function __destruct(){ //結束前執行的行為 } } 實例化類別:使用時,建立物件,實例化後可利用變數去使用物件。 class name2{ $a = new name();//實例化後稱為物件(實例化前稱為類) } 使用類別屬性:建立物件後,操作public屬性(實例化前稱為變數)。 class name2{ $a = new name(); $a->apple = 25;//操作公開變數 } 使用類別方法:建立物件後,操作public方法(實例化前稱為函式)。 class name2{ $a = new name(); $a->apple = 25; $how = $a->myMath(5);//操作公開方法(計算金額) } 控制可見度(修飾子): 封裝encapsulation:把類別的細節隱藏起來讓類別更安全,並減少耦合(互相糾纏不清)的狀況。 public 公開:可提供外部存取。可供:(自身類別)(子類別)(實體物件) protected 保護:只能在子類別(被繼承)與類別內直接存取。可供:(自身類別)(子類別) private 私有:只能在類別裡面存取。可供:(自身類別) 編寫存取函式(魔法函示):當存取到不存在、或沒有讀取權限的屬性時,就會自動觸發__get或__set。 public __get($name){ //回傳變數值(可自行設計) return $this->$name; } public __set($name, $value){ //寫入或創建一個值(可自行設計) $this->$name = $value; } 實作繼承:extends class a{ public function run($dog){ echo $dog.'跑'; } protected function eat($dog){ echo $dog.'吃'; } private function set($dog){ echo $dog.'座'; } public function up($dog){ echo $dog.'站'; } final function left($dog){ echo $dog.'往左'; } } class b extends a{ public function set($dog){ echo $dog.'就是不座下'; } public function up($dog){ echo $dog.'就是不站'; } final function left($dog){ echo $dog.'就是不往左'; } $a = new b(); //繼承與修飾子的關係: $a->run('吉娃娃');//顯示吉娃娃跑(public公開無法繼承) $a->eat('拉布拉多');//顯示拉布拉多吃(private保護無法繼承) $a->set('柴柴');//顯示柴柴就是不座下(private私有無法繼承) //覆寫:相同名稱方法會覆蓋父類別方法。 $a->up('柯基');//顯示柯基就是不站(雖然繼承了但是被覆寫) //繼承避免覆寫:final //在初始化時就會報錯 } 了解多重繼承:單繼承、多重繼承 PHP不支援多重繼承,只能繼承一個父類別,父類別可以擁有多個子類別,但你可以使用多個介面😊 實作介面:介面可讓類別一定要實作裡面所撰寫的變數與函式名稱,諾類別內沒實作會報錯。 interface Displayble{ function display(); } class a implements Displayble{ function display(){ //做什麼 } } 使用特徵:看不懂... 進階物件導向功能: 使用類別常數: echo Math::pi; 檢查類別型態與型態提示: $b instanceof A (B類別是A的子類別? 是 檢查是否為特定類別實例。) 延後靜態繫結:看不懂... self::whichclass(); 複製物件: $a = clone $b; 使用抽象類別: 用途:在複雜的階層中,確保每一個子類別都含有與覆寫某些特定的用法。這種功能也可以使用介面完成。 使用__call():來多載方法? 不常用。在許多物件導向語言中很常見 public function __call($method, $p){ if($method == "display"){ if(is_object($p[0])){ $this->displayObject($p[0]); }else if(is_array($p[0])){ $this->displayArray($p[0]); }else{ $this->displayScalar($p[0]); } } } 意義不明。 使用__autoload():如果你試著實例化一個尚未被宣告的類別時,他就會被自動呼叫。 function __autoload($name){ include_once $name.".php"; } 實作迭代器與迭代:foreach()迴圈來迭代物件的屬性,遍歷陣列常用。 $x = array('1','2','3','4','5'); foreach($x as $nowValue){ echo '現在數字為:'.$nowValue; } 產生器:取代return的yield可搭配foreach()來實現連續回傳。 function fizzbuzz($start, $end){ $current = $start; while($current <= $end){ if($current%3 == 0 && $current%5 == 0){ yield "fizzbuzz"; }else it($current%3 == 0){ yield "fizz"; }else it($current%5 == 0){ yield "buzz"; }else{ yield $current; } $current++; } } foreach(fizzbuzz(1,20) as $number){ echo $number.'<br>'; } 將類別轉換成字串:魔術方法是一種特殊方法,當對對象執行某些操作時,它會覆蓋 PHP 的默認操作。 public function __toString(){ return (var_export($this,True));//印出類別內的所有屬性值 } 使用反射API:如果你要與未知或未被列入文件的類別接觸時(例如:PHP腳本)可以使用。 命名空間:可將類別或函式群組化,可避免名稱衝突。 orders.php內容: <?php namespace orders; class order{ } class orderItem{ } ?> 使用include 'orders.php'; $myOrder = new orders\order();//可呼叫orders命名空間裡面的東西 使用子命名空間:與命名空間不同是他存在於命名空間內部,使用方式相同,多一層而已。 namespace orders\html\page; $myPage = new orders\html\page\index(); 暸解全域命名空間: namespace是以檔案為單位的。 任何不屬於已宣告的命名空間程式碼,都被歸類為全域變數命名空間。 如果已經在某個命名空間中,想使用全域命名空間(就是沒有命名空間的類別)的類別可以在前方加上\反斜線。 $mypage = new \Page(); 匯入命名空間,以及為他取個別名: 如果你想要使用bob\html\page命名空間內的程式碼,可以使用use bob\html\page as 自訂名稱。 use bob\html\page as myPage; $services = new myPage\Page();