Hook에는 글로벌 함수와 getInstance() 메소드를 포함하는 싱글턴 클래스 그리고 인스턴스를 자동으로 생성하는 방법으로 크게 세 가지를 지원합니다.
244 이슈가 해결되면 클로저도 지원하게 되겠죠.
PHP 8 미만에서는 getInstance()가 없는 클래스는 강제로 인스턴스를 생성하여 실행했지만, PHP 8에서는 Fatal error가 발생합니다.
아래 클래스는 PHP 8 미만에서는 someMethodC 메소드를 호출한 방법을 제외하고는 someMethodA, someMethodB는 warning 메시지를 출력하지만 동작은 합니다. 비록 인스턴스가 몇개가 생성되더라도요.
class SomeClass
{
public function __construct()
{
}
public function someMethodA()
{
error_log('someMethodA');
}
public static function someMethodB()
{
error_log('someMethodB');
}
public function someMethodC()
{
error_log('someMethodC');
}
}
add_event('CUSTOM_EVENT', array('SomeClass', 'someMethodA')); // Fatal error
add_event('CUSTOM_EVENT', array('SomeClass', 'someMethodB')); // Fatal error
// add_event('CUSTOM_EVENT', array(new SomeClass(), 'someMethodC')); // Fatal error. 이건 지금도 안 됨
run_event('CUSTOM_EVENT');
하지만 PHP 8 이상에서는 getInstance() 메소드를 호출하는 call_user_func(array($class, $this->singleton)) 코드로 인해 Fatal error가 발생합니다.
PHP Fatal error: Uncaught TypeError: call_user_func(): Argument #1 ($function) must be a valid callback, class ListenerClass does not have a method "getInstance" in ...
즉, Hook을 PHP 8 이상에서도 문제 없이 사용하려면 클래스에는 getInstance() 메소드를 포함하는 싱글턴 클래스를 사용해야 합니다.
하지만 , PHP 8 미만에서는 getInstance() 메소드가 없다면 항상 새로운 인스턴스를 생성하여 동작하도록 되어 있는데 이것이 PHP 8 이상에서는 Fatal error로 인해 사용할 수 없게 됩니다.
Hook에는 글로벌 함수와
getInstance()
메소드를 포함하는 싱글턴 클래스 그리고 인스턴스를 자동으로 생성하는 방법으로 크게 세 가지를 지원합니다.244 이슈가 해결되면 클로저도 지원하게 되겠죠.
PHP 8 미만에서는
getInstance()
가 없는 클래스는 강제로 인스턴스를 생성하여 실행했지만, PHP 8에서는 Fatal error가 발생합니다.아래 클래스는 PHP 8 미만에서는
someMethodC
메소드를 호출한 방법을 제외하고는someMethodA
,someMethodB
는 warning 메시지를 출력하지만 동작은 합니다. 비록 인스턴스가 몇개가 생성되더라도요.하지만 PHP 8 이상에서는
getInstance()
메소드를 호출하는call_user_func(array($class, $this->singleton))
코드로 인해 Fatal error가 발생합니다.즉, Hook을 PHP 8 이상에서도 문제 없이 사용하려면 클래스에는
getInstance()
메소드를 포함하는 싱글턴 클래스를 사용해야 합니다. 하지만 , PHP 8 미만에서는getInstance()
메소드가 없다면 항상 새로운 인스턴스를 생성하여 동작하도록 되어 있는데 이것이 PHP 8 이상에서는 Fatal error로 인해 사용할 수 없게 됩니다.https://github.com/gnuboard/gnuboard5/blob/4eba618a829e2065d7cd85235300355323b210e0/lib/Hook/hook.extends.class.php#L22-L32
/lib/Hook/hook.extend.php
파일에서 PHP warning 메시지를 무시하고 동작하는 상태이므로 호환성을 유지한채로 Fatal 오류를 방지해야 합니다. 무작정getInstance()
메소드를 호출하기 전에 확인이 필요합니다.또한, 아래와 같은 개선도 적용되면 좋겠네요.
244 클로저 사용 문제 해결
add_event('CUSTOM_EVENT', function() {})
add_event('CUSTOM_EVENT', array('SomeClass', 'someStaticMethod'))
add_event('CUSTOM_EVENT', 'SomeClass::someStaticMethod')
add_event('CUSTOM_EVENT', [$this, 'someMethod'])
아래와 같이 고쳐봤는데 호환성 확인은 더 필요합니다. 참고하여 위와 같은 개선이 가능하면 좋겠네요. (위에 링크한 hook.extends.class.php 코드 부분을 대체합니다.
error_log()
는 디버깅 참고를 위해 추가한 코드입니다.)이와 같이 변경 후 아래의 코드로 PHP 5.2.17, 7.0.x, 7.4.x, 8.0.0, 8.2.0 버전에서 테스트 했습니다.