Is there a way to safely override a class in PHP?

We all know that the notorious error “cannot override the class”. Is there a way to overcome this and actually declare a new class with the same name or is this impossible in PHP 5?

+7
oop php class
source share
7 answers

As Pekka and Techprioritor noted, no: you cannot. However, if you use PHP> = 5.3, you can use namespaces and the "use" construct to effectively "update" the class. Here is an example:

 // MyClass.php class MyClass { const MY_CONST = 1; } 
// MyNamespaceMyClass.php namespace Mynamespace; class MyClass { const MY_CONST = 2; }
// example.php require_once 'MyClass.php'; require_once 'MyNamespaceMyClass.php';
use Mynamespace\MyClass as MyClass;
echo MyClass::MY_CONST; // outputs 2

This way you have the desired result, since MyClass now refers to your class with names.

+12
source share

There may be a way to use some obscure extension, but in the base standard PHP, as far as I know, no.

However, you can always extend an existing class and, possibly, depending on your scenario, “smuggle” an instance of this extended class into the application you are working on.

+6
source share

It's impossible. Depending on the option you are using, namespaces like jpfuentes2 might work for you.

One hack is to implement a custom new “statement”.

Example:

 $GLOBALS['class_map'] = array('A' => 'A'); function _new($class){ $realClass = $GLOBALS['class_map'][$class]; return new $realClass; } 

class A {} $a = _new('A');

// change the implementation $GLOBALS['class_map']['A'] = 'B'; $a2 = _new('A');

Another hack is to use runkit to reimplement the class.

+2
source share

Perhaps a more modern answer for 2016, it looks like there are now at least 3 options:

Option 1. Using runkit

Link: http://php.net/manual/en/function.runkit-class-emancipate.php

bool runkit_class_emancipate ( string $classname )

"Convert an inherited class to a base class, removes any method whose scope is generic"

Although I have not tested this myself, this seems like a viable option if you have control over the downloaded extensions. The disadvantage here is that you lose all the methods of your ancestors.


Option 2. Using runkit again

Link: http://php.net/manual/en/function.runkit-method-redefine.php

bool runkit_method_redefine ( string $classname , string $methodname , string $args , string $code [, int $flags = RUNKIT_ACC_PUBLIC ] )

"Dynamically changes the code for this method"

This solves the problem of option 1 if your goal is to set up a method or two in the base class.


Option 3: Implementing the Autoloader

Link: http://php.net/manual/en/function.spl-autoload-register.php

bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] )

"Register the given function as an implementation of __autoload ()"

This is personally my favorite of 3, because:

  • It works in modern versions of PHP
  • It can work together with other autoloaders
  • This allows you to implement conditional logic around your overrides.

This is also the one for which I have some experience. An example implementation is as follows:

 // Some early point in your application // Ideally after other autoloaders have registered spl_autoload_register('autoload_override'); function autoload_override($class) { if ($class == 'TargetClassName') { include '/path/to/overriding/class.php'; } } 
+2
source share

AFAIK, overriding functions or exception classes is not possible in PHP.

If you could say what you are trying to do, maybe there is another solution ...

+1
source share

Basically, you cannot override a class. But if you really want it, you can. :) Anything is possible. Need a class that changes structure dynamically ? You can use the __call magic method and the state of the template.

 class Example { var $state; public function setImplementation($state) { $this->state = $state; } public function __call($method, $args) { if (method_exists($this->state, $method)) return $this->state->$method($args); else // error } } 

There is also a set of PHP tools for dynamically playing classes: http://php.net/manual/en/book.runkit.php

I know that the Rubeclaring class and its methods are possible in Ruby (and I consider this a mistake in the language design).

0
source share

Basically, we cannot override a class in PHP directly . If you need to get a redeclare class in php, I suggest you write this class in a separate file and use require_one to call this file on the desired page. It looks like this:

page1.php

 class abcd { function max() { echo "Hello World!!! count:-".$GLOBALS['x']; } } 

page2.php

 $i=10; for($x=0;$x<$i;$x++) { require_once "Page1.php"; $myclass = new abcd(); $myclass->max(); } 

Now it will work according to your desire . He worked for me .

The output will be as follows:

  Hello World!!! count:- 0 Hello World!!! count:- 1 Hello World!!! count:- 2 Hello World!!! count:- 3 Hello World!!! count:- 4 Hello World!!! count:- 5 Hello World!!! count:- 6 Hello World!!! count:- 7 Hello World!!! count:- 8 Hello World!!! count:- 9 
0
source share

All Articles