PHP:対象学習ノート向け、重点的シミュレーションMixin(組み込み)

53468 ワード

背景
Python、Node、RubyにとってPHPは学びやすく、使いやすい言語です.この特徴がWEB開発分野のトップにもなっているので、PHPの対象部分に対する学習ノートを記録します.
まず複雑な例を示します:Mixin(ドープ)
RubyとPythonはとてもきれいな文法サポートで組み込むことができますが、PHPは実現できますか?やってみましょう.
この文書は、他の言語の組み込み例を参照して、設計原則:「多重継承」を見直し、機会を見つけて「混入(Mixin)」を抱きしめてください。を参照してください.
PHP5.4提供されるTraitsメカニズムは、以下の例では5.3バージョンのメカニズムを用いてシミュレーションされた便利なシミュレーションで組み込まれる.
望ましい最終効果
 1 class Playable
 2 {
 3     public function play($that)
 4     {
 5         echo "    ,".$that->name;
 6     }
 7 }
 8 
 9 class Base extends _Object 
10 {
11     public $name = "   <br/>";
12 }
13 
14 class Child extends Base {}
15 
16 Base::implement(new Playable());
17 
18 $base = new Base();
19 $child = new Child();
20 
21 $base->play();
22 $child->play();

特にC#の拡張方法に似ているのではないでしょうか.
インプリメンテーションコード
 1 class _Object
 2 {
 3     private static $mixins = array();
 4 
 5     public static function implement($target)
 6     {
 7         $class = get_called_class();
 8 
 9         if (!isset(self::$mixins[$class]))
10         {
11             self::$mixins[$class] = array();
12         }
13 
14         foreach (get_class_methods($target) as $method)
15         {
16             self::$mixins[$class][$method] = $target;
17         }
18     }
19 
20     public function class_name()
21     {
22         return self::get_class($this);
23     }
24 
25     public function __call($method, $params)
26     {
27         $params = array_merge(array($this), $params);
28         $class  = $class = get_called_class();
29         
30         $mixin = $this->find_mixin($class, $method);
31 
32         call_user_func_array($mixin, $params);
33     }
34 
35     private function find_mixin($class, $method)
36     {
37         while ($class != NULL) 
38         {
39             if (isset(self::$mixins[$class][$method]))
40             {
41                 $target = self::$mixins[$class][$method];
42 
43                 return array($target, $method);
44             }
45 
46             $class = get_parent_class($class);
47         }
48 
49         throw new MethodException("   $method    ");
50     }
51 }

見ても分からないので大丈夫です.続きを見て、後でこれを見ます.
オブジェクト向け
多くの情報はコメントで見ることができ、文の中では二度と繰り返されません.
基本タイプ宣言
コード#コード#
 1 <?php
 2 
 3 header("content-type: text/html; charset=utf-8");
 4 
 5 // 6 //            ,          :public、protected private。
 7 class TestClass {
 8     //          private。
 9     private $private_property = "    <br/>";
10 
11     // var          public。
12     var $public_property = "    <br/>";
13 
14     //          public。
15     public function public_method() {
16         echo $this->private_property;
17     }
18 }
19 
20 $test = new TestClass();
21 
22 echo $test->public_property;
23 $test->public_method();
24 
25 ?>

実行結果
1 //     
2 //     

継承:継承とインタフェースの継承を実現
コード#コード#
 1 <?php 
 2 
 3 header("content-type: text/html; charset=utf-8");
 4 
 5 /*
 6  *   interface         ,                 。
 7  */
 8 interface Playable {
 9     function play();
10 }
11 
12 /*
13  *   abstract             。
14  */
15 abstract class Base {
16     private    $header = "";
17     private    $rooter = "";
18 
19     public function __construct($header, $rooter) {
20         $this->header = $header;
21         $this->rooter = $rooter;
22     }
23     
24     public function write() {
25         $this->writeHeader();
26         $this->writeContent();
27         $this->writeRooter();
28     }
29 
30     private function writeHeader() {
31         echo $this->header."<br/>";
32     }
33 
34     private function writeRooter() {
35         echo $this->rooter."<br/>";
36     }
37 
38     protected abstract function writeContent();
39 }
40 
41 /*
42  *   final               。
43  *   parent::               。
44  */
45 final class Child extends Base implements Playable {
46     private    $content = "";
47 
48     public function __construct($header, $rooter, $content) {
49         parent::__construct($header, $rooter);
50 
51         $this->content = $content;
52     }
53 
54     protected function writeContent() {
55         echo $this->content."<br/>";
56     }
57 
58     public function play() {
59         echo "   。。。<br/>";
60     }
61 
62     public function __destruct() {
63         echo "   <br/>";
64     }
65 }
66 
67 $child = new Child(" ", " ", "  ");
68 $child->write("   ");
69 $child->play();
70 
71 ?>

実行結果
1  
2   
3  
4    。。。
5    

静的メンバー
コード#コード#
 1 <?php
 2 
 3 header("content-type: text/html; charset=utf-8");
 4 
 5 class StaticBaseClass {
 6     public static $StaticProperty = "      <br/>";
 7     const MAX = "    <br/>";
 8 
 9     public static function staticMethod() {
10         /*           self   ,  self          ,         ,
11          *                          ,            static
12          *    。
13          */
14 
15         echo get_called_class()." self::\$StaticProperty ".self::$StaticProperty;
16         echo get_called_class()." StaticBaseClass::\$StaticProperty ".StaticBaseClass::$StaticProperty;
17         echo get_called_class()." static::\$StaticProperty ".static::$StaticProperty;
18 
19         echo get_called_class()." self::MAX ".self::MAX;
20         echo get_called_class()." StaticBaseClass::MAX ".StaticBaseClass::MAX;
21         echo get_called_class()." static::MAX ".static::MAX;
22     }
23 }
24 
25 class StaticChildClass extends StaticBaseClass {
26     public static $StaticProperty = "      <br/>";
27     const MAX = "    <br/>";
28 }
29 
30 //
31 StaticBaseClass::StaticMethod();
32 echo StaticBaseClass::$StaticProperty;
33 echo StaticBaseClass::MAX;
34 
35 //
36 StaticChildClass::StaticMethod();
37 echo StaticChildClass::$StaticProperty;
38 echo StaticChildClass::MAX;
39 
40 ?>

実行結果
 1 StaticBaseClass self::$StaticProperty       
 2 StaticBaseClass StaticBaseClass::$StaticProperty       
 3 StaticBaseClass static::$StaticProperty       
 4 StaticBaseClass self::MAX     
 5 StaticBaseClass StaticBaseClass::MAX     
 6 StaticBaseClass static::MAX     
 7       
 8     
 9 StaticChildClass self::$StaticProperty       
10 StaticChildClass StaticBaseClass::$StaticProperty       
11 StaticChildClass static::$StaticProperty       
12 StaticChildClass self::MAX     
13 StaticChildClass StaticBaseClass::MAX     
14 StaticChildClass static::MAX     
15       
16     

また魔法の方法
コード#コード#
 1 <?php
 2 
 3 header("content-type: text/html; charset=utf-8");
 4 
 5 /*
 6  *        :                   。
 7  */
 8 class WebDeveloper {
 9   public $info = array();
10 
11   //       ,              。
12   public function __set($item, $value) {
13     $this->info[$item] = $value;
14   }
15 
16   //       ,              。
17   public function __get($item) {
18     return $this->info[$item];
19   }
20 
21   //    isset   ,              。
22   public function __isset($item) {
23     return isset($this->info[$item]);
24   }
25 
26   //    unset   ,              。
27   public function __unset($item) {
28     unset($this->info[$item]);
29   }
30 
31   //         ,              。
32   public function __call($method_name, $args) {
33     echo $method_name, var_dump($args), "<br/>";
34   }
35 }
36 
37 $developer = new WebDeveloper();
38 $developer->name = "   ";
39 
40 echo "{$developer->name}<br/>";
41 echo (isset($developer->name) ? "TRUE" : "FALSE")."<br/>";
42 unset($developer->name);
43 echo (isset($developer->name) ? "TRUE" : "FALSE")."<br/>";
44 
45 $developer->saySomething('hi!','how are you!');
46 
47 ?>

出力結果
1    
2 TRUE
3 FALSE
4 saySomethingarray(2) { [0]=> string(3) "hi!" [1]=> string(12) "how are you!" } 

呼び出し可能なオブジェクト(実は魔法の方法)
コード#コード#
 1 <?php 
 2 header("content-type: text/html; charset=utf-8");
 3 
 4 class CallableClass
 5 {
 6     public function __invoke($x)
 7     {
 8         var_dump($x);
 9     }
10 }
11 
12 $obj = new CallableClass;
13 
14 $obj(5);
15 call_user_func_array($obj, array(5));
16 var_dump(is_callable($obj));
17 
18 ?>

結果の入力
1 int(5) int(5) bool(true) 

Reflection
コード#コード#
 1 <?php 
 2 
 3 header("content-type: text/html; charset=utf-8");
 4 
 5 /*
 6  *   interface         ,                 。
 7  */
 8 interface Playable {
 9     function play();
10 }
11 
12 /*
13  *   abstract             。
14  */
15 abstract class Base {
16     private    $header = "";
17     private    $rooter = "";
18 
19     public static $StaticProperty = "      <br/>";
20     const MAX = "    <br/>";
21 
22     public function __construct($header, $rooter) {
23         $this->header = $header;
24         $this->rooter = $rooter;
25     }
26     
27     public function write() {
28         $this->writeHeader();
29         $this->writeContent();
30         $this->writeRooter();
31     }
32 
33     private function writeHeader() {
34         echo $this->header."<br/>";
35     }
36 
37     private function writeRooter() {
38         echo $this->rooter."<br/>";
39     }
40 
41     protected abstract function writeContent();
42 }
43 
44 /*
45  *   final               。
46  *   parent::               。
47  */
48 final class Child extends Base implements Playable {
49     public $content = "";
50     public static $StaticProperty = "      <br/>";
51     const MAX = "    <br/>";
52 
53     public function __construct($header, $rooter, $content) {
54         parent::__construct($header, $rooter);
55 
56         $this->content = $content;
57     }
58 
59     protected function writeContent() {
60         echo $this->content."<br/>";
61     }
62 
63     public function play() {
64         echo "   。。。<br/>";
65     }
66 
67     public function __destruct() {
68         echo "   ";
69     }
70 }
71 
72 $child = new Child("  ", "  ", "  ");
73 
74 echo get_class($child).'<br/>';
75 print_r(get_class_methods(get_class($child)));
76 echo '<br/>';
77 print_r(get_class_vars(get_class($child)));
78 echo '<br/>';
79 echo $child->{"play"}();
80 ?>

出力結果
1 Child
2 Array ( [0] => __construct [1] => play [2] => __destruct [3] => write ) 
3 Array ( [content] => [StaticProperty] =>       
4 ) 
5    。。。
6    

コメント
PHPは静的タイプ、アヒルのタイプ、弱いタイプ、解釈実行言語に属し、これらの概念と対応する言語の特色を詳しく紹介する.