Extend PHP classes used internally without changing dependencies
P粉278379495
P粉278379495 2024-01-10 17:24:16
0
1
374

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.

P粉278379495
P粉278379495

reply all(1)
P粉189606269

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):

$code = file_get_contents(__DIR__ . '/vendor/path/to/R.php');
$code = str_replace('class R', 'class R_original', $code);
eval($code);

class R extends R_original {
   // Your code here
}

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.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template