PHP 中的事件驱动架构和挂钩

发布于 2024-11-26 15:10:09 字数 475 浏览 0 评论 0 原文

我计划开发一款具有 PHP 后端来与数据存储库通信的游戏。我在思考这个问题并得出结论,我们的游戏遵循的最佳设计范式将是事件驱动的。我希望有一个成就系统(类似于该网站的徽章系统),基本上我希望能够将这些“成就检查”与游戏中发生的许多不同事件挂钩。即:

当用户执行操作 X 时,会触发 Y 钩子,并调用所有附加函数来检查成就要求。

在构建这样的架构时,我将允许轻松添加新的成就,因为我所要做的就是将检查功能添加到正确的挂钩中,其他一切都会就位。

我不确定这是否是对我打算做的事情的一个很好的解释,但无论如何,我正在寻找以下内容:

  1. 关于如何编写事件驱动应用程序的良好参考资料
  2. 显示如何放置的代码片段PHP 函数中的“钩子”
  3. 代码片段显示如何将函数附加到第 2 点中提到的“钩子”

我对如何完成 2) 和 3) 有一些想法,但我希望有人精通此事可以提供一些线索关于最佳实践。

先感谢您!

I am planning on working on a game that has a PHP back-end to communicate with the data repository. I was thinking about it and concluded that the best design paradigm to follow for our game would be event driven. I am looking to have an achievement system (similar to the badges system of this website) and basically I would like to be able to hook these "achievement checks" into a number of different events that occur in the game. ie:

When a user does action X hook Y is fired and all attached functions are called to check against an achievement requirement.

In structuring the architecture like this I will allow for new achievements to be added easily as all I will have to do is add the checking function to the proper hook and everything else will fall into place.

I'm not sure if this is a great explanation of what I intend to do, but in any case I am looking for the following:

  1. Good reference material on how to code an event-driven application
  2. Code snippet(s) showing how to put a "hook" in a function in PHP
  3. Code snippet(s) showing how to attach a function to the "hook" mentioned in point 2

I have a few ideas as to how to accomplish 2) and 3) but I was hoping that somebody well-versed in the matter could shed some light on best practices.

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

隔岸观火 2024-12-03 15:10:10

关于如何编写事件驱动应用程序的良好参考资料

您可以使用“哑”回调来完成此操作 (演示):

class Hooks
{
    private $hooks;
    public function __construct()
    {
        $this->hooks = array();
    }
    public function add($name, $callback) {
        // callback parameters must be at least syntactically
        // correct when added.
        if (!is_callable($callback, true))
        {
            throw new InvalidArgumentException(sprintf('Invalid callback: %s.', print_r($callback, true)));
        }
        $this->hooks[$name][] = $callback;
    }
    public function getCallbacks($name)
    {
        return isset($this->hooks[$name]) ? $this->hooks[$name] : array();
    }
    public function fire($name)
    {
        foreach($this->getCallbacks($name) as $callback)
        {
            // prevent fatal errors, do your own warning or
            // exception here as you need it.
            if (!is_callable($callback))
                continue;

            call_user_func($callback);
        }
    }
}

$hooks = new Hooks;
$hooks->add('event', function() {echo 'morally disputed.';});
$hooks->add('event', function() {echo 'explicitly called.';});
$hooks->fire('event');

或者实现事件驱动应用程序中经常使用的模式:观察者模式

显示如何在 PHP 函数中放置“钩子”的代码片段

上面的手动链接(回调可以存储到变量中)和一些 观察者模式的 PHP 代码示例

Good reference material on how to code an event-driven application

You can either do this with "dumb" callbacks (Demo):

class Hooks
{
    private $hooks;
    public function __construct()
    {
        $this->hooks = array();
    }
    public function add($name, $callback) {
        // callback parameters must be at least syntactically
        // correct when added.
        if (!is_callable($callback, true))
        {
            throw new InvalidArgumentException(sprintf('Invalid callback: %s.', print_r($callback, true)));
        }
        $this->hooks[$name][] = $callback;
    }
    public function getCallbacks($name)
    {
        return isset($this->hooks[$name]) ? $this->hooks[$name] : array();
    }
    public function fire($name)
    {
        foreach($this->getCallbacks($name) as $callback)
        {
            // prevent fatal errors, do your own warning or
            // exception here as you need it.
            if (!is_callable($callback))
                continue;

            call_user_func($callback);
        }
    }
}

$hooks = new Hooks;
$hooks->add('event', function() {echo 'morally disputed.';});
$hooks->add('event', function() {echo 'explicitly called.';});
$hooks->fire('event');

Or implementing a pattern often used in event-driven applications: Observer Pattern.

Code snippet(s) showing how to put a "hook" in a function in PHP

The manual link above (callbacks can be stored into a variable) and some PHP code examples for the Observer Pattern.

羁客 2024-12-03 15:10:10

对于 PHP,我定期集成 Symfony 事件组件:http://components.symfony-project。 org/event-dispatcher/.

下面是一个简短的示例,您可以在 Symfony 的 Recipe 部分中找到它的扩展

<?php

class Foo
{
  protected $dispatcher = null;

    // Inject the dispatcher via the constructor
  public function __construct(sfEventDispatcher $dispatcher)
  {
    $this->dispatcher = $dispatcher;
  }

  public function sendEvent($foo, $bar)
  {
    // Send an event
    $event = new sfEvent($this, 'foo.eventName', array('foo' => $foo, 'bar' => $bar));
    $this->dispatcher->notify($event);
  }
}


class Bar
{
  public function addBarMethodToFoo(sfEvent $event)
  {
    // respond to event here.
  }
}


// Somewhere, wire up the Foo event to the Bar listener
$dispatcher->connect('foo.eventName', array($bar, 'addBarMethodToFoo'));

?>

这是我们集成到购物车中的系统,用于创建类似游戏的购物体验,将用户操作与游戏事件挂钩。当用户执行特定操作时,php 会触发事件,从而触发奖励。

示例 1:如果用户单击特定按钮 10 次,他们就会收到一颗星。

示例 2:当用户推荐朋友并且该朋友注册时,会触发一个事件,奖励原始推荐人积分。

For PHP I've regulary integrated the Symfony Event Component: http://components.symfony-project.org/event-dispatcher/.

Here's a short example below, which you can find expanded in Symfony's Recipe section.

<?php

class Foo
{
  protected $dispatcher = null;

    // Inject the dispatcher via the constructor
  public function __construct(sfEventDispatcher $dispatcher)
  {
    $this->dispatcher = $dispatcher;
  }

  public function sendEvent($foo, $bar)
  {
    // Send an event
    $event = new sfEvent($this, 'foo.eventName', array('foo' => $foo, 'bar' => $bar));
    $this->dispatcher->notify($event);
  }
}


class Bar
{
  public function addBarMethodToFoo(sfEvent $event)
  {
    // respond to event here.
  }
}


// Somewhere, wire up the Foo event to the Bar listener
$dispatcher->connect('foo.eventName', array($bar, 'addBarMethodToFoo'));

?>

This is the system we integrated into a shopping cart to create a game-like shopping experience, hooking user actions into game-events. When the user performed specific actions, php fired events causing rewards to be triggered.

Example 1: if the user clicked a specific button 10 times, they received a star.

Example 2: when the user refers a friend and that friend signs up an event is fired rewarding the original referrer with points.

看春风乍起 2024-12-03 15:10:10

查看 CodeIgniter 因为它有 内置挂钩

只需启用钩子:

$config['enable_hooks'] = TRUE;

然后定义你的钩子:

 $hook['post_controller_constructor'] = array(
                                'class'    => 'Hooks',
                                'function' => 'session_check',
                                'filename' => 'hooks.php',
                                'filepath' => 'hooks',
                                'params'   => array()
                                ); 

然后在你的类中使用它:

<?php

    class Hooks {
        var $CI;

        function Hooks() {
            $this->CI =& get_instance();
        }

        function session_check() {
            if(!$this->CI->session->userdata("logged_in") && $this->CI->uri->uri_string != "/user/login")
                redirect('user/login', 'location');
        }
    }

?> 

Check out CodeIgniter as it has hooks built right in.

Simply enable hooks:

$config['enable_hooks'] = TRUE;

And then define your hook:

 $hook['post_controller_constructor'] = array(
                                'class'    => 'Hooks',
                                'function' => 'session_check',
                                'filename' => 'hooks.php',
                                'filepath' => 'hooks',
                                'params'   => array()
                                ); 

Then use it in your class:

<?php

    class Hooks {
        var $CI;

        function Hooks() {
            $this->CI =& get_instance();
        }

        function session_check() {
            if(!$this->CI->session->userdata("logged_in") && $this->CI->uri->uri_string != "/user/login")
                redirect('user/login', 'location');
        }
    }

?> 
霞映澄塘 2024-12-03 15:10:10

新访问者可能会通过调查 ReactPHP 找到对 O/P 询问的答案的一些见解。如果您今天(2023 年)搜索短语“Event-Driven Arch in PHP”,ReactPHP 似乎是共同点。

A new visitor might find some insight into the answer to the O/P's inquiry by investigating ReactPHP. If you search the phrase "Event-Driven Arch in PHP" today (in 2023), ReactPHP seems to be the common denominator.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文