interconnectit / Search-Replace-DB

This script was made to aid the process of migrating PHP and MySQL based websites. Works with most common CMSes.
https://interconnectit.com/products/search-and-replace-for-wordpress-databases/
GNU General Public License v3.0
4k stars 855 forks source link

PHP 7.2 - count(): Parameter must be an array or an object that implements Countable #271

Closed ddarbyson closed 4 years ago

ddarbyson commented 5 years ago

This absolutely breaks databases data:

https://www.php.net/manual/en/migration72.incompatible.php

bms_categories: 12 rows, 0 changes found, 0 updates made in 0.00115500 seconds
bms_components: replacing mysite.domain.com with mysite.mynewdomain.com
bms_components: 39 rows, 0 changes found, 0 updates made in 0.00223200 seconds
bms_contact_details: replacing mysite.domain.com with mysite.mynewdomain.com
bms_contact_details: 3 rows, 0 changes found, 0 updates made in 0.00059300 seconds
bms_content: replacing mysite.domain.com with mysite.mynewdomain.com
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable
implode(): Invalid arguments passed
count(): Parameter must be an array or an object that implements Countable

After these errors, data is missing from the database.

I've been a long time user of interconnectit/Search-Replace-DB. So much so, that it's become a dependency for hundreds of websites which need to move between servers.

I really hope developers are watching this thread and will actively pursue PHP 7.2 compatibility.

ddarbyson commented 5 years ago

More information on the change of count() function in PHP 7.2 which breaks SRDB.

https://wiki.php.net/rfc/counting_non_countables

ddarbyson commented 5 years ago

More digging around... The error occurs on this line:

https://github.com/interconnectit/Search-Replace-DB/blob/master/srdb.class.php#L1156

$parts = mb_split( preg_quote( $search ), $subject );

Where "mb_split now return false with ISO strings". When $parts is passed to count() and implode() functions in lines https://github.com/interconnectit/Search-Replace-DB/blob/master/srdb.class.php#L1157-L1158 we get failures. This breaks search and replace and ends up corrupting data.

See PHP issue https://bugs.php.net/bug.php?id=78190

Looking at the collation for table it appears to be latin1_swedish_ci

ddarbyson commented 5 years ago

After sometime I came to the conclusion that updating the collation would resolve this issue. However, what is critical to note, is SRDB does not exit or produce an exit status when a error or critical warning occurs. In my case, latin1_swedish_ci collation with PHP 7.2 caused complete data corruption without any notice. Since I use SRDB in a wrapper script to process hundreds of websites at a time, not reporting exit status would produce false-positives. There would be no way of knowing data had been corrupted unless exitstaus != 0 was produced.

I improved the error_hander callback to account for this in the following pull request.

https://github.com/interconnectit/Search-Replace-DB/pull/272

markdelf commented 5 years ago

The code in https://github.com/interconnectit/Search-Replace-DB/pull/274/files worked well for my sites

loorlab commented 5 years ago

@markdelf Yeah ! ✔

gianluigi-icit commented 4 years ago

thanks, we are merging that code into the new version

CodeBrauer commented 4 years ago

@gianluigi-icit - The issue still persists. Could you merge #274 before closing?