Validating a CSV file is really a CSV file

I want the CSV file uploaded by one of our clients to be truly a CSV file in PHP. I handle the download myself. I am not bothered by malicious users, but I'm worried about those who try to download Excel workbooks. If I am mistaken, the Excel workbook and CSV can still have the same MIME, so checking this is not enough.

Is there one regular expression that can handle validation of a CSV file, is it really a CSV file? (I don’t need parsing ... what for PHP fgetcsv () for.) I have seen a few, but they are usually followed by comments like "this does not work for case X".

Is there any other better way to handle this?

(I expect the CSV to contain first and last names, department names ... nothing unusual.)

+3
source share
5 answers

You can write a RE that will give you an idea if the file is valid CSV or not, but perhaps the best approach would be to try to parse the file as if it were a CSV (with fgetcsv () called, and consider it Invalid if the call failed?

In other words, the best way to check if a file is a valid CSV file is to try to parse it as such and assume that if you couldn't parse, it was not a CSV!

+2
source

Unlike other file formats, CSV does not have control bytes in the file header. It starts right away with the evidence.

, , , .

, (= ).

+6

- CSV . str_getcsv, . , CSV .

str_getcsv, str_getcsv http://www.electrictoolbox.com/php-str-getcsv-function/:

if (!function_exists('str_getcsv')) {
    function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
        $fp = fopen("php://memory", 'r+');
        fputs($fp, $input);
        rewind($fp);
        $data = fgetcsv($fp, null, $delimiter, $enclosure); // $escape only got added in 5.3.0
        fclose($fp);
        return $data;
    }
}
+3

, CSV ( , , ..). , , , ASCII - . , Excel , .

+3

CSV, , .

Before you begin, you need to know which separator is used in the CSV file . After that, the easiest way to check is to use the fgetcsv function . For instance:

<?php
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $num = count($data); // Number of fields in a row.
        if ($num !== 5)
        {
            // OMG! Column count is not five!
        }
        else if (intval($data[$c]) == 0)
        {
            // OMG! Customer thinks we sold a car for $0!
        }
    }
    fclose($handle);
}
?>
0
source

Source: https://habr.com/ru/post/1765369/


All Articles