2014-11-23 4 views
2

__autoload()을 사용할 때 오류가 발생했습니다. 여기 __autoload를 사용할 때 표준 표준 오류가 발생했습니다.

동일한 파일 간단한 두 클래스의 예이다 :

class A 
{ 
    public function check($a, $b) 
    { 
     $subClass = new B(); 

     return $subClass->check($a); 
    } 
} 

class B extends A 
{ 
    public function check($a) 
    { 
     return $a; 
    } 
} 
$a = new A(); 
$a->check(77, 44); 

모든 것이 OK이고; 예상대로 작동합니다.

Strict standards: Declaration of B::check() should be compatible with that of A::check()

재현하려면 :

파일해서, A.php

class A 
{ 
    public function check($a, $b) 
    { 
     $subClass = new B(); 

     return $subClass->check($a); 
    } 
} 

파일 B.php 내가 각 클래스 파일을 생성하고 __autoload()를 사용할 때, 오류가 :

class B extends A 
{ 
    public function check($a) 
    { 
     return $a; 
    } 
} 

file test.php

function __autoload($className) 
{ 
    require_once $className . '.php'; 
} 
$a = new A(); 
$a->check(77, 44); 

그럼 왜 __autoload을 사용하는 경우에만이 오류가 발생합니까?

+0

이것은'__autoload' 때문에 발생하는 것은 아닙니다. 다른 파일을 단순히'include '하면 같은 문제가 발생합니다. 그러나 그것은 이상합니다. – Boann

+0

좋습니다. 왜이 오류가 나타 났습니까? 클래스 B에서 check() 메소드를 원하는대로 설정할 수 있지만 (클래스 A()는 추상적 메소드가 아니기 때문에), 이유는 무엇입니까? – sergio

+0

2로 정의 된'B :: check()' 'A :: check()'와 같은 argumnets? –

답변

1

이 메시지는 실행시 실패 할 수있는 가능한 메서드 호출이 있음을 의미합니다. return $subClass->check($a);class A 부모 메소드에 서명이있는 class B 메소드를 호출합니다.

다른 서명 (A의 2 매개 변수와 B의 1 매개 변수)은 추상 오류인지 엄격한 오류를 생성합니다.

class A 
{ 
    public function check($a, $b) 
    { 
     $subClass = new B(); 

     return $subClass->check($a, NULL); 
    } 
} 

class B extends A 
{ 
    public function check($a, $b) 
    { 
     return $a; 
    } 
} 

function __autoload($className) 
{ 
    require_once $className . '.php'; 
} 
$a = new A(); 
$a->check(77, 44); 

나는 당신이 그것을 확장되는 클래스에 새로운 클래스를 인스턴스화하여 달성하기 위해 노력하고 무엇을 물어 봐도 : 서명이 동일한 경우

그것은 작동?

+0

이 오류가 자동로드에 나타나는 이유는 아닙니다. 또한 상속 및 다형성에 따라 매개 변수의 수를 변경할 수 있습니다. – sergio

+0

@Boann이 지적했듯이 이것은 자동로드의 문제가 아니며'include()'에서도 발생합니다. 그건 그렇고, 하나의 파일에 모든 경우에도 동일한 오류가 발생합니다. – Nevertheless

+0

한 가지 더, 당신은 이것이 상속과 다형성에 따라 가능하다고 말하지만, 맞습니다.하지만 그것은'E_STRICT'입니다. – Nevertheless

2

실제로는 이 아닌 - 이상한로드 코드입니다. 엄격한 표준 오류는 일 것입니다..

단일 파일의 경우 오류가 나타나지 않는 이유는 PHP가 클래스를로드하는 방식과 오류보고 모드가 설정되는시기 때문입니다. 여기에 약간의 설명이 있습니다 : https://bugs.php.net/bug.php?id=46851.

한마디로

:

  • 별도의 파일이나 메인 파일에보고 E_STRICT을 설정 한 후, 그들이로드 (예 : __autoload 또는 include와 같은) 파일의 클래스를 정의하면, 그래서 오류가 표시됩니다.

  • 주 파일에 직접 클래스를 정의하면 E_STRICT 오류보고 기능을 켜기 전에 스크립트가 실행되기 전에 클래스가로드되어 오류가 표시되지 않습니다.

  • 이상하게도 메인 파일 에 클래스를 정의하고 (클래스 B, 클래스 A) 순서를 반대로하면 오류가 표시됩니다.위에 링크 된 페이지에 따르면, 이것은 PHP가 조금 늦게까지로드하지 않기 때문입니다.

  • php.ini에서 E_STRICT 오류보고 기능을 켜기 때문에 스크립트가 시작되기 전에 이미 켜져 있으므로 클래스로드 방법에 관계없이 오류가 표시됩니다.


서브 클래스는이 인수의 다른 수와 방법을 무시하는 것은 잘못 있음을 말하고, 오류의 목적을 이해합니다.

위키 백과에 Liskov substitution principle를 참조하십시오

The Liskov substitution principle states that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).

는 현재 우리가이 코드를 가지고 :

이제 B가 확장 이후
$a = new A(); 
$a->check(77, 44); 

,이 B가의 하위 유형을 나타냅니다, 그리고 위의에 따라 원칙적으로 유형 A의 객체가 유형 B의 객체로 대체 될 수 있어야합니다. 그러나 어떤 일이 발생하는지 살펴보십시오.

$a = new B(); 
$a->check(77, 44); 

평소처럼 check 메서드를 호출하지만 두 개의 인수가 필요하지 않으므로 호출이 의미가 없습니다.

PHP는 일반적으로 매우 엄격하지 않으므로 부적절한 대체는 작동하지만 엄격한 표준 오류를 설정하면 이에 대해 경고 할 수 있습니다.

+0

ini 파일에서 오류를 켜고 간단한 파일에서 오류가 발생하지 않습니다. 또한, 나는 정말로 그것을 이해할 수 없다, polymorphhism에 따르면 나는 오류가 없다. 그래서 나는 왜 이것에 직면 했는가? – sergio

+0

@ sergio 나는 오류를 보았다. php.ini를 변경 한 후에/etc를 다시 시작 했습니까? 어쨌든 오류는 정확합니다. 클래스가 메소드를 오버라이드 (override) 해, 다른 인수를 취하는 것은 적절하지는 않습니다. – Boann

+0

아니요, 서버에 설치할 때 일찍 설정 했으므로 없습니다. 그리고 다시 astend를 다시 시작한 후) – sergio

관련 문제