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; }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 孟德尔随机化结果不一致
  • ¥15 深度学习残差模块模型
  • ¥50 怎么判断同步时序逻辑电路和异步时序逻辑电路
  • ¥15 差动电流二次谐波的含量Matlab计算
  • ¥15 Can/caned 总线错误问题,错误显示控制器要发1,结果总线检测到0
  • ¥15 C#如何调用串口数据
  • ¥15 MATLAB与单片机串口通信
  • ¥15 L76k模块的GPS的使用
  • ¥15 请帮我看一看数电项目如何设计
  • ¥23 (标签-bug|关键词-密码错误加密)