Использовать функцию с указанными c параметрами по умолчанию в php? - PullRequest
0 голосов
/ 29 февраля 2020

Предположим, у меня есть следующая функция:

<?php
    function MyFunction($color="green", $type="wood", $shape="circle")
    {
        echo "Its a ", $color , " " , $shape, ", made of " , $type , ".";
    }

    MyFunction();    // prints Its a green circle, made of wood.
?>

Все три параметра в функции являются необязательными.

Я знаю, что могу пропустить параметр, набрав null в его слот для параметров. Например, чтобы изменить древесину на plasti c, мне нужно было бы набрать:

MyFunction(null,"plastic");

Как я могу вызвать ту же функцию и проанализировать, какую переменную я хочу изменить, не используя что-то необычное как массив?

Например, если мы возьмем Powershell, код будет выглядеть следующим образом:

function MyFunction()
{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$False)][string]color=green,
        [Parameter(Mandatory=$False)][string]type=wood,
        [Parameter(Mandatory=$False)][string]circle=circle
    )

    write-host "Its a" $color $shape", made out of" $type"."
}

В Powershell я могу вызвать функцию двумя способами.

MyFunction "red", "plastic", "square"

или

MyFunction -type "plastic"

Как мне достичь второго пути в php? Например, предположим, что следующий код действителен:

MyFunction ($type="plastic");

Ответы [ 4 ]

1 голос
/ 29 февраля 2020

Если вы действительно не хотите использовать массив, я бы посоветовал вам установить значение параметра null для использования значения по умолчанию. Но он установлен в теле функции.

function MyFunction($color=null, $type=null, $shape=null)
{
    echo "Its a ", $color ?? 'green' , " " , $shape ?? 'circle', ", made of " , $type?? 'wood' , ".";
}

Я использую здесь оператор null coalescing . Для получения дополнительной информации перейдите по ссылке.

1 голос
/ 29 февраля 2020

Я бы предложил работать с объектами-значениями, потому что вы не можете получить одну функцию, как описано в PHP. Возможное решение может выглядеть следующим образом. (Тип безопасности включен)

class Thing
{
    protected string $color = 'green';
    protected string $type = 'wood';
    protected string $shape = 'circle';

    public function getColor(): string
    {
        return $this->color;
    }

    public function setColor(string $color): self
    {
        $this->color = $color;
        return $this;
    }

    public function getType(): string
    {
        return $this->type;
    }

    public function setType(string $type): self
    {
        $this->type = $type;
        return $this;
    }

    public function getShape(): string
    {
        return $this->shape;
    }

    public function setShape(string $shape): self
    {
        $this->shape = $shape;
        return $this;
    }

    public function __toString(): string
    {
        return "Its a " . $this->color . " " . $this->shape . " made of " . $this->type . ".";
    }
}

function yourFunction(Thing $thing): void
{
    echo $thing;
}

$thing = (new Thing())
    ->setColor('red')
    ->setShape('rectangle');

yourFunction($thing); // Its a red rectangle made of wood.

Поскольку мы работаем с объектом-значением, вам больше не нужно иметь дело с параметрами функции. Объект обладает всеми необходимыми вам свойствами. С помощью функций получения и установки вы можете получить все необходимые значения. Если значение не установлено, вместо него будет работать значение по умолчанию. Ваша функция принимает только объект в качестве параметра.

0 голосов
/ 29 февраля 2020

На данный момент кажется, что это невозможно. Я хотел избежать массивов, потому что я не мог понять, как установить значения по умолчанию, но мне удалось выяснить эту часть. Я все еще хотел бы лучшее решение, но сейчас это ближе всего к тому, что я хочу. Я оставлю вопрос открытым, когда PHP фактически начнет его поддерживать, и кто-то отправит правильный ответ.

Код, который я сейчас использую, выглядит следующим образом:

<?php
    function MyFunction($params=null)
    {   // define defaults
        $arg['color'] = 'green';
        $arg['shape'] = 'circle';
        $arg['type'] = 'wood';

        if( isset($params) )
        {
            $arg = array_merge($arg,$params);
        }

        echo "Its a ", $arg['color'] , " " , $arg['shape'], ", made of " , $arg['type'] , ".";
    }
    MyFunction(); 
    // prints Its a green circle, made of wood.

    MyFunction(array('type'=>'plastic', 'shape'=>'square'));
    // prints Its a green square, made of plastic.

?>

РЕДАКТИРОВАТЬ: уточнение этой идеи к тому, что я действительно хочу, делает код более уродливым в самой функции, но делает вызов функции намного более привлекательным.

<?php
    function MyFunction(...$params)
    {   // define defaults
        $arg['color'] = 'green';
        $arg['shape'] = 'circle';
        $arg['type'] = 'wood';

        if( count($params)>0 )
        {   // We have more than 0 params

            foreach($params as $id=>$param)
            {
                if( strpos($param,"=") )
                {   // if we have a param assigner.
                    $array = explode('=', $param);              
                    $array2[$array[0]]=$array[1];
                    $arg = array_merge($arg,$array2);
                }
                else
                {   // assume the params are in correct order.
                    $arraykeys = array_keys($arg);
                    $arg[ $arraykeys[$id] ] = $param;
                }
            }

        }


        echo "Its a ", $arg['color'] , " " , $arg['shape'], ", made of " , $arg['type'] , ".<br/>";
    }

    MyFunction();    // prints Its a green circle, made of wood.
    MyFunction('red', 'square');    // prints Its a red square, made of wood.
    MyFunction('color=pink', 'type=plastic');    // prints Its a pink circle, made of plastic.
?>
0 голосов
/ 29 февраля 2020

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

Но в версиях 5.6.x вы можете использовать распаковку аргументов в функциях. PHP

Пример:

function add($a, $b, $c) {
    return $a + $b + $c;
}

$operators = [2, 3];
echo add(1, ...$operators);

Выход: 10

Также вы можете использовать более старый подход func_get_args () Пример:

function foo(){

    $numargs = func_num_args();
    echo "Number of arguments: $numargs \n";

    if ($numargs >= 2) {
        echo "Second argument is: " . func_get_arg(1) . "\n";
    }

    $arg_list = func_get_args();

    for ($i = 0; $i < $numargs; $i++) {
        echo "Argument $i is: " . $arg_list[$i] . "\n";
    }

}

foo(1, 2, 3);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...