I get a fatal error: Fatal error: Class 'Foo1' not found in .../Foo2.php on line 5
with the following files:
index.php:
<?php
require_once("./Foo1.php");
?>
<h1>Success</h1>
Foo1.php:
<?php
require_once('./IFoo.php');
require_once('./Bar.php');
class Foo1 implements IFoo
{
/** @var Bar */
private $bar;
}
IFoo.php:
<?php
interface IFoo {
}
Bar.php:
<?php
require_once('./Foo2.php');
class Bar {
/** @var Foo2 */
private $foo;
}
Foo2.php:
<?php
require_once("./Foo1.php");
class Foo2 extends Foo1
{
}
Questions:
implements IFoo
statements, this code works?Update Most of the solutions proposed, involved autoloading. Unfortunately, my problem is on a old project with a lot of existing code and a lot of bad practice. We are really far from PSR-0 standard.
What is the cost of introducing autoloading in terms of performances?
I suggest to use Autoloading Standard PSR-0. It describes the mandatory requirements that must be adhered to for autoloader interoperability.
Anyway in this case:
Foo1.php
You are including Bar.php
and because of this line: require_once('./Foo2.php');
, Class Foo2
extends Class Foo1
. But Class Foo1
is not defined yet! You can extend a class only after It's definition.
So It seems that require_once('./Foo2.php');
not should be in Bar.php
. Or You should move require_once('./Bar.php');
after class Foo1
definition.
<?php
require_once('./IFoo.php');
class Foo1 implements IFoo
{
/** @var Bar */
private $bar;
}
require_once('./Bar.php');
If you modify Foo1.php file to this
<?php
require_once('./IFoo.php');
class Foo1 implements IFoo
{
/** @var Bar */
private $bar;
}
require_once('./Bar.php');
?>
This works.
The reason is PHP is interpreted language (interpreter executes the script line by line). So, in your case interpreter misses the Foo1 declaration statement and raises an error when it encounters an undefined class Foo1 in Foo2.php.
require
/ include
) in file with class definition.Foo1
implements IFoo
, php does not know anything about IFoo
, so it can not register class Foo1
. since no autoloader is registered, php starts to interpret the code with, omitting class declaration from Foo1.php
, until other files are included and parsed. When it reaches Foo2.php
it is not including Foo1.php
(due to require_once
) and starts interpreting the file - here it encounters class Foo1
that's definition was skipped due to non-existant at that time interface implementation. At this point php has no idea that Foo1 was declared in already required Foo1.php
, since it hadn't got a chance to intepret this file wholly.