2

プロジェクトで参照するために、かなり大きな CSV ファイルを取り、それを MySQL データベースに挿入しようとしています。ファイルの最初の行を使用して、各列に varchar ではなく適切なデータ型を使用してテーブルを作成したいと思います。最終的な目標は、このプロセスを自動化することです。似たようなファイルがいくつかありますが、それぞれに異なるデータがあり、CSV ファイルの「列」の量が異なります。私が抱えている問題は、gettype() が必要に応じて、int、float、および string ではなく、各列の「string」を返すことです。

プラットフォームは PHP 5、OS は ubuntu 8.04

これまでの私のコードは次のとおりです。

<?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 ;';

例 1 行目:1,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0,0,0,,0,0,1,0,50,'リコールの言葉 (OLD)',

4

4 に答える 4

4

Nouveauのコードに基づいて構築すると、これを行うことができます

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";

}

スイッチに「case 'double':」が追加されていることに注意してください。ただし、標準の uk/us 番号でのみ機能するため、int/float チェックを行うためのより良い方法があるかもしれません。

于 2008-10-06T08:37:47.953 に答える
2
<?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 ;';
于 2008-10-06T08:44:29.593 に答える
2

値をキャストして、元の値と比較してみてください。

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;
}

さらに、丸められた数値の最初のケースで小数点記号の存在を確認しますが、小数点以下の部分があります。

于 2008-10-06T07:59:46.593 に答える
1

正規表現を使用すると、柔軟なソリューションが得られます。日付フィールドを検出する必要がある場合は、これが最適です。

于 2008-10-06T08:43:38.817 に答える