I want to override a PHP class in Laravel, but it is being extended by several other classes that I don't want to bother with. The overall structure is as follows
class A extends R { } class B extends R { } class C extends R { } class D extends R { }
Where A/B/C/D/R are all classes in the external package.
I want to extend A/B/C/D to P
without changing any of those files (which would be a maintenance burden), so that the P class extends R
. So I can make additions to the P
class.
I've been looking into class_alias()
which allows me to connect to the autoloader. This will load class P
correctly.
The code I used is:
// Some bootstrap file: class_alias( P::class, R::class );
// My modification: class P extends R { // ... }
But I got an error:
ErrorException: Cannot declare class
R
because the name is already in use
I'm looking for a solution that can extend an inner PHP class while preventing the full file contents of the class from being copied. I don't even know if it can be done. The class I want to extend does not fit into the Laravel service container, so there is no first-party way to add functionality.
class_alias by itself is not enough, because in order for P to extend R, both classes must exist. And class_alias has nothing to do with autoloading, it just declares a class with two names.
What you actually need is to define a real class R with a new name, and then define your own class with the name R (you don't actually need class_alias).
One approach is to dynamically rewrite the source code of the target class and then load the modified copy, as shown below (untested):
Importantly, this needs to be run before the normal autoloader attempts to define the class. For example, you can use
spl_autoload_register
with the$prepend
option set to true.