Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] continue y/o brake en foreach

Estas en el tema de continue y/o brake en foreach en el foro de PHP en Foros del Web. Hola compañeros, hace tiempo que no me toca preguntar. Veamos, hasta ahora he utilizado la función continue o brake para saltar un elemento dentro de ...
  #1 (permalink)  
Antiguo 06/07/2017, 09:17
Avatar de ArturoGallegos
Moderador
 
Fecha de Ingreso: febrero-2008
Ubicación: Morelia, México
Mensajes: 6.774
Antigüedad: 16 años, 2 meses
Puntos: 1146
continue y/o brake en foreach

Hola compañeros, hace tiempo que no me toca preguntar.


Veamos, hasta ahora he utilizado la función continue o brake para saltar un elemento dentro de un bucle,



tipo

Código PHP:
Ver original
  1. foreach ($xxx as $value) {
  2.       if($value == 'xxxx'){
  3.         continue;
  4.       }
  5.       // aqui mis acciones para el caso contrario
  6.     }


Mi problema viene en que necesito hacer un foreach (o cualquier otra función recursiva) para llamar a una función que evalué el valor enviado.
por ejemplo:


Código PHP:
Ver original
  1. public function evalXXX($valor){
  2.     if($valor == 'xxxx'){
  3.       continue;
  4.     }
  5.     // aquí mis acciones
  6.   }
  7.   public function xxx(){
  8.     foreach ($xxx as $value) {
  9.       $this->evalXXX($value);
  10.     }
  11.   }


Y como resultado me produce un error ya que continue no se puede utilizar de esa forma dentro de una función.


Estoy utilizando PHP 7.1 , alguien conoce alguna alternativa para hacer que el bucle se salte ese item y pase a la siguiente evaluación.

Última edición por ArturoGallegos; 06/07/2017 a las 09:38
  #2 (permalink)  
Antiguo 06/07/2017, 09:28
alvaro_trewhela
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: continue y/o brake en foreach

Antes que nada el signo igual (=) es de asignación, el doble signo igual (==) es de comparación, cabe destacar que tanto break y continue no son funciones, son sentencias, en cuanto a la tuyo no te compliques la vida:



Código PHP:
Ver original
  1. foreach ($xxx as $value) {
  2.     if($value != "xxxx"){
  3.     // aqui mis acciones
  4.     }
  5. }

Saludos.
  #3 (permalink)  
Antiguo 06/07/2017, 09:36
Avatar de ArturoGallegos
Moderador
 
Fecha de Ingreso: febrero-2008
Ubicación: Morelia, México
Mensajes: 6.774
Antigüedad: 16 años, 2 meses
Puntos: 1146
Respuesta: continue y/o brake en foreach

jaja sorry, fue un ejemplo elaborado al momento ahorita lo corrijo, fuera de eso el problema va mas aya de eso... ya que el valor no lo puedo evaluar directamente en el foreach

la función que se manda llamar hace una consulta sql que es procesada para obtener mas datos y en base a estos decidir si saltarse el elemento o continuar al procesamiento de lo obtenido.

Aunque vaya al contradicción, el interés de saltarme el item desde esa función no es porque no pueda hacerlo directamente en el foreach, sino para evitar duplicar código, que es el fin de usar POO en el proyecto.

En todo caso tienes razón para salir del paso duplicare código para hacer una validación previa a llamar la función, pero sera una chapuza ya que no debería.

Si alguien mas tiene otra idea se agradece.
  #4 (permalink)  
Antiguo 06/07/2017, 12:44
alvaro_trewhela
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: continue y/o brake en foreach

A lo que voy yo es que

Código PHP:
Ver original
  1. public function evalXXX($valor){
  2.     if($valor == 'xxxx'){
  3.     continue;
  4.     }
  5. // aquí mis acciones
  6. }

Es equivalente a

Código PHP:
Ver original
  1. public function evalXXX($valor){
  2.     if($valor != "xxxx"){
  3.     // aquí mis acciones
  4.     }
  5. }

Saludos
  #5 (permalink)  
Antiguo 06/07/2017, 15:08
 
Fecha de Ingreso: octubre-2010
Ubicación: España
Mensajes: 1.007
Antigüedad: 13 años, 6 meses
Puntos: 123
Respuesta: continue y/o brake en foreach

Por que no hacer que la funcion retorne un boleano para evaluar si se continua o no con el ciclo


Código PHP:
function evalXXX($valor)
{
    if(
$valor == 'xxxx')
    {
        return 
true;
    }
    else
    {
        return 
false;
    }
}

foreach (
$xxx as $value)
{
        if( 
evalXXX($value) )
        {
            continue;
        }
 } 
__________________
Unset($vida['malRollo']);

Última edición por xerifandtomas; 06/07/2017 a las 15:18
  #6 (permalink)  
Antiguo 06/07/2017, 23:38
Avatar de ArturoGallegos
Moderador
 
Fecha de Ingreso: febrero-2008
Ubicación: Morelia, México
Mensajes: 6.774
Antigüedad: 16 años, 2 meses
Puntos: 1146
Respuesta: continue y/o brake en foreach

@xerifandtomas tienes toda toda la razón, un return me detiene todo el ciclo, lo descarte en su momento porque extrañamente un scope que utilizo en laravel mediante terminal al retornar null o false me retorna un bucle que me saturaba la memoria.

Pero después de tantas vueltas caí en cuenta que no tiene porque ser false o null, le retorne un -1 y me funciona.


@alvaro_trewhela entiendo tu punto y tienes toda la razón, para el ejemplo expuesto funciona y es valido, creo que minimice demasiado el caso y el ejemplo, debiendo explicar que usaba laravel y sus scope mediante cronjobs.

Por si a alguien le sirve, al ejecutar un cronjob en laravel (5.4) para enviar correos tenia esto

Scope: aquí es donde no podía retornar null, false o 0 porque entra en un bucle muy extenso que satura la memoria del servidor. y al utilizar continue o break arrojaba un error que detenía todo.
PHP Fatal error: 'continue' not in the 'loop' or 'switch' context in
Código PHP:
Ver original
  1. public function scopeTemplate($query, $type, $version, $data){
  2.         $result = $query->where('type', $type)->where('version', $version)->first();
  3.         if(is_null($result)){
  4. // este return es el que no me dejaba avanzar
  5.             return -1;
  6.         }
  7.  
  8.         $parsed = preg_replace_callback('/{{(.*?)}}/', function ($matches) use ($data) {
  9.             list($shortCode, $index) = $matches;
  10.             if( isset($data[trim($index)]) ) {
  11.                 return $data[trim($index)];
  12.             } else {
  13.                 throw new Exception("Shortcode {$shortCode} not found in template", 1);
  14.             }
  15.  
  16.         }, $result->template);
  17.  
  18.         return ['content' => $parsed, 'from' => $result->from, 'from_name' => $result->from_name, 'subject' => $result->subject];
  19.     }


y este es el controlador que lo llama:
Código PHP:
Ver original
  1. public function SendEmail($type, $version, $data){
  2.         $datos = User::where('id', $data['xxxx'])->first();
  3.         $xxxx_data = array(
  4.             'xxx_nombre' => $datos ->name,
  5.             'xxx_info' => $datos->firma
  6.         );
  7.         $email_data = emails_template::Template($type, $version, array_merge($data, $xxxx_data));
  8.         if($email_data == -1){
  9.             return false;
  10.         }
  11.        
  12.         Mail::send([], [], function($message) use ($email_data, $data)
  13.         {
  14.             $message
  15.                 ->to('xxxxx', 'xxxx')
  16.                 ->from('xxxxx', 'xxxx')
  17.                 ->subject($email_data['subject'])
  18.                 ->setBody($email_data['content'], 'text/html');
  19.         });
  20.     }

Dado que el scope entraba en un bucle, al validar $email_data no conseguía una respuesta o bien contenía los datos producidos durante el bucle, que no tenían relación con el valor esperado.... cualquiera que fuera el caso continuaba hasta llegar a la función Mail que hacia tronar todo el sistema de envió, de un controlador principal arriba de este.
  #7 (permalink)  
Antiguo 07/07/2017, 08:37
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: continue y/o brake en foreach

Solo como nota al margen el problema pudo haberse evitado si en lugar de hacer la condición hubieras dejado que se generará la excepción usando firstOrFail en lugar de first, de esa forma esto
Código PHP:
Ver original
  1. $result = $query->where('type', $type)->where('version', $version)->first();
  2.         if(is_null($result)){
  3. // este return es el que no me dejaba avanzar
  4.             return -1;
  5.         }
Hubiera quedado como
Código PHP:
Ver original
  1. $result = $query->where('type', $type)->where('version', $version)->firstOrFail();
si no te regresa ningún valor se genera una excepción del tipo ModelNotFoundException y no requiere el if dentro de la función ni el if que tienes en el controlador el cual desaparece y solo queda la llamada a la consulta
Código PHP:
Ver original
  1. $email_data = emails_template::Template($type, $version, array_merge($data, $xxxx_data));
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.

Etiquetas: foreach
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:36.