chamar um método estático dentro de uma classe?


166

como chamo um método estático de outro método dentro da mesma classe?

$this->staticMethod();

ou

$this::staticMethod();

13
Você pode estar interessado nisto ( selfvs. $this): stackoverflow.com/questions/151969/php-self-vs-this #
Felix Kling

Apenas um FYI, seu primeiro exemplo é uma variável de instância que chama um método estático, o que não é possível porque um método estático faz parte da classe e não é acessível por meio de uma variável de instância.
Joãoeson

você pode excluir o $ this agora, por favor, não funcionará se apenas usar métodos estáticos e nenhuma instância existir.
malhal

Respostas:


321

...mas por que? $ this-> staticMethod () também funciona. Você pode explicar por que self :: staticMethod () é mais correto (se for)?
Ian Dunn

29
@Ian Dunn Simplificando, $thissó existe se um objeto foi instanciado e você só pode usá-lo a $this->methodpartir de um objeto existente. Se você não tem um objeto, mas apenas chama um método estático e nesse método deseja chamar outro método estático na mesma classe, é necessário usá-lo self::. Portanto, para evitar erros em potencial (e avisos estritos), é melhor usar self.
jeroen

1
Obrigado! Em laravel, descobri que estava acidentalmente chamando o método estático em um controlador estendido usando $this, mas o problema não apareceu até o código ser enviado stage. nenhum erro voltou, o valor era justo 0. ter cuidado com isso, o usoself::
blamb

44

Vamos supor que esta seja sua classe:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

De dentro do foo()método, vamos olhar para as diferentes opções:

$this->staticMethod();

Então isso chama staticMethod()como método de instância, certo? Isso não. Isso ocorre porque o método é declarado como public statico intérprete o chamará como método estático e, portanto, funcionará conforme o esperado. Pode-se argumentar que isso torna menos óbvio a partir do código que uma chamada de método estático está ocorrendo.

$this::staticMethod();

Desde o PHP 5.3 você pode usar $var::method()para significar <class-of-$var>::; isso é bastante conveniente, embora o caso de uso acima ainda seja pouco convencional. Isso nos leva à maneira mais comum de chamar um método estático:

self::staticMethod();

Agora, antes de começar a pensar que ::é o operador de chamada estática, deixe-me dar outro exemplo:

self::bar();

Isso será impresso baz = 1, o que significa isso $this->bar()e self::bar()fará exatamente a mesma coisa; isso ::é apenas um operador de resolução de escopo. É lá para fazer parent::, self::e static::trabalho e dar-lhe acesso a variáveis estáticas; como um método é chamado depende de sua assinatura e de como o chamador foi chamado.

Para ver tudo isso em ação, consulte esta saída do 3v4l.org .


self::bar()parece enganador - isso agora está obsoleto? (usando self::para chamar um método de instância em vez de um método estático).
Página

@ToolmakerSteve de que maneira você diria que é enganosa?
Ja͢ck

Logicamente falando, não há selfquando invocar um método estático. Por definição: o método estático pode ser chamado de qualquer lugar e não recebe um parâmetro "self". No entanto, vejo a conveniência dessa phpsintaxe, para que você não precise escrever MyClassName::. Estou acostumado a linguagens de tipo estatico, em que o compilador deve receber todas as variáveis ​​disponíveis no escopo atual, para que (o equivalente a) self::possa ser omitido. Então, apenas um disse self instanceMethod; não há razão para dizer self staticMethod.
Página

15

Esta é uma resposta muito tardia, mas adiciona alguns detalhes às respostas anteriores

Quando se trata de chamar métodos estáticos no PHP de outro método estático na mesma classe, é importante diferenciar entre selfe o nome da classe.

Tome por exemplo este código:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

A saída deste código é:

Classe original

Classe estendida

Isso ocorre porque selfse refere à classe em que o código está, e não à classe do código do qual está sendo chamado.

Se você quiser usar um método definido em uma classe que herda a classe original, precisará usar algo como:

$class = get_called_class();
$class::function_name(); 

2
Eu achei isso informativo. Um pequeno detalhe, eu não diria que as outras respostas são "enganosas". Mais preciso dizer que eles são "incompletos"; eles não abordam a questão (não solicitada) do que self::faz no caso (raro) em que um método estático A chama outro método estático B e B foi substituído em uma subclasse. IMHO, é menos confuso restringir a substituição do método aos métodos de "instância"; use essa habilidade com moderação no nível estático. Em outras palavras, os leitores do seu código esperam que o método substitua os métodos de instância (que é a essência da codificação OO), mas não os estáticos.
Home

1
Muito útil e faz sentido que uma extensão da classe não seja a classe original. Portanto, é lógico que selfnão seria usado nesse caso. Você declarou uma classe separada como uma extensão da primeira classe. Usar selfdentro da classe estendida se referiria à classe estendida. Isso não contradiz as outras respostas, mas certamente ajuda a demonstrar o escopo de self.
iyrin

2

Na versão posterior do PHP self::staticMethod();também não funcionará. Irá lançar o erro padrão estrito.

Nesse caso, podemos criar objetos da mesma classe e chamar por objeto

aqui está o exemplo

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}

Você pode fazer isso, embora, se fun1não estiver usando self, não seja lógico torná-lo um método de instância. A maneira correta de fazer isso em php é declarar public static function fun1, em seguida, chamar, especificando a classe: Foo::fun1. Estou certo de que essa é a maneira pretendida de corrigir esse erro padrão estrito.
Home
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.