我们都知道臭名昭着的“不能重新宣布上课”的错误。有没有任何方法可以克服这个问题并实际声明一个具有相同名称的新类,或者这在PHP 5中是不可能的?
答案 0 :(得分:13)
正如Pekka和Techpriester都指出的那样:不,你做不到。但是,如果您使用PHP> = 5.3,则可以使用namespaces和“use”构造来有效地“重新声明”该类。这是一个例子:
// 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
因此,您已获得所需的结果,因为MyClass现在引用了您的命名空间类。
答案 1 :(得分:6)
可能有一种方法使用一些不起眼的扩展,但在基本的标准PHP中,据我所知,没有。
但是,您可以始终扩展现有类,并且 - 根据您的情况,可能会将该扩展类的实例“偷偷”到您正在处理的应用程序中。
答案 2 :(得分:2)
这是不可能的。根据用例,名称空间(如jpfuentes2)可能适合您。
一个黑客就是实现一个自定义的新“运营商”。
实施例:
$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');
另一个黑客是使用runkit来重新实现一个类。
答案 3 :(得分:2)
2016年的答案可能更为现代,看起来现在至少有3个选项:
参考:http://php.net/manual/en/function.runkit-class-emancipate.php
bool runkit_class_emancipate ( string $classname )
“将继承的类转换为基类,删除范围为祖先的任何方法”
虽然我自己没有对此进行测试,但如果您可以控制加载的扩展,那么它似乎是一个可行的选项。这里的缺点是你失去了所有祖先方法。
参考: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 ] )
“动态更改给定方法的代码”
如果您的目标是在基类上调整一两个方法,这就解决了选项1的问题。
参考:http://php.net/manual/en/function.spl-autoload-register.php
bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] )
“将给定的函数注册为__autoload()实现”
这是我个人最喜欢的3,因为:
这也是我做的经验之一。示例实现如下:
// 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';
}
}
答案 4 :(得分:1)
AFAIK,在PHP中无法重新声明现有的函数或类。
如果你能说出来,你想要做什么,也许还有另一种解决方案......
答案 5 :(得分:0)
基本上你不能重新开课。但如果你真的想,你可以。 :) 一切皆有可能。需要一个类,它会改变它的结构动态?您可以使用魔术方法__call和模式状态。
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
}
}
还有一个PHP工具包可以动态地使用类:http://php.net/manual/en/book.runkit.php
我知道在Ruby中重新声明类及其方法是可能的(我会认为这是语言设计中的一个错误。)
答案 6 :(得分:0)
基本上我们无法在PHP directly
中重新声明一个类。如果您需要在php中重新声明一个类,那么我建议您在单独的文件中编写该类,并使用require_one
将该文件调用到所需的页面。它如下:
<强> 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 as you desired。它适用于me。
输出如下:
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