Foros del Web » Programando para Internet » PHP »

Recorrer un array dentro de un foreach

Estas en el tema de Recorrer un array dentro de un foreach en el foro de PHP en Foros del Web. Hola por aquí, tengo el siguiente problema. Tengo una función que me devuelve de la base de datos un array con una lista de usuarios ...
  #1 (permalink)  
Antiguo 06/11/2014, 12:25
Avatar de rogertm
Mod->Cuba
 
Fecha de Ingreso: julio-2005
Ubicación: /home/Cuba/Habana/rogertm/
Mensajes: 2.922
Antigüedad: 18 años, 8 meses
Puntos: 638
Pregunta Recorrer un array dentro de un foreach

Hola por aquí, tengo el siguiente problema. Tengo una función que me devuelve de la base de datos un array con una lista de usuarios que inicialmente tienen en su estado el status de Pendiente (pending), ahora, lo que quiero es que el encargado de estos usuarios les pueda cambiar el estado a Aprovado, Desaprovado o Pendiente, dependiendo del estado anterior.

Los datos de los usuarios que quiero cambiar los guardo en $request_users, supongo que el error está en el foreach dentro del foreach, pero ahora lo que sucede es que se actualiza solo el último elemento del array que viene por $_GET, y necesito que se actualizen todos...

Código PHP:
Ver original
  1. // Algo así es lo que tengo de la Base de Datos
  2. $notes = array(
  3.     'user_1'    => array(
  4.         'user'        => 1,
  5.         'status'    => 'pending',
  6.     ),
  7.     'user_2'    => array(
  8.         'user'        => 2,
  9.         'status'    => 'pending',
  10.     ),
  11.     'user_3'    => array(
  12.         'user'        => 3,
  13.         'status'    => 'pending',
  14.     ),
  15.     'user_4'    => array(
  16.         'user'        => 4,
  17.         'status'    => 'pending',
  18.     ),
  19.     'user_5'    => array(
  20.         'user'        => 5,
  21.         'status'    => 'pending',
  22.     ),
  23. );
  24.  
  25. $status         = ( isset( $_REQUEST['status'] ) ) ? $_REQUEST['status'] : null;
  26. $updated_users     = array();
  27. $request_users    = array();
  28. foreach ( $_REQUEST['user'] as $single_user ) :
  29.     array_push( $request_users, $single_user );
  30. endforeach;
  31. foreach ( $notes as $key => $value ) :
  32.     foreach ( $request_users as $single_user ) :
  33.         if ( $value['user'] == $single_user ) :
  34.             if ( $status == 'approved' || $status == 'pending' ) :
  35.                 $update_user = array(
  36.                     $key     => array(
  37.                         'user'        => $single_user,
  38.                         'status'    => $status,
  39.                     ),
  40.                 );
  41.             elseif ( $status == 'disapprove' ) :
  42.                 $update_user = array();
  43.             endif;
  44.         else :
  45.             $update_user = array(
  46.                 $key    => array(
  47.                     'user'        => $value['user'],
  48.                     'status'    => $value['status'],
  49.                 ),
  50.             );
  51.         endif;
  52.     endforeach;
  53.         $updated_users = array_merge( $updated_users, array_slice( $update_user, -1 ) );
  54. endforeach;

Como siempre agradezco cualquier ayuda que me puedan brindar.

Saludos!
__________________
Friki y Blogger por Cuenta Propia:213
Twenty'em: Theming is Prose
  #2 (permalink)  
Antiguo 06/11/2014, 16:01
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: Recorrer un array dentro de un foreach

Hace poco se me presentó un caso similar en el trabajo, en el cual, tenía un array que contenías arrays de información (un array asociativo), con la particularidad de que, cada array hijo, contenía la información de todos los registros a actualizar y no los tenías por separado, en otras palabras, tenía algo como esto:

Código PHP:
Ver original
  1.     'nombre' => Array( //Nombres
  2.         0 => 'Juan',
  3.         1 => 'Luis',
  4.         2 => 'José'
  5.     ),
  6.     'apellido' => Array( //Apellidos
  7.         0 => 'Pérez',
  8.         1 => 'Gonzáles',
  9.         2 => 'Gómez'
  10.     ),
  11.     'id' => Array( //IDs
  12.         0 => 25,
  13.         1 => 3,
  14.         2 => 159
  15.     ),
  16.     'usuario' => 123
  17. )

Y como hace un tiempo leí que ejecutar consultas SQL en un bucle con PHP no era muy eficiente que digamos, decidí utilizar la sintaxis CASE WHEN THEN END, que es así:

Código MySQL:
Ver original
  1. UPDATE tabla
  2.     nombre = CASE id
  3.         WHEN 25 THEN 'Juan'
  4.         WHEN 3 THEN 'Luis'
  5.         WHEN 159 THEN 'José'
  6.     END,
  7.     apellido = CASE id
  8.         WHEN 25 THEN 'Pérez'
  9.         WHEN 3 THEN 'Gonzáles'
  10.         WHEN 159 THEN 'Gómez'
  11.     END
  12. WHERE usuario = 123

De este modo, actualizo a los tres registros en los dos campos (nombre y apellido), siempre y cuando el usuario que esté realizando la edición, tenga por identificador el '123'.

Para formar la cadena de consulta con PHP, utilicé un bucle con el cual recorrí al primer hijo del bucle padre, excepto al último pues no es un array. Antes de esto, creé dos variables en las cuales iré concatenando los valores. En cada iteración, concateno en cada variable los valores, más o menos así:

Código PHP:
Ver original
  1. //Todos los datos fueron desinfectados antes de llegar a este punto y los extraje del array padre con la función extract()
  2. //El array con los nombres se llama $nombre y el de apellidos, $apellido
  3. $consulta = 'UPDATE tabla SET ';
  4. $nombres = 'nombre = CASE id ';
  5. $apellidos = 'END, apellido = CASE id ';
  6. $condicion = 'WHERE usuario = ' . $usuario;
  7. for ($i = 0, $l = count($nombre); $i < $l; $i++){
  8.     $nombres .= "WHEN " . $id[$i] . " THEN '" . $nombre[$i] . "' ";
  9.     $apellidos .= "WHEN " . $id[$i] . " THEN '" . $apellido[$i] . "' ";
  10. }
  11. $consulta .= $nombres . $apellidos . ' END ' . $condicion;
  12. mysqli_query($conexion, $consulta) or exit ('Se produjo un error');

Ojalá pueda serte de ayuda.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 07/11/2014 a las 06:27 Razón: Me faltaron las 'keys' de los arrays.
  #3 (permalink)  
Antiguo 06/11/2014, 17:33
 
Fecha de Ingreso: octubre-2014
Ubicación: Cancun
Mensajes: 80
Antigüedad: 9 años, 6 meses
Puntos: 4
Respuesta: Recorrer un array dentro de un foreach

por que no haces una consulta simple selecionado los eelemntos que tenga tal estado y cambiarlos de golpe?

bueno yo haria una consulta asi:

selecionar todos los elementos de la tabla Nombre donde estado sea igual a "Pendiente"

y ya con un mysql fetch array los recupero todos bueno eso haria yo
__________________
Inmobiliairia en cancun
  #4 (permalink)  
Antiguo 07/11/2014, 10:15
Avatar de rogertm
Mod->Cuba
 
Fecha de Ingreso: julio-2005
Ubicación: /home/Cuba/Habana/rogertm/
Mensajes: 2.922
Antigüedad: 18 años, 8 meses
Puntos: 638
Respuesta: Recorrer un array dentro de un foreach

A ver chicos, agradezco la ayuda, pero la cosa es básicamente de php, lo seguro es que no me expliqué bien antes.

Obtengo un array de la base de datos y lo que necesito es basándome en ese array, construir uno nuevo, y ese nuevo es el que inserto en la base de datos mediante una función.

El código es simple en la manera que lo planteo aquí, porque mi duda es pura de php, pero es un pedazo de código de una función de WordPress, osea, ya tengo la función que me da el array de la base de datos, y tengo otra que hace el update al registro.

En fin y básicamente lo que necesito es: por cada iteración que hago al array que viene de la BD, comparar cada usuario que viene por $_GET (el foreach dentro del foreach) y si es el mismo, pues actualizar su estado (status), una vez comparado todo, pues construyo un nuevo array y este es el que inserto en el registro... Pero ahora como está mi código, solo actualiza el último elemento del array que obtengo por $_GET...

Si ponen ese código en un archivo y acceden via web con una url del tipo ?user=1?user=2?user=3?status=approved y hacen un print_r($notes) y print_r($updated_users) se darán cuenta de lo que digo...

Quiero cambiar el estado a todos los usuarios que vienen por $_GET

Gracias nuevamente...
__________________
Friki y Blogger por Cuenta Propia:213
Twenty'em: Theming is Prose
  #5 (permalink)  
Antiguo 07/11/2014, 11:12
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: Recorrer un array dentro de un foreach

Fíjate que, en el ejemplo que te muestro, también utilizo un array asociativo y realizo actualizaciones según dos datos. En tu caso que solo deseas cambiar el estado, en lugar de formar dos grupos de casos, solo utilizarías uno.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 08/11/2014 a las 07:56 Razón: Corrección
  #6 (permalink)  
Antiguo 07/11/2014, 14:20
Avatar de IsaBelM
Colaborador
 
Fecha de Ingreso: junio-2008
Mensajes: 5.032
Antigüedad: 15 años, 10 meses
Puntos: 1012
Respuesta: Recorrer un array dentro de un foreach

es un problema de sobre-escritura. prueba ahora
Cita:
$status = ( isset( $_REQUEST['status'] ) ) ? $_REQUEST['status'] : null;
$updated_users = array();
$request_users = array();
foreach ( $_REQUEST['user'] as $single_user ) :
array_push( $request_users, $single_user );
endforeach;


foreach ( $notes as $key => $value ) :
for ($i = 0; $i < sizeof($request_users); $i++) :

if ( $value['user'] == $request_users[$i] ) :

if ( $status == 'approved' || $status == 'pending' ) :
$update_user = array(
$key => array(
'user' => $request_users[$i],
'status' => $status,
),
);
break;
elseif ( $status == 'disapprove' ) :
$update_user = array();
endif;
else :

$update_user = array(
$key => array(
'user' => $value['user'],
'status' => $value['status'],
),
);
endif;
endfor;
$updated_users = array_merge( $updated_users, array_slice( $update_user, -1 ) );
endforeach;
pd: Alexis88 me ha gustado la consulta desconectada
__________________
if(ViolenciaDeGénero) {alert('MUJER ASESINADA');}

Última edición por IsaBelM; 07/11/2014 a las 14:32
  #7 (permalink)  
Antiguo 11/11/2014, 09:51
Avatar de rogertm
Mod->Cuba
 
Fecha de Ingreso: julio-2005
Ubicación: /home/Cuba/Habana/rogertm/
Mensajes: 2.922
Antigüedad: 18 años, 8 meses
Puntos: 638
De acuerdo Respuesta: Recorrer un array dentro de un foreach

Bueno, debo agradecer, literalmente me han resuelto el problema...

Finalmente el código quedó así:
Código PHP:
Ver original
  1. $notes = array(
  2.     'user_1'    => array(
  3.         'user'        => 1,
  4.         'status'    => 'pending',
  5.     ),
  6.     'user_22'    => array(
  7.         'user'        => 22,
  8.         'status'    => 'pending',
  9.     ),
  10.     'user_13'    => array(
  11.         'user'        => 13,
  12.         'status'    => 'pending',
  13.     ),
  14.     'user_4'    => array(
  15.         'user'        => 4,
  16.         'status'    => 'pending',
  17.     ),
  18.     'user_512'    => array(
  19.         'user'        => 512,
  20.         'status'    => 'pending',
  21.     ),
  22. );
  23.  
  24. $status         = ( isset( $_REQUEST['status'] ) ) ? $_REQUEST['status'] : null;
  25. $updated_users     = array();
  26. foreach ( $notes as $key => $value ) :
  27.     for ($i = 0; $i < count($_REQUEST['user']); $i++) :
  28.         if ( $value['user'] == $_REQUEST['user'][$i] ) :
  29.             if ( $status == 'approved' || $status == 'pending' ) :
  30.                 $update_user = array(
  31.                     $key     => array(
  32.                         'user'        => $_REQUEST['user'][$i],
  33.                         'status'    => $status,
  34.                     ),
  35.                 );
  36.             elseif ( $status == 'disapprove' ) :
  37.                 $update_user = array();
  38.             endif;
  39.             break;
  40.         else :
  41.             $update_user = array(
  42.                 $key    => array(
  43.                     'user'        => $value['user'],
  44.                     'status'    => $value['status'],
  45.                 ),
  46.             );
  47.         endif;
  48.     endfor;
  49.         $updated_users = array_merge( $updated_users, array_slice( $update_user, -1 ) );
  50. endforeach;
Cambié la función sizeof() por count() por una cuestión pura de manía, y cambié el break al final de la sentencia if... pues si el estado es disapprove debo eliminar el usuario del registro en la BD

Para ampliar un poquito, y matar la curiocidad de quien la padezca, cuando me pasan este tipo de cosas trabajando con WP, trato de simplificar el código y lo trabajo en un archivo php simple y sato, que es lo que he mostrado aquí, pero también les traigo la función original, por si hace algún bien a alguien
Código PHP:
Ver original
  1. function humi_mentor_update_multi_supported_users(){
  2.     $status            = ( isset( $_REQUEST['status'] ) ) ? $_REQUEST['status'] : null;
  3.     $current_users    = get_user_meta( get_current_user_id(), 'humi_mentor_supported_users', true );
  4.     $updated_users    = array();
  5.  
  6.     // Check for multi user update
  7.     $multi_nonce    = ( isset( $_REQUEST['update_bulk_users_field'] ) ) ? $_REQUEST['update_bulk_users_field'] : null;
  8.     if ( ! wp_verify_nonce( $multi_nonce, 'update_bulk_users_attr' ) ) return;
  9.  
  10.     if ( wp_verify_nonce( $multi_nonce, 'update_bulk_users_attr' ) ) :
  11.         // Check if there is something to do
  12.         if ( $status == 'null' ) :
  13.             $redirect = apply_filters( 'humi_mentor_update_supported_users_fail', add_query_arg( array( 'update-multi-user' => 'false' ), get_permalink() ) );
  14.             wp_safe_redirect( $redirect );
  15.             exit();
  16.         endif;
  17.         foreach ( $current_users as $key => $value ) :
  18.             for ( $i = 0; $i < count( $_REQUEST['user'] ); $i++ ) :
  19.                 if ( $value['user'] == $_REQUEST['user'][$i] ) :
  20.                     if ( $status == 'approved' || $status == 'pending' ) :
  21.                         $update_user = array(
  22.                             $key     => array(
  23.                                 'user'        => $_REQUEST['user'][$i],
  24.                                 'status'    => $status,
  25.                             ),
  26.                         );
  27.                     elseif ( $status == 'disapprove' ) :
  28.                         $update_user = array();
  29.                         delete_user_meta( $value['user'], 'humi_user_mentor' );
  30.                     endif;
  31.                     break;
  32.                 else :
  33.                     $update_user = array(
  34.                         $key    => array(
  35.                             'user'        => $value['user'],
  36.                             'status'    => $value['status'],
  37.                         ),
  38.                     );
  39.                 endif;
  40.             endfor;
  41.             $updated_users = array_merge( $updated_users, array_slice( $update_user, -1 ) );
  42.         endforeach;
  43.         update_user_meta( get_current_user_id(), 'humi_mentor_supported_users', $updated_users );
  44.  
  45.         $redirect = apply_filters( 'humi_mentor_update_supported_users_success', add_query_arg( array( 'update-multi-user' => 'true' ), get_permalink() ) );
  46.         wp_safe_redirect( $redirect );
  47.         exit();
  48.     endif;
  49. }
  50. add_action( 'template_redirect', 'humi_mentor_update_multi_supported_users' );

Gracias nuevamente por la ayuda y la prontitud...
__________________
Friki y Blogger por Cuenta Propia:213
Twenty'em: Theming is Prose

Etiquetas: foreach, usuarios
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 15:45.