1

I have a problem with including classes. Here's a simple example to explain the problem:

Class no. 1 (path: /home/day/Class_A.php):

class Class_A {
  public function sayHi() {
    echo "Good day";
  }
}

Class no. 2 (path: /home/test/Class_B.php):

class Class_B {
  public function greeting() {
    if(class_exists("Class_A")!=true)
      include "../day/Class_A.php";
    $test = new Class_A();
    $test->sayHi();
  }
}

PHP file (path: /home/php.php)

if(class_exists("Class_B")!=true)
  include "test/Class_B.php";
  $g = new Class_B;
  $g->greeting();

The problem is when php.php includes Class_B and Class_B includes Class_A, Class_B fails to open Class_B because the path of the object of the class is now the same as the php.php file.

My question is: Is there a good and simple way to get around this?

user1163278
  • 411
  • 6
  • 20
  • Store classes under a directory that you can add to the include path. Use require_once and make the path (in the require_once construct) relative to the path added to the include path for classes. – ghbarratt Jul 30 '12 at 20:53

3 Answers3

6

Try changing:

include "../day/Class_A.php";

to

include dirname(__FILE__) . '/../day/Class_A.php';

This way, your include will be relative to the file that is doing the include (Class_B).

drew010
  • 68,777
  • 11
  • 134
  • 162
  • Thanks, but I actually want the opposite, that is: it will always be relative to the class. – user1163278 Jul 30 '12 at 21:06
  • Is Class_B always going to be in `/dir/test/` and Class_A will always be in `/dir/day/` ? – drew010 Jul 30 '12 at 21:12
  • Then if you use the method I gave it should be fine. `dirname(__FILE__)` returns the path from the file that code is executed in, which is Class_B. – drew010 Jul 30 '12 at 21:22
  • Yes it did. I missed the "/" before ".." earlier. This is what I was looking for. Thanks man. – user1163278 Jul 30 '12 at 21:27
  • Ah good, sorry about that yeah I forgot it originally and then edited the post to add the `/` but you were quick and tried it before the edit :) – drew010 Jul 30 '12 at 21:29
0

Looks like greeting is not a static function so you can't do:

Class_B::greeting();

You'd have to get a class B object and called greeting on it or add static to greetings declarations.

Second, why not uuse require_once? In php.php

require_once('test/ClassB.php');

And in ClassB.php:

require_once('../day/ClassA.php');

Ricardo Villamil
  • 5,031
  • 2
  • 30
  • 26
  • I read that require_once is not a good idea because it looses memory. Don't remember the reason. I'll fix Class_B.. – user1163278 Jul 30 '12 at 21:08
  • Not that it loses memory but it adds logic since it has to check if a file has already been loaded, but I think the benefits and simplicity outweight these small performance issues. Take a look at this: http://stackoverflow.com/questions/186338/why-is-require-once-so-bad-to-use – Ricardo Villamil Jul 31 '12 at 14:22
0

Use __autoload which is a magic function, that you define, that enables PHP to let you know when it doesn't have a class loaded, but that class needs to be loaded.

If you define the __autoload function like so,
function __autoload ($classname)
{
    require('/path/to/my/classes/'.$classname.'.php');
}
you no longer need to add
require_once('/path/to/my/classes/MyClass.php');
into your files, because the first time that PHP encounters
$mine = new MyClass();
or
MyClass::staticMethodCall();
it will automatically call the __autoload function that you defined earlier.
__autoload('MyClass');

Resource: http://blog.samshull.com/2010/02/why-you-should-use-autoload-function-in.html

Johndave Decano
  • 2,101
  • 2
  • 16
  • 16