2009-09-25 17 views
7

Estoy seguro de que hay algo mejor en esto. Cualquier ayuda será apreciada.Argumentos de funciones opcionales de PHP con matriz. ¿Cómo codificar/Mejor forma de codificar?

Quiero pasar una matriz a una función php que contiene el argumento y todos los argumentos son opcionales. Estoy usando el código de encendido y de ninguna manera soy un experto. Debajo está lo que he estado usando hasta ahora:

function addLinkPost($postDetailArray) { 

    if (isset($postDetailArray['title'])) { 
     $title = $postDetailArray['title']; } 
    else { 
     $title = "Error: No Title"; 
    } 

    if (isset($postDetailArray['url'])) { 
     $url  = $postDetailArray['url']; 
    } else { 
     $url  = "no url"; 
    } 
    if (isset($postDetailArray['caption'])) { 
     $caption = $postDetailArray['caption']; 
    } else { 
     $caption = ""; 
    } 
    if (isset($postDetailArray['publish'])) { 
     $publish = $postDetailArray['publish']; 
    } else { 
     $publish = TRUE; 
    } 
    if (isset($postDetailArray['postdate'])) { 
     $postdate = $postDetailArray['postdate']; 
    } else { 
     $postdate = "NOW()"; 
    } 
    if (isset($postDetailArray['tagString'])) { 
     $tagString = $postDetailArray['tagString']; 
    } else { 
     $tagString = ""; 
    } 

Respuesta

10

Se podía hacerlo de esta manera:

function addLinkPost(array $postDetailArray) 
{ 
    $fields = array(
     'key' => 'default value', 
     'title' => 'Error: No Title', 
    ); 

    foreach ($fields as $key => $default) { 
     $$key = isset($postDetailArray[$key]) ? $postDetailArray[$key] : $default; 
    } 
} 

Simplemente edita el array $ campos con su clave y su valor por defecto.

+0

Debe ser un poco cuidadoso haciendo cosas como esta, especialmente si los datos son proporcionados por el usuario, porque es similar a register_globals. –

+0

@Tom Aunque personalmente lo implementaría usando una matriz para almacenar los valores en oposición a la función de ámbito de variable local que usó en su pregunta y utilicé en mi respuesta, podría implementar una comprobación rápida en el ciclo foreach para ignorar cualquier claves suministradas que no están en la matriz $ fields – Inspire

+0

En realidad, pensándolo bien, mi ejemplo itera sobre la matriz de $ fields en lugar de $ postDetailArray, por lo que la verificación de la clave no sería necesaria. – Inspire

0

pienso que el ejemplo está bien. No creo que haya mucho más optimización que hacer aquí, excepto tal vez dejando algunos corchetes.

opcionalmente, se puede comprobar la función extracto en PHP

0

¿Qué tal:

function getdefault($value, $default = null) { 
    return isset($value) ? $value : $default; 
} 

function addLinkPost($postDetailArray) { 
    $title = getdefault($postDetailArray['title'], 'Error: No Title'); 
    $url = getdefault($postDetailArray['url'], 'no url'); 
    $caption = getdefault($postDetailArray['caption'], ''); 
    $publish = getdefault($postDetailArray['publish'], TRUE); 
    $postdate = getdefault($postDetailArray['postdate'], 'NOW()'); 
    $tagString = getdefault($postDetailArray['tagString'], ''); 
} 

o alternativamente:

$defaults = array(
    'title' => 'Error: No Title', 
    'url' => 'no url', 
    'caption' => '', 
    'publish' => TRUE, 
    'postdate' => 'NOW()', 
    'tagString' => '', 
); 

function addLinkPost($postDetailArray) { 
    global $defaults; 
    foreach ($defaults as $k => $v) { 
    $$k = isset($postDetailArray[$k]) ? $postDetailArray[$k] : $v; 
    } 
} 

Con la advertencia de que si tiene una clave de selección de ' predeterminado 'en $defaults, sobrescribirá el $defaults global.

+0

Eso ('$ postDetailArray [ 'titulo'] ') podría emitir un aviso. –

4

Usar el conjunto como argumento es una buena idea en este caso. Sin embargo, puede simplificar un poco el código en la función utilizando el operador ternario (http://dk.php.net/ternary):

$ title = isset ($ postDetailArray ['title'])? $ postDetailArray ['title']: 'Error: sin título';

Usted podría simplificar aún más haciendo lo siguiente:

function addLinkPost($data) { 

$arguments = array('title', 'url', 'caption', 'publish', 'postdate', 'tagString'); 

foreach ($arguments as $value) { 
    $$value = isset($data[$value]) ? $data[$value] : 'Error: No '.$value; 
} 

}

+0

Acabo de darme cuenta de que no debería ser 'Error: No ...' para todas las opciones, pero aún así ... Ya entendiste la idea. – Jonas

0

Prueba esto:

function addLinkPost($postDetailArray) { 

    foreach($array as $key=>$value){ 
    $$key = (isset($value) && !empty($value)) ? $value : ('no '.$key); 
    } 
    //all keys are available as variables 
    var_dump($url); var_dump($publish); //etc 
} 
0

usted podría hacer todos los elementos de los parámetros de matriz de la función. Compruebe si el primero es una matriz en la función y, si es así, extraiga la matriz.

function addLinkPost($title = null, $url = null, $caption = null, $publish = null, $postDate = null, $tagString = null) 
{ 
     if(is_array($title)) { 
      extract($title); 
     } 

     .... 
} 

Quizás eso hace que el código sea un poco más claro.

27

Puede usar una matriz de valores predeterminados y luego fusionar la matriz de argumentos con los valores predeterminados. Los valores predeterminados se anularán si aparecen en la matriz de argumentos. Un ejemplo sencillo:

$defaults = array(
    'foo' => 'aaa', 
    'bar' => 'bbb', 
    'baz' => 'ccc', 
); 

$options = array(
    'foo' => 'ddd', 
); 


$merged = array_merge($defaults, $options); 

print_r($merged); 

/* 

Array 
(
    [foo] => ddd 
    [bar] => bbb 
    [baz] => ccc 
) 

*/ 

En su caso, que sería:

function addLinkPost($postDetailArray) { 
    static $defaults = array(
     'title'  => 'Error: No Title', 
     'url'  => 'no url', 
     'caption' => '', 
     'publish' => true, 
     'postdate' => 'NOW()', 
     'tagString' => '', 
    ); 

    $merged = array_merge($defaults, $postDetailArray); 

    $title  = $merged['title']; 
    $url  = $merged['url']; 
    $caption = $merged['caption']; 
    $publish = $merged['publish']; 
    $postdate = $merged['postdate']; 
    $tagString = $merged['$tagString']; 
} 
+0

Esta es la manera de hacerlo. Obtiene el resultado deseado y obtiene un resumen muy legible de cuáles son los valores predeterminados. Básicamente, es dejar que PHP lo haga por usted en lugar de hacerlo usted mismo. PHP proporciona tantas maravillosas funciones de matriz que aborrezco el bucle sobre una matriz: cada vez que veo un bucle en una matriz, huelo algo que probablemente pueda ser reemplazado por funciones de matriz nativa. – grantwparks

+0

Estoy de acuerdo - esta es de lejos la forma más fácil de hacerlo. Menos LOC no siempre es mejor. – calumbrodie

+0

Elegante! Sin embargo, tenga en cuenta que no es estrictamente necesario el uso de una matriz "fusionada" separada. Agrego lo siguiente como una mejora adicional a mi código existente: $ argsR = array_merge ($ defaultsR, $ argsR; ($ argsR es la matriz de argumentos de función existente pasada y procesada por la función existente). –

Cuestiones relacionadas