<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                > PHP 使用了一段時間, 從對OOP的不了解, 再到使用, 覺得挺好, 特寫下 OOP并不是為了面向對象而面向對象, 而是為了達到代碼的`重用性`、`靈活性`、`擴展性` # 對象和類 從先有對象才有人類, 這個來說, 有點不合理的合理 類:具有相同屬性的一組對象的集合 對象:類實例化之后就是對象 看下一般的類的定義 ```php <?php class Person{ // 成員變量 private $name; private $sex; private $age; // 構造函數 function __construct($name="",$sex="",$age=""){ if($name===""||$sex===""||$age===""){ throw new Exception("must set name , sex, age"); } $this->name = $name; $this->age = $age; $this->sex = $sex; } // 析構函數 function __destruct(){ echo "byebye\n"; } // 成員方法 function eat(){ echo "my name is ". $this->name; } function sleep(){ echo "i am sleeping"; } } // 類的實例化 $jaime = new Person("jaime", "man", 24); $jaime->eat(); ?> ``` 保存為index.php, 在命令窗口輸入 ```shell $ php index.php my name is jaime byebye ``` 如果 ```php $jaime = new Person("jaime", "man", 24); ``` 改為 ```php $jaime = new Person("jaime", "man"); ``` 則會觸發異常, 會有以下的消息出來, 包括錯誤信息, 錯誤行數, 和堆棧信息 ```shell $ php index.php Fatal error: Uncaught exception 'Exception' with message 'must set name , sex, age' in E:\net\index.php on line 15 Exception: must set name , sex, age in E:\net\index.php on line 15 Call Stack: 0.0025 242440 1. {main}() E:\net\index.php:0 0.0025 243016 2. Person->__construct() E:\net\index.php:30 ``` # 對象和內存 說點理論上的東西吧, 內存的分類: 堆(heap): 不可直接存取, 存儲占有空間很大的數據類型的數據 棧(stack): 可以直接存取, 存儲占用相同空間長度并且占用空間小的數據, 如存放局部變量,函數參數,當前狀態,函數調用信息等 ```php $jaime = new Person("jaime", "man", 24); ``` $jaime是存放在棧內存里面的引用變量, 即存儲在堆中對象的首地址, 一個指針 new Person 實例化出來的對象是存放在堆內存里面的, 是真正的對象實例 # 對象和成員 變量,方法(內部成員函數)的前綴: private: 私有成員 public: ?公有成員(外部接口),沒有加修飾, 默認就是public protected: 保護型成員, 繼承的類可以調用 訪問private修飾的變量 ```shell Fatal error: Cannot access private property Person::$name in E:\net\index.php on line 36 ``` 如果想訪問private, protected修飾的成員: 1. 把private改為public 2. 使用__get(), ___set()魔術方法, 但是還是寫出代碼來看看根據實際情況使用 ```php <?php class Person{ private $name; private $sex; private $age; function __construct($name="",$sex="",$age=""){ if($name===""||$sex===""||$age===""){ throw new Exception("must set name , sex, age"); } $this->name = $name; $this->age = $age; $this->sex = $sex; } function __destruct(){ echo "byebye\n"; } function eat(){ echo "my name is ". $this->name."\n"; } function sleep(){ echo "i am sleeping\n"; } function __get($property_name){ $access_array = ['age','name'];// 只允許訪問age,name兩個私有成員 if(in_array($property_name, $access_array)){ return ($this->$property_name); } else{ return NULL; } } function __set($property_name, $value){ $access_array = ['age'];// 只允許訪問age這個私有成員 if(in_array($property_name, $access_array)){ $this->$property_name = $value; } } } $jaime = new Person("jaime", "man", 24); $jaime->eat(); echo ($jaime->age === NULL)? "NULL":$jaime->age; echo "\n"; echo ($jaime->sex === NULL)? "NULL":$jaime->sex; $jaime->age = 80; echo "\n"; echo ($jaime->age === NULL)? "NULL":$jaime->age; echo "\n"; $jaime->name = "lll"; echo ($jaime->name === NULL)? "NULL":$jaime->name; echo "\n"; ?> ``` 執行結果如下 ```shell $ php index.php my name is jaime 24 NULL 80 jaime byebye ``` # 類的繼承 ```php <?php class Person{ private $name; private $sex; private $age; function __construct($name="",$sex="",$age=""){ if($name===""||$sex===""||$age===""){ throw new Exception("must set name , sex, age"); } $this->name = $name; $this->age = $age; $this->sex = $sex; } function __destruct(){ echo "byebye\n"; } function hello(){ echo "my name is ". $this->name."\n"; } function sleep(){ echo "i am sleeping\n"; } } class Student extends Person { private $school; function __construct($name, $sex, $age, $school) { // 調用父類方法, 構造函數 parent::__construct($name, $sex, $age); $this->school = $school; } // 重載了父類方法 function sleep(){ echo "afternoon sleep\n"; // 調用父類方法 parent::sleep(); } } $jaime = new Student("jaime", "man", 24,"zh"); $jaime->hello(); $jaime->sleep(); ?> ``` 執行后輸出 ```shell $ php index.php my name is jaime afternoon sleep i am sleeping byebye ``` 調用父類的方法需要用parent # 靜態成員和常量 no bb, show code ```php <?php class Person { // 靜態成員屬性 public static $contry = "China"; public static function say(){ // 靜態成員方法, 通過self訪問其它靜態成員 // 類里面的靜態方法只能訪問類的靜態的屬性 echo "I live in ".self::$contry."\n"; } public function show(){ echo "xxx".self::$contry."\n"; } } // 輸出靜態屬性 echo Person::$contry."\n"; // 調用靜態方法, 外部調用用類名::靜態方法 Person::say(); // 給靜態屬性重新賦值 Person::$contry = "American"; Person::say(); (new Person())->show(); ?> ``` 結果 ```shell $ php is.php China en I live in China I live in American xxxAmerican en ``` 類的靜態變量,類似于全局變量,能夠被所有類的實例共享,類的靜態方法也是一樣的,類似于全局函數, 靜態成員被這個類的每個實例對象所共享 訪問靜態方法訪問靜態成員不能用`$this`, 需要用`self` `$this`表示了此方法的對象 'self'表示此靜態方法所在的類, self::成員 # 抽象方法和抽象類 什么叫抽象?不具體的就叫抽象! so 抽象方法 : 類里面沒有具體方法體的方法(其實就是不具體的方法) 抽象類: 含有抽象方法的類, 抽象類不能實例化會報錯"Cannot instantiate abstract class <classname>", 有點像C里面的函數聲明, 僅僅只是一個聲明 ```php <?php abstract class AbstractClass{ // 抽象類里面可以有不是抽象的成員 public $variable; // 抽象方法 abstract function fun1(); abstract function fun2(); function fun3{ echo "我是抽象類中的非抽象方法"; } } class demo0 extends AbstractClass{ // 子類必須把父類中的抽象方法全部都實現, 否則子類中還存在抽象方法,仍是抽象類 function fun1(){ echo "call ".__FUNCTION__."\n"; } function fun2(){ echo "call ".__FUNCTION__."\n"; } } // 我這里是想不出名字, 不建議這樣做, 因為demo0實例化了3次 (new demo0())->fun1(); (new demo0())->fun2(); (new demo0())->fun3(); ?> ``` # 接口interface ## 什么是接口? 如果一個內里面所有的方法都是抽象方法, 我們可以把聲明方式換為接口 接口是一種特殊的抽象類, 接口不能包含成員的任何代碼,只定義成員身。接口成員的具體代碼由實現接口的類提供 ```php <?php interface One{ // 定義常量 const con = "xonst"; // 定義抽象方法, 不用加abstract, 因為都是abstract function fun1(); function fun2(); } ?> ``` ## 接口的繼承 ```php <?php interface Two extends One{ function fun3(); function fun4(); } ?> ``` ## 接口的實現 ```php <?php interface One{ // 定義常量 const con = "xonst"; // 定義抽象方法, 不用加abstract, 因為都是abstract function fun1(); function fun2(); } interface Two extends One{ function fun3(); function fun4(); } // 使用“implements”這個關鍵字去實現接口中的抽象方法 class demo implements Two { function fun1() { echo "call ".__FUNCTION__."\n"; } function fun2() { echo "call ".__FUNCTION__."\n"; } function fun3() { echo "call ".__FUNCTION__."\n"; } function fun4() { echo "call ".__FUNCTION__."\n"; } } (new demo())->fun1(); (new demo())->fun2(); (new demo())->fun3(); (new demo())->fun4(); ?> ``` ## 一個類實現多個接口 一個人要遵守的法律不止一步吧, 所以see code ```php <?php interface One{ // 定義常量 const con = "xonst"; // 定義抽象方法, 不用加abstract, 因為都是abstract function fun1(); function fun2(); } interface Two{ function fun3(); function fun4(); } // 注意這里 class demo implements One, Two { function fun1() { echo "call ".__FUNCTION__."\n"; } function fun2() { echo "call ".__FUNCTION__."\n"; } function fun3() { echo "call ".__FUNCTION__."\n"; } function fun4() { echo "call ".__FUNCTION__."\n"; } } (new demo())->fun1(); (new demo())->fun2(); (new demo())->fun3(); (new demo())->fun4(); ?> ``` 你娶了你老婆你得對她的家人負責吧, 就像下面 ```php // 使用extends繼承一個類,使用implements實現多個接口 class demo extend AbstractClass implements One, Two{ ...... // 所有接口中的方法都要實現才可以實例化對象 } ``` # 反射Reflection 作用: 導出或提取出關于類、方法、屬性、參數等的詳細信息, 執行, 甚至是判斷類中某個方法是否存在 這里我不做多說, 看我在實際的項目中的實際應用, 這是一個API的入口處理函數, 如果存在這個方法就執行并返回結果, 不存在就拋出異常, 因為接口函數是不斷增加甚至是變化的, 使用反射作為api的入口可以讓你的具體的api函數變化了入口也不用改 ``` try { // 使用工廠方法實例化具體的接口 $instance = new \Api\Library\ApiFactory($module, $server, $this->params); // 反射方法 $action = new \ReflectionMethod($instance->instance, $method); // 判斷方法的類型 if (!$action->isPublic() || $action->isStatic()) throw new \ReflectionException(); // 驗證api參數 $validator = new \Api\Library\ApiValidator(); $result = $validator->check($this->params); if (false === $result) { $this->result['code'] = $validator->code ? : $this->result['code']; $this->result['msg'] = $validator->msg ? : $this->result['msg']; throw new \Exception(); } } catch(\Exception $e){ $this->_format(); } // excute $this->result['result'] = $instance->$method(); $this->result['code'] = $instance->getCode(); $this->result['msg'] = $instance->getMsg(); $this->_format(); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看