SELF no PHP

Artigo que explica como e onde pode ser utilizada a palavra reservada SELF no contexto de programação orientada a objetos da linguagem PHP.

Você sabia?

Outro dia descobri algo bastante básico, mas que não havia encontrado na documentação do PHP. Trata-se de algumas das utilizações da palavra reservada "self".

Bom, eu utilizava "self" basicamente para chamar métodos estáticos ou acessar atributos estáticos da classe. O que descobri é que ele também serve para instanciar um objeto da classe corrente. Vamos a um exemplo de uma classe singleton. Antes eu fazia assim:

class teste_singleton {
    private static $instancia = null;

    /**
     * Construtor privado
     */
    private function __construct() {
        // void
    }

    /**
     * Nao permitir clonagem
     */
    public function __clone() {
        throw new Exception('Singleton nao permite clonagem');
    }

    /**
     * Devolve uma instancia singleton da classe corrente
     * @return teste_singleton
     */
    public static function get_instancia() {
        if (self::$instancia === null) {
            $classe = __CLASS__;
            self::$instancia = new $classe();
        }
        return self::$instancia;
    }

    ...
}

Observe que eu jogava o valor da constante __CLASS__ em uma variável apenas para criar uma instância de forma genérica. Com isso, eu podia mudar o nome da minha classe sem afetar o comportamento do script. No entanto, é muito chato ter que usar uma variável só pra isso. Do novo jeito, eu uso a palavra "self" assim:

...

    /**
     * Devolve uma instancia singleton da classe corrente
     * @return teste_singleton
     */
    public static function get_instancia() {
        if (self::$instancia === null) {
            self::$instancia = new self();
        }
        return self::$instancia;
    }

...

Ou seja, como "self" é uma palavra reservada de PHP, não podemos criar uma classe chamada "self", logo, ao fazer "new self" estamos instanciando um objeto da própria classe.

Outra utilidade é para utilização com o operador "instanceof". Para checar se um objeto era da classe corrente, eu jogava a constante __CLASS__ em uma variável e fazia o teste. Antes era assim:

class teste {

    public function foo($obj) {
        $classe = __CLASS__;
        if ($obj instanceof $classe) {
            ...
        }
    }

    ...
}

Agora fica assim:

class teste {

    public function foo($obj) {
        if ($obj instanceof self) {
            ...
        }
    }

    ...
}

8 comentários

Anônimo disse...

sabia do self, mas não da constante, para classes n estaticas, fazia assim get_class($this)

Kerwin Muriel disse...

:( ainda preciso aprender muito mesmo... nem sei pra que serve esse singleton, vc pode explicar de uma forma detalhada, mas simples para um leigo entender?

Rubens Takiguti Ribeiro (autor do blog) disse...

Olá, Kerwin, obrigado por comentar no meu blog. Vou tentar explicar e, caso tenha dúvidas, fique a vontade para perguntar.

"Singleton" é o nome de um design de projeto que visa solucionar um problema comum em sistemas de informação através de uma proposta de solução pré-definida.

O objetivo dele é prover uma classe que só pode ter um único objeto. Para isso, ele define um padrão que impede a criação de objetos da classe através do contrutor (chamada ao "new") e propõe a implementação de um método que cria um objeto quando solicitado (o método "getInstance" ou "get_instancia").

Porém, este método não é igual ao contrtutor, que sempre cria um objeto novo. Ao invés disso, ele cria um objeto na primeira vez que ele é invocado, e apenas devolve este mesmo objeto quando é invocado nas vezes posteriores.

Um lugar onde é útil usar singleton é, por exemplo, em uma classe que guarda configurações do sistema. Seja onde for necessário consultar alguma informação do objeto que guarda configurações do sistema, este objeto é o mesmo e não é preciso criar um novo objeto sempre que algum ponto do código necessitar. Ao invés disso, implementa-se o padrão singleton e sempre se obtém o mesmo objeto quando solicitado.

Agora clareou?