[php] 정적 변수를 초기화하는 방법

이 코드가 있습니다 :

private static $dates = array(
  'start' => mktime( 0,  0,  0,  7, 30, 2009),  // Start date
  'end'   => mktime( 0,  0,  0,  8,  2, 2009),  // End date
  'close' => mktime(23, 59, 59,  7, 20, 2009),  // Date when registration closes
  'early' => mktime( 0,  0,  0,  3, 19, 2009),  // Date when early bird discount ends
);

다음과 같은 오류가 발생합니다.

구문 분석 오류 : 19 행의 /home/user/Sites/site/registration/inc/registration.class.inc에서 구문 오류, 예기치 않은 ‘(‘, ‘예상’) ‘

그래서, 내가 잘못하고있는 것 같아 …하지만 그렇게하지 않으면 어떻게 할 수 있습니까? 일반 문자열로 mktime을 변경하면 작동합니다. 나는 내가 할 수 있다는 것을 알고 그래서 종류의 같은 …

누구나 포인터가 있습니까?



답변

PHP는 이니셜 라이저에서 사소한 표현식을 구문 분석 할 수 없습니다.

클래스를 정의한 직후에 코드를 추가하여이 문제를 해결하는 것을 선호합니다.

class Foo {
  static $bar;
}
Foo::$bar = array(…);

또는

class Foo {
  private static $bar;
  static function init()
  {
    self::$bar = array(…);
  }
}
Foo::init();

PHP 5.6 은 이제 일부 표현식을 처리 할 수 ​​있습니다.

/* For Abstract classes */
abstract class Foo{
    private static function bar(){
        static $bar = null;
        if ($bar == null)
            bar = array(...);
        return $bar;
    }
    /* use where necessary */
    self::bar();
}


답변

클래스 로딩을 제어 할 수 있다면 거기서 정적 초기화를 수행 할 수 있습니다.

예:

class MyClass { public static function static_init() { } }

클래스 로더에서 다음을 수행하십시오.

include($path . $klass . PHP_EXT);
if(method_exists($klass, 'static_init')) { $klass::staticInit() }

보다 무거운 솔루션은 ReflectionClass와의 인터페이스를 사용하는 것입니다.

interface StaticInit { public static function staticInit() { } }
class MyClass implements StaticInit { public static function staticInit() { } }

클래스 로더에서 다음을 수행하십시오.

$rc = new ReflectionClass($klass);
if(in_array('StaticInit', $rc->getInterfaceNames())) { $klass::staticInit() }


답변

정적 변수를 작동시키는 방법을 찾는 대신 게터 함수를 만드는 것을 선호합니다. 특정 클래스에 속하는 배열이 필요하고 구현하기가 훨씬 간단한 경우에도 유용합니다.

class MyClass
{
   public static function getTypeList()
   {
       return array(
           "type_a"=>"Type A",
           "type_b"=>"Type B",
           //... etc.
       );
   }
}

리스트가 필요할 때마다 getter 메소드를 호출하면됩니다. 예를 들면 다음과 같습니다.

if (array_key_exists($type, MyClass::getTypeList()) {
     // do something important...
}


답변

Tjeerd Visser와 porneL의 답변을 조합하여 사용합니다.

class Something
{
    private static $foo;

    private static getFoo()
    {
        if ($foo === null)
            $foo = [[ complicated initializer ]]
        return $foo;
    }

    public static bar()
    {
        [[ do something with self::getFoo() ]]
    }
}

그러나 더 좋은 해결책은 정적 메소드를 없애고 싱글 톤 패턴을 사용하는 것입니다. 그런 다음 생성자에서 복잡한 초기화를 수행합니다. 또는 “서비스”로 만들고 DI를 사용하여 필요한 클래스에 주입하십시오.


답변

정의에서 설정하기에는 너무 복잡합니다. 그래도 정의를 null로 설정 한 다음 생성자에서 정의를 확인하고 변경되지 않은 경우 설정하십시오.

private static $dates = null;
public function __construct()
{
    if (is_null(self::$dates)) {  // OR if (!is_array(self::$date))
         self::$dates = array( /* .... */);
    }
}


답변

이 코드 부분에서는 함수를 호출 할 수 없습니다. 다른 코드보다 먼저 init () 유형의 메소드를 실행하면 변수를 채울 수 있습니다.


답변

PHP 7.0.1에서는 다음을 정의 할 수있었습니다.

public static $kIdsByActions = array(
  MyClass1::kAction => 0,
  MyClass2::kAction => 1
);

그런 다음 다음과 같이 사용하십시오.

MyClass::$kIdsByActions[$this->mAction];