Uso de PHP para tomar la primera línea de un archivo CSV y crear una tabla MySQL con los datos

StackOverflow https://stackoverflow.com/questions/173498

  •  05-07-2019
  •  | 
  •  

Pregunta

Estoy intentando tomar un archivo CSV bastante grande e insertarlo en una base de datos MySQL para hacer referencia en un proyecto. Me gustaría usar la primera línea del archivo para crear la tabla utilizando los tipos de datos adecuados y no varchar para cada columna. El objetivo final es automatizar este proceso ya que tengo varios archivos similares, pero cada uno tiene datos diferentes y una cantidad diferente de " columnas " en archivos CSV. El problema que tengo es que gettype () está devolviendo 'cadena' para cada columna en lugar de int, float y cadena como quisiera.

La plataforma es PHP 5, el sistema operativo es Ubuntu 8.04

aquí está mi código hasta ahora:

<?php

// GENERATE TABLE FROM FIRST LINE OF CSV FILE

$inputFile = 'file.csv';
$tableName = 'file_csv';

$fh = fopen($inputFile, 'r');
    $contents = fread($fh, 5120); // 5KB
fclose($fh);

$fileLines = explode("\n", $contents); // explode to make sure we are only using the first line.

$fieldList = explode(',', $fileLines[0]); // separate columns, put into array
echo 'CREATE TABLE IF NOT EXISTS `'.$tableName.'` ('."<br/>\n";
for($i = 0; $i <= count($fieldList); $i++)
{
    switch(gettype($fieldList[$i])) {
        case 'integer':
            $typeInfo = 'int(11)';
            break;
        case 'float':
            $typeInfo = 'float';
            break;
        case 'string':
            $typeInfo = 'varchar(80)';
            break;
        default:
            $typeInfo = 'varchar(80)';
            break;
    }
if(gettype($fieldList[$i]) != NULL) echo "\t".'`'.$i.'` '.$typeInfo.' NOT NULL, --'.gettype($fieldList[$i]).' '.$fieldList[$i]."<br/>\n";
}
echo '  PRIMARY KEY  (`0`)'."<br/>\n";
echo ') ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;';

Ejemplo de primera línea:     1,0,0,0,0,0,0,0,0,0,0,0,0000000,0.000000,0,0,0,0, 0,0,1,0,50, 'Word of Recall ( ANTIGUO) ',

¿Fue útil?

Solución

Aprovechando Nouveau 's código podría hacer esto

for($i = 0; $i <= count($fieldList); $i++)
{
    if (is_numeric($fieldList[$i]))
    {
        if (strpos($fieldList[$i],'.') !== false){
            $fieldList[$i] = (int)$fieldList[$i];
        }else{
            $fieldList[$i] = (float)$fieldList[$i];
        }
    }

    switch(gettype($fieldList[$i])) {
        case 'integer':
            $typeInfo = 'int(11)';
            break;
        case 'float':
        case 'double':
            $typeInfo = 'float';
            break;

        case 'string':
            $typeInfo = 'varchar(80)';
            break;
        default:
            $typeInfo = 'varchar(80)';
            break;
    }
if(gettype($fieldList[$i]) != NULL) echo "\t".'`'.$i.'` '.$typeInfo.' NOT NULL, --'.gettype($fieldList[$i]).' '.$fieldList[$i]."<br/>\n";

}

Eso funciona, tenga en cuenta la adición de " case 'double': " en el conmutador, pero puede haber una mejor manera de realizar la comprobación int / float, ya que solo funcionan con los números estándar de uk / us.

Otros consejos

Intente convertir el valor y compararlo con el original:

define('DECIMAL_SEPARATOR', '.');

switch ($fieldList[$i])
{
    case (string)(int)$fieldList[$i]:
        $typeInfo = (strpos($fieldList[$i], DECIMAL_SEPARATOR) === false) ? 'int(11)' : 'float';
        break;
    case (string)(float)$fieldList[$i]:
        $typeInfo = 'float';
        break;
    default:
        $typeInfo = 'varchar(80)';
        break;
}

Adicionalmente, verifique la presencia de un separador decimal en el primer caso para los números que son redondos, pero tienen la parte de la fracción decimal.

<?php

// GENERATE TABLE FROM FIRST LINE OF CSV FILE

$inputFile = 'file.csv';
$tableName = 'file_csv';

$fh = fopen($inputFile, 'r');
    $contents = fread($fh, 5120); // 5KB
fclose($fh);

$fileLines = explode("\n", $contents);

$fieldList = explode(',', $fileLines[0]);
echo 'CREATE TABLE IF NOT EXISTS `'.$tableName.'` ('."<br/>\n";
for($i = 0; $i <= count($fieldList); $i++)
{

    if(strlen($fieldList[$i]) == 0) $typeInfo = 'varchar(80)';
    if(preg_match('/[0-9]/', $fieldList[$i])) $typeInfo = 'int(11)';
    if(preg_match('/[\.]/', $fieldList[$i])) $typeInfo = 'float';
    if(preg_match('/[a-z\\\']/i', $fieldList[$i])) $typeInfo = 'varchar(80)';

    echo "\t".'`'.$i.'` '.$typeInfo.' NOT NULL, -- '.gettype($fieldList[$i]).' '.$fieldList[$i]."<br/>\n";
}
echo '  PRIMARY KEY  (`0`)'."<br/>\n";
echo ') ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;';

El uso de expresiones regulares le dará una solución flexible. Si necesita detectar campos de fecha, este es el camino a seguir.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top