jueves, 8 de octubre de 2015

Como llenar una tabla con un archivo plano desde php


Algo muy usado para poder alimentar una tabla en una base de datos sin recurrir a digitar dato por dato en un formulario es subirlo de manera masiva con un archivo plato y código en php se puede hacer una actualización o un insert a una tabla sin preocuparnos de que se digite mal. En el siguiente post voy a explicar como hacer este proceso.

Comenzamos por la caja de examinar que se encargara de cargar el archivo para subirlo.


ac_UploadTables.php

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Carga de Archivos Masivos</title>
</head>

<body>

<script>
/********************************************************************/
/*Esta función Revisa que el Formato del Archivo que se cargue sea el Correcto*/
/********************************************************************/
function checkfile(sender){
 var validExts = new Array('.csv');
 var fileExt = sender.value;
 fileExt = fileExt.substring(fileExt.lastIndexOf('.'));
 
 if(validExts.indexOf(fileExt) < 0){
  alert("El archivo no corresponde al formato permitido. El formato permitido es: " + validExts.toString() + ".");
  document.getElementById('TxtArchivo').value = '';
  return false;
 }
 else return true;
}
</script>

/*Diseño-> El formulario envía por action la URl que se encargara de efectuar la subida de datos masivos*/
<span class="Estilo18">Cargar Archivos Planos</span><br> 
<form method="post" name="FrmUpload" id="FrmUpload" action="ejecuta_UploadTables.php" enctype="multipart/form-data">
    <table width="100%" align="center">
        <tr>
         <td width="24%" align="left"> </td><td width="36%" align="left"> </td><td width="76%" align="left"> </td>
        </tr>
        <tr>
         <td bgcolor="#D9ECEF" align="left" valign="middle">
              <b>1. Subir Cuentas Contrato: </b>
            </td>
         <td align="left" valign="middle" colspan="2">
          <input name="TxtArchivo" id="TxtArchivo"  type="file"   size="35" onChange="checkfile(this);" accept="text/csv" style="background: #FFF; -moz-box-sizing: border-box;"  />
          <input name="BtnEnviar" id="BtnEnviar" type="submit" class="button"  value="Subir" />                       
         </td>
        </tr>
    </table>
</form>

/*Se utiliza para mostrar si el archivo se cargo correctamente en la base de datos*/
<hr class="style-separador">
<div id="divRespAjax" class="ui-widget"> 
    <div id="wrapMsgAjax" class="ui-state-highlight ui-corner-all">
    
        <p id="respAjax">
        <?php
        if(isset($_GET['success'])){
            ?>
            <label>Archivo cargado Correctamente...</label>
            <?php
        }
        else if(isset($_GET['error'])){
            ?>
            <label>Problemas al Cargar el Archivo!</label>
            <?php
        }
      ?>   
        </p> 
    </div>
</div>

</body>
</html>


Luego Seguimos con el archivo que ejecutará toda la acción.

ejecuta_UploadTables.php

 <?php
set_time_limit(0);
ini_set('memory_limit', '-1');
ini_set('display_errors', 'On');
ini_set('display_errors', 1);
include('conec.class.php');//se llama el archivo conexión
$ob_consulta = conec::iniciar();//esta es la forma de instanciar la clase del archivo conexión, ya que como es privada  no se puede llamar por new por lo tanto se llama de esta manera.

if(isset($_POST['BtnEnviar'])){
 
 $Tmp =  $_FILES['TxtArchivo']['tmp_name'];
 $Nombre = '/spool/tempUpload/CuentasContrato.csv';
 
 move_uploaded_file($Tmp,$Nombre);
 
 $fila = 0;
 $Insert = '';
 $Lista = '';
 if(($gestor = fopen($Nombre, 'r')) !== FALSE){
  while(($datos = fgetcsv($gestor, 1000, ";")) !== FALSE){
   if($fila > 0 /*&& $datos[0] != ''*/){
    $sCC = $datos[0];
    $Value = "('".$sCC."'),";
    $Insert .= $Value;
   }
   $fila++;
  }
  $Insert = substr($Insert, 0, -1).';';
  fclose($gestor);
  
  $SqlDel = " DELETE FROM
    TemporalCntContrato
   ";
  $RsetDel = $ob_consulta->ejecutar($SqlDel);// cada vez que se ejecuta una consulta se utiliza esta forma.
  
  $Sql = " INSERT INTO
     TemporalCntContrato
      (cc)
    VALUES $Insert";
  $Rset = $ob_consulta->ejecutar($Sql);
  
  header('Location: ../ac_UploadTables.php?success');
 }else{
  
  header('Location: ../ac_UploadTables.php?error');
 }
}


Adicional, este es el archivo conec.class.php es decir el archivo conexión que yo utilizo en este momento para poder ejecutar las consultas desde ejecutar_UploadTables.php, está completo con mas de una función que más adelante usaré entonces por si se preguntan la manera de ejecutar las consultas, aquí les dejo el archivo. Tengan en cuenta que se necesita otro archivo para llamar los datos de las variables como nombre del servidor, el usuario y la contraseña, esto se hace por seguridad. Espero le sea de mucha ayuda.

conec.class.php

# Clase encargada de gestionar las conexiones a la base de datos.
class conec
{
 private $servidor;
 private $usuario;
 private $password;
 private $base_datos;
 private $link;
 private $rsc;
 private $array;
 public $rutaRelativa;
 private $ruta;

 static $_instance;
 
 # La función construct es privada para evitar que el objeto pueda ser creado mediante new
 private function __construct($rutaRelativa)
 {
  if($rutaRelativa ) $this->rutaRelativa = $rutaRelativa;
  $this->conxion_default();
  $this->conectar();
 }

 # Evitamos el clonaje del objeto. Patrón Singleton
 private function __clone(){ }
 
 # Función encargada de crear, si es necesario, el objeto. Esta es la función que debemos llamar desde 
 # fuera de la clase para instanciar el objeto, y así, poder utilizar sus métodos
 public static function iniciar($rutaRelativa = '', $nuevo = 1)
 {
  if($nuevo) self::$_instance = new self($rutaRelativa);
  else
   if (!(self::$_instance instanceof self))
     self::$_instance = new self($rutaRelativa);
  
  return self::$_instance;
 }
 
 # Inicia los parametros por defecto para la conexion a la bd ( servidor, usuarios, clave, bd)
 public function conxion_default()
 {
  $carpeta = explode('/', $_SERVER["PHP_SELF"]);
  $this->ruta = ($this->rutaRelativa) ? $this->rutaRelativa : $_SERVER["DOCUMENT_ROOT"].'/'.$carpeta[1].'/conexion';
  $contenido = include($this->ruta . '/bd.inc.php');
  
  $this->servidor = trim( $servidor );
  $this->usuario = trim( $usuario  );
  $this->password = trim( $password  );
  $this->base_datos = trim( $bd );
 }
 
 # Realiza la conexión a la base de datos.
 private function conectar()
 {
  $this->link = mysqli_connect($this->servidor, $this->usuario, $this->password);
  if( $this->link === false ) die($this->servidor.', '.$this->usuario.' Error al conectar a MySql.');
  if( mysqli_select_db($this->link, $this->base_datos) === false )
   die('Error al conectar la base de datos.');
  @mysqli_query("SET NAMES 'utf8'");
 }
        
 # Método para ejecutar una sentencia sql.
 public function ejecutar($sql)
 {
  $this->stmt = mysqli_query($this->link, $sql);
  if( $this->stmt === false ) $this->errores( $sql, 1 );
  return $this->stmt;
 }
        
    # Método para ejecutar multiples sentencias sql.
 public function multi_ejecutar($sql){                
                /* execute multi query */
                if (mysqli_multi_query($this->link, $sql)) {
                    do {
                        /* store first result set */
                        if ($result = mysqli_store_result($this->link)) {
                            while ($row = mysqli_fetch_row($result)) {
                            }
                            mysqli_free_result($result); 
                        }
                        
                        if(mysqli_more_results($this->link)){
                            
                        }
                    }while (mysqli_more_results($this->link) && mysqli_next_result($this->link)); 
                }
                $this->stmt  = mysqli_errno($this->link);
                if($this->stmt!=0){
                    $this->errores( $sql, 1 );
                }
                return $this->stmt;
 }

 # Método para obtener una fila de resultados de la sentencia sql.
 public function obtener_fila($rsc, $fila = 0)
 {
  if ($fila == 0){
   $this->array = mysqli_fetch_array($rsc);
  }
  else
  {
   mysqli_data_seek($rsc, $fila);
   $this->array = mysqli_fetch_array($rsc);
  }
  return $this->array;
 }
 
 # Obtiene una fila del resource, si no se envia el segundo parametro se obtiene la primera.
 public function obtener_fila_a($rsc, $fila = 0)
 {
  if ($fila == 0){
   $this->array = mysqli_fetch_assoc($rsc);
  }
  else
  {
   mysqli_data_seek($rsc, $fila);
   $this->array = mysqli_fetch_assoc($rsc);
  }
  return $this->array;
 }
 
 # Retorna una sola fila de la consulta enviada en un array, agrega el limit 1 por defecto.
 public function una_fila($sql){
  $sql .= " LIMIT 0, 1";
  $rsc = $this->ejecutar($sql);
  return $this->obtener_fila($rsc);
 }
 
 # Retorna una sola fila de la consulta enviada en un array asociativo, agrega el limit 1 por defecto.
 public function una_fila_a($sql)
 {
  $sql = $sql . " LIMIT 0, 1";
  $rsc = $this->ejecutar($sql);
  return $this->obtener_fila_a($rsc);
 }
 
 # Retorna el valor del primer campo, de la primera fila de la consulta enviada.
 public function un_campo($sql)
 {
  $fila = $this->una_fila( $sql);
  return $fila[0];
 }

 # Devuelve el último id del insert introducido
 public function ultimo(){
  return mysqli_insert_id($this->link);
 }
 
 # Devuelve el numero de filas que se encontraron en la consulta.
 public function num_reg( $rsc ){
  return mysqli_num_rows($rsc);
 }
 
 # Registra los errores ocacionados por las consultas mysql.
 private function errores($sql, $tipo = 0)
 {
  switch( $tipo )
  {
   case 1: $motivo = "Error en la consulta: ( ".mysqli_error($this->link)." ) "; break;
   case 2: $motivo = 'Consulta vacia.'; break;
   default: $motivo = 'Mostrar Consulta.'; break;
  }
  
  # Detectar dirección IP
  if (!empty($_SERVER['HTTP_CLIENT_IP'])) $ip = $_SERVER['HTTP_CLIENT_IP'];
  elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  else $ip = $_SERVER['REMOTE_ADDR'];
  
  $fecha = date('d / m / Y -  h:i');
  $msj = " \r\n---- \r\n".$fecha." \r\n".$motivo." \r\n".'Consulta : '. $sql."  \r\n";
  file_put_contents( $this->ruta."/mysql.log", $msj, FILE_APPEND ); 
 }
 
 # Mostrar mensajes que se deseen en un archivo plano.
 public function mostrar($texto)
 {
  $this->errores($texto);
 }
 
 # Devuelve 1 registro del resource formato objeto
 public function obtener_objFila($rsc){
  $oRow = mysqli_fetch_object($rsc);
  return $oRow;
 }
 
 # Devuelve los registros del resource formato objeto
 public function obtener_objFilas($rsc){
  $aRta = array();
  while( $oRow = $this->obtener_objFila($rsc) ){
   $aRta[] = $oRow;
  }
  return $aRta;
 }
 
 # Devuelve los registros del resource formato objeto
 public function obtener_objFilaUnica($rsc){
  $oRta = new stdClass();
  while( $oRow = $this->obtener_objFila($rsc) ){
   $oRta = $oRow;
  }
  return $oRta;
 }
        
     # Metodo para cerrar conexion 
      public function cerrarConexion() {
           mysqli_close($this->link);
        }
        
        
}



No hay comentarios:

Publicar un comentario