Run .sql file from php

2

I have to make a program in php that executes two files .sql, both will create a table within my database 'form of payments'. The .sql files I already have, I just have to do the program in php.

This is the sql file:

-- MySQL dump 10.13  Distrib 5.7.12, for Win32 (AMD64)
--
-- Host: 158.69.25.165    Database: nexumApp
-- ------------------------------------------------------
-- Server version   5.7.16-0ubuntu0.16.04.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS,             FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table 'formasPago'
--

DROP TABLE IF EXISTS 'formasPago';
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE 'formasPago' (
'idFormaPago' int(11) NOT NULL AUTO_INCREMENT,
'nombre' varchar(255) NOT NULL,
'estatus' int(11) NOT NULL,
PRIMARY KEY ('idFormaPago')
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table 'formasPago'
--

LOCK TABLES 'formasPago' WRITE;
/*!40000 ALTER TABLE 'formasPago' DISABLE KEYS */;
INSERT INTO 'formasPago' VALUES (1,'Nexum Energy Card',1),(2,'GasoPass',1),        (3,'Sodexo',1),(4,'Energex',1),(5,'Visa',1),(6,'Efectivale',1),(7,'UltraGas',1),(8,'Edenred',1),(9,'Visa Electron',1),(10,'Sodexo',1),(11,'Accor',1),(12,'Ticket Car',1),(13,'Mastercard',1),(14,'Credigas',1),(15,'Inbursa',1),(16,'Credigas',1),(17,'American Express',1),(18,'Vale Gasored',1),(19,'PowerGas',1);
/*!40000 ALTER TABLE 'formasPago' ENABLE KEYS */;
UNLOCK TABLES;

--
-- Dumping routines for database 'nexumApp'
--
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2017-02-27 16:28:00
    
asked by Paloma Alvarado 03.07.2017 в 23:42
source

3 answers

1

The easiest thing I can do, assuming that the database is on the same server where the php is running, is to launch the command directly with system () , since in a single line of code you would have the problem solved.

<?php
$comando = 'mysql -u usuario -p contraseña base_a_cargar < archivo.sql';

$ultima_linea = system($comando, $retornoCompleto);

print_r( $ultima_linea );
print_r( $retornoCompleto );

If for whatever reason you could not use system (), you could do it with PHP , remember that MySQLi provides functions to run multiple querys a basic example could be the following:

// Se asume conexión en $mysqli


// Recuperamos el fichero como un string
$fileSQL = file_get_contents('ruta_fichero.sql');


/* Ejecutar consulta multiquery */
if ($mysqli->multi_query($fileSQL)) {
    do {
        /* Almacenar primer juego de resultados */
        if ($result = $mysqli->store_result()) {
            while ($row = $result->fetch_assoc()) {
                print_r($row);
                echo "<br/>";
            }
            $result->free();
        }
        /* mostrar divisor */
        if ($mysqli->more_results()) {
            printf("-----------------\n");
        }
      // Avanzar al siguiente resultado
    } while ($mysqli->next_result());
}

/* cerrar conexión */
$mysqli->close();
    
answered by 04.07.2017 в 15:51
-2

An easy way would be with a function similar to this

function ejecutarSQL($_rutaArchivo, $_conexionDB)
{
  $queries = explode(';', file_get_contents($_rutaArchivo));
  foreach($queries as $query)
  {
    if($query != '')
    {
      $_conexionDB->query($query): // Asumo un objeto conexión que ejecuta consultas
    }
  }
}

The problem would only have it if you have comments in the sql file.

Seeing the problem, the function that can best solve the proposed, will be

function executeSqlScript($_db, $_fileName) {
    $sql = file_get_contents($_fileName); // Leo el archivo
    // Lo siguiente hace gran parte de la magia, nos devuelve todos los tokens no vacíos del archivo
        $tokens = preg_split("/(--.*\s+|\s+|\/\*.*\*\/)/", $sql, null, PREG_SPLIT_NO_EMPTY);
    $length = count($tokens);

    $query = '';
    $inSentence = false;
    $curDelimiter = ";";
    // Comienzo a recorrer el string
    for($i = 0; $i < $length; $i++) {
 $lower = strtolower($tokens[$i]);
 $isStarter = in_array($lower, array( // Chequeo si el token actual es el comienzo de una consulta
     'select', 'update', 'delete', 'insert',
     'delimiter', 'create', 'alter', 'drop', 
     'call', 'set', 'use'
 ));

 if($inSentence) { // Si estoy parseando una sentencia me fijo si lo que viene es un delimitador para terminar la consulta
     if($tokens[$i] == $curDelimiter || substr(trim($tokens[$i]), -1*(strlen($curDelimiter))) == $curDelimiter) { 
  // Si terminamos el parseo ejecuto la consulta
  $query .= str_replace($curDelimiter, '', $tokens[$i]); // Elimino el delimitador
  $_db->query($query);
  $query = ""; // Preparo la consulta para continuar con la siguiente sentencia
  $tokens[$i] = '';
  $inSentence = false;
     }
 }
 else if($isStarter) { // Si hay que comenzar una consulta, verifico qué tipo de consulta es
     // Si es delimitador, cambio el delimitador usado. No marco comienzo de secuencia porque el delimitador se encarga de eso en la próxima iteración
     if($lower == 'delimiter' && isset($tokens[$i+1]))  
  $curDelimiter = $tokens[$i+1]; 
     else
  $inSentence = true; // Si no, comienzo una consulta 
     $query = "";
 }
 $query .= "{$tokens[$i]} "; // Voy acumulando los tokens en el string que contiene la consulta
    }
}

Although surely it will not be the best that can be done

    
answered by 04.07.2017 в 10:14
-3

From PHP you can execute SQL sequences, for example:

   <?php
$mysqli = new mysqli("ejemplo.com", "usuario", "contraseña", "basedatos");
if ($mysqli->connect_errno) {
    echo "Falló la conexión con MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1)")) {
    echo "Falló la creación de la tabla: (" . $mysqli->errno . ") " . $mysqli->error;
}
?>
    
answered by 04.07.2017 в 09:53