Estou confuso sobre valores padrão para funções PHP. Digamos que eu tenho uma função como esta:
function foo($blah, $x = "some value", $y = "some other value") {
// code here!
}
E se eu quiser usar o argumento padrão para $ x e definir um argumento diferente para $ y?
Tenho experimentado maneiras diferentes e estou ficando cada vez mais confusa. Por exemplo, eu tentei estes dois:
foo("blah", null, "test");
foo("blah", "", "test");
Mas ambos não resultam em um argumento padrão adequado para $ x. Eu também tentei defini-lo pelo nome da variável.
foo("blah", $x, $y = "test");
Eu esperava que algo assim funcionasse. Mas não funciona como eu esperava. Parece que não importa o que eu faça, terei que digitar os argumentos padrão de qualquer maneira, toda vez que invocar a função. E devo estar perdendo algo óbvio.
foo("blah", , "test");
?Respostas:
Eu proporia alterar a declaração da função da seguinte maneira para que você possa fazer o que deseja:
Dessa forma, você pode fazer uma chamada como
foo('blah', null, 'non-default y value');
e fazê-la funcionar como quiser, onde o segundo parâmetro$x
ainda obtém seu valor padrão.Com esse método, passar um valor nulo significa que você deseja o valor padrão para um parâmetro quando deseja substituir o valor padrão para um parâmetro que vem depois dele.
Como indicado em outras respostas,
Se eu tenho um método que pode aceitar números variáveis de parâmetros e parâmetros de tipos variados, geralmente declaro a função semelhante à resposta mostrada por Ryan P.
Aqui está outro exemplo (isso não responde à sua pergunta, mas é esperançosamente informativo:
fonte
null
valor real ao parâmetro, já que toda vez ele atribui o valor padrão. Mesmo que você tenha outro valor especial para quando você realmente deseja um nulo (por exemplo, quando $ x == "use_null" cria $ x = null), não seria possível atribuir um valor especial como o valor literal do parâmetro (neste caso, a cadeia "use_null"). Então, só não se esqueça de usar uma "chave" única, nunca desejou para quando você quiser usar o valor padrão (e você quernull
ser uma opção válida)Argumentos opcionais funcionam apenas no final de uma chamada de função. Não há como especificar um valor para $ y em sua função sem especificar também $ x. Algumas linguagens suportam isso por meio de parâmetros nomeados (VB / C # por exemplo), mas não PHP.
Você pode emular isso se usar uma matriz associativa para parâmetros em vez de argumentos - ou seja,
Em seguida, chame a função da seguinte maneira:
fonte
isset($args['x'])
, pois atualmente substituiria uma sequência vazia, uma matriz vazia oufalse
pelo valor padrão.$x = !array_key_exists('x',$args) ? 'default x value' : $args['x'];
É realmente possível:
Se você gostaria de fazer isso é outra história :)
ATUALIZAR:
Os motivos para evitar essa solução são:
Mas na verdade pode ser útil em situações em que:
você não quer / não pode alterar a função original.
você pode alterar a função, mas:
null
(ou equivalente) não é uma opção (consulte o comentário de DiegoDD )func_num_args()
Sobre o desempenho, um teste muito simples mostra que o uso da API do Reflection para obter os parâmetros padrão torna a chamada de função 25 vezes mais lenta , enquanto ainda leva menos de um microssegundo . Você deve saber se pode viver com isso.
Obviamente, se você quiser usá-lo em um loop, deverá obter o valor padrão antecipadamente.
fonte
fonte
$defaults = [ 'x' => 'some value', 'y' => 'some other value'];
A única maneira que eu sei de fazê-lo é omitindo o parâmetro. A única maneira de omitir o parâmetro é reorganizar a lista de parâmetros para que o que você deseja omitir seja após os parâmetros que você PRECISA definir. Por exemplo:
Então você pode chamar foo como:
Isso resultará em:
fonte
Recentemente, tive esse problema e encontrei esta pergunta e respostas. Enquanto as perguntas acima funcionam, o problema é que elas não mostram os valores padrão para os IDEs que os suportam (como PHPStorm).
se você usar
null
, não saberá qual seria o valor se deixá-lo em branco.A solução que prefiro é colocar também o valor padrão na definição da função:
A única diferença é que preciso garantir que eles sejam iguais - mas acho que é um preço pequeno a pagar pela clareza adicional.
fonte
Você não pode fazer isso diretamente, mas um pouco de manipulação de código torna possível emular.
fonte
null
nesse caso é conceitualmente mais organizado do quefalse
.false
é uma opção mais arriscada do quenull
, porque php é uma linguagem não estrita.!$x
será verdadeiro para várias entradas diferentes, que podem surpreender o programador:0
,''
. Considerando quenull
, com , você pode usar!isset
como um teste mais rigoroso.fonte
Meus 2 centavos com operador coalescente nulo
??
(desde PHP 7)Você pode conferir mais exemplos no meu repl.it
fonte
Nesse caso, quando o objeto é melhor - porque você pode configurá-lo para conter xey, configurar padrões etc.
A abordagem com o array está próxima de criar o objeto (de fato, o objeto é um monte de parâmetros e funções que trabalharão sobre o objeto, e o array de tomada de função funcionará sobre alguns parâmetros do grupo)
Certamente, você sempre pode fazer alguns truques para definir nulo ou algo assim como padrão
fonte
Você também pode verificar se possui uma sequência vazia como argumento para poder chamar como:
foo('blah', "", 'non-default y value', null);
Abaixo da função:
Não importa se você preencher
null
ou""
, você ainda obterá o mesmo resultado.fonte
Passe uma matriz para a função, em vez de parâmetros individuais e use o operador coalescente nulo (PHP 7+).
Abaixo, estou passando uma matriz com 2 itens. Dentro da função, estou verificando se o valor do item1 está definido, se não for atribuído o cofre padrão.
fonte
$args['item1'] = $args['item1']??'default value';
no PHP 7+. se $ args ['item1'] for nulo, adefault value
string será atribuída a $ args ['item1'] #