Wednesday, 25 May 2011

PHP required_once(), include_once() errors

So I'm writing a Object Oriented webapp in PHP, and I have discovered a problem that hopefully the solution I found is useful to someone.

The Problem:

I have a front controller that delegates its tasks to a Service class, and that Service class has a few references to the domain objects. Here is my folder structure:

/var/www:
frontController.php
/var/www/service:
FruitService.php
/var/www/domain:
Apple.php
Orange.php  

Now in my FruitService.php, I originally had a couple of require_once() like so:

require_once('../domain/Apple.php');
require_once('../domain/Orange.php');

Seems reasonable right? WRONG! I spend about an hour trying to see why PHP fails with this nasty message:

PHP Warning:  require_once(../domain/Question.php) [<a href='function.require-once'>function.require-once</a>]: failed to open stream: No such file or directory in FruitService.php on line 2

PHP Warning:  require_once(../domain/Question.php) [<a href='function.require-once'>function.require-once</a>]: failed to open stream: No such file or directory in FruitService.php on line 2
It turns out that since your controller is serving the page, all the paths would have to be relative to that location of the controller. So in my example, this would work if I were to put it in FruitController.php:

require_once('domain/Apple.php');
require_once('domain/Banana.php');

However, this is a really bad idea since if you have another controller that uses the FruitController then your include path will break;

The formal solution would be to use the varible $_SERVER['DOCUMENT_ROOT'], so it would look like this:

require_once($_SERVER['DOCUMENT_ROOT'] . '/domain/Apple.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/domain/Apple.php');

No comments:

Post a Comment