5

I knew that in PHP you could define a class and regardless of its position in the file, you could use the class. For example, take a look at the code below:

<?php 

//First case. No errors.
class Second extends First{}
class First{};

//Second case. Still nothing.
abstract class B extends A{};
class C extends B{};
class A{};

//Fatal error!
class C1 extends B1 { };
abstract class B1 extends A1{ };
class A1 { };
?>

First two cases are fine but not the last one. Why? Is there any rule? Fatal Error

P.S; I'm using PHP 5.6.25, Apache 2.4, CentOS 6.7.

undone
  • 7,857
  • 4
  • 44
  • 69

2 Answers2

2

I can't find a written rule for that, but seeing the result of this:

<?php
//A1 Exists
echo class_exists("A1")?"A1 Exists<br>":"A1 Not exists<br>";
//B1 Not exists
echo class_exists("B1")?"B1 Exists<br>":"B1 Not exists<br>";
//C1 Not exists
echo class_exists("C1")?"C1 Exists<br>":"C1 Not exists<br>";
class C1 extends B1 {};
class B1 extends A1{ };
class A1 { };
?>

I can figure out that the interpreter can look back and forward to look for the parent class, but when you chain a third level of inheritance it can't predict that B1 is going to exist.

If you do:

<?php
//A1 Exists
echo class_exists("A1")?"A1 Exists<br>":"A1 Not exists<br>";
//B1 Not exists
class B1 extends A1{ };
class A1 { };
?>

It says 'ok, I didn't see class A1 declaration before, but I see that it is ahead'.

MarioZ
  • 981
  • 7
  • 16
  • I verified this 'issue' still exists in PHP 7.0 and am tempted to say your explanation is correct. It would appear that the parser uses the tokenization result of the entire file to "patch" incorrect declaration orders for legacy reasons, but indeed only parses them in a straight inheritance chain. Therefore it consistently fails at level 3 or higher in multiple scenarios. – Niels Keurentjes Jan 17 '17 at 23:35
1

I am sorry to say, but this is not true, even though it looks so:

I knew that in PHP you could define a class and regardless of its position in the file, you could use the class.

Lets check the documentation

Note: Classes must be defined before they are used! If you want the class Named_Cart to extend the class Cart, you will have to define the class Cart first. If you want to create another class called Yellow_named_cart based on the class Named_Cart you have to define Named_Cart first. To make it short: the order in which the classes are defined is important.

Axalix
  • 2,831
  • 1
  • 20
  • 37