• 技术文章 >php教程 >php手册

    PHP类中的魔术方法(Magic Method)简明总结,magicmethod

    2016-06-13 09:29:08原创376

    PHP类中的魔术方法(Magic Method)简明总结,magicmethod


    1. __construct()和__destruct()

    在实例被 创建/销毁 的时候被调用,都可以传递0个或多个参数。

    class A
     {
      function A()
      {
       echo "build A";
      }
    
      function __destruct()
      {
       echo "destroy A";
      }
     }
    
     $obj = new A();
     //unset($obj);

    Note:The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

      关于构造函数,PHP5.3.3开始,一个定义在某个特定的命名空间里的class中以类名命名的方法将不再被认为是构造函数。在无命名空间的类中与原来一样依旧是构造函数。如:

    namespace Foo;
    class Bar {
      public function Bar() {
        // treated as constructor in PHP 5.3.0-5.3.2
        // treated as regular method as of PHP 5.3.3
      }
    }

    如果没有namespace Foo; 那么Bar()还将被当作构造函数。另外,如果存在下面的情况:

    function __construct()
      {
       echo "construct A";
      }
    
      function A()
      {
       echo "build A";
      }
    
      function __destruct()
      {
       echo "destroy A";
      }
     }
    

    即既包含__construct()又包含与类名同名的函数,那么将只调用__construct()。

    2. __call()和__callStatic()

    当尝试调用一个不存在的方法时调用该方法。两个参数,一个是方法名,一个是被调用方法的参数数组。

    class MethodTest
    {
      public function __call($name, $arguments)
      {
        // Note: value of $name is case sensitive.
        echo "Calling object method '$name' "
           . implode(' ', $arguments). "
    "; } public static function __callStatic($name, $arguments) { // Note: value of $name is case sensitive. echo "Calling static method '$name' " . implode(' ', $arguments). "
    "; } } $obj = new MethodTest; $obj->runTest('in','object','context'); MethodTest::runTest('in','static','context');

    其中,$arguments作为一个array传入。运行结果:

    Calling object method 'runTest' in object context
    Calling static method 'runTest' in static context

    还要注意函数的作用域protected和private:

    class TestMagicCallMethod {
      public function foo()
      {
        echo __METHOD__.PHP_EOL."
    "; } public function __call($method, $args) { echo __METHOD__.PHP_EOL."
    "; if(method_exists($this, $method)) { $this->$method(); } } protected function bar() { echo __METHOD__.PHP_EOL."
    "; } private function baz() { echo __METHOD__.PHP_EOL."
    "; } } $test = new TestMagicCallMethod(); $test->foo(); /** * Outputs: * TestMagicCallMethod::foo */ $test->bar(); /** * Outputs: * TestMagicCallMethod::__call * TestMagicCallMethod::bar */ $test->baz(); /** * Outputs: * TestMagicCallMethod::__call * TestMagicCallMethod::baz */

    3.__get()和__set()

      当试图读取一个对象并不存在的属性的时候被调用。

      Note:我们可以用这个函数实现类似java中反射的各种操作。

    class Test
    {
      public function __get($key)
      {
       echo $key . " not exists";
      }
      public function __set($key,$value)
      {
       echo $key . " = ".$value;
      }
    }
    
    $t = new Test();
    echo $t->name."
    "; $t->name = "abc";

    输出:
    name not exists
    name = abc

    4. __toString()

     这个方法类似于java的toString()方法,当我们直接打印对象的时候回调用这个函数,函数必须返回一个string。

    class Test
    {
      private $name = "abc";
      private $age = 12;
    
      public function __toString()
      {
        return "name : $this->name, age : $this->age";
      }
    }
    
    $t = new Test();
    echo $t;

    输出:

    name : abc, age : 12


    详细说明一下php5中的魔术方法

    PHP处理对象部分的内核完全重新开发过,提供更多功能的同时也提高了性能。在以前版本的php中,处理对象和处理基本类型(数字,字符串)的方式是一样的。这种方式的缺陷是:当将对象赋值给一个变量时,或者通过参数传递对象时,对象将被完全拷贝一份。在新的版本里,上述操作将传递引用(可以把引用理解成对象的标识符),而非值。
    很多PHP程序员可能甚至没有察觉到老的对象处理方式。事实上,大多数的php应用都可以很好地运行。或者仅仅需要很少的改动。
    私有和受保护成员
    PHP5引入了私有和受保护成员变量的概念。我们可以用它来定义类成员的可见性。
    例子
    受保护成员可以被子类访问, 而私有成员只能被类本身访问。

    代码:--------------------------------------------------------------------------------

    class MyClass {
    private $Hello = "Hello, World!\n";
    protected $Bar = "Hello, Foo!\n";
    protected $Foo = "Hello, Bar!\n";

    function printHello() {
    print "MyClass::printHello() " . $this->Hello;
    print "MyClass::printHello() " . $this->Bar;
    print "MyClass::printHello() " . $this->Foo;
    }
    }

    class MyClass2 extends MyClass {
    protected $Foo;

    function printHello() {
    MyClass::printHello(); /* Should print */
    print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */
    print "MyClass2::printHello() " . $this->Bar; /* Shouldn't print (not declared)*/
    print "MyClass2::printHello() " . $this->Foo; /* Should print */
    }
    }

    $obj = new MyClass();
    print $obj->Hello; /* Shouldn't print out anything */
    print $obj->Bar; /* Shouldn't print out anything */
    print $obj->Foo; /* Should......余下全文>>
     

    php魔术方法

    这样绕的话是为了安全,也就是面向对象里封装的理念,如果直接设置Public那么没个对象都可以自由设置这个属性的值了,而且没有经过任务逻辑判断,这样绕弯的话可以增加安全性
     

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:PHP 魔术方法 php
    上一篇:ThinkPHP实现将SESSION存入MYSQL的方法,thinkphpmysql 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • php利用新浪接口查询ip获取地理位置• php 连接 mysql数据库操作类• 字符过滤程序• JavaScript+PHP应用一:网页• 第十节--抽象方法和抽象类--ClassesandObjectsinPHP510
    1/1

    PHP中文网