palavra-chave `static` dentro da função?


110

Eu estava olhando a fonte do Drupal 7 e encontrei algumas coisas que não tinha visto antes. Eu fiz algumas pesquisas iniciais no manual do php, mas não explicou esses exemplos.

O que a palavra-chave staticfaz com uma variável dentro de uma função?

function module_load_all($bootstrap = FALSE) {
    static $has_run = FALSE

Respostas:


155

Faz com que a função lembre o valor da variável fornecida ( $has_runno seu exemplo) entre várias chamadas.

Você pode usar isso para diferentes fins, por exemplo:

function doStuff() {
  static $cache = null;

  if ($cache === null) {
     $cache = '%heavy database stuff or something%';
  }

  // code using $cache
}

Neste exemplo, o ifseria executado apenas uma vez. Mesmo se doStuffocorrerem várias chamadas para .


4
Além disso, se a função foi executada uma vez, ela não redefinirá o valor de $cachepara nullem chamadas posteriores, certo?
user151841

7
@ user151841 $cachesó será redefinido entre as solicitações. Portanto, sim, ele não será redefinido nas chamadas posteriores na mesma solicitação (ou execução do script).
Yoshi

14
@Muhammad porque é exatamente isso que as palavras-chave estáticas fazem.
Yoshi

2
Acredito ifque a verificação de condição $cache === nullseria executada toda vez que essa função fosse chamada, mas não se o código do bloco $cache = '..'fosse executado.
Aivaras de

o que acontece se a função for um método em uma classe, a variável estática é compartilhada entre as instâncias?
santiago arizti

83

Parece que ninguém mencionou até agora, que as variáveis ​​estáticas dentro de diferentes instâncias da mesma classe permanecem seu estado. Portanto, tenha cuidado ao escrever o código OOP.

Considere isto:

class Foo
{
    public function call()
    {
        static $test = 0;

        $test++;
        echo $test . PHP_EOL; 
    }
}

$a = new Foo();
$a->call(); // 1
$a->call(); // 2
$a->call(); // 3


$b = new Foo();
$b->call(); // 4
$b->call(); // 5

Se você quiser que uma variável estática lembre seu estado apenas para a instância da classe atual, é melhor manter uma propriedade de classe, como esta:

class Bar
{
    private $test = 0;

    public function call()
    {
        $this->test++;
        echo $this->test . PHP_EOL; 
    }
}


$a = new Bar();
$a->call(); // 1
$a->call(); // 2
$a->call(); // 3


$b = new Bar();
$b->call(); // 1
$b->call(); // 2

1
Ai! Isso me mordeu mais de uma vez. Eu esperava que a estática se aplicasse apenas à instância, fornecendo memoização; mas essa era uma maneira errada de pensar, porque "estático" no contexto das classes significa para a classe como um todo. Propriedades, métodos e variáveis ​​AND.
systemovich

14

Dado o seguinte exemplo:

function a($s){
    static $v = 10;
    echo $v;
    $v = $s;
}

Primeira chamada de

a(20);

sairá 10, então $vserá 20. A variável $vnão é coletada como lixo após o término da função, pois é uma variável estática (não dinâmica). A variável permanecerá dentro de seu escopo até que o script termine totalmente.

Portanto, a seguinte chamada de

a(15);

será então emitido 20e definido $vcomo 15.


9

A estática funciona da mesma maneira que em uma classe. A variável é compartilhada por todas as instâncias de uma função. Em seu exemplo particular, uma vez que a função é executada, $ has_run é definido como TRUE. Todas as execuções futuras da função terão $ has_run = TRUE. Isso é particularmente útil em funções recursivas (como uma alternativa para passar a contagem).

Uma variável estática existe apenas no escopo de uma função local, mas não perde seu valor quando a execução do programa deixa esse escopo.

Veja http://php.net/manual/en/language.variables.scope.php


3

variável estática em uma função significa que não importa quantas vezes você chame a função, há apenas 1 variável.

<?php

class Foo{
    protected static $test = 'Foo';
    function yourstatic(){
        static $test = 0;
        $test++;
        echo $test . "\n"; 
    }

    function bar(){
        $test = 0;
        $test++;
        echo $test . "\n";
    }
}

$f = new Foo();
$f->yourstatic(); // 1
$f->yourstatic(); // 2
$f->yourstatic(); // 3
$f->bar(); // 1
$f->bar(); // 1
$f->bar(); // 1

?>

3

Para expandir a resposta de Yang

Se você estender uma classe com variáveis ​​estáticas, as classes estendidas individuais manterão sua "própria" estática referenciada que é compartilhada entre as instâncias.

<?php
class base {
     function calc() {
        static $foo = 0;
        $foo++;
        return $foo;
     }
}

class one extends base {
    function e() {
        echo "one:".$this->calc().PHP_EOL;
    }
}
class two extends base {
    function p() {
        echo "two:".$this->calc().PHP_EOL;
    }
}
$x = new one();
$y = new two();
$x_repeat = new one();

$x->e();
$y->p();
$x->e();
$x_repeat->e();
$x->e();
$x_repeat->e();
$y->p();

saídas:

um: 1
dois : 1
um: 2
um : 3 <- x_repetir
um: 4
um : 5 <- x_repetir
dois : 2

http://ideone.com/W4W5Qv


1

Dentro de uma função, staticsignifica que a variável manterá seu valor sempre que a função for chamada durante o carregamento da página.

Portanto, no exemplo que você deu, se você chamar uma função duas vezes, se for definida $has_runcomo true, a função poderá saber que foi chamada anteriormente porque $has_runainda seria igual a truequando a função iniciar pela segunda vez.

O uso da staticpalavra - chave neste contexto é explicado no manual do PHP aqui: http://php.net/manual/en/language.variables.scope.php

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.