Подтвердить что ты не робот

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

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

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

function foo($a,$b='', $c='') {
    // whatever
}


foo("hello", $c="bar"); // we want $b as the default, but specify $c

Спасибо

4b9b3361

Ответ 1

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


"Решение" должно было бы использовать только один параметр, массив и всегда передавать его... Но не всегда все в нем.

Например:

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 больше не сможет дать какой-либо намек... Что плохое.

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

Ответ 2

Нет, 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       
}

Посмотрите на действие.

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

Как и в 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;
}

Ответ 6

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

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'
    ));

Ответ 7

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

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

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

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

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

Ответ 8

Обычно вы не можете, но я думаю, что существует много способов передать именованные аргументы функции 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

Ответ 9

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

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))

Ответ 10

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

test(null,null,"hello")

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

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

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

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

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

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

Ответ 11

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

Ввод & перед $c

Ответ 12

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

substr($str,0,10);

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

Ответ 13

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

Кроме того, попробуйте использовать пустые строки, а не пустые строки, поскольку более определенно проверить их существование, используя 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");

Ответ 14

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

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

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

Ответ 15

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

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

test(array('c'=>'Hello'));

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

Ответ 16

Вот работа:

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');

АЛЬТЕРНАТИВЫ: Лично я бы пошел с этим методом.

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

Второй вызов:

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

Ответ 17

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

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.