Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extended class not found when Base class is in a separate include file

Tags:

oop

php

This doesn't work:

test.php:

include_once('test-include.php');  

$main = new mainClass();

//======================================================================
class mainClass { 
   function __construct() {
      $test2 = new Test2();
      echo $test2->var;
   }
}

//======================================================================
class Test2 extends Test1 { // test2
  var $var = 'b';
}

test-include.php:

// this does get printed out, so I know the include statement is working
echo 'DEBUG: this is the test-include.php file<br>'; 

//======================================================================
class Test1 { // test1
  var $var = 'a';
}

It gives the following error

PHP Fatal error:  Class 'Test2' not found in /path/to/test.php on line 8

whereas this does work

test2.php:

// this is in the same position as the include statement in test.php
//======================================================================
class Test1 { // test1
  var $var = 'a';
}

$main = new mainClass();

//======================================================================
class mainClass { 
   function __construct() {
      $test2 = new Test2();
      echo $test2->var;
 }
}

//======================================================================
class Test2 extends Test1 { // test2
  var $var = 'b';
}

Why does putting the Base class (Test1) in an include file cause the child class that is extending it to not be found? In other words, the first example is failing because it can't find Test2 when we attempt to instantiate it. This kind of makes sense as we haven't gotten to Test2 in the code execution flow yet. However, in the second example (without the include statement) there's no error, even though it's a similar situation (we haven't reached the Test2 class in code execution yet)

Oh, and this is under version 5.1.6.

UPDATE:

OK, Daff is correct - if I move

$main = new mainClass();

to the end in the test.php example, it works. I would still like to know why it doesn't work if the above line isn't at the end - it works just fine in the test2.php example which doesn't have the $main = new mainClass() line at the end.

UPDATE 2:

OK, I've tried using require, require_once and include in place of include_once - none of these work. And I also added a test echo statement to the test-include.php file and it gets printed out (plus I don't get an error about a non-existent include file) so I know the include statement is working.

like image 633
Bill Avatar asked Sep 01 '09 22:09

Bill


2 Answers

This should have something to do with the definition order and that EVERY class should be included before you actually work with them. If you put the call of

$main = new mainClass();

At the end of your script it works fine even with the include file because all the classes are defined already. Eventually you should have a look at the PHP autoload function because you will get rid of these problem with one small function.

like image 175
Daff Avatar answered Oct 13 '22 11:10

Daff


OK, I think I may have figured this one out. According to this bug report:

http://bugs.php.net/bug.php?id=30453

PHP 4 allowed classes to be defined after they are used but for PHP 5, in the words of the end poster on the bug thread:

PHP5 supports it [declaring classes after they are used] for backward compatibility, but we don't plan support for all combinations.

So I'm guessing this particular case is one of those unsupported combinations.

like image 25
Bill Avatar answered Oct 13 '22 12:10

Bill