Có một mẫu quan sát quan sát. Plugin sẽ tự đăng ký và sẽ nhận được thông báo khi móc được gọi.
Một điều khác có trong tâm trí là gọi lại trong PHP. Và có một số similar question already với số an answer. Nó cho thấy móc dựa trên callbacks.
Mẫu quan sát chạy hơi ngắn vì móc bạn thường muốn cung cấp những thứ như đối số và giá trị trả lại.Câu trả lời được liên kết sử dụng callbacks cũng không có cái này, vì vậy tôi đã viết một lớp ví dụ nhỏ Hooks
cung cấp các móc/sự kiện có tên cho các cuộc gọi lại đã đăng ký và cách đăng ký các lớp của riêng bạn, ví dụ: một cục sạc.
Ý tưởng là khá cơ bản:
- Một móc có một cái tên và số không hoặc nhiều callbacks đính kèm.
- Tất cả các móc được quản lý trong lớp học
Hooks
.
- Mã chính gọi móc bằng cách gọi hàm trên đối tượng
Hooks
.
- Plugins (và các lớp khác) có thể đăng ký gọi lại của riêng chúng, được thực hiện với sự trợ giúp của giao diện
Registerable
.
Một số mã ví dụ với một plugin và hai móc:
<?php
Namespace Addon;
class Hooks
{
private $hooks = array();
private $arguments;
private $name;
private $return;
public function __call($name, array $arguments)
{
$name = (string) $name;
$this->name = $name;
$this->arguments = $arguments;
$this->return = NULL;
foreach($this->getHooks($name) as $hook)
{
$this->return = call_user_func($hook, $this);
}
return $this->return;
}
public function getHooks($name)
{
return isset($this->hooks[$name]) ? $this->hooks[$name] : array();
}
public function getArguments()
{
return $this->arguments;
}
public function getName()
{
return $this->name;
}
public function getReturn()
{
return $this->return;
}
public function setReturn($return)
{
$this->return = $return;
}
public function attach($name, $callback)
{
$this->hooks[(string) $name][] = $callback;
}
public function register(Registerable $plugin)
{
$plugin->register($this);
}
}
interface Registerable
{
public function register(Hooks $hooks);
}
class MyPlugin implements Registerable
{
public function register(Hooks $hooks)
{
$hooks->attach('postPublished', array($this, 'postPublished'));
$hooks->attach('postDisplayFilter', array($this, 'filterToUpper'));
}
public function postPublished()
{
echo "MyPlugin: postPublished.\n";
}
public function filterToUpper(Hooks $context)
{
list($post) = $context->getArguments();
return strtoupper($post);
}
}
$hooks = new Hooks();
$plugin = new MyPlugin();
$hooks->register($plugin);
$hooks->postPublished();
echo $hooks->postDisplayFilter("Some post text\n");
tôi đã thực hiện nó theo cách này để ngăn chặn điều đó mỗi Plugin phải có một lớp cơ sở bê tông chỉ vì nó muốn tận dụng móc . Ngoài ra tất cả mọi thứ có thể đăng ký móc, điều duy nhất cần thiết là một cuộc gọi lại. Ví dụ một chức năng ẩn danh:
$hooks->attach('hookName', function() {echo "Hook was called\n";});
Bạn tuy nhiên có thể tạo cho mình một lớp cơ sở plugin, mà ví dụ thực hiện các register
chức năng và sẽ tự động đăng ký chức năng mà có một thẻ docblock nhất định hoặc tên của một hàm
class MyNewPlugin extends PluginSuper
{
/**
* @hook postPublished
*/
public function justAnotherFunction() {}
public hookPostPublished() {}
}
Siêu lớp có thể sử dụng số Reflection để thêm các móc khi chạy. Tuy nhiên, sự phản chiếu có thể làm chậm mọi thứ và có thể làm cho mọi việc khó khăn hơn để gỡ lỗi.
Bạn chưa thêm mã vào câu hỏi thực sự sẽ hiển thị cú pháp bạn hỏi. Vui lòng thêm mã đó nếu không khó nói. – hakre
có thể trùng lặp của [Cách tốt nhất để cho phép các plugin cho một ứng dụng PHP] (http://stackoverflow.com/questions/42/best-way-to-allow-plugins-for-a-php-application) – hakre