Sobes.tech
Middle

Quais são os métodos mágicos existentes em PHP e como são utilizados?

sobes.tech IA

Resposta da IA

Métodos mágicos em PHP são métodos especiais que começam com dois underlines (por exemplo, __construct) e que são chamados automaticamente em certas situações.

Os principais métodos mágicos e seus usos:

  • __construct(): É chamado ao criar um objeto de uma classe. Usado para inicializar propriedades do objeto e realizar ações iniciais.

    <?php
    class MyClass {
        public function __construct() {
            echo "Objeto criado!";
        }
    }
    $obj = new MyClass(); // Irá exibir "Objeto criado!"
    
  • __destruct(): É chamado ao destruir o objeto (por exemplo, quando o script termina ou o objeto é removido da memória). Usado para liberar recursos (fechar arquivos, conexões com bancos de dados).

    <?php
    class MyClass {
        public function __destruct() {
            echo "Objeto destruído!";
        }
    }
    $obj = new MyClass();
    unset($obj); // Irá exibir "Objeto destruído!"
    
  • __call(string $name, array $arguments): É chamado ao tentar invocar um método inacessível ou inexistente no contexto do objeto. $name contém o nome do método, $arguments é um array de argumentos.

    <?php
    class MyClass {
        public function __call($name, $arguments) {
            echo "Método '{$name}' não acessível chamado com argumentos: " . implode(', ', $arguments);
        }
    }
    $obj = new MyClass();
    $obj->nonExistentMethod('arg1', 'arg2'); // Irá exibir "Método 'nonExistentMethod' não acessível chamado com argumentos: arg1, arg2"
    
  • __callStatic(string $name, array $arguments): É chamado ao tentar invocar um método estático inacessível ou inexistente no contexto da classe. Similar a __call, mas para chamadas estáticas.

    <?php
    class MyClass {
        public static function __callStatic($name, $arguments) {
            echo "Método estático '{$name}' não acessível chamado com argumentos: " . implode(', ', $arguments);
        }
    }
    MyClass::nonExistentStaticMethod('static_arg'); // Irá exibir "Método estático 'nonExistentStaticMethod' não acessível chamado com argumentos: static_arg"
    
  • __get(string $name): É chamado ao tentar obter o valor de uma propriedade inacessível ou inexistente no contexto do objeto. $name contém o nome da propriedade.

    <?php
    class MyClass {
        private $data = ['key' => 'value'];
        public function __get($name) {
            if (array_key_exists($name, $this->data)) {
                return $this->data[$name];
            }
            return null;
        }
    }
    $obj = new MyClass();
    echo $obj->key; // Irá exibir "value"
    echo $obj->nonExistentKey; // Irá exibir uma string vazia (dependendo do valor retornado null)
    
  • __set(string $name, mixed $value): É chamado ao tentar definir o valor de uma propriedade inacessível ou inexistente no contexto do objeto. $name contém o nome da propriedade, $value é o valor a ser definido.

    <?php
    class MyClass {
        private $data = [];
        public function __set($name, $value) {
            $this->data[$name] = $value;
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    $obj->newKey = 'newValue';
    print_r($obj->getData()); // Irá exibir Array ( [newKey] => newValue )
    
  • __isset(string $name): É chamado ao usar isset() ou empty() em uma propriedade inacessível ou inexistente no contexto do objeto. Retorna um booleano.

    <?php
    class MyClass {
        private $data = ['present' => 'value'];
        public function __isset($name) {
            return array_key_exists($name, $this->data);
        }
    }
    $obj = new MyClass();
    var_dump(isset($obj->present));     // Irá exibir bool(true)
    var_dump(isset($obj->absent));      // Irá exibir bool(false)
    
  • __unset(string $name): É chamado ao usar unset() em uma propriedade inacessível ou inexistente no contexto do objeto.

    <?php
    class MyClass {
        private $data = ['remove_me' => 'value_to_remove'];
        public function __unset($name) {
            if (array_key_exists($name, $this->data)) {
                unset($this->data[$name]);
                echo "Propriedade '{$name}' removida.\n";
            }
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    print_r($obj->getData());
    unset($obj->remove_me); // Irá exibir "Propriedade 'remove_me' removida." e removerá o elemento de $data
    print_r($obj->getData());
    
  • __sleep(): É chamado antes da serialização do objeto usando serialize(). Deve retornar um array de nomes de propriedades que devem ser serializadas.

    <?php
    class MyClass {
        public $prop1 = 'value1';
        public $prop2 = 'value2';
        public function __sleep() {
            return ['prop1']; // Serializa apenas prop1
        }
    }
    $obj = new MyClass();
    $serialized = serialize($obj); // Serializa apenas prop1
    echo $serialized; // Irá exibir aproximadamente O:7:"MyClass":1:{s:5:"prop1";s:6:"value1";}
    
  • __wakeup(): É chamado após a desserialização do objeto usando unserialize(). Usado para restaurar conexões com bancos de dados ou outras ações necessárias após a restauração do objeto.

    <?php
    class MyClass {
        public $prop1;
        public $resource; // Suponha que seja um recurso de conexão
        public function __wakeup() {
            // Restaurar o recurso, por exemplo, uma conexão com o banco de dados
            $this->resource = fopen('/tmp/my_file.txt', 'w'); // Exemplo
            echo "Objeto despertado e recurso restaurado!\n";
        }
        public function __sleep() {
            // Em __sleep não serializamos o recurso
            return ['prop1'];
        }
        public function __destruct() {
            if (is_resource($this->resource)) {
                fclose($this->resource);
                echo "Recurso fechado.\n";
            }
        }
    }
    $obj = new MyClass();
    $obj->prop1 = 'valor desserializado';
    $serialized = serialize($obj);
    unset($obj);
    
    $deserialized_obj = unserialize($serialized); // Chamará __wakeup()
    var_dump($deserialized_obj->prop1);
    
  • __toString(): É chamado quando o objeto é usado como uma string (por exemplo, com echo ou concatenação). Deve retornar uma representação em string do objeto.

    <?php
    class MyClass {
        public $name = "MyObject";
        public function __toString() {
            return "Objeto do tipo MyClass com nome: " . $this->name;
        }
    }
    $obj = new MyClass();
    echo $obj; // Irá exibir "Objeto do tipo MyClass com nome: MyObject"
    
  • __invoke(...): É chamado ao tentar invocar o objeto como uma função. Pode aceitar qualquer número de argumentos.

    <?php
    class MyCallableClass {
        public function __invoke(...$args) {
            echo "Objeto foi chamado como função com argumentos: " . implode(', ', $args);
        }
    }
    $obj = new MyCallableClass();
    $obj('arg1', 123); // Irá exibir "Objeto foi chamado como função com argumentos: arg1, 123"
    
  • __set_state(array $properties): É chamado estaticamente para classes exportadas com var_export(). Recebe um array de propriedades exportadas. Deve criar um novo objeto da classe e retorná-lo.

    <?php
    class MyClass {
        public $prop;
        public static function __set_state(array $properties) {
            $obj = new MyClass();
            $obj->prop = $properties['prop'];
            return $obj;
        }
    }
    $obj = new MyClass();
    $obj->prop = 'valor exportado';
    $exported = var_export($obj, true); // Exporta o objeto
    // $exported conterá o código para criar o objeto, usando __set_state()
    eval('$restored_obj = ' . $exported . ';');
    var_dump($restored_obj); // Irá exibir o objeto MyClass com a propriedade 'valor exportado'
    
  • __debugInfo(): É chamado ao usar funções como var_dump() no objeto. O método deve retornar um array com informações sobre as propriedades do objeto que devem ser exibidas.

    <?php
    class MyClass {
        public $publicProp = 'public';
        private $privateProp = 'private';
        public function __debugInfo() {
            return ['publicProp' => $this->publicProp, 'private_info' => 'detalhes sobre privateProp'];
        }
    }
    $obj = new MyClass();
    var_dump($obj); // Irá exibir as informações retornadas por __debugInfo()
    
  • __clone(): É chamado após a operação de clonagem (clone) do objeto. Usado para cópia profunda de objetos internos ou estruturas de dados.

    <?php
    class SubObject {
        public $value;
        public function __construct($value) {
            $this->value = $value;
        }
    }
    class MyClass {
        public $object;
        public $anotherProp;
        public function __construct() {
            $this->object = new SubObject('initial');
            $this->anotherProp = 'original';
        }
        public function __clone() {
            // Clona o objeto interno para cópia profunda
            $this->object = clone $this->object;
        }
    }
    $obj = new MyClass();
    $cloned_obj = clone $obj;
    
    // Agora $obj->object e $cloned_obj->object são instâncias diferentes de SubObject
    $cloned_obj->object->value = 'modificado';
    
    var_dump($obj->object->value);       // Irá exibir "initial"
    var_dump($cloned_obj->object->value); // Irá exibir "modificado"
    

Tabela com uma breve descrição:

Método Descrição É chamado quando...
__construct() Construtor da classe. Quando uma nova instância da classe é criada.
__destruct() Destruidor da classe. Quando o objeto é destruído ou o script termina.
__call() Manipula chamadas a métodos inacessíveis ou inexistentes. Quando uma chamada a método inacessível ou inexistente é feita.
__callStatic() Manipula chamadas a métodos estáticos inacessíveis ou inexistentes. Quando uma chamada a método estático inacessível ou inexistente é feita.
__get() Manipula acesso a propriedades inacessíveis ou inexistentes. Quando se tenta obter o valor de uma propriedade inacessível ou inexistente.
__set() Manipula definição de valor para propriedades inacessíveis ou inexistentes. Quando se tenta definir uma propriedade inacessível ou inexistente.
__isset() Manipula isset() ou empty() em propriedades. Quando isset() ou empty() são usados em propriedades inacessíveis ou inexistentes.
__unset() Manipula unset() em propriedades. Quando unset() é usado em uma propriedade inacessível ou inexistente.
__sleep() Prepara o objeto para serialização. Quando serialize() é chamado no objeto.
__wakeup() Pós-processamento após desserialização. Quando unserialize() é chamado no objeto.
__toString() Representação do objeto como string. Quando o objeto é usado como string (por exemplo, com echo).
__invoke() Invoca o objeto como uma função. Quando o objeto é chamado como uma função.
__set_state() Cria um objeto após exportação com var_export(). Quando o código exportado por var_export() é avaliado.
__debugInfo() Fornece informações para var_dump(). Quando var_dump() é chamado no objeto.
__clone() Pós-processamento após clonagem. Quando clone é usado para clonar o objeto.