2010-06-10 4 views
11

기본 클래스에서 기본 클래스를 확장하는 클래스에서 정적 변수 세트를 사용할 수 있어야합니다. PHP 5.2에서 클래스 상속 : 확장 클래스에서 정적 변수를 재정의 하시겠습니까?

이를 고려

class Animal { 
    public static $color = 'black'; 

    public static function get_color() 
    { 
     return self::$color; 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 
} 

echo Animal::get_color(); // prints 'black' 
echo Dog::get_color(); // also prints 'black' 

이것은 PHP의 5.3.x에서 훌륭하게 작동 (Dog::get_color() 인쇄 '갈색')가 결합 늦게 정적이 있기 때문에. 하지만 프로덕션 서버는 PHP 5.2.11을 실행하므로 스크립트를 수정해야합니다.

이 문제를 해결하기위한 다소 멋진 해결 방법이 있습니까?

건배!
크리스토퍼

편집 : 아래에 언급 한 바와 같이 목표

이 내가 달성하기 위해 노력하고 무엇을 매우 단순화 된 예입니다. 내가 문제 (그리고 문제 자체)를 해결하는 데 사용했던 두 가지 옵션을 제공하면 누군가가 다른 해결책을 가질 수 있습니다 ...

"찾기"와 같은 기능을 가진 기본 데이터베이스 모델을 구축했습니다. , "find_by"및 "find_all"(모두 정적 임).

PHP 5.3에는 현재 호출 된 클래스의 이름을 확인하고 올바른 데이터베이스 테이블에 매핑하는 데 사용하는 get_called_class()이라는 함수가 있습니다. Ex 클래스 Userusers을 가리 킵니다.

get_called_class()은 PHP 5.2.x에는 존재하지 않으며 내가 발견 한 해킹 구현은 매우 신뢰할 만합니다. 그런 다음 클래스 이름을 포함하는 모든 모델 클래스에서 정적 변수를 사용하는이 옵션을 사용했습니다.

+1

내가'Dog'가'Animal'을 확장해야 같은데요? –

+0

당신은 절대적으로 맞습니다 :) – Christoffer

+1

더 설명하면, 행 클래스의 정적이 아닌 테이블 클래스의 메소드로 찾기/찾기 함수를 넣어야한다고 생각합니다 (이것은 여러분이 시도하는 것처럼 들리는 것입니다). – gnarf

답변

2

슬프게도 PHP 5.3 이전에는 늦은 정적 바인딩을 시뮬레이트 할 방법이 없습니다. 상속이 의도 한대로 작동하도록하는 유일한 방법은 인스턴스 변수와 메소드 인 경우입니다.

+0

정적 메서드를 사용하여 개체를 직접 만들 수 없다는 의미입니까? – Christoffer

+1

저장된 정적 데이터에 의존하지 않는 경우는 아닙니까? – VoteyDisciple

9

젠드 프레임 워크에서 서브 클래 싱 할 때이 문제가 발생했습니다. 내 결정은 순전히 정적 땅에서, 당신은 ... 하나의 옵션을 상속하는 클래스에서 함수를 다시 정의이었다 :

class Animal { 
    public static $color = 'black'; 

    public static function get_color() 
    { 
     return self::$color; 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 

    public static function get_color() 
    { 
     return self::$color; 
    } 
} 

당신은 인스턴스를 생성 할 수있는 경우 - 당신은 호출 클래스를 찾아 get_class($this)을 사용할 수 있습니다

class Animal { 
    public static $color = 'black'; 

    public function getColor() // note, not static 
    { 
     $class = get_class($this); 
     return $class::$color; 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 
} 

$animal = new Animal(); 
echo $animal->getColor(); // prints 'black' 
$dog = new Dog(); 
echo $dog->getColor(); // prints 'brown' 

다른 옵션은 정적 함수에 대한 함수 매개 변수를 사용하여 호출 된 클래스를 정의하는 것뿐이었습니다. __CLASS__이 기본값이 될 수 있으며 서브 클래스의 return parent::get_class($class)이 될 수 있습니다. PHP에서

class Animal { 
    public static $color = 'black'; 

    public static function get_color($class = __CLASS__) 
    { 
     // Super Simple Example Case... I imagine this function to be more complicated 
     return $class::$color; 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 

    public static function get_color($class = __CLASS__) 
    { 
     return parent::get_color($class); 
    } 
} 
+1

답변 해 주셔서 감사합니다. 제가 제공 한 예제에서 작동하지만 실제 사례는 좀 더 복잡합니다. 내가 실제로하고 싶은 일을 알려주고 내 의견을 편집합니다. 내가 시도한 것보다 다른 각도. – Christoffer

5

이 같은 패턴은 내가 공용 정적 속성을 반환하는 의심의 여지 당신이 정적 방법에 대한 self::를 사용하려고하는 유일한 방법은 (쉽게 정적 기능을 다시 사용하기 위해 사용될 수있다 5.3+는, 다음이 선호 될 것이다 :

class Animal { 
    public static $color = 'black'; 

    public static function get_color() 
    { 
     return static::$color; // Here comes Late Static Bindings 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 
} 

echo Animal::get_color(); // prints 'black' 
echo Dog::get_color(); // prints 'brown' 

Late Static Bindings (PHP.net)

관련 문제