PHP: How can I initialise a class that uses a trait from within a static method belonging to that same trait? (Can it be done?)

php

#1

I have a bunch of unrelated classes that initialise with remote data. They all use the CcErrorSubject trait. I’m trying to create a custom initialiser so that I can create instances of these classes and attach them to my error observer in one shot. I can’t find an example of how this is usually done.

This is my trait:

trait CcErrorSubject {
	private function attach_to_error_observer( $observer ) {
		$observer->attach( $this );
	}

	public static function init_with_error_observer( $args, $observer ) {
		$obj = new get_called_class()(...$args);
		$obj->attach_to_error_observer( $observer );
		return $obj;
	}

	abstract public function errors();
}

I would initialise an object using the trait like so:

$upstream_lists = UpstreamLists::init_with_error_observer( array( self::$credentials->unencrypted_api_key(), 'lists.name,lists.id' ), self::$errors );

With init_with_error_observer, I want to create a new instance of the class that is using the trait, then attach it to the specified error observer before returning it.

In my example, I’m trying to use get_called_class() to get the name of the class using the trait so that I can instantiate it. But this doesn’t work. I get an error message:

Parse error: syntax error, unexpected '(' in /Users/stuff/Stuff/wp/wp-content/plugins/chimptools/lib/trait-ccerrorhandler.php on line 11

When I try get_called_class() in psysh I get

PHP Warning:  get_called_class() called without object from outside a class on line 1.

If I can’t use get_called_class(), how do I initialise the class using the trait without knowing the name of the class? Am I even going about it the right way?

Edit: Of course, my first question should be, is it even possible in PHP?


#2

So, it looks like I hadn’t identified the problem correctly. I don’t know how to do it in a single line, but if I assign the class to a variable first, it works:

	public static function init_with_error_observer( $args, $observer ) {
		$class = get_called_class();
		$obj = new $class(...$args);
		$obj->attach_to_error_observer( $observer );
		return $obj;
	}

It seems that the_class(), get_called_class(), __CLASS__ and static::class are interchangeable in this example.

I do not yet know the correct syntax for creating the class without having to assign the class name to a variable first.