zoukankan      html  css  js  c++  java
  • 对象方法PHP中魔术方法的用法对象方法

    新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正

        每日一道理
    美丽是平凡的,平凡得让你感觉不到她的存在;美丽是平淡的,平淡得只剩下温馨的回忆;美丽又是平静的,平静得只有你费尽心思才能激起她的涟漪。
    /** PHP把全部以__(两个下划线)头开的类方法成当术魔方法。所以你义定自己的类方法时,不要以 __为前缀。 * */
    
    // __toString、__set、__get__isset()、__unset()
    /*
      The __toString method allows a class to decide how it will react when it is converted to a string.
      __set() is run when writing data to inaccessible members.
      __get() is utilized for reading data from inaccessible members.
      __isset() is triggered by calling isset() or empty() on inaccessible members.
      __unset() is invoked when unset() is used on inaccessible members.
     */
    class TestClass {
    
        private $data = array();
        public $foo;
    
        public function __construct($foo) {
            $this->foo = $foo;
        }
    
        public function __toString() {
            return $this->foo;
        }
    
        public function __set($name, $value) {
            echo "__set, Setting '$name' to '$value'\n";
            $this->data[$name] = $value;
        }
    
        public function __get($name) {
            echo "__get, Getting '$name'\n";
            if (array_key_exists($name, $this->data)) {
                return $this->data[$name];
            }
        }
    
        /** As of PHP 5.1.0 */
        public function __isset($name) {
            echo "__isset, Is '$name' set?\n";
            return isset($this->data[$name]);
        }
    
        /** As of PHP 5.1.0 */
        public function __unset($name) {
            echo "__unset, Unsetting '$name'\n";
            unset($this->data[$name]);
        }
    
    }
    
    $obj = new TestClass('Hello');
    echo "__toString, $obj\n";
    $obj->a = 1;
    echo $obj->a . "\n\n";
    var_dump(isset($obj->a));
    unset($obj->a);
    var_dump(isset($obj->a));
    echo "\n\n"; 
    /**
      输出结果如下:
      __toString, Hello
      __set, Setting 'a' to '1'
      __get, Getting 'a'
      __isset, Is 'a' set?
      bool(true)
      __unset, Unsetting 'a'
      __isset, Is 'a' set?
      bool(false)
     **/
    
    
    
    // __call  __callStatic
    /*
      mixed __call ( string $name , array $arguments )
      mixed __callStatic ( string $name , array $arguments )
      __call() is triggered when invoking inaccessible methods in an object context.
      __callStatic() is triggered when invoking inaccessible methods in a static context.
      The $name argument is the name of the method being called.
      The $arguments argument is an enumerated array containing the parameters passed to the $name'ed method.
     */
    class MethodTest {
        public function __call($name, $arguments) {
            // Note: value of $name is case sensitive.
            echo "__call, Calling object method '$name' " . implode(', ', $arguments) . "\n";
        }
    
        /** As of PHP 5.3.0 */
        public static function __callStatic($name, $arguments) {
            // Note: value of $name is case sensitive.
            echo "__callStatic, Calling static method '$name' " . implode(', ', $arguments) . "\n";
        }
    
    }
    
    $obj = new MethodTest;
    $obj->runTest('in object context', 'param2', 'param3');
    //MethodTest::runTest('in static context'); // As of PHP 5.3.0
    echo "\n\n"; 
    /**
     输出结果如下:
     __call, Calling object method 'runTest' in object context, param2, param3
      string(10) "__invoke: "
     */
    
    
    
    // __invoke
    /* 
      The __invoke method is called when a script tries to call an object as a function.
      Note: This feature is available since PHP 5.3.0.
    */
    class CallableClass {
        function __invoke($x) {
            var_dump($x);
        }
    }
    
    $obj = new CallableClass;
    //$obj(5);
    var_dump('__invoke: ' . is_callable($obj));
    echo "\n\n"; 
    
    
    
    
    
    // __sleep  __wakeup
    /*
      串行化serialize可以把量变括包对象,转化成连续bytes数据. 你可以将串行化后的量变存在一个文件里或在网络上传输. 
      然后再反串行化还原为来原的数据. 你在反串行化类的对象之前义定的类,PHP可以成功地存储其对象的性属和方法. 
      时有你可能须要一个对象在反串行化后当即执行. 为了这样的目标,PHP会动自寻觅__sleep和__wakeup方法.
      当一个对象被串行化,PHP会调用__sleep方法(如果存在的话). 在反串行化一个对象后,PHP 会调用__wakeup方法. 
      这两个方法都不受接参数. __sleep方法必须返回一个数组,含包须要串行化的性属. PHP会摈弃其它性属的值. 
      如果没有__sleep方法,PHP将存保全部性属.上面的例子示显了如何用__sleep和__wakeup方法来串行化一个对象. 
      Id性属是一个不算打保留在对象中的临时性属. __sleep方法保障在串行化的对象中不含包id性属. 
      当反串行化一个User对象,__wakeup方法建立id性属的新值. 这个例子被计设成自我坚持. 
      在现实开辟中,你可能发明含包源资(如像图或数据流)的对象须要这些方法
     */
    
    class User {
    
        public $name;
        public $id;
    
        function __construct() {
            //give user a unique ID 予赋一个别差 的ID
            $this->id = uniqid();
        }
    
        //__sleep返回值的类型是数组,数组中的值是不须要串型化的段字id
    
        function __sleep() {
            //do not serialize this->id 不串行化id
            return(array("name"));
        }
    
        function __wakeup() {
            //give user a unique ID
            $this->id = uniqid();
        }
    
    }
    
    //create object 立成一个东西
    $u = new User;
    $u->name = "Leon"; //serialize it 串行化 留心不串行化id性属,id的值被遗弃
    $s = serialize($u);
    echo "__sleep, __wakeup, s: $s"; //unserialize it 反串行化 id被从新赋值
    $u2 = unserialize($s); //$u and $u2 have different IDs $u和$u2有别差 的ID
    print_r($u);
    print_r($u2);
    echo "\n\n"; 
    /**
     输出结果如下:
      __sleep, __wakeup, s: O:4:"User":1:{s:4:"name";s:4:"Leon";}
      User Object
      (
      [name] => Leon
      [id] => 4db1b17640da1
      )
      User Object
      (
      [name] => Leon
      [id] => 4db1b17640dbc
      )
     */
    
    
    // __set_state
    /*
      This static method is called for classes exported by var_export() since PHP 5.1.0.
      The only parameter of this method is an array containing exported properties in the form array('property' => value, ...).
     */
    
    class A {
    
        public $var1;
        public $var2;
    
        public static function __set_state($an_array) { // As of PHP 5.1.0
            //$an_array打印出来是数组,而不是调用时递传的对象
            print_r($an_array);
            $obj = new A;
            $obj->var1 = $an_array['var1'];
            $obj->var2 = $an_array['var2'];
            return $obj;
        }
    
    }
    
    $a = new A;
    $a->var1 = 5;
    $a->var2 = 'foo';
    echo "__set_state:\n";
    eval('$b = ' . var_export($a, true) . ';'); 
    // $b = A::__set_state(array(
    // 'var1' => 5,
    // 'var2' => 'foo',
    // ));
    var_dump($b);
    echo "\n\n"; 
    /**
      输出结果如下:
      __set_state:
      Array
      (
      [var1] => 5
      [var2] => foo
      )
      object(A)#5 (2) {
      ["var1"]=>
      int(5)
      ["var2"]=>
      string(3) "foo"
      }
     */
    
    
    
    // __clone
    class SubObject {
    
        static $instances = 0;
        public $instance;
    
        public function __construct() {
            $this->instance = ++self::$instances;
        }
    
        public function __clone() {
            $this->instance = ++self::$instances;
        }
    
    }
    
    class MyCloneable {
    
        public $object1;
        public $object2;
    
        function __clone() {
            // Force a copy of this->object, otherwise
            // it will point to same object.
            $this->object1 = clone $this->object1;
        }
    
    }
    
    $obj = new MyCloneable();
    $obj->object1 = new SubObject();
    $obj->object2 = new SubObject();
    $obj2 = clone $obj;
    print("__clone, Original Object:\n");
    print_r($obj);
    print("__clone, Cloned Object:\n");
    print_r($obj2);
    echo "\n\n";
    /**
     输出结果如下:
     __clone, Original Object:
      MyCloneable Object
      (
      [object1] => SubObject Object
      (
      [instance] => 1
      ) [object2] => SubObject Object
      (
      [instance] => 2
      ))
      __clone, Cloned Object:
      MyCloneable Object
      (
      [object1] => SubObject Object
      (
      [instance] => 3
      ) [object2] => SubObject Object
      (
      [instance] => 2
      )) 
     */

    文章结束给大家分享下程序员的一些笑话语录: 火车
    一个年轻的程序员和一个项目经理登上了一列在山里行驶的火车,他们发现 列车上几乎都坐满了,只有两个在一起的空位,这个空位的对面是一个老奶 奶和一个年轻漂亮的姑娘。两个上前坐了下来。程序员和那个姑娘他们比较 暧昧地相互看对方。这时,火车进入山洞,车厢里一片漆黑。此时,只听见 一个亲嘴的声音,随后就听到一个响亮的巴掌声。很快火车出了山洞,他们 四个人都不说话。
    那个老奶奶在喃喃道, “这个年轻小伙怎么这么无礼, 不过我很高兴我的孙女 扇了一个巴掌”。
    项目经理在想,“没想到这个程序员居然这么大胆,敢去亲那姑娘,只可惜那 姑娘打错了人,居然给打了我。”
    漂亮的姑娘想,“他亲了我真好,希望我的祖母没有打疼他”。
    程序员坐在那里露出了笑容, “生活真好啊。 这一辈子能有几次机会可以在亲 一个美女的同时打项目经理一巴掌啊”

  • 相关阅读:
    (转)JVM参数的说明、简单记法和GC调优策略
    深度学习论文翻译解析(十二):Fast R-CNN
    深度学习论文翻译解析(十一):OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks
    vue中组建的创建和使用
    CountDownLatch的理解和使用
    java多线程并发编程中对一些概念和关键字的理解
    spring中访问变量的用法
    mysql中group by优化
    vue中实现标题的国际化
    mysql中的覆盖索引,二级索引和索引排序
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3033402.html
Copyright © 2011-2022 走看看