douzhong3038 2013-08-13 05:59
浏览 45
已采纳

PHP多重继承(继承链接),插件和性能

Disclaimer: What you're about to see is unconventional and could cause moderate to severe nausea. Keep an open mind. So many people have been asking about how to do this, and I don't think its necessarily a bad solution.

TL;DR - You could jump down to the Grand Finale if you're familiar with composition vs inheritance and multiple inheritance.

I've read a few things that suggest composition is better than inheritance. I understand that its usually a better approach (and I'm committed to using composition when possible), however lets assume that I'm stubborn and want to attempt multiple inheritance.

What I'm trying to do:

class A {}
class B {}
class AB extends A, B {} // doesn't work

What actually works:

class A {}
class B extends A {}
class AB extends B {} // inherits from both A and B

I don't mind this, but it won't work for a more modular (plugin) approach (lets say you don't know the names of the classes). In other words, if I were trying to create an OOP framework that allowed developers to extend a core class multiple times, you'd have to go in and edit the class definitions to extend B from A, C from B, and then potentially rename it back to the usable constructor.

What I'm REALLY trying to do:

class DisplayBase {}
class SomePluginDisplay extends DisplayBase {}
class CrazyPluginDisplay extends SomePluginDisplay {}
// ...
class Display extends {LastPlugin}Display {}

This is actually possible through the use of

eval("class $class_name extends $parent_class_name {}");

However, you wouldn't want to put any actual code inside eval, so you could use temporary class names.

Grand Finale

See: https://gist.github.com/beeblesox/6218135 (also pasted below)

class Base {
    function bse(){ echo "base <br />"; }
}

/* You would have to make a dependency-based loader
 * to keep track of class names.  Here, I'm just hard
* coding to show that it could work...
*/
$parent_class = 'Base';
eval("class _BaseA extends $parent_class {}");
class BaseA extends _BaseA {
    function a(){ echo "a <br />"; }
}

$parent_class = 'BaseA';
eval("class _BaseB extends $parent_class {}");
class BaseB extends _BaseB {
    function b(){ echo "b <br />"; }
}

$parent_class = 'BaseB';
eval("class _End extends $parent_class {}");
class End extends _End {
    function nd(){ echo "end <br />"; }
}

$ab = new End();
$ab->bse(); // base
$ab->a();    // a
$ab->b();    // b
$ab->nd();  // end

Note: You can't just eval the first line of the class (without the end }). This is why I used a temporary class to rename them.

The idea here is that there would be a final, blank class that the user would have as a clean slate to add their custom functionality. And, that final class would override and inherit from the core, and any number of loaded plugins.

Questions

I realize that having 1 or 2 (or 10) extra classes in the hierarchy (even though half of them are blank) isn't a great idea. However, I can't imagine the performance toll would be noticeable. Could the average page load increase by more than 1%?

As long as there is no user (external) input involved with the eval statement, can you see any other consequences?

Just to reiterate, I've read posts about composition. The problem with composition and interfaces, is that they don't allow you to reuse code. In many circumstances, inheritance provides the fastest, cleanest way to reuse and modify functionality without having to rewrite anything.

  • 写回答

1条回答 默认 最新

  • dqwmhrxt68679 2013-08-13 06:06
    关注

    If I understand correctly, I think you're looking for traits, introduced in PHP 5.4.0:

    trait A {}
    trait B {}
    class C { use A,B; }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题