Search code examples
phpfilecsvfgetcsv

PHP how to return false with file() for an empty .csv file?


Why do I always get a array with one item of empty string for an empty .csv file?

$content = file('products.csv');

print_r($content);

result:

Array ( [0] => )

Can I return false so that I know there is nothing in the csv file?


Solution

  • A single line test should get you the result:

    $empty = empty($content) || (count($content) === 1 && empty($content[0]));

    The following should avoid the "fake empty":

    $empty = empty($content) || (count($content) === 1 && $content[0] === '');

    If you need a re-usable function, and prefer, as you stated, to get an array or nothing, this may be helpful:

    function get_file($file_name = null, $strict = false) {
        $return = null;
        if(!empty($file_name) && is_readable($file_name)) {
            $contents = file($file_name);
            if(
                !empty($contents)
                && (
                    count($contents) > 1 
                    || (
                        !empty($contents[0])
                        || ($strict && $contents[0] !== '')
                    )
                )
            ) {
                $return = $contents;
            }
        }
        return $return;
    }
    

    I mean, we could get all kinds of creative and iterate over lines, etc. But I think you get the idea.

    If you want to get a CSV file, I would suggest using a method like fgetcsv() (repurposed):

    function getcsv($file_name, $headers = array(), $delimiter = ',', $enclosure = '"', $escape = "\\" ) {
        $contents = array();
        $get_headers = $headers === FALSE;
        $headers = is_array($headers) ? array_values($headers) : array();
        if(!empty($file_name) && is_readable($file_name)) {
            $row = 0;
            if (($handle = fopen($file_name, "r")) !== FALSE) {
                while (($data = fgetcsv($handle, 0, $delimiter, $enclosure, $escape)) !== FALSE) {
                    if($get_headers && empty($headers)) {
                        $headers = $data;
                        continue;
                    }
                    foreach($data as $i => $col_value) {
                        $col_name = isset($headers[$i]) ? $headers[$i] : $i;
                        $contents[$row][$col_name] = $col_value;
                    }
                    $row++;
                }
                fclose($handle);
            }
        }
    
        return $contents;
    }
    

    Note, above is not tested, just a quick draft, and I am going to bed. I'll edit it tomorrow if need be.

    Finally, if you are getting a single line, with white-space, and this validates as "empty" in your eyes, simple test it after a trim:

    $empty_line = trim($content[$line_num]) == '';
    

    Not sure what else to tell you. I think we have equipped you with quite a few tools and ways to validate this situation. Best of luck.