PHP中的类插件?
在学习PHP的过程中,我还遇到了一些问题,PHP是否实现了任何内置插件系统 因此,插件将能够改变核心组件的行为 例如,类似这样的工作方式:PHP中的类插件?,php,class,plugins,Php,Class,Plugins,在学习PHP的过程中,我还遇到了一些问题,PHP是否实现了任何内置插件系统 因此,插件将能够改变核心组件的行为 例如,类似这样的工作方式: include 'core.class.php'; include 'plugin1.class.php'; include 'plugin2.class.php'; new plugin2; 在哪里 php包含 class core { public function coremethod1(){ echo 'coremethod1';
include 'core.class.php';
include 'plugin1.class.php';
include 'plugin2.class.php';
new plugin2;
在哪里
php包含
class core {
public function coremethod1(){
echo 'coremethod1';
}
public function coremethod2(){
echo 'coremethod2';
}
}
class plugin1 extends core {
public function coremethod1(){
echo 'plugin1method1';
}
}
class plugin2 extends plugin1 {
public function coremethod2(){
echo 'plugin2method2';
}
}
plugin1.class.php包含
class core {
public function coremethod1(){
echo 'coremethod1';
}
public function coremethod2(){
echo 'coremethod2';
}
}
class plugin1 extends core {
public function coremethod1(){
echo 'plugin1method1';
}
}
class plugin2 extends plugin1 {
public function coremethod2(){
echo 'plugin2method2';
}
}
plugin2.class.php包含
class core {
public function coremethod1(){
echo 'coremethod1';
}
public function coremethod2(){
echo 'coremethod2';
}
}
class plugin1 extends core {
public function coremethod1(){
echo 'plugin1method1';
}
}
class plugin2 extends plugin1 {
public function coremethod2(){
echo 'plugin2method2';
}
}
这将是理想的,如果不是因为现在插件彼此可靠的问题,并删除其中一个插件:
include 'core.class.php';
//include 'plugin1.class.php';
include 'plugin2.class.php';
new plugin2;
破坏了整件事
有什么合适的方法可以做到这一点吗?
如果没有,他们可能会考虑移到一个支持这一点的不同语言……/P>
谢谢你的帮助
编辑:
显然,这是我的理解是缺乏的,所以这里有一个
试图澄清
php包含任何内容
include 'core.class.php';
include 'plugin1.class.php';
include 'plugin2.class.php';
$core = new core;
$core->coremethod1();//outputs plugin2method1
plugin1.class.php包含任何内容
include 'core.class.php';
include 'plugin1.class.php';
include 'plugin2.class.php';
$core = new core;
$core->coremethod1();//outputs plugin2method1
plugin2.class.php包含任何内容
include 'core.class.php';
include 'plugin1.class.php';
include 'plugin2.class.php';
$core = new core;
$core->coremethod1();//outputs plugin2method1
鉴于:
include 'core.class.php';
include 'plugin2.class.php';
$core = new core;
$core->coremethod1();//outputs plugin1method1
我对任何实现都感兴趣,即使是不涉及类的实现
比如说
include 'core.php';
//does core stuff
include 'core.php';
include 'plugin1';
//does extended core stuff
include 'core.php';
include 'plugin2';
//does extended core stuff
include 'core.php';
include 'plugin2';
include 'plugin1';
//does very extended core stuff
包含文件需要更改应用程序行为。它才有意义
我也不知道这是什么意思,所以请给我指出适当的命名,如果有的话,
核可以用PECL扩展(C++,我相信)扩展。 核心功能可以通过override\u功能覆盖(如果您安装了APD PECL扩展)
用户函数可以通过调用用户函数执行
如果你能解释一下你的计划,也许我们能提供一个更好的答案?你误用了“插件”这个术语。插件通常是一个代码包,它扩展或改变系统的基本功能-使实际PHP插件(在PHP世界中称为扩展),您将编写C或C++。
您在这里描述的只是将类或类树包含到当前执行中以供使用。有一种方法可以“自动”将它们引入当前的执行上下文,这就是通过
如果在阅读了有关自动加载的文档后,仍然不确定如何继续,请在此处发表评论,我将帮助您
编辑
好的,我明白你的意思了。你不能完全按照你想要的去做。当您执行新核心时代码>将返回类core
的实例-您根本无法修改它
但是,如果您愿意修改如何创建core
的实例,那么我想我有一些东西可以为您工作,它可能看起来像这样
class core {
public function coremethod1(){
echo 'coremethod1';
}
public function coremethod2(){
echo 'coremethod2';
}
/**
* @return core
*/
final public static function create()
{
// listed in order of preference
$plugins = array( 'plugin2', 'plugin1' );
foreach ( $plugins as $plugin )
{
if ( class_exists( $plugin ) )
{
return new $plugin();
}
}
return new self;
}
}
class plugin1 extends core {
public function coremethod1(){
echo 'plugin1method1';
}
}
class plugin2 extends plugin1 {
public function coremethod2(){
echo 'plugin2method2';
}
}
$core = core::create();
// test what we have
echo get_class( $core ), '<br>'
, $core->coremethod1(), '<br>'
, $core->coremethod2()
;
类核心{
公共函数coremethod1(){
回声“coremethod1”;
}
公共函数coremethod2(){
echo‘coremethod2’;
}
/**
*@返回核心
*/
最终公共静态函数create()
{
//按优先顺序列出
$plugins=array('plugin2','plugin1');
foreach($plugins作为$plugin)
{
如果(类_存在($plugin))
{
返回新的$plugin();
}
}
回归新自我;
}
}
类plugin1扩展了内核{
公共函数coremethod1(){
echo“pluginMethod1”;
}
}
类plugin2扩展了plugin1{
公共函数coremethod2(){
echo“plugin2方法2”;
}
}
$core=core::create();
//测试我们所拥有的
echo获取类($core),“
”
,$core->coremethod1(),“
”
,$core->coremethod2()
;
您的代码正在中断,因为plugin2扩展了plugin1,而您没有包括plugin1类。为什么不让类plugin2扩展核心呢?这似乎就是你想要的 如果您唯一担心的是不包括plugin1会产生错误,那么您可以求助于自动加载,让plugin2自动加载plugin1:
从
但是,如果您正在寻找类似traits/mixin的特性,那么答案是否定的。PHP目前还不支持这种特性。至少,您不希望在生产代码中使用API
更改对象在运行时的行为方式的正确方法是使用:
或模式:
$class = new Basic;
$class->setStrategy(function() { return 'foo'} );
echo $class->callStrategy(); // foo
$class->setStrategy(function() { return 'bar'} );
echo $class->callStrategy(); // bar
有关最常见的模式,请参见
编辑下面是一个如何使用装饰器创建插件的示例。假设,我们有一个类似的游戏,其中一些非玩家角色在虚拟空间中走动,不时与主角打招呼。这就是他们现在所做的。不过,我们希望他们的问候方式有所不同,这就是为什么在这个场景中我们需要我们的插件/装饰器
首先,我们定义了一些能够问候的对象应该具有的方法。我们不关心在特定对象上调用这些方法时它会做什么。我们只想确保这些方法可用,并且使用明确定义的输入调用它们:
interface GreetInterface
{
public function greet($name);
public function setGreeting($greeting);
}
接口基本上是任何实现对象必须履行的契约。在我们的例子中,合同上说,如果你是一个能打招呼的对象,你必须有两种方法。以任何你喜欢的方式实现它们,但是要有这些方法
现在让我们构建非玩家角色类,实现这个接口
class Dude implements GreetInterface
{
protected $greeting = 'hello';
public function greet($name)
{
return sprintf('%s %s', $this->greeting, $name);
}
public function setGreeting($greeting)
{
$this->greeting = $greeting;
return $this;
}
}
我想这是相当严重的。Dude类只是从接口定义了两个方法。调用greet()时,它将获取存储在greeting中的字符串,并将其前置到传递给greet方法的参数。setGreeting方法允许我们在运行时更改问候语。注意:您也可以添加一个getter(我只是懒惰)
现在来看看插件。我们将创建一个抽象的GreetPlugin类来包含一些,因为我们不想在实际的插件中重复代码。抽象插件类将实现GreetInterface,因此我们可以确保所有子类也实现该接口
由于Dude已经实现了接口,我们可以让插件扩展Dude,但这在概念上是错误的,因为扩展创建了is-a关系,但是
echo $regularDude->greet('Yuri'), PHP_EOL,
$frenchDude->greet('Yuri'), PHP_EOL,
$easygoingDude->greet('Yuri'), PHP_EOL,
$frenchEasyGoingDude->greet('Yuri'), PHP_EOL;
// gives
hello Yuri
éllo Yuri
heya Yuri
éya Yuri