Kata kunci `statis` di dalam fungsi?


110

Saya melihat sumber Drupal 7, dan saya menemukan beberapa hal yang belum pernah saya lihat sebelumnya. Saya melakukan beberapa pencarian awal di manual php, tetapi tidak menjelaskan contoh-contoh ini.

Apa yang dilakukan kata kunci staticterhadap variabel di dalam fungsi?

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

Jawaban:


155

Itu membuat fungsi mengingat nilai variabel yang diberikan ( $has_rundalam contoh Anda) di antara beberapa panggilan.

Anda dapat menggunakan ini untuk tujuan yang berbeda, misalnya:

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

Dalam contoh ini, ifhanya akan dijalankan sekali. Bahkan jika beberapa panggilan ke doStuffakan terjadi.


4
Selain itu, jika fungsi telah dijalankan sekali, itu tidak akan mengatur ulang nilai $cachemenjadi nullpada panggilan berikutnya, bukan?
pengguna151841

7
@ user151841 $cachehanya akan disetel ulang di antara permintaan. Jadi ya, itu tidak akan diatur ulang pada panggilan berikutnya dalam permintaan yang sama (atau eksekusi skrip).
Yoshi

14
@Muhammad karena itulah kata kunci statis .
Yoshi

2
Saya percaya ifpemeriksaan kondisi $cache === nullakan dijalankan setiap kali fungsi ini dipanggil, tidak dipikirkan jika kode blok $cache = '..'akan dieksekusi.
Aivaras

apa yang terjadi jika fungsinya adalah metode di kelas, apakah variabel statis dibagikan antar instance?
santiago arizti

83

Sepertinya tidak ada yang menyebutkan sejauh ini, bahwa variabel statis di dalam instance berbeda dari kelas yang sama tetap statusnya. Jadi berhati-hatilah saat menulis kode OOP.

Pertimbangkan ini:

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

Jika Anda ingin variabel statis mengingat statusnya hanya untuk instance kelas saat ini, Anda sebaiknya tetap menggunakan properti kelas, seperti ini:

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
Aduh! Ini telah menggigit saya lebih dari sekali. Saya mengharapkan statis untuk diterapkan ke contoh saja, memberikan memoization; Namun cara berpikir itu salah, karena "statis" dalam konteks kelas berarti bagi kelas secara keseluruhan. Properti, metode, DAN variabel.
systemovich

14

Diberikan contoh berikut:

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

Panggilan pertama

a(20);

akan menampilkan 10, lalu $vmenjadi 20. Variabel $vtidak dikumpulkan sampah setelah fungsi berakhir, karena ini adalah variabel statis (non-dinamis). Variabel akan tetap dalam ruang lingkupnya sampai skrip benar-benar berakhir.

Oleh karena itu, panggilan berikut ini

a(15);

kemudian akan menampilkan 20, dan kemudian disetel $vmenjadi 15.


9

Statis bekerja dengan cara yang sama seperti di kelas. Variabel dibagikan di semua contoh fungsi. Dalam contoh khusus Anda, setelah fungsi dijalankan, $ has_run disetel ke TRUE. Semua fungsi yang berjalan di masa mendatang akan memiliki $ has_run = TRUE. Ini sangat berguna dalam fungsi rekursif (sebagai alternatif untuk meneruskan hitungan).

Variabel statis hanya ada dalam lingkup fungsi lokal, tetapi tidak kehilangan nilainya ketika eksekusi program meninggalkan ruang lingkup ini.

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


3

variabel statis dalam suatu fungsi berarti bahwa tidak peduli berapa kali Anda memanggil fungsi tersebut, hanya ada 1 variabel.

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

Untuk memperluas jawaban Yang

Jika Anda memperluas kelas dengan variabel statis, masing-masing kelas yang diperluas akan menyimpan statis yang direferensikan "sendiri" yang dibagikan di antara instance.

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

keluaran:

satu: 1
dua : 1
satu: 2
satu : 3 <- x_repeat
satu: 4
satu : 5 <- x_repeat
dua : 2

http://ideone.com/W4W5Qv


1

Di dalam fungsi, staticberarti variabel akan mempertahankan nilainya setiap kali fungsi dipanggil selama masa pemuatan halaman.

Oleh karena itu dalam contoh yang Anda berikan, jika Anda memanggil suatu fungsi dua kali, jika disetel $has_runke true, maka fungsi tersebut akan dapat mengetahui bahwa fungsi tersebut sebelumnya telah dipanggil karena $has_runakan tetap sama dengan truesaat fungsi dimulai untuk kedua kalinya.

Penggunaan statickata kunci dalam konteks ini dijelaskan dalam manual PHP di sini: http://php.net/manual/en/language.variables.scope.php

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.