Class plugins in PHP?

I had a few more questions while studying PHP, does php implement any built-in plugin system?

so that the plugin can change the behavior of the main component.

for example, something like this works:

include 'core.class.php';
include 'plugin1.class.php';
include 'plugin2.class.php';
new plugin2;

where core.class.php contains

class core {
  public function coremethod1(){
    echo 'coremethod1';
  }
  public function coremethod2(){
    echo 'coremethod2';
  }
}

plugin1.class.php contains

class plugin1 extends core {
  public function coremethod1(){
    echo 'plugin1method1';
  }
}

plugin2.class.php contains

class plugin2 extends plugin1 {
  public function coremethod2(){
    echo 'plugin2method2';
  }
}

This would be ideal if it were not for the problem that the plugins are now reliable against each other and remove one of the plugins:

include 'core.class.php';
//include 'plugin1.class.php';
include 'plugin2.class.php';
new plugin2;

destroys it all ...

Are there any proper methods for this? if not, then I might consider switching to another language that supports this ...

Thanks for any help.

change obviously, this is my understanding that is missing, so try to find out.

core.class.php contains something ...

plugin1.class.php contains something ...

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

, , ., - .

, , , .

+3
4

, 1 , , plugin2 1 :

PHP spl_autoload

// Your custom class dir
define('CLASS_DIR', 'class/')

// Add your class dir to include path
set_include_path(get_include_path().PATH_SEPARATOR.CLASS_DIR);

// You can use this trick to make autoloader look 
// for commonly used "My.class.php" type filenames
spl_autoload_extensions('.class.php');

// Use default autoload implementation
spl_autoload_register();

, , /- , . PHP . API, .

Decorators:

$class = new BasicCache( new BasicValidators ( new Basic ) );

:

$class = new Basic;
$class->setStrategy(function() { return 'foo'} );
echo $class->callStrategy(); // foo
$class->setStrategy(function() { return 'bar'} );
echo $class->callStrategy(); // bar

. http://sourcemaking.com/design_patterns .


EDIT . , , - . , . , , / .

, , , . , , . , :

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(), , , , greet. setGreeting . : ( )

. GreetPlugin, , , . GreetInterface, , .

Dude , Dude, , is-a, Dude.

abstract class GreetPluginAbstract implements GreetInterface
{
    protected $inner;
    public function __construct(GreetInterface $inner)
    {
         $this->inner = $inner;
    }
    public function setGreeting($greeting)
    {
        $this->inner->setGreeting($greeting);
        return $this;
    }
    public function greet($name)
    {
        return $this->inner->greet($name);
    }
}

plugin : , GreetInterface. TypeHint , . , , , , . , , . .

. , , , , h. : , . ,

class FrenchPlugin extends GreetPluginAbstract
{
    public function greet($name) {
       return str_replace(array('h', 'e'), array('', 'é'),
                          $this->inner->greet($name));
    }
}

, , , . greet(), greet() , h- es és. - .

, , Heya, Hello. .

class EasyGoingPlugin extends GreetPluginAbstract
{
    protected $inner;
    public function __construct(GreetInterface $inner) {
         $this->inner = $inner->setGreeting('heya');
         parent::__construct($inner);
    }
}

, , greet , . setGreeting , . GreetInterface, , .

, setGreeting . , $this, setMethod. , . , : .

, , . Dudes. :

class DudeBuilder
{
     public static function build()
     {
         $dude = new Dude();
         $decorators = func_get_args();
         foreach($decorators as $decorator) {
             $decorator .= "Plugin";
             // require_once $decorator;
             $dude = new $decorator($dude);
         }
         return $dude;
     }
}

. Builder AbstractFactory, , Factory, , a factory. , ;)

Builder , , / / , , . , .

, , . , foreach. , , , . , , , , . . , PHP. , , , .

$regularDude         = DudeBuilder::build();
$frenchDude          = DudeBuilder::build('French');
$easygoingDude       = DudeBuilder::build('EasyGoing');
$frenchEasyGoingDude = DudeBuilder::build('French', 'EasyGoing');

, :

$regularDude         = new Dude;
$frenchDude          = new FrenchPlugin(new Dude);
$easygoingDude       = new EasyGoingPlugin(new Dude);
$frenchEasyGoingDude = new FrenchPlugin(new EasyGoingPlugin(new Dude));

Dudes. :

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

. - , , Car Horse, Builder. EasyGoing .

+5

"". , , , - PHP- ( PHP ) C ++.

, , . "", .

- , , , .

, , . , . new core;, 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()
;
+6

PHP PECL (, , ++).

( APD PECL) override_function

Custom functions can be performed with call_user_func.

Maybe if you could explain what you are planning, we can offer a better answer?

+2
source

Your code breaks because plugin2 extends plugin1 and you do not include the plugin1 class. Why not extend the plugin2 class to extend the kernel? This seems to be what you are going to do.

0
source

Source: https://habr.com/ru/post/1737542/


All Articles