• PHP Magic Methods


    Magic Methods

    The function names __construct()__destruct()__call()__callStatic()

    __get()__set()__isset()__unset()__sleep()__wakeup()__toString()__invoke()__set_state() and __clone() are magical in PHP classes.

    You cannot have functions with these names in any of your classes unless you want the magic functionality associated with them.

     

    Constructor

    void __construct ([ mixed $args [, $... ]] )
    <?php
    class BaseClass {
       function __construct() {
           print "In BaseClass constructor\n";
       }
    }
    
    class SubClass extends BaseClass {
       function __construct() {
           parent::__construct();
           print "In SubClass constructor\n";
       }
    }
    
    $obj = new BaseClass();
    $obj = new SubClass();
    ?>

     

    Destructor

    void __destruct ( void )
    <?php
    class MyDestructableClass {
       function __construct() {
           print "In constructor\n";
           $this->name = "MyDestructableClass";
       }
    
       function __destruct() {
           print "Destroying " . $this->name . "\n";
       }
    }
    
    $obj = new MyDestructableClass();
    ?>

     

    Property overloading

    public void __set ( string $name , mixed $value )
    public mixed __get ( string $name )
    public bool __isset ( string $name )
    public void __unset ( string $name )

    __set() is run when writing data to inaccessible properties.

    __get() is utilized for reading data from inaccessible properties.

    __isset() is triggered by calling isset() or empty() on inaccessible properties.

    __unset() is invoked when unset() is used on inaccessible properties.

    <?php
    class PropertyTest
    {
        /**  Location for overloaded data.  */
        private $data = array();
    
        /**  Overloading not used on declared properties.  */
        public $declared = 1;
    
        /**  Overloading only used on this when accessed outside the class.  */
        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;
        }
    
        /**  As of PHP 5.1.0  */
        public function __isset($name)
        {
            echo "Is '$name' set?\n";
            return isset($this->data[$name]);
        }
    
        /**  As of PHP 5.1.0  */
        public function __unset($name)
        {
            echo "Unsetting '$name'\n";
            unset($this->data[$name]);
        }
    
        /**  Not a magic method, just here for example.  */
        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";
    ?>

    The above example will output:

    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 <file> on line 70 in <file> on line 29

     

    Method overloading

    public mixed __call ( string $name , array $arguments )
    public static 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.

    <?php
    class MethodTest
    {
        public function __call($name, $arguments)
        {
            // Note: value of $name is case sensitive.
            echo "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 "Calling static method '$name' "
                 . implode(', ', $arguments). "\n";
        }
    }
    
    $obj = new MethodTest;
    $obj->runTest('in object context');
    
    MethodTest::runTest('in static context');  // As of PHP 5.3.0
    ?>

    The above example will output:

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

    __sleep and __wakeup()

    public array __sleep ( void )
    void __wakeup ( void )
    <?php
    class Connection
    {
        protected $link;
        private $server, $username, $password, $db;
        
        public function __construct($server, $username, $password, $db)
        {
            $this->server = $server;
            $this->username = $username;
            $this->password = $password;
            $this->db = $db;
            $this->connect();
        }
        
        private function connect()
        {
            $this->link = mysql_connect($this->server, $this->username, $this->password);
            mysql_select_db($this->db, $this->link);
        }
        
        public function __sleep()
        {
            return array('server', 'username', 'password', 'db');
        }
        
        public function __wakeup()
        {
            $this->connect();
        }
    }
    ?>

    __tostring()

    public string __toString ( void )

    The __toString() method allows a class to decide how it will react when it is treated like a string. For example, what echo $obj; will print. This method must return a string, as otherwise a fatal E_RECOVERABLE_ERROR level error is emitted.

    <?php
    // Declare a simple class
    class TestClass
    {
        public $foo;
    
        public function __construct($foo)
        {
            $this->foo = $foo;
        }
    
        public function __toString()
        {
            return $this->foo;
        }
    }
    
    $class = new TestClass('Hello');
    echo $class;
    ?>

    The above example will output:

    Hello

    It is worth noting that before PHP 5.2.0 the __toString() method was only called when it was directly combined with echo or print. Since PHP 5.2.0, it is called in any string context (e.g. in printf() with %s modifier) but not in other types contexts (e.g. with %d modifier). Since PHP 5.2.0, converting objects without __toString() method to string would cause E_RECOVERABLE_ERROR.

    __clone()

    void __clone ( void )

    Once the cloning is complete, if a __clone() method is defined, then the newly created object's __clone() method will be called, to allow any necessary properties that need to be changed.

    <?php
    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("Original Object:\n");
    print_r($obj);
    
    print("Cloned Object:\n");
    print_r($obj2);
    
    ?>

    The above example will output:

    Original Object:
    MyCloneable Object
    (
        [object1] => SubObject Object
            (
                [instance] => 1
            )
    
        [object2] => SubObject Object
            (
                [instance] => 2
            )
    
    )
    Cloned Object:
    MyCloneable Object
    (
        [object1] => SubObject Object
            (
                [instance] => 3
            )
    
        [object2] => SubObject Object
            (
                [instance] => 2
            )
    
    )

     

  • 相关阅读:
    node + express 搭建服务器,修改为自动重启服务器
    在sublime上运行node
    node + express本地搭建服务器,开启一个新的项目
    关于数据库的一些基本操作语句
    8.数据库编程
    2.关于偏函数
    7.多线程编程
    1.关于__call__的很有意思的用法
    6.python中的网络编程
    4.python中常用的魔法方法(长期更新)
  • 原文地址:https://www.cnblogs.com/bruceleeliya/p/2736772.html
Copyright © 2020-2023  润新知