简体   繁体   English

通过PHP通过Load Data InFile上传到MYSQL时验证数据

[英]Validate data when uploading to MYSQL with Load Data InFile via PHP

So I am quite happily uploading data to several tables in my database using Load Data infile. 因此,我很高兴使用Load Data infile将数据上传到数据库中的多个表。 My problem is when the data uploaded contains incorrectly formatted data such as a date in d/m/Y rather than Ymd. 我的问题是,当上传的数据包含格式错误的数据(例如d / m / Y中的日期而不是Ymd)时。

This does not prevent the data from being inserted, it just inserts it as 0000-00-00. 这不会阻止数据的插入,而只是将其作为0000-00-00插入。 What I desire is for it to fail so I can inform the user to fix the data before proceeding. 我希望它能够失败,因此我可以通知用户在继续操作之前先修复数据。

I am currently doing a check to ensure the file uploaded contains the correct columns by comparing it against sample file using the following little function: 我目前正在使用以下小功能通过将其与示例文件进行比较来确保上传的文件包含正确的列:

function check_csv($f_a, $f_b)
{
    $csv_upload = array_map("str_getcsv", file($f_a,FILE_SKIP_EMPTY_LINES))[0];
    $csv_sample = array_map("str_getcsv", file($f_b,FILE_SKIP_EMPTY_LINES))[0];
    $match = 'true';
    foreach ($csv_sample as $key => $value) {
        if($value != $csv_upload[$key]){
            $match = 'false';
            break 1;
        }
    }
    return $match;
}

... I realise now there is the array_diff() function that may have been useful here, I shall explore that later. ...我意识到现在有array_diff()函数在这里可能有用,我将在以后进行探讨。

Back to the matter in hand, would I need to do something within this function to check each of the values or is there an option for Load Data Infile that will force the behaviour I desire. 回到当前的问题,我是否需要在此函数内执行某些操作以检查每个值,或者是否存在“加载数据文件”选项,该选项将强制执行我想要的行为。

I would say that trying to do validation in MySQL, while using LOAD DATA INFILE, is pretty much an exercise in futility. 我想说,在使用LOAD DATA INFILE的同时尝试在MySQL中进行验证几乎是徒劳的。 For one, you use LOAD DATA INFILE, as a faster alternative than going through the parser. 首先,使用LOAD DATA INFILE作为比通过解析器更快的选择。 If you want to start slowing down there and conducting all manner of parsing, you might as well just not use LOADA DATA INFILE. 如果要开始减慢速度并进行所有形式的解析,则最好不要使用LOADA DATA INFILE。

I would suggest that you just do your validation in PHP on the CSV, and bail ( if necessary ) before even attempting to run it through MySQL. 我建议您只是在CSV上的PHP中进行验证,并在尝试通过MySQL进行运行之前将其保全( 如有必要 )。 That'd actually be more efficient since you won't have to bother hitting MySQL at all if the data isn't even valid. 这实际上会更有效率,因为即使数据无效,您也不必打扰MySQL。

Also, the code you're using to validate the CSV file above only compares the values of the first row of the CSV. 另外,您用于验证上述CSV文件的代码仅会比较CSV第一行的值。 That doesn't actually validate that any of the proceeding rows have the correct number of columns. 这实际上并不能验证任何后续行的列数是否正确。 You also don't need array_diff() for this. 您也不需要array_diff() Simply compare the column count of each row in the CSV to the expected column count. 只需将CSV中每一行的列数与预期的列数进行比较即可。

For example, let's say you expect exactly 4 columns in every row in the CSV, and you expect column 2 to have the formatted date of Ymd : 例如,假设您期望CSV的每一行中恰好有4列,并且您希望第2列的格式日期为Ymd

$row = 1;
$expectedColumnNum = 4; // we expect exactly 4 columns
if (($handle = fopen("uploaded.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle)) !== FALSE) {
        // Verify every row contains exact number of expected columns
        if (count($data) != $expectedColumnNum) {
            echo "CSV does not contain the expected number of columns on row $row!\n";
            break;
        }
        // Verify the second column is a formatted date of Y-m-d
        if (!DateTime::createFromFormat('Y-m-d', $data[1])) {
            echo "CSV does not contain valid formatted date on row $row!\n";
            break;
        }
        $row++;
    }
    fclose($handle);
}

If the above validation checks out then you're good to run it through MySQL using LOAD DATA INFILE. 如果上面的验证成功了,那么您最好使用LOAD DATA INFILE通过MySQL运行它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM