Ricerca…


__get (), __set (), __isset () e __unset ()

Ogni volta che si tenta di recuperare un determinato campo da una classe in questo modo:

$animal = new Animal();
$height = $animal->height;

PHP invoca il metodo magico __get($name) , con $name uguale a "height" in questo caso. Scrivere in un campo classe in questo modo:

$animal->height = 10;

__set($name, $value) metodo magico __set($name, $value) , con $name uguale a "height" e $value uguale a 10 .

PHP ha anche due funzioni built-in isset() , che controllano se esiste una variabile e unset() , che distrugge una variabile. Verifica se un campo oggetti è impostato in questo modo:

isset($animal->height);

__isset($name) la funzione __isset($name) su quell'oggetto. Distruggere una variabile in questo modo:

unset($animal->height);

__unset($name) la funzione __unset($name) su quell'oggetto.

Normalmente, quando non si definiscono questi metodi sulla classe, PHP recupera semplicemente il campo così come è memorizzato nella classe. Tuttavia, puoi sovrascrivere questi metodi per creare classi che possano contenere dati come una matrice, ma che siano utilizzabili come un oggetto:

class Example {
    private $data = [];

    public function __set($name, $value) {
        $this->data[$name] = $value;
    }

    public function __get($name) {
        if (!array_key_exists($name, $this->data)) {
            return null;
        }

        return $this->data[$name];
    }

    public function __isset($name) {
        return isset($this->data[$name]);
    }

    public function __unset($name) {
        unset($this->data[$name]);
    }
}

$example = new Example();

// Stores 'a' in the $data array with value 15
$example->a = 15;

// Retrieves array key 'a' from the $data array
echo $example->a; // prints 15

// Attempt to retrieve non-existent key from the array returns null
echo $example->b; // prints nothing

// If __isset('a') returns true, then call __unset('a')
if (isset($example->a)) {
    unset($example->a));
}

funzione vuota () e metodi magici

Nota che chiamare empty() su un attributo di classe invocherà __isset() perché come afferma il manuale PHP:

empty () è essenzialmente l'equivalente conciso di ! isset ($ var) || $ var == false

__construct () e __destruct ()

__construct() è il metodo magico più comune in PHP, perché viene utilizzato per impostare una classe quando viene inizializzata. L'opposto del metodo __construct() è il metodo __destruct() . Questo metodo viene chiamato quando non ci sono più riferimenti a un oggetto che hai creato o quando ne imponi la sua eliminazione. La garbage collection di PHP pulirà l'oggetto chiamando prima il suo distruttore e quindi rimuovendolo dalla memoria.

class Shape {
    public function __construct() {
        echo "Shape created!\n";
    }
}

class Rectangle extends Shape {
    public $width;
    public $height;

    public function __construct($width, $height) {
        parent::__construct();

        $this->width = $width;
        $this->height = $height;
        echo "Created {$this->width}x{$this->height} Rectangle\n"; 
    }

    public function __destruct() {
        echo "Destroying {$this->width}x{$this->height} Rectangle\n";
    }
}

function createRectangle() {
    // Instantiating an object will call the constructor with the specified arguments
    $rectangle = new Rectangle(20, 50);

    // 'Shape Created' will be printed
    // 'Created 20x50 Rectangle' will be printed
}

createRectangle();
// 'Destroying 20x50 Rectangle' will be printed, because
// the `$rectangle` object was local to the createRectangle function, so
// When the function scope is exited, the object is destroyed and its
// destructor is called.

// The destructor of an object is also called when unset is used:
unset(new Rectangle(20, 50));

__accordare()

Ogni volta che un oggetto viene trattato come una stringa, viene chiamato il metodo __toString() . Questo metodo dovrebbe restituire una rappresentazione stringa della classe.

class User {
    public $first_name;
    public $last_name;
    public $age;

    public function __toString() {
        return "{$this->first_name} {$this->last_name} ($this->age)";
    }
}

$user = new User();
$user->first_name = "Chuck";
$user->last_name = "Norris";
$user->age = 76;

// Anytime the $user object is used in a string context, __toString() is called

echo $user; // prints 'Chuck Norris (76)'

// String value becomes: 'Selected user: Chuck Norris (76)'
$selected_user_string = sprintf("Selected user: %s", $user);

// Casting to string also calls __toString()
$user_as_string = (string) $user;

__invocare()

Questo metodo magico viene chiamato quando l'utente tenta di richiamare l'oggetto come una funzione. Possibili casi d'uso possono includere alcuni approcci come la programmazione funzionale o alcuni callback.

class Invokable
{
    /**
     * This method will be called if object will be executed like a function:
     *
     * $invokable();
     *
     * Args will be passed as in regular method call.
     */
    public function __invoke($arg, $arg, ...)
    {
        print_r(func_get_args());
    }
}

// Example:
$invokable = new Invokable();
$invokable([1, 2, 3]);

// optputs:
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)

__call () e __callStatic ()

__call() e __callStatic() vengono chiamati quando qualcuno chiama il metodo oggetto inesistente in oggetto o contesto statico.

class Foo
{
    /**
     * This method will be called when somebody will try to invoke a method in object
     * context, which does not exist, like:
     *
     * $foo->method($arg, $arg1);
     *
     * First argument will contain the method name(in example above it will be "method"),
     * and the second will contain the values of $arg and $arg1 as an array.
     */
    public function __call($method, $arguments)
    {
        // do something with that information here, like overloading
        // or something generic.
        // For sake of example let's say we're making a generic class,
        // that holds some data and allows user to get/set/has via
        // getter/setter methods. Also let's assume that there is some
        // CaseHelper which helps to convert camelCase into snake_case.
        // Also this method is simplified, so it does not check if there
        // is a valid name or
        $snakeName = CaseHelper::camelToSnake($method);
        // Get get/set/has prefix
        $subMethod = substr($snakeName, 0, 3);

        // Drop method name.
        $propertyName = substr($snakeName, 4);

        switch ($subMethod) {
            case "get":
                return $this->data[$propertyName];
            case "set":
                $this->data[$propertyName] = $arguments[0];
                break;
            case "has":
                return isset($this->data[$propertyName]);
            default:
                throw new BadMethodCallException("Undefined method $method");
        }
    }

    /**
     * __callStatic will be called from static content, that is, when calling a nonexistent
     * static method:
     *
     * Foo::buildSomethingCool($arg);
     *
     * First argument will contain the method name(in example above it will be "buildSomethingCool"),
     * and the second will contain the value $arg in an array.
     *
     * Note that signature of this method is different(requires static keyword). This method was not
     * available prior PHP 5.3
     */
    public static function __callStatic($method, $arguments)
    {
        // This method can be used when you need something like generic factory
        // or something else(to be honest use case for this is not so clear to me).
        print_r(func_get_args());
    }
}

Esempio:

$instance = new Foo();

$instance->setSomeState("foo");
var_dump($instance->hasSomeState());      // bool(true)
var_dump($instance->getSomeState());      // string "foo"

Foo::exampleStaticCall("test");
// outputs:
Array
(
    [0] => exampleCallStatic
    [1] => test
)

__sleep () e __wakeup ()

__sleep e __wakeup sono metodi correlati al processo di serializzazione. serialize funzione serialize verifica se una classe ha un metodo __sleep . Se è così, verrà eseguito prima di qualsiasi serializzazione. __sleep dovrebbe restituire una matrice dei nomi di tutte le variabili di un oggetto che dovrebbe essere serializzato.

__wakeup a sua volta verrà eseguito da unserialize se è presente in classe. L'intenzione è di ristabilire le risorse e altre cose che sono necessarie per essere inizializzate in caso di unserializzazione.

class Sleepy {
    public $tableName;
    public $tableFields;
    public $dbConnection;

    /**
     * This magic method will be invoked by serialize function.
     * Note that $dbConnection is excluded.
     */
    public function __sleep()
    {
        // Only $this->tableName and $this->tableFields will be serialized.
        return ['tableName', 'tableFields'];
    }

    /**
     * This magic method will be called by unserialize function.
     *
     * For sake of example, lets assume that $this->c, which was not serialized,
     * is some kind of a database connection. So on wake up it will get reconnected.
     */
    public function __wakeup()
    {
        // Connect to some default database and store handler/wrapper returned into
        // $this->dbConnection
        $this->dbConnection = DB::connect();
    }
}

__informazioni di debug()

Questo metodo viene chiamato da var_dump() quando si var_dump() dumping di un oggetto per ottenere le proprietà che dovrebbero essere mostrate. Se il metodo non è definito su un oggetto, verranno mostrate tutte le proprietà pubbliche, protette e private. - Manuale PHP

class DeepThought {
    public function __debugInfo() {
        return [42];
    }
}
5.6
var_dump(new DeepThought());

L'esempio sopra uscirà:

class DeepThought#1 (0) {
}
5.6
var_dump(new DeepThought());

L'esempio sopra uscirà:

class DeepThought#1 (1) {
  public ${0} =>
  int(42)
}

__clone()

__clone viene invocato utilizzando la parola chiave clone . È usato per manipolare lo stato dell'oggetto dopo la clonazione, dopo che l'oggetto è stato effettivamente clonato.

class CloneableUser
{
    public $name;
    public $lastName;

    /**
     * This method will be invoked by a clone operator and will prepend "Copy " to the
     * name and lastName properties.
     */
    public function __clone()
    {
        $this->name = "Copy " . $this->name;
        $this->lastName = "Copy " . $this->lastName;
    }
}

Esempio:

$user1 = new CloneableUser();
$user1->name = "John";
$user1->lastName = "Doe";

$user2 = clone $user1; // triggers the __clone magic method

echo $user2->name;     // Copy John
echo $user2->lastName; // Copy Doe


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow