Перегрузка функций PHP
Как я могу перегрузить функции PHP?
Одинаково ли определение функции, если у нее есть аргументы, и иначе, если аргументов нет? Возможно ли это в PHP? Или я должен использовать if else, чтобы проверить, есть ли параметры, переданные из $_GET и POST, и связать их?
Ответ 1
Вы не можете перегружать функции 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);
Ответ 2
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)
>
>
Ответ 3
Чтобы перегрузить функцию, просто передайте параметр как null по умолчанию:
class ParentClass
function mymethod($arg1 = null, $arg2 = null, $arg3 = null)
if( $arg1 == null && $arg2 == null && $arg3 == null )
return ‘function has got zero parameters
‘;
> else
$str = »;
if( $arg1 != null )
$str .= «arg1 = «.$arg1.»
«;
if( $arg2 != null )
$str .= «arg2 = «.$arg2.»
«;
if( $arg3 != null )
$str .= «arg3 = «.$arg3.»
«;
return $str;
>
>
>
// и вызовите его в порядке, указанном ниже .
$obj = new ParentClass;
echo ‘
$obj->mymethod()
‘;
echo $obj->mymethod();
echo ‘
$obj->mymethod(null,»test»)
‘;
echo $obj->mymethod(null,’test’);
echo ‘
$obj->mymethod(«test»,»test»,»test»)
‘;
echo $obj->mymethod(‘test’,’test’,’test’);
Ответ 4
/*******************************
* author : hishamdalal@gmail.com
* version : 3.8
* create on : 2017-09-17
* updated on : 2020-01-12
* download example: https://github.com/hishamdalal/overloadable
*****************************/
#> 1. Include Overloadable class
class Overloadable
static function call($obj, $method, $params=null)
$class = get_class($obj);
// Получение реального имени метода
$suffix_method_name = $method.self::getMethodSuffix($method, $params);
if (method_exists($obj, $suffix_method_name))
// Вызов метода
return call_user_func_array(array($obj, $suffix_method_name), $params);
>else
throw new Exception(‘Попытка вызова неизвестного метода ‘.$class.’::’.$suffix_method_name);
>
>
static function getMethodSuffix($method, $params_ary=array())
$c = ‘__’;
if(is_array($params_ary))
foreach($params_ary as $i=>$param)
// Добавление специальных символов в конец имени метода
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’:
// Поддержка параметра закрытия
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;
>
// Получение ссылочной переменной по имени
static function &refAccess($var_name)
$r =& $GLOBALS[«$var_name»];
return $r;
>
>
//———————————————————-
#> 2. создать новый класс
//———————————————————-
class test
private $name = ‘test-1’;
#> 3. Добавьте __call ‘магический метод’ в ваш класс
// Вызов перегружаемого класса
// вы должны скопировать этот метод в свой класс, чтобы активировать перегрузку
function __call($method, $args)
return Overloadable::call($this, $method, $args);
>
#> 4. Добавьте ваши методы с __ и тип arg как одну букву, т . е .:(__i, __s, __is) и так далее.
#> 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]++; // изменение опорного значения
$array[‘val’]++; // изменение опорного значения
>
// anotherFunction(string)
function anotherFunction__s($key)
pre(‘anotherFunction(string ‘.$key.’)’, __function__);
// Получение ссылки
$a2 =& Overloadable::refAccess($key); // $a2 =& $GLOBALS[‘val’];
$a2 *= 3; // изменение опорного значения
>
>
//———————————————————-
// Немного данных для работы:
$val = 10;
class obj
private $x=10;
>
//———————————————————-
#> 5. С оздайте свой объект
// Начать
$t = new test;
#> 6. Вызовите свой метод
// Вызовите первый метод без args:
$t->func();
// Вывод: func(void)
$t->func($val);
// Вывод: func(integer 10)
$t->func(«hello»);
// Вывод: func(string hello)
$t->func(«str», new obj());
/* Вывод:
func(string str, obj Object (
[x:obj:private] => 10)
)
*/
// вызов метода с функцией закрытия
$t->func(function($n)
return strtoupper($n);
>);
/* Вывод:
func(Array (
[0] => Closure Object ( [parameter] => Array ( [$n] =>)
)
[1] => TEST-1)
);
*/
## Передача по ссылке:
echo ‘
$val=’.$val;
// Вывод: $val=10
$t->anotherFunction(array(&$val, ‘val’=>&$val));
/* Output:
anotherFunction(Array (
[0] => 10 [val] => 10)
)
*/
echo ‘Result: $val=’.$val;
// Вывод: $val=12
$t->anotherFunction(‘val’);
// Вывод: anotherFunction(string val)
echo ‘Result: $val=’.$val;
// Вывод: $val=36
// Вспомогательные функции
//———————————————————-
function pre($mixed, $title=null)
$output = «
«;
echo $output;
>
//———————————————————-
Ответ 5
Еще один вариант использования:
class abs
public function volume($arg1=null, $arg2=null, $arg3=null)
if($arg1 == null && $arg2 == null && $arg3 == null)
echo «function has no arguments.
«;
>
else if($arg1 != null && $arg2 != null && $arg3 != null)
$volume=$arg1*$arg2*$arg3;
echo «volume of a cuboid «.$volume .»
«;
> else if($arg1 != null && $arg2 != null)
$area=$arg1*$arg2;
echo «area of square = » .$area .»
«;
> else if($arg1 != null)
$volume=$arg1*$arg1*$arg1;
echo «volume of a cube = «.$volume .»
«;
>
>
>
$obj=new abs();
echo «Без аргументов.
«;
$obj->volume();
echo «Для одного аргумента.
«;
$obj->volume(3);
echo «Для двух аргументов.
«;
$obj->volume(3,4);
echo «Для трех аргументов.
«;
$obj->volume(3,4,5);
?>
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Механизм перегрузки функций
Данная функциональность объявлена УСТАРЕВШЕЙ, начиная с PHP 7.2.0 и была УДАЛЕНА в версии PHP 8.0.0. Использовать эту функцию крайне не рекомендуется.
Зачастую заставить работать существующее PHP-приложение в многобайтовом окружении оказывается довольно трудной задачей. Это происходит, потому что большинство PHP-приложений написано с использованием стандартных функций обработки строк, таких как substr() , которые не умеют работать со строками в многобайтовых кодировках.
mbstring поддерживает механизм ‘перегрузки функций’, который позволяет сообщить приложению о том, что используется многобайтовая кодировка, без модификации кода, отвечающего за работу со строками. Например, если включена перегрузка функций, то функция mb_substr() будет вызываться вместо substr() . Этот механизм во многих случаях позволяет портировать приложения, поддерживающие только однобайтовые кодировки, в многобайтное окружение.
Для использования механизма перегрузки функций нужно задать настройке mbstring.func_overload в php.ini положительное значение, которое представляет собой комбинацию битовых масок, определяющих категории функций, которые нужно перегружать. Это будет число 1 для перегрузки функции mail() . 2 для строковых функций, 4 для функций регулярных выражений. Например, если значение настройки равно 7, то почтовые, строковые и функции регулярных выражений будут перегружаться. Список перегружаемых функций приведён ниже.
значение настройки mbstring.func_overload | исходная функция | перегруженная функция |
---|---|---|
1 | mail() | mb_send_mail() |
2 | strlen() | mb_strlen() |
2 | strpos() | mb_strpos() |
2 | strrpos() | mb_strrpos() |
2 | substr() | mb_substr() |
2 | strtolower() | mb_strtolower() |
2 | strtoupper() | mb_strtoupper() |
2 | stripos() | mb_stripos() |
2 | strripos() | mb_strripos() |
2 | strstr() | mb_strstr() |
2 | stristr() | mb_stristr() |
2 | strrchr() | mb_strrchr() |
2 | substr_count() | mb_substr_count() |
Замечание:
Не рекомендуется использовать перегрузку функций в контексте каждой директории, так как добиться стабильной работы в этом случае пока не удалось, и это может привести к неожидаемому поведению приложения.