C ++ background에서 온다;)
어떻게 PHP 함수를 오버로드 할 수 있습니까?
인수가있는 경우 하나의 함수 정의, 인수가없는 경우 다른 함수 정의? PHP에서 가능합니까? 아니면 $ _GET 및 POST에서 전달 된 매개 변수가 있는지 확인하려면 다른 방법을 사용해야합니까 ?? 그들과 관련이 있습니까?
overloading
것은 질문에서 요구되는 것과는 다른 단어의 의미입니다 . (자세한 내용은 허용 된 답변을 참조하십시오.)
C ++ background에서 온다;)
어떻게 PHP 함수를 오버로드 할 수 있습니까?
인수가있는 경우 하나의 함수 정의, 인수가없는 경우 다른 함수 정의? PHP에서 가능합니까? 아니면 $ _GET 및 POST에서 전달 된 매개 변수가 있는지 확인하려면 다른 방법을 사용해야합니까 ?? 그들과 관련이 있습니까?
overloading
것은 질문에서 요구되는 것과는 다른 단어의 의미입니다 . (자세한 내용은 허용 된 답변을 참조하십시오.)
답변:
PHP 함수를 오버로드 할 수 없습니다. 함수 시그니처는 이름 만 기반으로하며 인수 목록을 포함하지 않으므로 동일한 이름의 두 함수를 가질 수 없습니다. PHP에서 클래스 메소드 오버로드 는 다른 많은 언어와 다릅니다. PHP는 같은 단어를 사용하지만 다른 패턴을 설명합니다.
그러나 가변 개수의 인수를 사용 하는 가변 함수 를 선언 할 수 있습니다 . 당신이 사용하는 것이 func_num_args()
및 func_get_arg()
전달 된 인수를 얻기 위해, 일반적을 사용합니다.
예를 들면 다음과 같습니다.
function myFunc() {
for ($i = 0; $i < func_num_args(); $i++) {
printf("Argument %d: %s\n", $i, func_get_arg($i));
}
}
/*
Argument 0: a
Argument 1: 2
Argument 2: 3.5
*/
myFunc('a', 2, 3.5);
myFunc(/*...*/)
.
PHP는 전통적인 메소드 오버로딩을 지원하지 않지만, 원하는 것을 달성 할 수있는 한 가지 방법은 __call
매직 메소드를 이용하는 것입니다.
class MyClass {
public function __call($name, $args) {
switch ($name) {
case 'funcOne':
switch (count($args)) {
case 1:
return call_user_func_array(array($this, 'funcOneWithOneArg'), $args);
case 3:
return call_user_func_array(array($this, 'funcOneWithThreeArgs'), $args);
}
case 'anotherFunc':
switch (count($args)) {
case 0:
return $this->anotherFuncWithNoArgs();
case 5:
return call_user_func_array(array($this, 'anotherFuncWithMoreArgs'), $args);
}
}
}
protected function funcOneWithOneArg($a) {
}
protected function funcOneWithThreeArgs($a, $b, $c) {
}
protected function anotherFuncWithNoArgs() {
}
protected function anotherFuncWithMoreArgs($a, $b, $c, $d, $e) {
}
}
__call()
이전 에이 사용을 보지 못했습니다 . 꽤 창의적입니다 (약간의 장황한 경우)! +1
함수를 오버로드하려면 단순히 기본적으로 매개 변수를 null로 전달하십시오.
class ParentClass
{
function mymethod($arg1 = null, $arg2 = null, $arg3 = null)
{
if( $arg1 == null && $arg2 == null && $arg3 == null ){
return 'function has got zero parameters <br />';
}
else
{
$str = '';
if( $arg1 != null )
$str .= "arg1 = ".$arg1." <br />";
if( $arg2 != null )
$str .= "arg2 = ".$arg2." <br />";
if( $arg3 != null )
$str .= "arg3 = ".$arg3." <br />";
return $str;
}
}
}
// and call it in order given below ...
$obj = new ParentClass;
echo '<br />$obj->mymethod()<br />';
echo $obj->mymethod();
echo '<br />$obj->mymethod(null,"test") <br />';
echo $obj->mymethod(null,'test');
echo '<br /> $obj->mymethod("test","test","test")<br />';
echo $obj->mymethod('test','test','test');
overload
되었으므로 PHP에서 함수에 의미 할 수있는 모든 것입니다. 독자들이 알고 있어야합니다.
일부 사람들에게는 해킹 일 수 있지만 Cakephp가 일부 기능을 수행하는 방법 에서이 방법을 배웠고 유연성이 마음에 들기 때문에 그것을 적응 시켰습니다.
아이디어는 다른 유형의 인수, 배열, 객체 등을 가지고 있으며 전달 된 것을 감지하고 거기에서 나갑니다.
function($arg1, $lastname) {
if(is_array($arg1)){
$lastname = $arg1['lastname'];
$firstname = $arg1['firstname'];
} else {
$firstname = $arg1;
}
...
}
<?php
/*******************************
* author : hishamdalal@gmail.com
* version : 3.8
* create on : 2017-09-17
* updated on : 2020-01-12
*****************************/
#> 1. Include Overloadable class
class Overloadable
{
static function call($obj, $method, $params=null) {
$class = get_class($obj);
// Get real method name
$suffix_method_name = $method.self::getMethodSuffix($method, $params);
if (method_exists($obj, $suffix_method_name)) {
// Call method
return call_user_func_array(array($obj, $suffix_method_name), $params);
}else{
throw new Exception('Tried to call unknown method '.$class.'::'.$suffix_method_name);
}
}
static function getMethodSuffix($method, $params_ary=array()) {
$c = '__';
if(is_array($params_ary)){
foreach($params_ary as $i=>$param){
// Adding special characters to the end of method name
switch(gettype($param)){
case 'array': $c .= 'a'; break;
case 'boolean': $c .= 'b'; break;
case 'double': $c .= 'd'; break;
case 'integer': $c .= 'i'; break;
case 'NULL': $c .= 'n'; break;
case 'object':
// Support closure parameter
if($param instanceof Closure ){
$c .= 'c';
}else{
$c .= 'o';
}
break;
case 'resource': $c .= 'r'; break;
case 'string': $c .= 's'; break;
case 'unknown type':$c .= 'u'; break;
}
}
}
return $c;
}
// Get a reference variable by name
static function &refAccess($var_name) {
$r =& $GLOBALS["$var_name"];
return $r;
}
}
//----------------------------------------------------------
#> 2. create new class
//----------------------------------------------------------
class test
{
private $name = 'test-1';
#> 3. Add __call 'magic method' to your class
// Call Overloadable class
// you must copy this method in your class to activate overloading
function __call($method, $args) {
return Overloadable::call($this, $method, $args);
}
#> 4. Add your methods with __ and arg type as one letter ie:(__i, __s, __is) and so on.
#> methodname__i = methodname($integer)
#> methodname__s = methodname($string)
#> methodname__is = methodname($integer, $string)
// func(void)
function func__() {
pre('func(void)', __function__);
}
// func(integer)
function func__i($int) {
pre('func(integer '.$int.')', __function__);
}
// func(string)
function func__s($string) {
pre('func(string '.$string.')', __function__);
}
// func(string, object)
function func__so($string, $object) {
pre('func(string '.$string.', '.print_r($object, 1).')', __function__);
//pre($object, 'Object: ');
}
// func(closure)
function func__c(Closure $callback) {
pre("func(".
print_r(
array( $callback, $callback($this->name) ),
1
).");", __function__.'(Closure)'
);
}
// anotherFunction(array)
function anotherFunction__a($array) {
pre('anotherFunction('.print_r($array, 1).')', __function__);
$array[0]++; // change the reference value
$array['val']++; // change the reference value
}
// anotherFunction(string)
function anotherFunction__s($key) {
pre('anotherFunction(string '.$key.')', __function__);
// Get a reference
$a2 =& Overloadable::refAccess($key); // $a2 =& $GLOBALS['val'];
$a2 *= 3; // change the reference value
}
}
//----------------------------------------------------------
// Some data to work with:
$val = 10;
class obj {
private $x=10;
}
//----------------------------------------------------------
#> 5. create your object
// Start
$t = new test;
#> 6. Call your method
// Call first method with no args:
$t->func();
// Output: func(void)
$t->func($val);
// Output: func(integer 10)
$t->func("hello");
// Output: func(string hello)
$t->func("str", new obj());
/* Output:
func(string str, obj Object
(
[x:obj:private] => 10
)
)
*/
// call method with closure function
$t->func(function($n){
return strtoupper($n);
});
/* Output:
func(Array
(
[0] => Closure Object
(
[parameter] => Array
(
[$n] =>
)
)
[1] => TEST-1
)
);
*/
## Passing by Reference:
echo '<br><br>$val='.$val;
// Output: $val=10
$t->anotherFunction(array(&$val, 'val'=>&$val));
/* Output:
anotherFunction(Array
(
[0] => 10
[val] => 10
)
)
*/
echo 'Result: $val='.$val;
// Output: $val=12
$t->anotherFunction('val');
// Output: anotherFunction(string val)
echo 'Result: $val='.$val;
// Output: $val=36
// Helper function
//----------------------------------------------------------
function pre($mixed, $title=null){
$output = "<fieldset>";
$output .= $title ? "<legend><h2>$title</h2></legend>" : "";
$output .= '<pre>'. print_r($mixed, 1). '</pre>';
$output .= "</fieldset>";
echo $output;
}
//----------------------------------------------------------
이건 어때?
function($arg = NULL) {
if ($arg != NULL) {
etc.
etc.
}
}
PHP 5.6에서 당신은 사용할 수있는 플랫 연산자를 ...
마지막 매개 변수로와 페지 func_get_args()
과 func_num_args()
:
function example(...$args)
{
count($args); // Equivalent to func_num_args()
}
example(1, 2);
example(1, 2, 3, 4, 5, 6, 7);
인수를 풀어서 사용할 수도 있습니다 :
$args[] = 1;
$args[] = 2;
$args[] = 3;
example(...$args);
다음과 같습니다.
example(1, 2, 3);
<?php
class abs
{
public function volume($arg1=null, $arg2=null, $arg3=null)
{
if($arg1 == null && $arg2 == null && $arg3 == null)
{
echo "function has no arguments. <br>";
}
else if($arg1 != null && $arg2 != null && $arg3 != null)
{
$volume=$arg1*$arg2*$arg3;
echo "volume of a cuboid ".$volume ."<br>";
}
else if($arg1 != null && $arg2 != null)
{
$area=$arg1*$arg2;
echo "area of square = " .$area ."<br>";
}
else if($arg1 != null)
{
$volume=$arg1*$arg1*$arg1;
echo "volume of a cube = ".$volume ."<br>";
}
}
}
$obj=new abs();
echo "For no arguments. <br>";
$obj->volume();
echo "For one arguments. <br>";
$obj->volume(3);
echo "For two arguments. <br>";
$obj->volume(3,4);
echo "For three arguments. <br>";
$obj->volume(3,4,5);
?>
PHP는 현재 오버로드를 지원하지 않습니다. 이것이 다른 프로그래밍 언어와 같은 다른 버전으로 구현되기를 바랍니다.
이 라이브러리를 체크 아웃하면 클로저 측면에서 PHP 오버로드를 사용할 수 있습니다. https://github.com/Sahil-Gulati/Overloading
슬프게도 C #에서와 같이 PHP에는 과부하가 없습니다. 하지만 약간의 트릭이 있습니다. 기본 null 값으로 인수를 선언하고 함수에서 확인합니다. 그렇게하면 내 함수가 인수에 따라 다른 작업을 수행 할 수 있습니다. 아래는 간단한 예입니다.
public function query($queryString, $class = null) //second arg. is optional
{
$query = $this->dbLink->prepare($queryString);
$query->execute();
//if there is second argument method does different thing
if (!is_null($class)) {
$query->setFetchMode(PDO::FETCH_CLASS, $class);
}
return $query->fetchAll();
}
//This loads rows in to array of class
$Result = $this->query($queryString, "SomeClass");
//This loads rows as standard arrays
$Result = $this->query($queryString);