2009-06-30 27 views
64

OK Olvidé totalmente cómo omitir los argumentos en PHP.¿Cómo omitiría argumentos opcionales en una llamada a función?

Digamos que tengo:

function getData($name, $limit = '50', $page = '1') { 
    ... 
} 

¿cómo iba a llamar a esta función para que el parámetro media toma el valor por defecto (es decir, '50'.)?

getData('some name', '', '23'); 

¿Lo anterior sería correcto? Parece que no puedo hacer que esto funcione.

+1

@Chuck para lo ¿Estás buscando exactamente? ¿Como una solución alternativa o una clase para implementar esto o ...? – Rizier123

+0

@ Rizier123 Estoy preguntando si la versión actual de PHP soporta saltar argumentos (como en otros lenguajes). Las respuestas actuales pueden estar desactualizadas. De la descripción de la recompensa: "Las respuestas actuales tienen cinco años. ¿La versión actual de PHP cambia las cosas?" –

+1

@Chuck Entonces la respuesta será probablemente: que nada ha cambiado; sin una solución/código, no obtendrá su funcionalidad. – Rizier123

Respuesta

43

Tu publicación es correcta.

Desafortunadamente, si necesita usar un parámetro opcional al final de la lista de parámetros, debe especificar todo hasta ese último parámetro. En general, si desea mezclar y combinar, déles valores predeterminados de '' o null, y no los use dentro de la función si son ese valor predeterminado.

+0

¿Puedes dar un ejemplo? –

35

No hay forma de "omitir" un argumento que no sea especificar un valor predeterminado como false o null.

A partir de PHP carece de un poco de azúcar sintáctica cuando se trata de esto, a menudo se verá algo como esto:

checkbox_field(array(
    'name' => 'some name', 
    .... 
)); 

Lo cual, dicho tan elocuente en los comentarios, se usan matrices para emular argumentos con nombre.

Esto ofrece la máxima flexibilidad, pero puede no ser necesario en algunos casos. Por lo menos, puede mover lo que crea que no se espera la mayor parte del tiempo hasta el final de la lista de argumentos.

+1

Identificaría el 'algo así' como 'el uso de matrices para emular argumentos con nombre', FWIW. :) – chaos

+0

Blerg. Multa.;) –

+1

A pesar de ser más flexible, debe recordar los parámetros que debe/puede establecer (ya que no están en la firma). Por lo tanto, al final puede que no sea tan útil como parece, pero, por supuesto, esto depende del contexto. –

1

Para cualquier parámetro omitido (debe) ir con el parámetro predeterminado, para estar en el lado seguro.

(conformarse con nula donde el parámetro por defecto es '' o similar o vice versa te meterá en troublew ...)

27

No, no es posible omitir los argumentos de esta manera. Puede omitir los argumentos de paso solo si se encuentran al final de la lista de parámetros.

Hubo una propuesta oficial para esto: https://wiki.php.net/rfc/skipparams, que se rechazó. La página de la propuesta se vincula con otras preguntas sobre este tema.

+0

Entonces, ¿cómo tienen las funciones de PHP opciones de más/menos parámetros? –

+0

PHP tiene soporte para valores de parámetros predeterminados. Pero esos parámetros deben estar al final de la lista. – Cristik

+0

¿Puede proporcionar un ejemplo de código de esto? –

2

No puede omitir los argumentos, pero puede usar los parámetros de la matriz y debe definir solo 1 parámetro, que es una matriz de parámetros.

function myfunction($array_param) 
{ 
    echo $array_param['name']; 
    echo $array_param['age']; 
    ............. 
} 

Y se puede añadir tantos parámetros que necesita, no es necesario definirlos. Cuando llama a la función, coloca sus parámetros de esta manera:

myfunction(array("name" => "Bob","age" => "18", .........)); 
2

Como se mencionó anteriormente, no podrá omitir los parámetros. He escrito esta respuesta para proporcionar algún apéndice, que era demasiado grande para colocar en un comentario.

@Frank Nocke proposes para llamar a la función con sus parámetros por defecto, por lo que tienen por ejemplo

function a($b=0, $c=NULL, $d=''){ //... 

se debe utilizar

$var = a(0, NULL, 'ddd'); 

que funcionalmente ser la misma que la omisión de los dos primeros ($b y $c) parámetros.

No está claro cuáles son los valores predeterminados (es 0 tipeado para proporcionar el valor predeterminado, ¿o es importante?).

También existe el peligro de que el problema de los valores predeterminados esté conectado a la función externa (o incorporada), cuando los valores predeterminados podrían cambiarse por el autor de la función (o método). Entonces, si no cambia su llamada en el programa, podría cambiar su comportamiento sin intención.

Algunos solución alternativa podría ser la definición de algunas constantes globales, como DEFAULT_A_B que sería "valor por defecto del parámetro B de la función A" y "omitir" parámetros de esta manera:

$var = a(DEFAULT_A_B, DEFAULT_A_C, 'ddd'); 

Para las clases es más fácil y más elegante si define constantes de clase, porque son parte del alcance global, por ej.

class MyObjectClass { 
    const DEFAULT_A_B = 0; 

    function a($b = self::DEFAULT_A_B){ 
    // method body 
    } 
} 
$obj = new MyObjectClass(); 
$var = $obj->a(MyObjectClass::DEFAULT_A_B); //etc. 

Tenga en cuenta que esta constante predeterminado se define exactamente una vez en todo el código (no hay valor incluso en declaración de método), por lo que en caso de algunos cambios inesperados, siempre suministrar la función/método con el valor predeterminado correcto .

La claridad de esta solución es, por supuesto, mejor que el suministro de valores por defecto sin procesar (como NULL, 0 etc.) que no dicen nada a un lector.

(Estoy de acuerdo que llamar como $var = a(,,'ddd'); sería la mejor opción)

0

Bueno como todos los demás ya se ha dicho, que lo que quiere no será posible en PHP sin añadir ninguna línea de código en la función.

Pero se puede colocar este fragmento de código en la parte superior de una función para obtener su funcionalidad:

foreach((new ReflectionFunction(debug_backtrace()[0]["function"]))->getParameters() as $param) { 
    if(empty(${$param->getName()}) && $param->isOptional()) 
     ${$param->getName()} = $param->getDefaultValue(); 
} 

Así que, básicamente con debug_backtrace() consigo el nombre de la función en la que se coloca el código, a continuación, crear una nuevo objeto ReflectionFunction y repite todos los argumentos de función.

En el ciclo simplemente compruebo si el argumento de la función es empty() Y el argumento es "opcional" (significa que tiene un valor predeterminado). En caso afirmativo, simplemente asigno el valor predeterminado al argumento.

Demo

0

establecer el límite a null

function getData($name, $limit = null, $page = '1') { 
    ... 
} 

y llamar a esa función

getData('some name', null, '23'); 

si desea establecer el límite que puede pasar como argumento

getData('some name', 50, '23'); 
5

nada ha cambiado con respecto a ser capaz de saltar argumentos opcionales, sin embargo tienen una sintaxis correcta y ser capaz de especificar NULL para argumentos que quiero saltar, así es como yo lo haría:

define('DEFAULT_DATA_LIMIT', '50'); 
define('DEFAULT_DATA_PAGE', '1'); 

/** 
* getData 
* get a page of data 
* 
* Parameters: 
*  name - (required) the name of data to obtain 
*  limit - (optional) send NULL to get the default limit: 50 
*  page - (optional) send NULL to get the default page: 1 
* Returns: 
*  a page of data as an array 
*/ 

function getData($name, $limit = NULL, $page = NULL) { 
    $limit = ($limit==NULL) ? DEFAULT_DATA_LIMIT : $limit; 
    $page = ($page==NULL) ? DEFAULT_DATA_PAGE : $page; 
    ... 
} 

Esto puede el ser llamado así: getData('some name',NULL,'23'); y cualquiera que llame a la función en el futuro no necesita recordar los valores predeterminados cada vez o la constante declarada para ellos.

-5
getData('some name'); 

simplemente no pasan ellos y el valor por defecto será aceptado

-1

probar esto.

function getData($name, $limit = NULL, $page = '1') { 
       if (!$limit){ 
       $limit = 50; 
       } 
} 

getData('some name', '', '23'); 
-2

No puede omitir el parámetro del medio en su llamada a la función. Sin embargo, se puede evitar con esto:

function_call('1', '2', '3'); // Pass with parameter. 
function_call('1', null, '3'); // Pass without parameter. 

Función:

function function_call($a, $b='50', $c){ 
    if(isset($b)){ 
     echo $b; 
    } 
    else{ 
     echo '50'; 
    } 
} 
0

As advised earlier, nada cambió. Tenga cuidado, sin embargo, demasiados parámetros (especialmente los opcionales) es un fuerte indicador de olor a código.

Tal vez su función es hacer demasiado:

// first build context 
$dataFetcher->setPage(1); 
// $dataFetcher->setPageSize(50); // not used here 
// then do the job 
$dataFetcher->getData('some name'); 

Algunos parámetros pueden ser agrupados de forma lógica:

$pagination = new Pagination(1 /*, 50*/); 
getData('some name', $pagination); 
// Java coders will probably be familiar with this form: 
getData('some name', new Pagination(1)); 

En última instancia, siempre se puede introducir un grupo ad-hoc parameter object:

$param = new GetDataParameter(); 
$param->setPage(1); 
// $param->setPageSize(50); // not used here 
getData($param); 

(que es solo una versión glorificada de la menos formal parameter array technique)

A veces, el mismo motivo para hacer que un parámetro sea opcional es incorrecto. En este ejemplo, ¿está realmente previsto que $page sea opcional? ¿Salvar un par de personajes realmente hace la diferencia?

// dubious 
// it is not obvious at first sight that a parameterless call to "getData()" 
// returns only one page of data 
function getData($page = 1); 

// this makes more sense 
function log($message, $timestamp = null /* current time by default */); 
-2

Como @IbrahimLawal señaló. Lo mejor es simplemente configurarlos en los valores null. Simplemente verifique si el valor pasado es null en el que usa los valores predeterminados definidos.

<?php 
define('DEFAULT_LIMIT', 50); 
define('DEFAULT_PAGE', 1); 

function getData($name, $limit = null, $page = null) { 
    $limit = is_null($limit) ? DEFAULT_LIMIT : $limit; 
    $page = is_null($page) ? DEFAULT_PAGE : $page; 
    ... 
} 
?> 

Espero que esto ayude.

+0

Simplemente duplicó la respuesta. Más bien, podrías haber votado al alza o haber comentado sobre él. –

3

La respuesta simple es No. Pero, ¿por qué omitir al volver a organizar los argumentos logra esto?

El suyo es un "Uso incorrecto de los argumentos de la función por defecto" y no funcionará como esperaba.

Una nota al margen de la documentación de PHP:

Al utilizar argumentos por defecto, estos deben estar en el lado derecho de los argumentos no predeterminados; de lo contrario, las cosas no funcionarán como se espera.

considerar lo siguiente:

function getData($name, $limit = '50', $page = '1') { 
    return "Select * FROM books WHERE name = $name AND page = $page limit $limit"; 
} 

echo getData('some name', '', '23'); // won't work as expected 

la salida será:

"Select * FROM books WHERE name = some name AND page = 23 limit" 

el uso correcto de los argumentos de la función por defecto debería ser así:

function getData($name, $page = '1', $limit = '50') { 
    return "Select * FROM books WHERE name = $name AND page = $page limit $limit"; 
} 

echo getData('some name', '23'); // works as expected 

La salida será:

"Select * FROM books WHERE name = some name AND page = 23 limit 50" 

Poniendo el valor por defecto a la derecha después de que los no-valores por defecto se asegura de que siempre va a retun el valor por defecto para esa variable si no está definido/dada Aquí es un link para referencia y donde esos ejemplos provienen.

Editar: Establecerlo en null como otros sugieren que podría funcionar y es otra alternativa, pero puede que no sea lo que usted desea. Siempre establecerá el valor predeterminado en nulo si no está definido.

0

Este fragmento:

 

    function getData($name, $options) { 
     $default = array(
      'limit' => 50, 
      'page' => 2, 
     ); 
     $args = array_merge($default, $options); 
     print_r($args); 
    } 

    getData('foo', array()); 
    getData('foo', array('limit'=>2)); 
    getData('foo', array('limit'=>10, 'page'=>10)); 

respuesta es:

 

    Array 
    (
     [limit] => 50 
     [page] => 2 
    ) 
    Array 
    (
     [limit] => 2 
     [page] => 2 
    ) 
    Array 
    (
     [limit] => 10 
     [page] => 10 
    ) 

+2

Agradable. Pero una pequeña explicación sería útil. – showdev

+0

Buena respuesta, pero si desea omitir el parámetro opcional, hágalo de esta manera: function getData ($ name, $ args = array()) {$ defaults = array ('limit': => 50, 'page' => 2); $ args = array_merge ($ defaults, $ args); } Ahora es posible llamar a esta función con solo el primer parámetro como este: getData ('foo'); – EchoSin

0

Esto es lo que haría:

<?php 

    function getData($name, $limit = '', $page = '1') { 
      $limit = (EMPTY($limit)) ? 50 : $limit; 
      $output = "name=$name&limit=$limit&page=$page"; 
      return $output; 
    } 

    echo getData('table'); 

    /* output name=table&limit=50&page=1 */ 

    echo getData('table',20); 

    /* name=table&limit=20&page=1 */ 

    echo getData('table','',5); 

    /* output name=table&limit=50&page=5 */ 

    function getData2($name, $limit = NULL, $page = '1') { 
      $limit = (ISSET($limit)) ? $limit : 50; 
      $output = "name=$name&limit=$limit&page=$page"; 
      return $output; 
    } 

    echo getData2('table'); 

    // /* output name=table&limit=50&page=1 */ 

    echo getData2('table',20); 

    /* output name=table&limit=20&page=1 */ 

    echo getData2('table',NULL,3); 

    /* output name=table&limit=50&page=3 */ 

?> 

Esperamos que esto ayude a alguien

Cuestiones relacionadas