işlev içinde `static` anahtar kelimesi?


Yanıtlar:


155

İşlevin, $has_runbirden çok çağrı arasında verilen değişkenin değerini ( örneğinizde) hatırlamasını sağlar .

Bunu farklı amaçlar için kullanabilirsiniz, örneğin:

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

Bu örnekte, ifyalnızca bir kez çalıştırılacaktır. Birden fazla çağrı yapılsa bile doStuff.


4
Ayrıca, işlev bir kez çalıştıysa, sonraki aramalarda $cacheto değerini sıfırlamaz null, değil mi?
user151841

7
@ user151841 $cacheyalnızca istekler arasında sıfırlanacaktır. Yani evet, aynı istekteki (veya komut dosyasının yürütülmesi) sonraki aramalarda sıfırlanmayacaktır .
Yoshi

14
@Muhammad çünkü statik anahtar kelimelerin yaptığı şey bu.
Yoshi

2
Bu işlev her çağrıldığında ifkoşul kontrolünün $cache === nullyürütüleceğine inanıyorum , eğer blok kodu $cache = '..'çalıştırılacaksa değil.
Aivaras

İşlev bir sınıftaki yöntemse ne olur, statik değişken örnekler arasında paylaşılır mı?
santiago arizti

83

Şimdiye kadar kimsenin bahsetmediği görülüyor ki, aynı sınıfın farklı örneklerindeki statik değişkenler durumlarında kalıyor. OOP kodunu yazarken dikkatli olun.

Bunu düşün:

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

Statik bir değişkenin durumunu yalnızca geçerli sınıf örneği için hatırlamasını istiyorsanız, aşağıdaki gibi bir sınıf özelliğine bağlı kalmanız daha iyi olur:

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
Ah! Bu beni birden fazla ısırdı. Statik öğenin yalnızca örnek için geçerli olmasını ve not alma olanağı sunmasını bekliyordum; ama bu yanlış bir düşünce biçimiydi, çünkü sınıflar bağlamında "statik" bir bütün olarak sınıf için anlam ifade ediyor. Özellikler, yöntemler ve değişkenler.
systemovich

14

Aşağıdaki örnek verildiğinde:

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

İlk çağrı

a(20);

çıktı olacak 10, sonra $volacak 20. Değişken$v , statik (dinamik olmayan) bir değişken olduğundan, işlev sona erdikten sonra çöp olarak toplanmaz. Değişken, komut dosyası tamamen bitene kadar kapsamı içinde kalacaktır.

Bu nedenle, aşağıdaki çağrı

a(15);

daha sonra çıktı alacak 20ve sonra $volacak şekilde ayarlanacaktır 15.


9

Statik, bir sınıfta olduğu gibi çalışır. Değişken, bir işlevin tüm örnekleri arasında paylaşılır. Özel örneğinizde, işlev çalıştırıldığında, $ has_run TRUE olarak ayarlanır. İşlevin gelecekteki tüm çalıştırmalarında $ has_run = TRUE olacaktır. Bu, özellikle özyinelemeli işlevlerde yararlıdır (sayımı geçmeye alternatif olarak).

Statik bir değişken yalnızca yerel bir işlev kapsamında bulunur, ancak program yürütülmesi bu kapsamı terk ettiğinde değerini kaybetmez.

Bkz. Http://php.net/manual/en/language.variables.scope.php


3

Bir işlevdeki statik değişken, işlevi kaç kez çağırırsanız çağırın, yalnızca 1 değişken olduğu anlamına gelir.

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

Genişletmek için Yang'ın cevabını

Statik değişkenlerle bir sınıfı genişletirseniz, tek tek genişletilmiş sınıflar örnekler arasında paylaşılan "kendi" referanslı statiklerini tutacaktır.

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

çıktılar:

bir 1:
İki : 1
on: 2
bir : 3 <- x_repeat
on: 4
bir : 5 <- x_repeat
iki : 2

http://ideone.com/W4W5Qv


1

Bir fonksiyonun içinde static değişkenin, işlev her çağrıldığında sayfanın yüklenme süresi boyunca değerini koruyacağı anlamına gelir.

İki kez bir işlevi çağırmak eğer set nedenle örnekte sen, verdiğim $has_runiçin true, o işlev çünkü daha önce isminin verildiğini bilmek mümkün olacaktır $has_runhala eşit olacağını trueişlevi ikinci kez başladığında.

Kullanımı staticbu bağlamda anahtar kelime burada PHP kılavuzunda açıklanmıştır: http://php.net/manual/en/language.variables.scope.php

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.