【问题标题】:PHP workaround to extend classes of the same name?扩展同名类的PHP解决方法?
【发布时间】:2011-10-25 04:06:58
【问题描述】:

我知道扩展同名的类是不可能的,但我很好奇是否有人知道加载类然后重命名它的方法,所以我以后可以用原始名称扩展它。希望喜欢以下内容:

<?php 
//function to load and rename Class1 to Class2: does something like this exist?
load_and_rename_class('Class1', 'Class2');

//now i can extend the renamed class and use the original name:
class Class1 extends Class2{
}
?>

编辑: 好吧,我知道在有大型类文件库的基本 OOP 环境中,这将是一种糟糕的做法。但是我使用的是 CakePHP MVC 框架,能够以这种方式扩展插件类非常有意义,因为该框架遵循一个完善的命名约定(模型名称、视图名称、控制器名称、url 路由(http:// /site.com/users)等)。

到目前为止,要扩展 CakePHP 插件(例如:Users 插件),您必须通过添加前缀(如 AppUsers)来扩展所有具有不同名称的模型、视图和控制器类,然后再进行一些编码以重命名变量名称,然后您必须对重命名的 url 路由等进行编码,以最终回到“用户”名称约定。

由于 MVC 框架代码组织良好,如果能够实现上述内容,则代码中很容易理解。

【问题讨论】:

  • 真的永远不要再想这样的事情!它违反了几乎所有的好习惯
  • 尽管我并没有真正理解您的要求,但我可以说这听起来是个坏主意,源于对相关技术的一些根本误解。
  • @markus:简而言之,他想用一个新的类替换一个现有的类,它应该扩展前一个类。坏主意,是的。
  • 你为什么不重命名这个类呢? class BaseClass_Extended extends BaseClass?
  • 我不想对 Cake 说任何话。我不想说太多,因此简短地说:“并且可能值得取代正统的 OOP 基础” 问题是,Cake 是建立在这个“正统的 PHP 基础”之上的。我向你保证,你迟早会破坏你的应用程序,即使考虑到这样的黑客攻击。

标签: php oop


【解决方案1】:

我正在尝试弄清楚为什么有必要这样做。我只能想到下面的例子:

在您无法控制的上下文中,初始化一个对象:

// A class you can't change
class ImmutableClass {
    private function __construct() {
        $this->myObject = new AnotherImmutableClass();
    }
}

$immutable = new ImmutableClass();

// And now you want to call a custom, currently non existing method on myObject
// Because for some reason you need the context that this instance provides
$immutable->myObject->yourCustomMethod();

所以现在你想在不编辑任何一个 Immutable 类的情况下向 AnotherImmutableClass 添加方法。

这是绝对不可能的。

您可以从该上下文中做的所有事情就是将该对象包装在一个装饰器中,或者运行一个辅助函数,传递该对象。

// Helper function
doSomethingToMyObject($immutable->myObject);
// Or decorator method
$myDecoratedObject = new objectDecorator($immutable->myObject);
$myDecoratedObject->doSomethingToMyObject();

对不起,如果我弄错了棍子的一端。

有关装饰器的更多信息,请参阅此问题: how to implement a decorator in PHP?.

【讨论】:

    【解决方案2】:

    我碰巧理解您为什么要这样做,并且想出了实现最终目标的方法。对于其他人来说,这是作者可能正在处理的一个例子......

    在整个 CakePHP 应用程序中,您可能会引用辅助类(例如 > $this->Form->input();)

    然后在某些时候,您可能想要向该 input() 函数添加一些内容,但仍使用 Form 类名,因为它贯穿于您的应用程序。同时,虽然您不想重写整个 Form 类,而只是更新它的一小部分。所以考虑到这个要求,实现它的方法是这样的......

    您确实必须将现有类从 Cake 核心中复制出来,但您不对其进行任何更改,然后当您升级 cake 时,您只需将准确的副本复制到这个新目录。 (例如复制 lib/Cake/View/Helper/FormHelper.php 到 app/View/Helper/CakeFormHelper.php)

    然后您可以添加一个名为 app/View/Helper/FormHelper.php 的新文件,并让该 FormHelper 扩展 CakeFormHelper,即。

    App::uses('CakeFormHelper', 'View/Helper');
    
    FormHelper extends CakeFormHelper {
        // over write the individual pieces of the class here
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 2015-02-27
      • 1970-01-01
      相关资源
      最近更新 更多