Skip to content

Instantly share code, notes, and snippets.

@nexpr
Created February 7, 2016 11:44
Show Gist options
  • Save nexpr/02f2e5075d6995fbd3fd to your computer and use it in GitHub Desktop.
Save nexpr/02f2e5075d6995fbd3fd to your computer and use it in GitHub Desktop.
php overload for method
<?php
class test{
use Overload;
function test__num($a){
return $a * $a;
}
function test__num2($a, $b){
return $a + $b;
}
function test__char($s){
return $s . $s;
}
}
test::$overload_rule = [
"test" => [
[
"type" => ["num", "num"],
"name" => "num2"
],[
"type" => ["num"],
"name" => "num"
],[
"type" => ["char"],
"name" => "char"
]
]
];
test::$argtype_rule = [
"num" => function($a){
return is_int($a) || is_float($a);
},
"char" => function($a){
return is_string($a) && strlen($a) === 1;
}
];
$t = new test();
var_dump($t->test("a"));
var_dump($t->test(123));
var_dump($t->test(123, 234));
try{
$t->test("ab");
}catch(Exception $e){
echo "Error: ", $e->getMessage();
}
<?php
trait Overload{
static $overload_rule = [];
static $argtype_rule = [];
function __call($name, $args){
$rule = self::$overload_rule;
$argtype_rule = self::$argtype_rule;
if(array_key_exists($name, $rule)){
$matched_rule = $rule[$name];
foreach($matched_rule as $item){
foreach($item["type"] as $idx => $type){
if($idx === count($args)) continue 2;
if(isset($argtype_rule[$type]) && $argtype_rule[$type]($args[$idx])){
continue;
}else{
continue 2;
}
}
return [$this, $name . "__" . $item["name"]](...$args);
}
}
throw new Exception("method `${name}' not found");
}
}
<?php
class test{
use Overload;
function test__num($a){
return $a * $a;
}
function test__num2($a, $b){
return $a + $b;
}
function test__char($s){
return $s . $s;
}
function getOverloadRule(){
return [
"base" => [
"test" => [
[
"type" => ["num", "num"],
"name" => "num2"
],[
"type" => ["num"],
"name" => "num"
],[
"type" => ["char"],
"name" => "char"
]
]
],
"condition" => [
"num" => function($a){
return is_int($a) || is_float($a);
},
"char" => function($a){
return is_string($a) && strlen($a) === 1;
}
]
];
}
}
$t = new test();
var_dump($t->test("a"));
var_dump($t->test(123));
var_dump($t->test(123, 234));
try{
$t->test("ab");
}catch(Exception $e){
echo "Error: ", $e->getMessage();
}
<?php
trait Overload{
function __call($name, $args){
$rule = $this->getOverloadRule();
$overload_rule = $rule["base"];
$argtype_rule = $rule["condition"];
if(array_key_exists($name, $overload_rule)){
$matched_rule = $overload_rule[$name];
foreach($matched_rule as $item){
foreach($item["type"] as $idx => $type){
if($idx === count($args)) continue 2;
if(isset($argtype_rule[$type]) && $argtype_rule[$type]($args[$idx])){
continue;
}else{
continue 2;
}
}
return [$this, $name . "__" . $item["name"]](...$args);
}
}
throw new Exception("method `${name}' not found");
}
abstract function getOverloadRule();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment