Foros del Web » Programando para Internet » PHP »

ejecutar una funcion dentro de otra

Estas en el tema de ejecutar una funcion dentro de otra en el foro de PHP en Foros del Web. Hola a todos, no se si el titulo va a corde con lo que necesito pero espero explicarme bien, estoy ingresando a dos tablas relacionadas ...
  #1 (permalink)  
Antiguo 15/03/2018, 17:24
 
Fecha de Ingreso: octubre-2011
Mensajes: 132
Antigüedad: 13 años, 2 meses
Puntos: 4
ejecutar una funcion dentro de otra

Hola a todos, no se si el titulo va a corde con lo que necesito pero espero explicarme bien, estoy ingresando a dos tablas relacionadas ciertos registros, pero en la segunda tabla se pueden ingresar 1, 2, 3 o mas registros a la ves, aca un ejemplo de lo que tengo me funciona pero en dos funciones diferentes sin ningun problema:

en mi controlador tengo esto
Código PHP:
Ver original
  1. public funcion nuevo()
  2. {
  3. //codigo ...
  4.  
  5. $fecha_enc = date('Y-m-d', strtotime($_POST['fecha_enc']));
  6.  
  7.             $this->_encuestas->registrarEncuesta(
  8.             $this->getPostParam('titulo'),
  9.             $this->getPostParam('cargo'),
  10.             $this->getPostParam('departamento'),
  11.             $this->getPostParam('provincia'),
  12.             $this->getPostParam('distrito'),
  13.             $fecha_enc);
  14.  
  15.             $num = count($this->_encuestas->getCandidatosCount());
  16.             // var_dump($num);
  17.              for ($i=0; $i<$num; $i++) {
  18.                 $this->_encuestas->insertOpcionesEncuesta(
  19.                     $_POST['candidato'][$i]
  20.                 );
  21.             }
  22. }

y en el modelo:

Código PHP:
Ver original
  1. public function registrarEncuesta($titulo, $cargo, $departamento, $provincia, $distrito, $fecha_enc)
  2.     {
  3.         $this->_db->prepare("INSERT INTO encuestas (id, titulo, id_cargo, id_pais, id_departamento, id_provincia, id_distrito, fecha_encuesta, fecha_registro, usuario_registrador) VALUES (null, :titulo, :cargo, 1, :departamento, :provincia, :distrito, :fecha_enc, now(), '" . Session::get('id_usuario') . "')"
  4.         )->execute(array(
  5.             ':titulo'           => $titulo,
  6.             ':cargo'            => $cargo,
  7.             ':departamento'     => $departamento,
  8.             ':provincia'        => $provincia,
  9.             ':distrito'         => $distrito,
  10.             ':fecha_enc'        => $fecha_enc)
  11.         );
  12.  
  13.     public function insertOpcionesEncuesta($id_candidato){
  14.         $sql = "SELECT MAX(id) AS id FROM encuestas LIMIT 1";
  15.         $query = $this->_db->prepare($sql);
  16.         $query->execute();
  17.         $row = $query->fetch();
  18.         $sql = "INSERT INTO opciones (id, id_encuesta, id_candidato) VALUES (null, :id_encuesta, :id_candidato)";
  19.         $statement = $this->_db->prepare($sql);
  20.         $statement->execute(array(
  21.             ':id_encuesta'   => $row['id'],
  22.             ':id_candidato'  => $id_candidato
  23.         ));
  24.     }

con esto me funciona perfecto pero que pasa si no registra la primera funcion la segfunda me ingresaria con el id del ultimo registro de la primera tabla ya registrada antes, por lo que necesito saber como ejecutar la segunda consulta si y solo si la primera se ejecuto correctamente, esto meterlo talvez en una TRANSACCION, espero alguien me peuda dar una ayuda al respecto.
  #2 (permalink)  
Antiguo 15/03/2018, 21:11
Avatar de xfxstudios  
Fecha de Ingreso: junio-2015
Ubicación: Valencia - Venezuela
Mensajes: 2.448
Antigüedad: 9 años, 5 meses
Puntos: 263
Respuesta: ejecutar una funcion dentro de otra

para ello puedes trabajar con try catch

Código PHP:
Ver original
  1. public function loquesea(){
  2.     try{
  3.         //AQUI PRIMERA EJECUCIÓN DE TUSA CONSULTAS
  4.         $a = $this->_db->prepare("INSERT INTO encuestas (id, titulo, id_cargo, id_pais, id_departamento, id_provincia, id_distrito, fecha_encuesta, fecha_registro, usuario_registrador) VALUES (null, :titulo, :cargo, 1, :departamento, :provincia, :distrito, :fecha_enc, now(), '" . Session::get('id_usuario') . "')"
  5.             )->execute(array(
  6.                 ':titulo'           => $titulo,
  7.                 ':cargo'            => $cargo,
  8.                 ':departamento'     => $departamento,
  9.                 ':provincia'        => $provincia,
  10.                 ':distrito'         => $distrito,
  11.                 ':fecha_enc'        => $fecha_enc)
  12.             );
  13.        
  14.         if(!$a){
  15.             throw new Exception("AQUI EL ERROR GENERADO");
  16.             //Si se genera la excepcion, se corta automaticamente la ejecución de la secuencia, por ende no llegara a la siguiente funcion o peticion
  17.         }
  18.         return $this->segunda($id);//Aqui solicito la ejecución de la segunda funcion
  19.  
  20.     }catch(Exception $e){
  21.         $this->db->rollback();
  22.         return $e->getMessage();
  23.     }
  24. }

Ahora debes tomar en cuenta que esto:

$sql = "SELECT MAX(id) AS id FROM encuestas LIMIT 1";

podría traerte ciertos problemas al concurrir varios usuarios en la ejecución del código, sería bueno trabajar con un código personalizado a parte de la id de control primaria, de esa manera tendrías mayor control sobre las operaciones.
__________________
[email protected]
HITCEL
  #3 (permalink)  
Antiguo 16/03/2018, 10:24
 
Fecha de Ingreso: octubre-2011
Mensajes: 132
Antigüedad: 13 años, 2 meses
Puntos: 4
Respuesta: ejecutar una funcion dentro de otra

hola, gracias por responder, tengo serias dudas con respecto a tu ayuda.

La funcion loquesea() es un nombre cualquiera que le puedo poner a dicha funcion?
Como paso los parametros a la primera consulta?
$a = registrarEncuesta($titulo, $cargo, $departamento, $provincia, $distrito, $fecha_enc)
la segunda consulta me la ejecuta en su respectiva funcion y la que esta dentro con un error: Notice: Undefined variable: id in
  #4 (permalink)  
Antiguo 16/03/2018, 17:39
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 15 años, 3 meses
Puntos: 214
Respuesta: ejecutar una funcion dentro de otra

Saludo

Pues puedes hacer una combinación,
es decir, en tu función inicial que hace el insert,
envías también el parámetro de las opciones,
ejecutas el insert, y obtienes el id de la inserción
(podrías usar $this->_db->insert_id() o similar, dependiendo las funciones de db)

Y una vez obtengas ese dato, haces el recorrido
que haces en el controlador, pero ahora en el modelo.

Y la excepción que te muestra con id es porque la variable
esta ahí, pero no se le asigna valor en ningún momento,
en cuyo caso en el ejemplo, podrías hacer un else del if,
y en este obtener el valor del id insertado.
__________________
"Si consigues ser algo más que un hombre, si te entregas a un ideal, si nadie puede detenerte, te conviertes en algo muy diferente."
Visita piggypon.com
  #5 (permalink)  
Antiguo 19/03/2018, 07:57
 
Fecha de Ingreso: octubre-2011
Mensajes: 132
Antigüedad: 13 años, 2 meses
Puntos: 4
Respuesta: ejecutar una funcion dentro de otra

Hola aun no logro resolver esta duda, tengo esto en mi codigo:

Código PHP:
public function registrarEncuesta($titulo$cargo$departamento$provincia$distrito$fecha_enc$id_candidato)
    {
        try {
            
$this->_db->beginTransaction(); // iniciar transacción
            // tabla 1
            
$this->_db->prepare("INSERT INTO encuestas (id, titulo, id_cargo, id_pais, id_departamento, id_provincia, id_distrito, fecha_encuesta, fecha_registro, usuario_registrador) VALUES (null, :titulo, :cargo, 1, :departamento, :provincia, :distrito, :fecha_enc, now(), '" Session::get('id_usuario') . "')"
                
)->execute(array(
                    
':titulo'           => $titulo,
                    
':cargo'            => $cargo,
                    
':departamento'     => $departamento,
                    
':provincia'        => $provincia,
                    
':distrito'         => $distrito,
                    
':fecha_enc'        => $fecha_enc)
                );
            
$lastReciboId $this->_db->lastInsertId();
            
// tabla 2

          /*  ¿AQUI QUE COLOCO? */

            
$this->_db->commit();
            echo 
'Datos insertados';
        } catch (
PDOException $e) {
            
// si ocurre un error hacemos rollback para anular todos los insert
            
$this->_db->rollBack();
            echo 
$e->getMessage();
        }
    } 
  #6 (permalink)  
Antiguo 19/03/2018, 08:31
 
Fecha de Ingreso: octubre-2011
Mensajes: 132
Antigüedad: 13 años, 2 meses
Puntos: 4
Respuesta: ejecutar una funcion dentro de otra

Hola bueno con esto me funciona no se si podria optimizarlo o mejorar el codigo

controlador:
Código PHP:
$fecha_enc date('Y-m-d'strtotime($_POST['fecha_enc']));
             for (
$i=0$i<count($_POST['candidato']); $i++) {
                
$candidato[] = $_POST['candidato'][$i];
            }

            
$this->_encuestas->registrarEncuesta(
            
$this->getPostParam('titulo'),
            
$this->getPostParam('cargo'),
            
$this->getPostParam('departamento'),
            
$this->getPostParam('provincia'),
            
$this->getPostParam('distrito'),
            
$fecha_enc,
            
$candidato); 
Modelo:

Código PHP:
public function registrarEncuesta($titulo$cargo$departamento$provincia$distrito$fecha_enc$id_candidato)
    {
        try {
            
$this->_db->beginTransaction(); // iniciar transacción
            // tabla 1
            
$this->_db->prepare("INSERT INTO encuestas (id, titulo, id_cargo, id_pais, id_departamento, id_provincia, id_distrito, fecha_encuesta, fecha_registro, usuario_registrador) VALUES (null, :titulo, :cargo, 1, :departamento, :provincia, :distrito, :fecha_enc, now(), '" Session::get('id_usuario') . "')"
                
)->execute(array(
                    
':titulo'           => $titulo,
                    
':cargo'            => $cargo,
                    
':departamento'     => $departamento,
                    
':provincia'        => $provincia,
                    
':distrito'         => $distrito,
                    
':fecha_enc'        => $fecha_enc)
                );
            
$lastReciboId $this->_db->lastInsertId();
            for (
$i=0$i<count($id_candidato); $i++) {
                
$sql "INSERT INTO opciones (id, id_encuesta, id_candidato) VALUES (null, :id_encuesta, :id_candidato)";
                
$statement $this->_db->prepare($sql);
                
$statement->execute(array(
                    
':id_candidato'  => $id_candidato[$i],
                    
':id_encuesta'   => $lastReciboId
                
));
                }

            
$this->_db->commit();
            echo 
'Datos insertados';
        } catch (
PDOException $e) {
            
// si ocurre un error hacemos rollback para anular todos los insert
            
$this->_db->rollBack();
            echo 
$e->getMessage();
        }
    } 
  #7 (permalink)  
Antiguo 19/03/2018, 08:45
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 15 años, 3 meses
Puntos: 214
Respuesta: ejecutar una funcion dentro de otra

Saludo

Pues tal vez podrías envíar el parámetro $_POST de candidato directamente
al modelo, en vez de recorrerlo antes en el controlador, así evitas
doble recorrido.

Y otra podría ser que no uses $_POST como tal,
para eso puedes hacer lo mismo que haces con los demás parámetros,
el getPostParam.
__________________
"Si consigues ser algo más que un hombre, si te entregas a un ideal, si nadie puede detenerte, te conviertes en algo muy diferente."
Visita piggypon.com
  #8 (permalink)  
Antiguo 19/03/2018, 10:33
 
Fecha de Ingreso: octubre-2011
Mensajes: 132
Antigüedad: 13 años, 2 meses
Puntos: 4
Respuesta: ejecutar una funcion dentro de otra

Hola gracias por la respuesta, tengo una consulta respecto a la transaccion, hice a proposito un error para que no me ingrese los egistros a la segunda tabla, y necesito que si no ingresa ningun registro la primera tabla tampoco pero me sucede que si lo ingresa asi no haya ingresado ningun registro en la segunda como puedo resolver problema?
  #9 (permalink)  
Antiguo 19/03/2018, 10:52
 
Fecha de Ingreso: octubre-2011
Mensajes: 132
Antigüedad: 13 años, 2 meses
Puntos: 4
Respuesta: ejecutar una funcion dentro de otra

Creo que esto me funciona pero tengo ciertas dudas con parte del coidgo

Código PHP:
public function registrarEncuesta($titulo$cargo$departamento$provincia$distrito$fecha_enc$id_candidato)
    {
        try {
            
$this->_db->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);
            
$this->_db->beginTransaction(); // iniciar transacción
            
$a $this->_db->prepare("INSERT INTO encuestas (id, titulo, id_cargo, id_pais, id_departamento, id_provincia, id_distrito, fecha_encuesta, fecha_registro, usuario_registrador) VALUES (null, :titulo, :cargo, 1, :departamento, :provincia, :distrito, :fecha_enc, now(), '" Session::get('id_usuario') . "')"
                
)->execute(array(
                    
':titulo'           => $titulo,
                    
':cargo'            => $cargo,
                    
':departamento'     => $departamento,
                    
':provincia'        => $provincia,
                    
':distrito'         => $distrito,
                    
':fecha_enc'        => $fecha_enc)
                );
            
$lastReciboId $this->_db->lastInsertId();
            if (!
$a) {
                throw new 
Exception("ERROR AL INGRESAR LOS DATOS");
            } else {
                for (
$i=0$i<count($id_candidato); $i++) {
                    
$b $sql "INSERT INTO opciones (id, id_encuesta, id_candidato) VALUES (null, :id_encuesta, :id_candidato)";
                    
$statement $this->_db->prepare($sql);
                    
$statement->execute(array(
                    
':id_candidato'  => $id_candidato[$i],
                    
':id_encuesta'   => $lastReciboId
                
));
                }
            }
            if(
$a && $b) {
                
$this->_db->commit();
            } else {
                
$this->_db->rollBack();
            }
            
// echo 'Datos insertados correctamente';
        
} catch (PDOException $e) {
            
// si ocurre un error hacemos rollback para anular todos los insert
            
$this->_db->rollBack();
            throw 
$e;
            
// echo $e->getMessage();
        
}
    } 
  #10 (permalink)  
Antiguo 19/03/2018, 12:05
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 15 años, 3 meses
Puntos: 214
Respuesta: ejecutar una funcion dentro de otra

Pues $b es igual al query, debería ser igual al $statement (como esta $a)

Y el if-else de $a vs $b debería ir en el ciclo,
para que valide cada operación a la tabla opciones.
__________________
"Si consigues ser algo más que un hombre, si te entregas a un ideal, si nadie puede detenerte, te conviertes en algo muy diferente."
Visita piggypon.com
  #11 (permalink)  
Antiguo 19/03/2018, 13:04
 
Fecha de Ingreso: octubre-2011
Mensajes: 132
Antigüedad: 13 años, 2 meses
Puntos: 4
Respuesta: ejecutar una funcion dentro de otra

Gracias por tus respuestas, modifique el codigo asi:

Controller:

Código PHP:
$fecha_enc date('Y-m-d'strtotime($_POST['fecha_enc']));
            
$candidato $_POST['candidato'];

            
$this->_encuestas->registrarEncuesta(
            
$this->getPostParam('titulo'),
            
$this->getPostParam('cargo'),
            
$this->getPostParam('departamento'),
            
$this->getPostParam('provincia'),
            
$this->getPostParam('distrito'),
            
$fecha_enc,
            
$candidato); 
y en el model:

Código PHP:
public function registrarEncuesta($titulo$cargo$departamento$provincia$distrito$fecha_enc, array $id_candidato)
    {
        try {
            
$this->_db->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);
            
$this->_db->beginTransaction(); // iniciar transacción
            
$a $this->_db->prepare("INSERT INTO encuestas (id, titulo, id_cargo, id_pais, id_departamento, id_provincia, id_distrito, fecha_encuesta, fecha_registro, usuario_registrador) VALUES (null, :titulo, :cargo, 1, :departamento, :provincia, :distrito, :fecha_enc, now(), '" Session::get('id_usuario') . "')"
                
)->execute(array(
                    
':titulo'           => $titulo,
                    
':cargo'            => $cargo,
                    
':departamento'     => $departamento,
                    
':provincia'        => $provincia,
                    
':distrito'         => $distrito,
                    
':fecha_enc'        => $fecha_enc)
                );
            
$lastReciboId $this->_db->lastInsertId();
            if (!
$a) {
                throw new 
Exception("ERROR AL INGRESAR LOS DATOS");
            } else {
                for (
$i=0$i<count($id_candidato); $i++) {
                    
$sql "INSERT INTO opciones (id, id_encuesta, id_candidato) VALUES (null, :id_encuesta, :id_candidato)";
                    
$b $statement $this->_db->prepare($sql);
                    
$statement->execute(array(
                    
':id_candidato'  => $id_candidato[$i],
                    
':id_encuesta'   => $lastReciboId
                
));
                }
                if(
$a && $b) {
                    
$this->_db->commit();
                } else {
                    
$this->_db->rollBack();
                }
            }
            
// echo 'Datos insertados correctamente';
        
} catch (PDOException $e) {
            
// si ocurre un error hacemos rollback para anular todos los insert
            
$this->_db->rollBack();
            throw 
$e;
            
// echo $e->getMessage();
        
}
    } 
Ahra hare el editar, gracias
  #12 (permalink)  
Antiguo 19/03/2018, 13:26
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 11 años, 5 meses
Puntos: 379
Respuesta: ejecutar una funcion dentro de otra

Cita:
Iniciado por stevens82 Ver Mensaje
Gracias por tus respuestas, modifique el codigo asi:

Controller:

Código PHP:
$fecha_enc date('Y-m-d'strtotime($_POST['fecha_enc']));
            
$candidato $_POST['candidato'];

            
$this->_encuestas->registrarEncuesta(
            
$this->getPostParam('titulo'),
            
$this->getPostParam('cargo'),
            
$this->getPostParam('departamento'),
            
$this->getPostParam('provincia'),
            
$this->getPostParam('distrito'),
            
$fecha_enc,
            
$candidato); 
y en el model:

Código PHP:
public function registrarEncuesta($titulo$cargo$departamento$provincia$distrito$fecha_enc, array $id_candidato)
    {
        try {
            
$this->_db->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);
            
$this->_db->beginTransaction(); // iniciar transacción
            
$a $this->_db->prepare("INSERT INTO encuestas (id, titulo, id_cargo, id_pais, id_departamento, id_provincia, id_distrito, fecha_encuesta, fecha_registro, usuario_registrador) VALUES (null, :titulo, :cargo, 1, :departamento, :provincia, :distrito, :fecha_enc, now(), '" Session::get('id_usuario') . "')"
                
)->execute(array(
                    
':titulo'           => $titulo,
                    
':cargo'            => $cargo,
                    
':departamento'     => $departamento,
                    
':provincia'        => $provincia,
                    
':distrito'         => $distrito,
                    
':fecha_enc'        => $fecha_enc)
                );
            
$lastReciboId $this->_db->lastInsertId();
            if (!
$a) {
                throw new 
Exception("ERROR AL INGRESAR LOS DATOS");
            } else {
                for (
$i=0$i<count($id_candidato); $i++) {
                    
$sql "INSERT INTO opciones (id, id_encuesta, id_candidato) VALUES (null, :id_encuesta, :id_candidato)";
                    
$b $statement $this->_db->prepare($sql);
                    
$statement->execute(array(
                    
':id_candidato'  => $id_candidato[$i],
                    
':id_encuesta'   => $lastReciboId
                
));
                }
                if(
$a && $b) {
                    
$this->_db->commit();
                } else {
                    
$this->_db->rollBack();
                }
            }
            
// echo 'Datos insertados correctamente';
        
} catch (PDOException $e) {
            
// si ocurre un error hacemos rollback para anular todos los insert
            
$this->_db->rollBack();
            throw 
$e;
            
// echo $e->getMessage();
        
}
    } 
Ahra hare el editar, gracias
No era necesario complicar tu códifgo como lo hiciste para capturar excepciones.
Tu código original estaba bien, solo tienes que capturar una excepción mas general porque solo esperas que falle los insert y pueden suceder otras cosas.
agrega un catch adicional para que captures un Exception y debe de funcionar sin necesidad de usar condiciones
Código PHP:
Ver original
  1. public function registrarEncuesta($titulo, $cargo, $departamento, $provincia, $distrito, $fecha_enc, $id_candidato)
  2. {
  3.         try {
  4.             $this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  5.             $this->_db->beginTransaction();
  6.            
  7.             $this->_db->prepare("INSERT INTO encuestas (id, titulo, id_cargo, id_pais, id_departamento, id_provincia, id_distrito, fecha_encuesta, fecha_registro, usuario_registrador) VALUES (null, :titulo, :cargo, 1, :departamento, :provincia, :distrito, :fecha_enc, now(), '" . Session::get('id_usuario') . "')"
  8.                 )->execute(array(
  9.                     ':titulo'           => $titulo,
  10.                     ':cargo'            => $cargo,
  11.                     ':departamento'     => $departamento,
  12.                     ':provincia'        => $provincia,
  13.                     ':distrito'         => $distrito,
  14.                     ':fecha_enc'        => $fecha_enc)
  15.                 );
  16.                
  17.             $lastReciboId = $this->_db->lastInsertId();
  18.             for ($i=0; $i<count($id_candidato); $i++) {
  19.                 $sql = "INSERT INTO opciones (id, id_encuesta, id_candidato) VALUES (null, :id_encuesta, :id_candidato)";
  20.                 $statement = $this->_db->prepare($sql);
  21.                 $statement->execute(array(
  22.                     ':id_candidato'  => $id_candidato[$i],
  23.                     ':id_encuesta'   => $lastReciboId
  24.                 ));
  25.                 }
  26.  
  27.             $this->_db->commit();
  28.             echo 'Datos insertados';
  29.            
  30.         } catch (PDOException $e) {
  31.             // si ocurre un error hacemos rollback para anular todos los insert
  32.             $this->_db->rollBack();
  33.             echo $e->getMessage();
  34.         } catch (Exception $e) {
  35.             //si sucede otra cosa inesperada
  36.             $this->_db_rollbak()
  37.             //aqui puedes mandar a un log el mensaje de error $e->getMessage()
  38.         }
  39. }
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #13 (permalink)  
Antiguo 19/03/2018, 14:18
 
Fecha de Ingreso: octubre-2011
Mensajes: 132
Antigüedad: 13 años, 2 meses
Puntos: 4
Respuesta: ejecutar una funcion dentro de otra

Hola hhs, gracias por responder, a eso mereferia hacerlo menos complicado, otra consulta para la modificacion de las opciones, tengo que hacer una consulta para eliminar y otra para insertar no es asi?

Etiquetas: encuesta, funcion, query, registro, select, sql, tabla
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 06:39.