PHP所提供的”重载”(overloading)是指动态地”创建”类属性和方法。我们是通过魔术方法(magic methods)来实现的。
属性重载: __get() __set() __isset() __unset()
类重载: __call() __callStatic
属性重载使用如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 class PropertyTest { private $data = array (); public $declared = 1 ; private $hidden = 2 ; public function __set ($name , $value ) { echo "Setting '$name ' to '$value '\n" ; $this ->data[$name ] = $value ; } public function __get ($name ) { echo "Getting '$name '\n" ; if (array_key_exists($name , $this ->data)) { return $this ->data[$name ]; } $trace = debug_backtrace(); trigger_error( 'Undefined property via __get(): ' . $name . ' in ' . $trace [0 ]['file' ] . ' on line ' . $trace [0 ]['line' ], E_USER_NOTICE); return null ; } public function __isset ($name ) { echo "Is '$name ' set?\n" ; return isset ($this ->data[$name ]); } public function __unset ($name ) { echo "Unsetting '$name '\n" ; unset ($this ->data[$name ]); } public function getHidden ( ) { return $this ->hidden; } } echo "<pre>\n" ;$obj = new PropertyTest;$obj ->a = 1 ;echo $obj ->a . "\n\n" ;var_dump(isset ($obj ->a)); unset ($obj ->a);var_dump(isset ($obj ->a)); echo "\n" ;echo $obj ->declared . "\n\n" ;echo "Let's experiment with the private property named 'hidden':\n" ;echo "Privates are visible inside the class, so __get() not used...\n" ;echo $obj ->getHidden() . "\n" ;echo "Privates not visible outside of class, so __get() is used...\n" ;echo $obj ->hidden . "\n" ;$obj ->hidden=333 ; echo $obj ->hidden . "\n" ;echo $obj ->getHidden() . "\n" ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ## 输出结果如下 Setting 'a' to '1' Getting 'a' 1 Is 'a' set? bool(true) Unsetting 'a' Is 'a' set? bool(false) 1 Let's experiment with the private property named 'hidden': Privates are visible inside the class, so __get() not used... 2 Privates not visible outside of class, so __get() is used... Getting 'hidden' Notice: Undefined property via __get(): hidden in F:\phpStudy\WWW\kod\data\public\test\1.php on line 134 in F:\phpStudy\WWW\kod\data\public\test\1.php on line 90 Setting 'hidden' to '333' Getting 'hidden' 333 2
方法重载使用如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Action {public function tj ( ) { echo 'tj天气预报<br/>' ; } public function __call ($m ,$p ) { echo $m ,'天气预报<br/>' ; } } $c =new Action();$c ->tj();$city =$_GET ['method' ];if (isset ($city )){$c ->$city ();} ?>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class MethodTest { public function __call ($name , $arguments ) { echo "Calling object method '$name ' " . implode(', ' , $arguments ). "\n" ; } public static function __callStatic ($name , $arguments ) { echo "Calling static method '$name ' " . implode(', ' , $arguments ). "\n" ; } } $obj = new MethodTest;$obj ->runTest('in object context' );MethodTest::runTest('in static context' ); -----
过载实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Magic { function __call ($name ,$arguments ) { if ($name =='foo' ) { if (is_int($arguments [0 ])) $this ->foo_for_int($arguments [0 ]); if (is_string($arguments [0 ])) $this ->foo_for_string($arguments [0 ]); } } private function foo_for_int ($x ) { print ("oh an int!" ); } private function foo_for_string ($x ) { print ("oh a string!" ); } } $x = new Magic();$x ->foo(3 );$x ->foo("3" );-----