
<!DOCTYPE html>
<html lang="zh" data-goose-resource data-theme="gf-light">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="color-scheme" content="light dark">
    <meta name="theme-color" content="#fbfdff" data-goose-theme-color>
    <title>PHP[017]:事件监听 - GooseForum</title>
    <meta name="description" content="阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。">
    <link rel="canonical" href="https://gooseforum.online/p/post/252">
    
    
    <meta property="og:title" content="PHP[017]:事件监听">
    <meta property="og:description" content="阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。">
    <meta property="og:type" content="article">
    <meta property="og:url" content="https://gooseforum.online/p/post/252">
    <meta property="og:site_name" content="GooseForum">
    
    <meta property="article:published_time" content="2019-03-18T23:20:09&#43;08:00">
    <meta property="article:modified_time" content="2025-12-30T20:46:43&#43;08:00">
    <meta property="article:author" content="abandon1a2b">
    <meta property="article:section" content="Coding">
    <meta property="article:tag" content="Coding">
    
    
    <meta name="twitter:card" content="summary">
    <meta name="twitter:title" content="PHP[017]:事件监听">
    <meta name="twitter:description" content="阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。">
    
    
    <script type="application/ld+json" data-goose-jsonld="page">{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"PHP[017]:事件监听","description":"阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。","text":"阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。","author":{"@type":"Person","name":"abandon1a2b","url":"https://gooseforum.online/u/1"},"publisher":{"@type":"Organization","name":"GooseForum","url":"https://gooseforum.online"},"datePublished":"2019-03-18T23:20:09+08:00","dateModified":"2025-12-30T20:46:43+08:00","url":"https://gooseforum.online/p/post/252","mainEntityOfPage":"https://gooseforum.online/p/post/252","articleSection":"Coding","keywords":["Coding"],"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":277}]}</script>
    <link rel="icon" href="/static/pic/icon.webp">
    <script defer src="https://umami.leancodebox.online/script.js" data-website-id="0a633415-dd84-4264-98cd-a006e6a8fefc"></script>
    <link rel="stylesheet" href="/assets/assets/site-DMKa7mM5.css" crossorigin>
<script type="module" src="/assets/assets/site-BNzyJZpy.js" crossorigin></script>

    <link id="goose-site-theme-link" rel="stylesheet" href="/site-theme.css?v=3535d0c163954d2c">
</head>
<body class="bg-base-200 text-base-content antialiased">
    <script id="goose-payload" type="application/json">{"component":"article.detail","props":{"article":{"id":252,"title":"PHP[017]:事件监听","description":"","url":"/p/post/252","html":"\u003cpre\u003e\u003ccode class=\"language-php\"\u003e\u0026lt;?php\n\nclass Event\n{\n    protected static $listens = array();\n\n    public static function listen($event, $callback, $once = false)\n    {\n        if (!is_callable($callback)) return false;\n        self::$listens[$event][] = array('callback' =\u0026gt; $callback, 'once' =\u0026gt; $once);\n        return true;\n    }\n\n    public static function one($event, $callback)\n    {\n        return self::listen($event, $callback, true);\n    }\n\n    public static function remove($event, $index = null)\n    {\n        if (is_null($index))\n            unset(self::$listens[$event]);\n        else\n            unset(self::$listens[$event][$index]);\n    }\n\n    public static function trigger()\n    {\n        if (!func_num_args()) return;\n        $args = func_get_args();\n        $event = array_shift($args);\n        if (!isset(self::$listens[$event])) return false;\n        foreach ((array)self::$listens[$event] as $index =\u0026gt; $listen) {\n            $callback = $listen['callback'];\n            $listen['once'] \u0026amp;\u0026amp; self::remove($event, $index);\n            call_user_func_array($callback, $args);\n        }\n    }\n}\n\n\n// 增加监听walk事件 \nEvent::listen('walk', function () {\n    echo \u0026quot;I am walking...n\u0026quot;;\n}); \n// 增加监听walk一次性事件 \nEvent::listen('walk', function () {\n    echo \u0026quot;I am listening...n\u0026quot;;\n}, true); \n// 触发walk事件 \nEvent::trigger('walk'); \n/* \nI am walking... \nI am listening... \n */\nEvent::trigger('walk'); \n/* \nI am walking... \n */\n\nEvent::one('say', function ($name = '') {\n    echo \u0026quot;I am {$name}n\u0026quot;;\n});\n\nEvent::trigger('say', 'deeka'); // 输出 I am deeka \nEvent::trigger('say', 'deeka'); // not run \n\nclass Foo\n{\n    public function bar()\n    {\n        echo \u0026quot;Foo::bar() is calledn\u0026quot;;\n    }\n\n    public function test()\n    {\n        echo \u0026quot;Foo::foo() is called, agrs:\u0026quot; . json_encode(func_get_args()) . \u0026quot;n\u0026quot;;\n    }\n}\n\n$foo = new Foo;\n\nEvent::listen('bar', array($foo, 'bar'));\nEvent::trigger('bar');\n\nEvent::listen('test', array($foo, 'test'));\nEvent::trigger('test', 1, 2, 3);\n\nclass Bar\n{\n    public static function foo()\n    {\n        echo \u0026quot;Bar::foo() is calledn\u0026quot;;\n    }\n}\n\nEvent::listen('bar1', array('Bar', 'foo'));\nEvent::trigger('bar1');\n\nEvent::listen('bar2', 'Bar::foo');\nEvent::trigger('bar2');\n\nfunction bar()\n{\n    echo \u0026quot;bar() is calledn\u0026quot;;\n}\n\nEvent::listen('bar3', 'bar');\nEvent::trigger('bar3');\n\u003c/code\u003e\u003c/pre\u003e\n","articleStatus":1,"processStatus":0,"author":{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp","wornBadge":{"code":"king","type":"system","grantMode":"manual","name":"King","description":"社区之王","iconType":"asset","iconKey":"","iconUrl":"/static/badges/king.svg","color":"amber","level":"special","isEnabled":true,"isWearable":true,"sortOrder":1,"source":"manual","reason":"管理员手动授予","grantedAt":"2026-06-07 18:52:33"}},"participants":[{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp","wornBadge":{"code":"king","type":"system","grantMode":"manual","name":"King","description":"社区之王","iconType":"asset","iconKey":"","iconUrl":"/static/badges/king.svg","color":"amber","level":"special","isEnabled":true,"isWearable":true,"sortOrder":1,"source":"manual","reason":"管理员手动授予","grantedAt":"2026-06-07 18:52:33"}}],"categories":[{"id":4,"name":"Coding","url":"/c/Coding/4","color":"#8241d6"}],"replyCount":0,"maxReplyNo":0,"viewCount":277,"likeCount":0,"isLiked":false,"isBookmarked":false,"isWatched":false,"createdAt":"2019-03-18 23:20:09","updatedAt":"2025-12-30 20:46:43"},"replies":[],"hotTopics":[{"id":432,"title":"一些建议和bug","description":"Footer 中的 Primary 类使用 Html，无法编译 url 和 a 标签，会显示纯 Html 代码 下方文字内容 （Primary）\"，还是会出现原html， Power by \u003ca href=\"https://github.com/leancodebox/GooseForum\"\u003eGooseForum\u003c/a\u003e. “外部资源链接 / Meta 标签” 若为空，则会导致无法保存，500错误...","url":"/p/post/432","pinWeight":0,"processStatus":0,"author":{"id":28,"username":"yannis","avatarUrl":"/file/img/avatars/avatar_28_1779205979/ebd0888e-11d4-439f-8a99-fc5de7bd00eb.webp"},"participants":[{"id":28,"username":"yannis","avatarUrl":"/file/img/avatars/avatar_28_1779205979/ebd0888e-11d4-439f-8a99-fc5de7bd00eb.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"}],"categories":[{"id":8,"name":"吐槽/脑洞","url":"/c/%E5%90%90%E6%A7%BD%2F%E8%84%91%E6%B4%9E/8","color":"#5d41d6"}],"replyCount":52,"viewCount":628,"activityText":"2026-06-16 09:40:52","lastUpdateTime":"2026-06-16 09:40:52"},{"id":467,"title":"震惊！！点进标题帖子，返回键会回到顶部？？","description":"顶部往下刷到底点进标题帖子，返回键会回到顶部，没有返回到刚刚点进标题帖子的停留！每次返回还得往下刷找找刚刚点进的帖子😅","url":"/p/post/467","pinWeight":0,"processStatus":0,"author":{"id":51,"username":"weilaimeng","avatarUrl":"/static/pic/8.webp"},"participants":[{"id":51,"username":"weilaimeng","avatarUrl":"/static/pic/8.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"}],"categories":[{"id":8,"name":"吐槽/脑洞","url":"/c/%E5%90%90%E6%A7%BD%2F%E8%84%91%E6%B4%9E/8","color":"#5d41d6"}],"replyCount":18,"viewCount":142,"activityText":"2026-06-18 09:55:30","lastUpdateTime":"2026-06-18 09:55:30"},{"id":439,"title":"请问大佬怎么用宝塔部署此项目","description":"这个有没有宝塔的安装教程，看这个论坛系统不错，界面也好看，但是不会安装，因为doxker有其他的项目，这个不会安装，能不能出个宝塔安装的教程？。","url":"/p/post/439","pinWeight":0,"processStatus":0,"author":{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},"participants":[{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"}],"categories":[{"id":6,"name":"GooseForum","url":"/c/GooseForum/6","color":"#41d641"}],"replyCount":13,"viewCount":204,"activityText":"2026-05-27 23:59:39","lastUpdateTime":"2026-05-27 23:59:39"},{"id":475,"title":"正文内容的背景和右侧卡片相连了？","description":"RT RT","url":"/p/post/475","pinWeight":0,"processStatus":0,"author":{"id":44,"username":"yannisme","avatarUrl":"/static/pic/3.webp"},"participants":[{"id":44,"username":"yannisme","avatarUrl":"/static/pic/3.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},{"id":28,"username":"yannis","avatarUrl":"/file/img/avatars/avatar_28_1779205979/ebd0888e-11d4-439f-8a99-fc5de7bd00eb.webp"}],"categories":[{"id":6,"name":"GooseForum","url":"/c/GooseForum/6","color":"#41d641"},{"id":8,"name":"吐槽/脑洞","url":"/c/%E5%90%90%E6%A7%BD%2F%E8%84%91%E6%B4%9E/8","color":"#5d41d6"}],"replyCount":9,"viewCount":61,"activityText":"2026-06-29 15:49:51","lastUpdateTime":"2026-06-29 15:49:51"},{"id":453,"title":"纪念一下第一次王者上百星","description":"","firstImageUrl":"/file/img/2026/06/04/664129e0-2015-4d58-bb01-b9abd5def8ea.webp","url":"/p/post/453","pinWeight":0,"processStatus":0,"author":{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},"participants":[{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"}],"categories":[{"id":11,"name":"Game","url":"/c/Game/11","color":"#d66e41"}],"replyCount":8,"viewCount":124,"activityText":"2026-06-06 21:20:10","lastUpdateTime":"2026-06-06 21:20:10"},{"id":443,"title":"部署有没有内存限制","description":"1h1g可以呀玩不，有没有限制，大佬用的什么配置服务器说说呗","url":"/p/post/443","pinWeight":0,"processStatus":0,"author":{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},"participants":[{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"}],"categories":[{"id":6,"name":"GooseForum","url":"/c/GooseForum/6","color":"#41d641"}],"replyCount":8,"viewCount":142,"activityText":"2026-05-30 11:38:25","lastUpdateTime":"2026-05-30 11:38:25"}],"permissions":{"isOwnArticle":false,"canReply":false,"canModerateArticle":false}},"meta":{"title":"PHP[017]:事件监听 - GooseForum","description":"阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。","canonical":"https://gooseforum.online/p/post/252","openGraph":{"title":"PHP[017]:事件监听","description":"阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。","type":"article","url":"https://gooseforum.online/p/post/252","siteName":"GooseForum","publishedTime":"2019-03-18T23:20:09+08:00","modifiedTime":"2025-12-30T20:46:43+08:00","author":"abandon1a2b","section":"Coding","tags":["Coding"]},"twitter":{"card":"summary","title":"PHP[017]:事件监听","description":"阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。"},"jsonLd":{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"PHP[017]:事件监听","description":"阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。","text":"阅读 PHP[017]:事件监听，参与 GooseForum 的社区讨论。","author":{"@type":"Person","name":"abandon1a2b","url":"https://gooseforum.online/u/1"},"publisher":{"@type":"Organization","name":"GooseForum","url":"https://gooseforum.online"},"datePublished":"2019-03-18T23:20:09+08:00","dateModified":"2025-12-30T20:46:43+08:00","url":"https://gooseforum.online/p/post/252","mainEntityOfPage":"https://gooseforum.online/p/post/252","articleSection":"Coding","keywords":["Coding"],"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":277}]}},"layout":{"site":{"name":"GooseForum","description":"🦢 大鹅栖息地 | 自由漫谈的江湖茶馆","logo":"/static/pic/icon.webp","favicon":"/static/pic/icon.webp","externalLinks":"\u003cscript defer src=\"https://umami.leancodebox.online/script.js\" data-website-id=\"0a633415-dd84-4264-98cd-a006e6a8fefc\"\u003e\u003c/script\u003e","brandType":"default","brandText":"","brandImage":""},"viewer":{"id":0,"username":"","email":"","avatarUrl":"","isAuthenticated":false,"canAccessAdmin":false,"isModerator":false,"requiresEmailVerification":false,"adminPermissions":[]},"sidebar":{"categories":[{"id":6,"label":"GooseForum","url":"/c/GooseForum/6","color":"#41d641"},{"id":7,"label":"AI","url":"/c/AI/7","color":"#b941d6"},{"id":4,"label":"Coding","url":"/c/Coding/4","color":"#8241d6"},{"id":8,"label":"吐槽/脑洞","url":"/c/happy/8","color":"#5d41d6"},{"id":10,"label":"HelpMe","url":"/c/HelpMe/10","color":"#41d644"},{"id":11,"label":"Game","url":"/c/Game/11","color":"#d66e41"}],"activeKey":"category_4"},"footer":{"links":[{"name":"RSS","url":"/rss.xml"},{"name":"Site Map","url":"/sitemap.xml"},{"name":"GooseForum","url":"https://github.com/leancodebox/GooseForum"}],"primary":["GooseForum © 2024"]},"unread":{"notifications":false,"messages":false,"moderationReports":false},"theme":{"enabled":true,"href":"/site-theme.css?v=3535d0c163954d2c","colors":{"gf-dark":"#101418","gf-light":"#fbfdff"},"current":"gf-light","themeColor":"#fbfdff"}},"url":"https://gooseforum.online/p/post/252","version":"1.0"}</script>

    <div id="goose-app" aria-live="polite"></div>

    <noscript>
        

<main>
    <article>
        <h1>PHP[017]:事件监听</h1>
        
        <p>
            
            
            <a href="/c/Coding/4" rel="tag">Coding</a>
            
            
            <a href="/u/1">abandon1a2b</a>
            <time datetime="2019-03-18T23:20:09&#43;08:00">2019-03-18 23:20:09</time>
            <time datetime="2025-12-30T20:46:43&#43;08:00">更新于 2025-12-30 20:46:43</time>
            <span>0 回复</span>
            <span>0 赞</span>
            <span>277 浏览</span>
        </p>
        <div>
            <pre><code class="language-php">&lt;?php

class Event
{
    protected static $listens = array();

    public static function listen($event, $callback, $once = false)
    {
        if (!is_callable($callback)) return false;
        self::$listens[$event][] = array('callback' =&gt; $callback, 'once' =&gt; $once);
        return true;
    }

    public static function one($event, $callback)
    {
        return self::listen($event, $callback, true);
    }

    public static function remove($event, $index = null)
    {
        if (is_null($index))
            unset(self::$listens[$event]);
        else
            unset(self::$listens[$event][$index]);
    }

    public static function trigger()
    {
        if (!func_num_args()) return;
        $args = func_get_args();
        $event = array_shift($args);
        if (!isset(self::$listens[$event])) return false;
        foreach ((array)self::$listens[$event] as $index =&gt; $listen) {
            $callback = $listen['callback'];
            $listen['once'] &amp;&amp; self::remove($event, $index);
            call_user_func_array($callback, $args);
        }
    }
}


// 增加监听walk事件 
Event::listen('walk', function () {
    echo &quot;I am walking...n&quot;;
}); 
// 增加监听walk一次性事件 
Event::listen('walk', function () {
    echo &quot;I am listening...n&quot;;
}, true); 
// 触发walk事件 
Event::trigger('walk'); 
/* 
I am walking... 
I am listening... 
 */
Event::trigger('walk'); 
/* 
I am walking... 
 */

Event::one('say', function ($name = '') {
    echo &quot;I am {$name}n&quot;;
});

Event::trigger('say', 'deeka'); // 输出 I am deeka 
Event::trigger('say', 'deeka'); // not run 

class Foo
{
    public function bar()
    {
        echo &quot;Foo::bar() is calledn&quot;;
    }

    public function test()
    {
        echo &quot;Foo::foo() is called, agrs:&quot; . json_encode(func_get_args()) . &quot;n&quot;;
    }
}

$foo = new Foo;

Event::listen('bar', array($foo, 'bar'));
Event::trigger('bar');

Event::listen('test', array($foo, 'test'));
Event::trigger('test', 1, 2, 3);

class Bar
{
    public static function foo()
    {
        echo &quot;Bar::foo() is calledn&quot;;
    }
}

Event::listen('bar1', array('Bar', 'foo'));
Event::trigger('bar1');

Event::listen('bar2', 'Bar::foo');
Event::trigger('bar2');

function bar()
{
    echo &quot;bar() is calledn&quot;;
}

Event::listen('bar3', 'bar');
Event::trigger('bar3');
</code></pre>

        </div>
    </article>

    
</main>


    </noscript>
</body>
</html>





