Intereting Posts

назвали необязательные аргументы PHP?

Возможно ли в PHP 4/5 указать именованный необязательный параметр при вызове, пропуская те, которые вы не хотите указывать (например, в python)?

Что-то вроде:

function foo($a,$b='', $c='') { // whatever } foo("hello", $c="bar"); // we want $b as the default, but specify $c 

благодаря

Related of "назвали необязательные аргументы PHP?"

Нет, это невозможно: если вы хотите передать третий параметр, вам нужно передать второй. Именованные параметры также невозможны.

«Решение» – это использовать только один параметр, массив и всегда передавать его … Но не всегда все это определяет.

Например :

 function foo($params) { var_dump($params); } 

И называя это так:

 foo(array( 'a' => 'hello', )); foo(array( 'a' => 'hello', 'c' => 'glop', )); foo(array( 'a' => 'hello', 'test' => 'another one', )); 

Вы получите этот результат:

 array 'a' => string 'hello' (length=5) array 'a' => string 'hello' (length=5) 'c' => string 'glop' (length=4) array 'a' => string 'hello' (length=5) 'test' => string 'another one' (length=11) 

Но мне не очень нравится это решение:

  • Вы потеряете phpdoc
  • Ваша IDE больше не сможет дать какой-либо намек … Что плохо

Поэтому я бы пошел с этим только в очень конкретных случаях – для функций с большим количеством опциональных параметров, например …

Нет, PHP не может передавать аргументы по имени.

Если у вас есть функция, которая принимает много аргументов, и все они имеют значения по умолчанию, вы можете подумать о том, чтобы заставить функцию принимать массив аргументов:

 function test (array $args) { $defaults = array('a' => '', 'b' => '', 'c' => ''); $args = array_merge($defaults, array_intersect_key($args, $defaults)); list($a, $b, $c) = array_values($args); // an alternative to list(): extract($args); // you can now use $a, $b, $c } 

Смотрите в действии .

Нет, это не так.

Единственный способ, которым вы можете это сделать, – это использовать массивы с именованными ключами, а что нет.

С PHP, порядок аргументов имеет значение. Вы не можете указать конкретный аргумент неуместно, но вместо этого вы можете пропустить аргументы, передав NULL, если вы не возражаете, чтобы значение в вашей функции имело значение NULL.

 foo("hello", NULL, "bar"); 

Начиная с PHP 5.4 у вас есть синтаксис коротких массивов (не обязательно указывать массивы с громоздким «массивом» и вместо этого использовать «[]»).

Вы можете имитировать именованные параметры разными способами: один хороший и простой способ:

 bar('one', ['a1' => 'two', 'bar' => 'three', 'foo' => 'four']); // output: twothreefour function bar ($a1, $kwargs = ['bar' => null, 'foo' => null]) { extract($kwargs); echo $a1; echo $bar; echo $foo; } 

Это не совсем красиво, но это трюк, некоторые могут сказать.

 class NamedArguments { static function init($args) { $assoc = reset($args); if (is_array($assoc)) { $diff = array_diff(array_keys($assoc), array_keys($args)); if (empty($diff)) return $assoc; trigger_error('Invalid parameters: '.join(',',$diff), E_USER_ERROR); } return array(); } } class Test { public static function foobar($required, $optional1 = '', $optional2 = '') { extract(NamedArguments::init(get_defined_vars())); printf("required: %s, optional1: %s, optional2: %s\n", $required, $optional1, $optional2); } } Test::foobar("required", "optional1", "optional2"); Test::foobar(array( 'required' => 'required', 'optional1' => 'optional1', 'optional2' => 'optional2' )); 

Вы можете сохранить phpdoc и возможность устанавливать значения по умолчанию, передавая объект вместо массива, например

 class FooOptions { $opt1 = 'x'; $opt2 = 'y'; /* etc */ }; 

Это также позволяет выполнять строгую проверку типов в вызове функции, если вы хотите:

 function foo (FooOptions $opts) { ... } 

Разумеется, вы можете заплатить за это, добавив дополнительную детализацию объекта FooOptions. К сожалению, нет абсолютно бесплатной езды.

Обычно вы не можете, но я думаю, что есть много способов передать именованные аргументы функции PHP. Лично я ретранслирую по определению с использованием массивов и просто вызываю то, что мне нужно передать:

 class Test{ public $a = false; private $b = false; public $c = false; public $d = false; public $e = false; public function _factory(){ $args = func_get_args(); $args = $args[0]; $this->a = array_key_exists("a",$args) ? $args["a"] : 0; $this->b = array_key_exists("b",$args) ? $args["b"] : 0; $this->c = array_key_exists("c",$args) ? $args["c"] : 0; $this->d = array_key_exists("d",$args) ? $args["d"] : 0; $this->e = array_key_exists("e",$args) ? $args["e"] : 0; } public function show(){ var_dump($this); } } $test = new Test(); $args["c"]=999; $test->_factory($args); $test->show(); 

Здесь приведен пример: http://sandbox.onlinephpfunctions.com/code/d7f27c6e504737482d396cbd6cdf1cc118e8c1ff

Если мне нужно передать 10 аргументов, и 3 из них – это данные, которые мне действительно нужны, НЕ ДАЖЕ SMART, чтобы перейти в функцию что-то вроде

 return myfunction(false,false,10,false,false,"date",false,false,false,"desc"); 

При подходе, который я даю, вы можете настроить любой из 10 аргументов в массив:

 $arr['count']=10; $arr['type']="date"; $arr['order']="desc"; return myfunction($arr); 

У меня есть сообщение в моем блоге, объясняющее этот процесс более подробно.

http://www.tbogard.com/2013/03/07/passing-named-arguments-to-a-function-in-php

Вот что я использовал. Определение функции принимает один необязательный аргумент массива, который указывает необязательные именованные аргументы:

 function func($arg, $options = Array()) { $defaults = Array('foo' => 1.0, 'bar' => FALSE); $options = array_merge($default, $options); // Normal function body here. Use $options['foo'] and // $options['bar'] to fetch named parameter values. ... } 

Обычно вы можете вызывать без каких-либо именованных аргументов:

 func("xyzzy") 

Чтобы указать необязательный именованный аргумент, передайте его в необязательном массиве:

 func("xyzzy", Array('foo' => 5.7)) 

Нет, не совсем. Есть несколько альтернатив, которые вы могли бы использовать.

 test(null,null,"hello") 

Или передайте массив:

 test(array('c' => "hello")); 

Тогда функция может быть:

 function test($array) { $c = isset($array[c]) ? $array[c] : ''; } 

Или добавьте функцию между ними, но я бы не предложил этого:

 function ctest($c) { test('','',$c); } 

Попробуйте function test ($a="",$b="",&$c=""){}

Помещение & до $c

Я так не думаю … Если вам нужно вызвать, например, функцию substr , которая имеет 3 параметра, и вы хотите установить $ length без установки $ start, вы будете вынуждены это сделать.

 substr($str,0,10); 

хороший способ переопределить это – всегда использовать массивы для параметров

Простой ответ. Нет, вы не можете.
Вы можете попробовать обойти его, передав объект / массив или используя другие шаблоны инъекций зависимостей.

Кроме того, попробуйте использовать нули, а не пустые строки, поскольку более определенно проверить их существование, используя is_null ()

например:

 function test ($a=null,$b=null,$c=null){ if (is_null($a) { //do something about $a } if (is_null($b) { //do something about $b } if (is_null($c) { //do something about $c } } 

для этого:

 test(null,null,"Hello"); 

В очень короткие, иногда да, используя отраженные и типизированные переменные. Однако я думаю, что это, вероятно, не то, что вам нужно.

Лучшее решение вашей проблемы, вероятно, должно пройти в 3 аргументах, поскольку функции обрабатывают недостающий внутри вашей функции самостоятельно

 <?php function test(array $params) { //Check for nulls etc etc $a = $params['a']; $b = $params['b']; ...etc etc } 

Вы не можете сделать это на python. Anway, вы можете передать ассоциативный массив и использовать записи массива по их имени:

 function test ($args=array('a'=>'','b'=>'','c'=>'')) { // do something } test(array('c'=>'Hello')); 

Это не уменьшает типизацию, но, по крайней мере, более описательно, имея имена аргументов, видимые и читаемые в вызове.

Вот работа:

 function set_param_defaults($params) { foreach($params['default_values'] as $arg_name => $arg_value) { if (!isset($params[$arg_name])) { $params[$arg_name] = $arg_value; } } return $params; } function foo($z, $x = null, $y = null) { $default_values = ['x' => 'default value for x', 'y' => 'default value for y']; $params = set_param_defaults(get_defined_vars()); print "$z\n"; print $params['x'] . "\n"; print $params['y'] . "\n"; } foo('set z value', null, 'set y value'); print "\n"; foo('set z value', 'set x value'); 

ALTERNATIVELY: Лично я бы пошел с этим методом.

 function foo($z, $x_y) { $x_y += ['x' => 'default value for x', 'y' => 'default value for y']; print "$z\n"; print $x_y['x'] . "\n"; print $x_y['y'] . "\n"; } foo('set z value', ['y' => 'set y value']); print "\n"; foo('set z value', ['x' => 'set x value']); 

Распечатывайте выходы для обоих примеров.

1-й вызов:

  • установить значение z
  • значение по умолчанию для x
  • установить значение y

2-й вызов:

  • установить значение z
  • установить значение x
  • значение по умолчанию для y

Просто используйте шаблон ассоциативного массива Drupal. Для необязательных аргументов по умолчанию просто примите аргумент $options который является ассоциативным массивом. Затем используйте оператор array + для установки любых отсутствующих ключей в массиве.

 function foo ($a_required_parameter, $options = array()) { $options += array( 'b' => '', 'c' => '', ); // whatever } foo('a', array('c' => 'c's value')); // No need to pass b when specifying c.