una - leer y mostrar archivo de texto en php
Usar PHP para tomar la primera línea de un archivo CSV y crear una tabla MySQL con los datos (4)
Estoy tratando de tomar un archivo CSV bastante grande e insertarlo en una base de datos MySQL para hacer referencia en un proyecto. Me gustaría utilizar 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 los archivos CSV. El problema que tengo es que gettype () devuelve ''cadena'' para cada columna en lugar de int, float y string como me gustaría.
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 Primera línea: 1,0,0,0,0,0,0,0,0,0,0,0,0,00.000000,0.000000,0,0,0,, 0,0,1,0,50, '' Palabra de Retiro (VIEJA) '',
El uso de expresiones regulares le dará una solución flexible. Si necesita detectar campos de fecha, este es el camino a seguir.
Intenta arrojar 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;
}
Además, 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 ;'';
Basándose en el código de Nouveau , podrías 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 interruptor, pero puede haber una mejor manera de hacer la comprobación int / float, ya que solo funcionaría con números estándar uk / us.