PHP의 추상 상수 - 자식 클래스가 상수를 정의하도록 강제합니다.
저는 당신이 PHP에서 추상 상수를 가질 수 없다는 것을 알았습니다.
하위 클래스에 상수를 정의하도록 강제할 수 있는 방법이 있습니까(추상 클래스 내부 메서드 중 하나에서 사용해야 함)?
이것은 약간의 '해킹'일 수도 있지만, 하위 클래스에서 상수가 선언되지 않은 경우에는 다른 오류 메시지를 사용하여 작업을 수행합니다.
자기 참조 상수 선언은 구문적으로 올바르고 문제 없이 구문 분석되며, 해당 선언이 실제로 런타임에 실행되는 경우에만 오류를 던집니다. 따라서 추상 클래스의 자기 참조 선언은 하위 클래스에서 재정의되어야 합니다. 그렇지 않으면 치명적인 오류가 발생합니다.Cannot declare self-referencing constant
.
이 예에서 추상적인 부모 클래스는Foo
모든 자식이 변수를 선언하도록 강제합니다.NAME
이 코드는 정상적으로 실행되고 출력됩니다.Donald
하지만, 만약 아이 클래스가Fooling
변수를 선언하지 않았습니다. 치명적인 오류가 트리거됩니다.
<?php
abstract class Foo {
// Self-referential 'abstract' declaration
const NAME = self::NAME;
}
class Fooling extends Foo {
// Overrides definition from parent class
// Without this declaration, an error will be triggered
const NAME = 'Donald';
}
$fooling = new Fooling();
echo $fooling::NAME;
A constant
이다.constant
없습니다abstract
또는private
내가 알기로는 PHP의 상수이지만, 당신은 다음과 같은 작업을 할 수 있습니다.
샘플 추상 클래스
abstract class Hello {
const CONSTANT_1 = 'abstract'; // Make Abstract
const CONSTANT_2 = 'abstract'; // Make Abstract
const CONSTANT_3 = 'Hello World'; // Normal Constant
function __construct() {
Enforcer::__add(__CLASS__, get_called_class());
}
}
이것은 잘 작동할 것입니다.
class Foo extends Hello {
const CONSTANT_1 = 'HELLO_A';
const CONSTANT_2 = 'HELLO_B';
}
new Foo();
막대가 오류를 반환합니다.
class Bar extends Hello {
const CONSTANT_1 = 'BAR_A';
}
new Bar();
Songo가 오류를 반환할 것입니다.
class Songo extends Hello {
}
new Songo();
시행자 클래스
class Enforcer {
public static function __add($class, $c) {
$reflection = new ReflectionClass($class);
$constantsForced = $reflection->getConstants();
foreach ($constantsForced as $constant => $value) {
if (constant("$c::$constant") == "abstract") {
throw new Exception("Undefined $constant in " . (string) $c);
}
}
}
}
유감스럽게도...상수는 주석에 정확히 쓰여 있는 것입니다, 상수입니다.일단 정의되면 다시 정의할 수 없기 때문에 PHP의 추상적인 상속이나 인터페이스를 통해 정의를 요구하는 것은 불가능합니다.
하지만...상수가 상위 클래스의 생성자에 정의되어 있는지 확인할 수 있습니다.그렇지 않으면 예외를 적용합니다.
abstract class A
{
public function __construct()
{
if (!defined('static::BLAH'))
{
throw new Exception('Constant BLAH is not defined on subclass ' . get_class($this));
}
}
}
class B extends A
{
const BLAH = 'here';
}
$b = new B();
이것이 당신의 초기 설명에서 제가 생각할 수 있는 가장 좋은 방법입니다.
아니요, 하지만 추상적인 방법과 같은 다른 방법을 시도할 수 있습니다.
abstract class Fruit
{
abstract function getName();
abstract function getColor();
public function printInfo()
{
echo "The {$this->getName()} is {$this->getColor()}";
}
}
class Apple extends Fruit
{
function getName() { return 'apple'; }
function getColor() { return 'red'; }
//other apple methods
}
class Banana extends Fruit
{
function getName() { return 'banana'; }
function getColor() { return 'yellow'; }
//other banana methods
}
또는 정적 멤버:
abstract class Fruit
{
protected static $name;
protected static $color;
public function printInfo()
{
echo "The {static::$name} is {static::$color}";
}
}
class Apple extends Fruit
{
protected static $name = 'apple';
protected static $color = 'red';
//other apple methods
}
class Banana extends Fruit
{
protected static $name = 'banana';
protected static $color = 'yellow';
//other banana methods
}
php 7.2에서 테스트되었지만 5.3 이후에는 이 동작을 아카이브하기 위해 최신 정적 바인딩을 활용할 수 있습니다.대부분의 경우 런타임에 치명적인 오류를 처리하지 않기 때문에 예외와 동일한 결과를 얻는 치명적인 오류가 발생합니다.원하는 경우 사용자 정의 오류 처리기를 쉽게 구현할 수 있습니다.
따라서 다음과 같은 이점이 있습니다.
<?php
abstract class Foo {
public function __construct() {
echo static::BAR;
}
}
class Bar extends Foo {
const BAR = "foo bar";
}
$bar = new Bar(); //foo bar
제거할 경우const
다음을 얻을 수 있습니다.
Fatal error: Uncaught Error: Undefined class constant 'BAR' in ...
제가 뭔가를 놓쳤을 수도 있지만, 늦은 정적 바인딩을 사용하는 것이 저에게는 효과적이었습니다.이것이 당신의 질문에 효과가 있습니까?
abstract class A{
const NAME=null;
static function f(){
return static::NAME;
}
}
class B extends A{
const NAME='B';
}
B::f();
PHP 인터페이스는 상수를 지원합니다.이것은 이상적이지 않습니다. 왜냐하면 여러분은 모든 어린이 클래스에 인터페이스를 구현해야 하기 때문입니다. 그래서 그것은 목적을 부분적으로 좌절시킵니다.
언급URL : https://stackoverflow.com/questions/10368620/abstract-constants-in-php-force-a-child-class-to-define-a-constant
'programing' 카테고리의 다른 글
Y축이 정수만 사용하도록 강제하는 방법 (0) | 2023.08.17 |
---|---|
MySQL에서 Forward Engineering을 시도하는 동안 오류 1064가 발생했습니다. (0) | 2023.08.17 |
일부 SQLite3 테이블의 데이터를 덤프하려면 어떻게 해야 합니까? (0) | 2023.08.17 |
문자열에 알파벳 문자가 포함되어 있는지 확인하려면 어떻게 해야 합니까? (0) | 2023.08.17 |
모두 비활성화하는 방법모두 비활성화하는 방법jQuery와 함께 폼 안에?jQuery와 함께 폼 안에? (0) | 2023.08.17 |