함수 내부의 '정적'키워드?


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.
user151841

7
@ user151841 $cache은 요청 사이에만 재설정됩니다. 예, 동일한 요청 (또는 스크립트 실행)에서 나중에 호출 할 때 재설정되지 않습니다 .
Yoshi 2011

14
@Muhammad는 static 키워드 가 하는 일이기 때문입니다 .
요시

2
저는 믿습니다 if조건 검사가 $cache === null,이 함수가 호출 될 때마다 실행의 블록 코드가 아닌 경우 생각 될 것입니다 $cache = '..'실행됩니다.
Aivaras 2015 년

함수가 클래스의 메서드 인 경우 정적 변수가 인스턴스간에 공유됩니까?
santiago arizti

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
아야! 이것은 나를 두 번 이상 물었습니다. 정적이 인스턴스에만 적용되어 메모를 제공 할 것으로 예상했습니다. 그러나 그것은 잘못된 생각입니다. 왜냐하면 클래스의 맥락에서 "정적"은 클래스 전체를 의미하기 때문입니다. 속성, 메서드 및 변수.
systemovich

14

다음 예가 주어집니다.

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

첫 번째 전화

a(20);

가 출력 10한 다음 $v20. 변수 $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();

출력 :

one : 1
two : 1
one : 2
one : 3 <-x_repeat
one : 4
one : 5 <-x_repeat
two : 2

http://ideone.com/W4W5Qv


1

함수 내부는 static페이지로드 수명 동안 함수가 호출 될 때마다 변수가 값을 유지함을 의미합니다.

따라서 주어진 예제에서 함수를 두 번 호출하면으로 설정 $has_run되어 있으면 함수가 두 번째로 시작될 때와 동일하기 true때문에 이전에 호출되었음을 알 수 $has_run있습니다 true.

static이 문맥 에서 키워드 의 사용법 은 다음 PHP 매뉴얼에 설명되어 있습니다 : http://php.net/manual/en/language.variables.scope.php

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.