PHP and circular dependencies

Today I noticed the strangest bug in PHP. Apparently there's a problem with circular dependencies and interfaces.

This is how the problem occurs:

  1. <?php
  2.  
  3. // this is class1.php
  4.  
  5. require_once 'iclass.php';
  6.  
  7. class class1 implements iclass {
  8.  
  9. }
  10.  
  11. ?>
  1. <?php
  2.  
  3. // this is class2.php
  4.  
  5. require_once 'class1.php';
  6.  
  7. class class2 extends class1 {
  8.  
  9. }
  10.  
  11. ?>
  1. <?php
  2.  
  3. // this is iclass.php
  4.  
  5. require_once 'class2.php';
  6.  
  7. interface iclass {
  8.  
  9. function setSomething(class2 $object);
  10.  
  11. }
  12.  
  13. ?>

Now, if you run class1.php, you will get the following error:

  1. Fatal error: Class 'class1' not found in /home/filemobile/testscript/class2.php on line 5

I know this is not proper OOP, but its still a strange error. Normally PHP is pretty good at these weird structures ;). Weirdest thing was that it happened for me on one server, but not the other.

There is a bug marked bogus for this, which is understandable. It would be great though if the PHP could somehow throw an error thats a bit more helpful =P. Its a strange error, especially since I could only reproduce it with this structure, and not with for example just 2 classes with circular dependencies.


3 Responses to PHP and circular dependencies

  1. 1 Richard Thomas 2007-08-14 3:24 pm

    None of your files load class2.php so unless you run class2.php your out of luck, since the other 2 classes to "cross load" you would be fine if you run class2.php

  2. 3 Gregory Beaver 2007-08-14 3:39 pm

    Actually, your code is buggy. You do not need the require_once in iclass.php, it works just fine without it, and then you don't get any error (except the missing abstract method in class1)

    Alternately, if you're feeling particularly anal about documenting requirements, you could move the require_once to the end of the file like so:

    Richard's comment is incorrect, class2.php does not solve anything, because the loading conflict still exists in class1.php.

    So in short, there's no bug in PHP at all.

  3. 2 Evert 2007-08-14 4:47 pm

    my example code was wrong (thats what you get from re-typing, without testing)

    The interface now makes use of class2 instead of class1.

    You were also right about not requireing that other class at all. I guess I made a habit out of using require_once whenever I use a class. Quite surprised it wasn't needed here..

    Oh well.. I got rid of this circular dependency anyway.. Its not good practice to start with =)

    Thanks for your comments



About

My name is Evert, and I've been writing semi-regularly on this blog since 2006.

I'm currently available for contract work.

more info.

Subscribe

Dropbox

Dropbox is a simple cross-platform online backup and sync application. The first 2GB of space is free, and both you and me get an extra 250MB extra space if you sign up through this link.