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?
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.