3

I'm writing some entities class in php, that may point between each other with a repository class (to avoid to query too much the database using a local entity repository):

class Foo
{
    public $fooId;
    public $bar;
    function __construct($entity_id)
    {
        /**
        * Some Database stuff to get Foo object based on $entity_id
        **/
        $this->bar = Repository::get('Bar', $databaseStuff->barId);
    }
}

class Bar
{
    public $foo;
    function __construct($entity_id)
    {
        /**
        * Some Database stuff to get Bar object based on $entity_id
        **/
        $this->bar = Repository::get('Bar', $databaseStuff->barId);
    }
}

class Repository
{
    private static $entities = [];
    /**
     * @param string $entity_name
     * @param int $entity_id
     * @return mixed
     */
    public static function &get($entity_name, $entity_id)
    {
        $entity_name = ucfirst(strtolower($entity_name));
        if(!isset(self::$entities[$entity_name][$entity_id]))
        {
            self::$entities[$entity_name][$entity_id] =& $entity_name($entity_id);
        }
        return self::$entities[$entity_name][$entity_id];
    }
}

$foo = new Foo(1337);

The problem is that i get a sort of timeout/stack overflow probably due to the fact of $foo->bar is a reference to a Bar object, but $bar->foo is a reference to a Foo object, etc...

  • I did not forgot to declare my function to return a reference using &get(), am i right?
  • My class is instantiated with =& operator.

What could be wrong in my code (or in my logic) ? Thanks.

15
  • I've never seen a function by-reference.. Commented Jul 12, 2015 at 3:54
  • PHP don't handle very well circular references, and some things are known to cause issues. For instance, if you try to serialize() that, it will produce output undefinitely until it either run out of memory or time. The garbage collector (or at least I think it is the gc that causes that) will also have some nasty performance issues and eventual crashes. I've had plenty of experience with that lately, and decided its best to avoid doing circular references in PHP. Commented Jul 12, 2015 at 3:54
  • How to deal with it so? In my case, i have an "User" class and an "Asset" class. The user have an avatar (which is an asset object), and the asset have an user (which is the user object). Commented Jul 12, 2015 at 4:03
  • 1
    Also, you are not calling get() at any point as far as I can tell. You should be calling &Repository::get() instead of just Repository(). Functions that return a reference must be called with & too in order to work. However, if you are returning an object, you can drop the whole reference thing. Objects are already implicitly passed by reference. To pass a copy of an object in PHP you must explicitly say it, with clone $object. Commented Jul 12, 2015 at 4:04
  • It's a bad copy/paste, i'm effectively calling Repository::get() Commented Jul 12, 2015 at 4:05

1 Answer 1

1

If I see it right, the constructor of Bar tries to create new Bar.
I suppose such a nested constructing will never end. Its the same e.g. when a function calls itself recursively with no way to exit.
The script will even not come to writing into Repository.

Ever tried xdebug? That could show the problem quite quickly.

And btw there are possibli bad Copy/Paste. The comment in class Foo does not match the line fallowing it. And you are setting $this->bar in class Bar, but only class variable $foo is declared.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes it's a bad copy/paste, and no i never tried xdebug, probably because it's too complicated to configure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.