◆ 今度の JS 化は EventEmitter!
◆ 今回もどこで使えるのかわからないな! 

PHP 書いてるとついやりたくなってしまって 今度は EventEmitter が実装されたよ
何言ってるのかわからないし どこに使うかもわからないですが 深く考えてはだめなのです

JavaScript でも作ってた overload 関数付きです

EventEmitter は JavaScript だと EvEmitter と呼んでましたがこれでも打つのが面倒だったので もう EvE になりました
大文字小文字なところも含めて どこかでみたような気がするようなですが 気にしないことにします
<?php
class EvE {
static $eve;
private $evs = [];

function on(...$args){
overload($args, [
[
"type" => ["string", "function", "int"],
"action" => function($evname, $evaction, $count){
$this->addEventListenerLimited($evname, $evaction, $count);
}
],[
"type" => ["string", "function"],
"action" => function($evname, $evaction){
$this->addEventListenerPermanent($evname, $evaction);
}
],[
"type" => null,
"action" => null
]
]);
}

private function addEventListenerPermanent($evname, $evaction){
$this->evs[$evname][] = [
"action" => $evaction,
"count" => -1
];
}
private function addEventListenerLimited($evname, $evaction, $count){
if($count <= 0){
throw new Exception("count must be positive integer value.");
}
$this->evs[$evname][] = [
"action" => $evaction,
"count" => $count
];
}

function off(...$args){
overload($args, [
[
"type" => ["string", "function"],
"action" => function($evname, $evaction){
$this->removeEventListener($evname, $evaction);
}
],[
"type" => ["string"],
"action" => function($evname){
$this->removeEventListenerByName($evname);
}
],[
"type" => ["function"],
"action" => function($evaction){
$this->removeEventListenerByAction($evaction);
}
],[
"type" => null,
"action" => null
]
]);
}

function clear(){
$this->evs = [];
}

private function removeEventListenerByName($evname){
unset($this->evs[$evname]);
}

private function removeEventListenerByAction($evaction){
foreach($this->evs as &$evactions){
foreach($evactions as $idx => $val){
if($val === $evaction) unset($evactions[$idx]);
}
}
}

private function removeEventListener($evname, $evaction){
if(isset($this->evs[$evname])){
foreach($this->evs[$evname] as $idx => $val){
if($val === $evaction) unset($this->evs[$evname][$idx]);
}
}
}

function emit($evname, ...$args){
if(isset($this->evs[$evname]) && is_array($this->evs[$evname])){
foreach($this->evs[$evname] as $idx => &$ev){
$is_stop = $ev["action"](...$args) === false;
if(--$ev["count"] === 0){
unset($this->evs[$evname][$idx]);
}
if($is_stop){
break;
}
}
}
}
}
EvE::$eve = new EvE();

function overload($args, $condition){
$result = null;
$typeMatch = function($args, $types){
if($types == null){
return true;
}
if(!is_array($types)){
return false;
}
foreach($types as $idx => $type){
$val = $args[$idx] ?? null;
switch($type){
case "int":
case "integer":
if(!is_int($val)) return false;
break;
case "float":
case "double":
if(!is_double($val)) return false;
break;
case "string":
if(!is_string($val)) return false;
break;
case "array":
if(!is_array($val)) return false;
break;
case "object":
if(!is_object($val)) return false;
break;
case "closure":
if(!($val instanceof Closure)) return false;
break;
case "function":
if(!is_callable($val)) return false;
break;
case null:
break;
default:
if(!($val instanceof $type))
return false;
}
}
return true;
};

foreach($condition as $ovfunc){
if($typeMatch($args, $ovfunc["type"])){
if(!$ovfunc["action"]){
throw new Exception("TypeError");
exit;
}else{
$result = $ovfunc["action"](...$args);
}
break;
}
}
return $result;
}

JavaScript のときよりはちょっと機能少なめです
PHP だと書くのも辛いですし



メソッドチェーンだったりメインループだったりといろいろあったのでまとめてみました

phjs.php

ムダに充実してきてますがどこにどう使うんですかね

Apache 捨てて アクセスごとにじゃなくて全部を 1 プロセスでやるなら Node.js と同じ感じで役立つ??