1

In my current application I have a number of objects that are required repeatedly

To save overhead of instantiating the same object over and over again, I keep an array of 'known' objects.
I can check the input data against the array, and - if already set - use the existing object, else go ahead to instantiate the new object and add the pointer reference to the relevant known objects array.

In most use cases, I can check prior to instantiating the class:

if(array_key_exists($identifier,$known_ClassObjects)){
   $object = $known_ClassObjects[$identifier];
} else {
   $object = new Class($params);
}

However, in some cases I can only identify that the object I am instantiating already exists once already inside it.

In that case I would like to be able to do one of 2 things:

  1. return the OTHER (pre-existing) object instead of this one, e.g.
class Test{

    public function __construct($params){
        
        //apply processing to $params, resulting in $identifier 

        if(array_key_exists($identifier, $known_ClassObjects)){ //$known_ClassObjects is global

             return $known_ClassObjects[$identifier];

        } else {

             //continue __construct() logic

             return $this;
        }

    }
}

However, PHP ALWAYS returns the current object, even with code return $other_object;

  1. 'Internally Clone' the current object from the found one [of the same class, obv] so that when it returns, it has the correct relevant properties populated.

NOTE: including any parent/child class properties -> I want to make this object EXACTLY the same as the found one.

So, if there was a PHP function clone_from(), it would work something like:

if(array_key_exists($identifier,$known_ClassObjects)){
   $this->clone_from ($known_ClassObjects[$identifier]);

} else {
   //continue with __construct()

}
return $this;

Given that 1. doesn't work and 2. doesn't seem to exist, I have only been able to do this in very 'hacky' ways: iterating through all properties of source object and setting all properties of current object.

However, this has obvious issues esp. with extended parent/child classes etc. which then requires things like reflection classes.

This seems like there SHOULD be a really simple solution, but I have been unable to find one

1
  • TL;DR: you can't. When you're in __construct, the new object already exists, and you're merely initialising it. You cannot return anything from __construct. After having called new Klass, you will get a new instance of the class, no way around that. Commented May 10, 2022 at 7:51

2 Answers 2

1

What you actually could do is using either a Singleton Pattern or a Factory pattern - in both cases, the creation of objects is controlled by some piece of code and you can decide, which object to return. Singleton already is a special form of a Factory pattern.

Consider this code

class Singleton {
    protected static $instance; 
    
    protected function __construct() { 
    }
    
    public static function instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
} 

The constructor is protected which will prevent a object construction from "outside" via new. However, there is also a static function instance with which somebody can request an object instance from the factory method.

$obj = Singleton::instance(); 

So, the (internal) object is created only once, and then delivered afterwards until the script ends.

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

1 Comment

Aha! That's really clever ... I like it! Thanks very much
1

However, PHP ALWAYS returns the current object, even with code return $other_object;

Constructor is not a regular function. You do not return from it. If you are in __construct() you are already constructing the new object. Before proceed, I strongly recommend you read at least: https://www.php.net/manual/en/language.oop5.decon.php

You most likely need a helper method or factory that would deal with that instead. Putting the logic you tried to place into your constructor is wrong.

Also you missed to clarify what the $identifier really is. But if that's object's property, then you can expose it (i.e. via getter) and have it read for your comparison/whatever by other code.

Comments

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.