Home > other >  CSV import problem since converting to PHP 8.1
CSV import problem since converting to PHP 8.1

Time:10-06

I have the following Wordpress function that worked in PHP 7. Since converting to 8.1, it's not working.

function dropdown_handler() {

$output = drop_function();
//send back text to replace shortcode in post
return $output;
}

function drop_function() {
//get the csv file with amounts
if ($file_handle = fopen("wp-content/plugins/drop/amounts.csv", "r")) {
while (!feof($file_handle) ) {
    $lines[] = fgetcsv($file_handle, 1024);
    
}
fclose($file_handle);
$lines = str_replace ("£","£",$lines);

}
else {
echo "Sorry, something went wrong";
}

In my error log I'm seeing "PHP Warning: Array to string conversion in" relating to the $lines = str_replace line but I think there's something wrong with the fopen statement.

Basically, the word Array is being stored in the $lines variable rather than the contents of the CSV file. Any ideas please?

CodePudding user response:

Your code was always broken, it's just broken in a slightly more obvious way than it used to be...

$lines[] = fgetcsv($file_handle, 1024);

fgetcsv, unless it fails, returns an array; you then add this array as a new item to another array, $lines. The result is an array of arrays, like this:

$lines = [
    ['line 1 first item', 'line 1 second item'],
    ['line 2 first item', 'line 2 second item'],
];

Later, you pass this whole array to str_replace; but str_replace only knows how to deal with a single dimension of array.

So this works:

$singleLine = ['line 1 first item', 'line 1 second item'];
var_dump(str_replace('item', 'ITEM', $singleLine));

But this doesn't:

var_dump(str_replace('item', 'ITEM', $lines));

Running that example on multiple versions of PHP reveals that under PHP 7.x, str_replace reacted by simply leaving the inner arrays untouched - in other words, it did nothing.

In PHP 8, it instead tries to turn each inner array into a string, issuing the warning and producing the word "Array" (which will then have any substitutions applied to it).

The fix for both PHP versions is to run the str_replace on each of the inner arrays, most simply by using array_map:

var_dump(
    array_map(
        fn($innerArray) => str_replace('item', 'ITEM', $innerArray),
        $lines
    )
);

Alternatively, you can just delete the str_replace line completely, since you were apparently happy enough when it wasn't actually doing anything.

  • Related