`static` ключове слово всередині функції?


110

Я дивився на джерело для Drupal 7, і знайшов деякі речі, яких раніше не бачив. Я поглянув на посібник з php, але це не пояснило цих прикладів.

Що робить ключове слово staticзі змінною всередині функції?

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

Відповіді:


155

Це змушує функцію запам'ятовувати значення даної змінної ( $has_runу вашому прикладі) між декількома викликами.

Ви можете використовувати це для різних цілей, наприклад:

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

У цьому прикладі ifвиконується лише один раз. Навіть якщо кілька викликів doStuffвідбудеться.


4
Крім того, якщо функція запустилася один раз, вона не скине значення значення $cacheдля nullпізніших викликів, правда?
користувач151841

7
@ user151841 $cacheбуде скинуто лише між запитами. Так що так, вона не буде скидатися на пізні дзвінки в одному запиті (або виконанні сценарію).
Йоші

14
@ Мухаммед, тому що саме це робить статичні ключові слова .
Йоші

2
Я вважаю, що ifперевірка $cache === nullстану виконується щоразу, коли ця функція викликається, не думає, чи $cache = '..'буде виконаний блок-код .
Айварас

що станеться, якщо функція є методом у класі, чи статична змінна поділяється між екземплярами?
Сантьяго Арісті

83

Схоже, ніхто досі не згадував, що статичні змінні в різних екземплярах одного класу залишаються їх станом. Тому будьте обережні при написанні коду OOP.

Врахуйте це:

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

Якщо ви хочете, щоб статична змінна запам’ятала її стан лише для поточного екземпляра класу, вам краще дотримуватися властивості класу, наприклад, такого:

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
Ой! Це мене не раз кусало. Я очікував, що статика застосує лише до екземпляра, забезпечуючи запам'ятовування; але це був неправильний спосіб мислення, тому що "статичне" в контексті класів означає для класу в цілому. Властивості, методи та змінні.
системович

14

Дано наступний приклад:

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

Перший дзвінок о

a(20);

виведе 10, то $vбути 20. Змінна $vне є сміттям, зібраним після закінчення функції, оскільки це статична (нединамічна) змінна. Змінна залишатиметься в її межах, поки сценарій повністю не закінчиться.

Тому наступний заклик о

a(15);

буде виводити 20, а потім встановити , $vщоб бути 15.


9

Статичний працює так само, як і в класі. Змінна поділяється на всі екземпляри функції. У вашому конкретному прикладі, як тільки функція запущена, $ has_run встановлюється на TRUE. Усі майбутні запуски функції матимуть $ has_run = TRUE. Це особливо корисно при рекурсивних функціях (як альтернатива передачі рахунку).

Статична змінна існує лише в локальній області функцій, але вона не втрачає свого значення, коли виконання програми залишає цю область.

Дивіться http://php.net/manual/en/language.variables.scope.php


3

статична змінна у функції означає, що незалежно від того, скільки разів ви викликаєте функцію, є лише 1 змінна.

<?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

Щоб розширити відповідь Ян

Якщо ви розширите клас зі статичними змінними, окремі розширені класи матимуть "власну" посилальну статику, яка поділяється між екземплярами.

<?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();

Виходи:

один: 1
два : 1
один: 2
один : 3 <- x_повторити
один: 4
один : 5 <- x_ повторити
два : 2

http://ideone.com/W4W5Qv


1

Всередині функції staticозначає, що змінна зберігатиме своє значення кожного разу, коли функція буде викликана протягом життя завантаження сторінки.

Тому в даному прикладі ви дали, якщо ви викликаєте функцію двічі, якщо він встановлений $has_runв true, то функція буде мати можливість знати , що він раніше був названий тому , що по- $has_run, як і раніше дорівнюватиме , trueколи функція починається вдруге.

Використання staticключового слова в цьому контексті пояснюється в посібнику PHP тут: http://php.net/manual/en/language.variables.scope.php

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.