2010-09-28 9 views
6

Estoy construyendo un sitio web que contiene usuarios con perfiles de usuario. Muchos de los campos en el perfil son opcionales.¿Qué es una solución más elegante a estas declaraciones if/elseif anidadas?

Existe una gran cantidad de contenido generado por los usuarios, por lo que debo mostrar el autor de este contenido en diferentes ubicaciones del sitio (comentarios, publicaciones, etc.). En el perfil del usuario, puede (opcionalmente) completar su "nombre", su "apellido" y un "nombre para mostrar".

Para mostrar el autor, escribí un método de ayuda que se ve a través de una matriz provista de estos campos y devuelve el nombre más adecuado para el usuario, en este orden de preferencia:

  1. Si el usuario llenada display_name, esto se mostrará.
  2. Si el usuario llenada first_name y last_name, pero sin display_name, mostrará los dos nombres
  3. Si el usuario sólo llenada first_name, se mostrará first_name.
  4. Si el usuario solo completó last_name, mostrará last_name.
  5. Si todo lo demás falla, un identificador de usuario se mostrará es decir user123
  6. Si ninguna de las claves de matriz están presentes, o el parámetro es NULL, el nombre se mostrará como NULL

El método funciona muy bien , pero es feo Debe haber una manera de embellecer esto con una alternativa a las declaraciones if/else anidadas.

public function nameify($names = NULL) { 
    $name = ''; 
    if (!empty($names)) { 
     if (!empty($names['display_name'])) { 
      $name = $names['display_name']; 
     } elseif (!empty($names['first_name'])) { 
      $name = $names['first_name']; 
      if (!empty($names['last_name'])) { 
       $name .= ' ' . $names['last_name']; 
      } 
     } elseif (!empty($names['last_name'])) { 
      $name = $names['last_name']; 
     } 

     if (empty($name) && !empty($names['id'])) { 
      $name = 'user' . $names['id']; 
     } else { 
      $name = 'NULL'; 
     } 
    } else { 
     $name = 'NULL'; 
    } 
    return $name; 
} 
+3

Sólo mal uso de 'operador return'. Se puede llamar no solo al final de la función sino a cualquier parte. Y * terminará la ejecución adicional *. Al igual que 'goto' hace. Vea la respuesta de x3ro para el ejemplo –

Respuesta

6
public function nameify($names = NULL) { 
    if ($names) { 
     if (!empty($names['display_name'])) { 
      return $names['display_name']; 
     } 
     if (!empty($names['first_name'])) { 
      $name = $names['first_name']; 
     } 
     if (!empty($names['last_name'])) { 
      $name .= ' ' . $names['last_name']; 
     } 
     if (empty($name) && !empty($names['id'])) { 
      $name = 'user' . $names['id']; 
     } 
    } 
    return $name ? ltrim($name) : 'NULL'; 
} 

Establecer el valor por defecto en primer lugar, y volver que si nada más partidos. Entonces, dado que siempre queremos devolver el nombre para mostrar si lo tenemos, hagamos eso.

EDIT: Tweak para evitar volver "NULO"

+0

Esto se ve muy legible. Me gusta. – Stephen

+0

No realice pruebas para obtener resultados positivos y luego continúe dentro de la declaración if, pero pruebe los "errores" y vuelva si aparecen. De esa forma, reduces la complejidad y la sangría. – fresskoma

+0

@ x3ro en su propia respuesta, comenzó siguiendo sus consejos, pero el segundo condicional hace exactamente lo que usted dice que no debe hacer. – Stephen

0

No es mucho, pero porque el nombre $ es al menos NULL:

public function nameify($names = NULL) { 
    $name = 'NULL'; 
    if (!empty($names)) { 
     if (!empty($names['display_name'])) { 
      $name = $names['display_name']; 
     } elseif (!empty($names['first_name'])) { 
      $name = $names['first_name']; 
      if (!empty($names['last_name'])) { 
       $name .= ' ' . $names['last_name']; 
      } 
     } elseif (!empty($names['last_name'])) { 
      $name = $names['last_name']; 
     } 

     if ($name=='NULL' && !empty($names['id'])) { 
      $name = 'user' . $names['id']; 
     } 
    } 
    return $name; 
} 
0

me gustaría ir con:

if(empty($names['display_name'])) { 
    $name = $names['first_name'] . ' ' $names['last_name']; 
else 
    $name = $names['display_name']; 

$name = trim($name); 
if(empty($name)) 
    $name = 'user'.$names['id']; 
if(empty($name)) 
    $name = 'NULL'; 

Ésta sería la 'lógica de la base' ... tendrá que haber otros controles como $names != NULL o algo ..

+0

nice .............. – Stewie

+1

Creo que quiere decir 'empty' y no'! Empty' en la línea uno. – Stephen

+0

@Stephen, lo tienes. Editaré Por favor, siéntase libre de editar las respuestas de los demás. – jrharshath

2

Usando condiciones ternarias podemos acortar un d embellecer el código:

public function nameify($names = NULL) { 
    $name = 'NULL'; 

    if (!empty($names)) { 

     $name = ($names['display_name']) ? $names['display_name'] : trim($names['first_name']." ".$names['last_name']); 

     if(!$name) $name = ($names['id'] > 0) ? 'user'.$names['id'] : 'NULL'; 
    } 

    return $name; 
} 
+0

No lo creo. Tengo advertencias y no obtengo nada. Simplemente lo verá como un valor nulo –

+0

Vaya. Quise decir un aviso. esto es de la documentación php 'Intentar acceder a una clave de matriz que no se ha definido es lo mismo que acceder a cualquier otra variable indefinida: se emitirá un mensaje de error de nivel E_NOTICE, y el resultado será NULL. – Stephen

+0

Ah, sí. Tengo mi nivel de error configurado para ignorar avisos. Dado que el resultado esperado es un NULL, el aviso es simplemente informativo y no causará ningún problema (a menos que tenga activados los avisos que normalmente no se producirían en un entorno de producción) –

0
//pointers to functions 
$arrayOfSulutions{"display_name_strategy", "full_name_strategy" ..., "null_strategy" } 
function display_name_strategy{ 
    return $names['display_name']; 
} 
$i = 0; 
while($res == null){ 
    $res = call($arrayOfSulutions[$i++]); 
} 
+0

@Stephen: Esta es la solución del mundo de Java) –

+0

-1 Por dos motivos: complejidad máxima (== tiempo máximo de depuración) y rendimiento mínimo (call_user_func es extremadamente lento en PHP) – fresskoma

+0

@ x3ro: rendimiento mínimo - sí. complejidad - no. Flexibilidad, ¡sí! –

0

Algo menos legible, pero eficaz):

list($idx,$name) = array_shift(array_filter(array(
    $names['display_name'], 
    implode(' ',array_filter(array($names['first_name'],$names['last_name']))), 
    'user'.$names['id']; 
    ))); 
+0

-1 "Algo menos legible" ... En serio, ¿quién va a depurar algo así ... Es por eso que odio PHP ... – fresskoma

+0

Por favor, no malinterprete mi comentario, es una idea clara, es solo nada que nadie deba usar en producción a menos que haya otra forma de hacerlo;) – fresskoma

+0

Bah, me encanta.Podría hacerse más legible, pero este es un bello ejemplo de algunas de las partes ocultas de php. –

1

propongo esto:

 
public function nameify($names = null) { 
    if(empty($names)) 
     return null; 

    if(!empty($names['display_name'])) 
     return $names['display_name']; 

    if(!empty($names['first_name'])) { 
     $name = $names['first_name']; 
     if (!empty($names['last_name'])) { 
      $name .= ' ' . $names['last_name']; 
     } 
     return $name; 
    } 

    if(!empty($names['id])) 
     return 'user' . $names['id']; 

    return null; 
} 
0

A State machine funciona muy bien para lógica involucrada como esa. Es muy simple de implementar también (usando una instrucción switch).

+0

¿Tiene un ejemplo de cómo implementar esta abstracción para mi problema? Incluso si está en un pseudo código, me gustaría verlo. – Stephen

+0

Secundado, me gustaría ver el código para esto. –

+0

Aunque he aceptado la respuesta de Chuck Vose, todavía estoy interesado en esta. – Stephen

0

No estoy seguro de que mi versión sería más simple, pero aquí está:

public function nameify($names = null) { 
    $result = array(); 

    if(!empty($names['display_name'])) { 
     array_push($result,$names['display_name']); 
    } else { 
     if(!empty($names['first_name'])) { 
      array_push($result, $names['first_name']); 
     } 
     if(!empty($names['last_name'])) { 
      array_push($result, $names['last_name']); 
     } 
    } 

    if(empty($result) && !empty($names['id'])) { 
     array_push($result, 'user'.$names['id']); 
    } 

    return (empty($result) ? 'NULL' : implode(' ', $result)); 
} 
Cuestiones relacionadas