Reputation: 2616
I am currently working on a plugin, and I am stuck with an issue. I executed an SQL request on my database through PhpMyAdmin (which I implemented later through a plugin update mechanism), the request looked like this:
UPDATE `wp_options`
SET `option_value` = replace( `option_value` , 'model', 'ldp_model' )
WHERE `option_name` LIKE 'ldp_container%'
As you can see, I am updating all options value having name beginning by 'ldp_container'. Later in the code execution, when I am retrieving the option value, I am getting a value being false
using:
$termId = $term->term_id;
$termMeta = get_option("ldp_container_$termId"); // $termMeta = false
I looked in this issue, and I got to the point where it seems that when I update/create this option, as I used:
update_option("ldp_container_$termID", $termMeta);
instead of
update_option("ldp_container_$termID", $termMeta, false);
The value of this option become part of the alloptions
cache. So, retrieving it always return false now, and I do not know how to flush this cache.
Using a plugin update mechanism based on version number, I tried to flush the Wordpress object cache using:
$flush_cache = wp_cache_flush(); // returns true
And the Database query cache too:
$wpdb->flush();
I also tried explicitely deleting those options keys from the cache using a query then looping on results and calling wp_cache_delete:
$result = $wpdb->get_results(
"SELECT 'option_name'
FROM $wpdb->options
WHERE 'option_name' LIKE '%ldp_container_%';"
);
foreach ( $result as $current ) {
wp_cache_delete($current, 'options');
}
Still, no luck.
Does anybody have a clue for me here ?
Thanks,
EDIT:
Seems like my error is somewhere else.
After some debugging using Atom and Xdebug, it points out that the issue is with the unserialize method applied to the string retrieved from the database in the file /wp-includes/option.php as follows:
return apply_filters( 'option_' . $option, maybe_unserialize( $value ) );
maybe_unserialize do that:
if ( is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in
return unserialize( $original );
return $original;
The call to the unserialize fails, so it returns false and then the false value is cached...
Using an online unserializer it confirms that the string is not correct, but I do not get why yet.
Upvotes: 4
Views: 3798
Reputation: 2616
So, as I assumed my issue was due to the modification in serialized objects I was executing directly on the database. Because of the nature of serialized objects, looking like this:
a:1:{s:9:"ldp_model";s:1651:"{...
The 1651
being the number of characters in the ldp_model
string, if you change anything inside this sting, then unserializing using unserialize()
will return false, because the actual number of characters is different from the one indicated.
In my case, the solution was to instead of executing a database update of this kind:
$wpdb->query(
"UPDATE $wpdb->options
SET `option_value` = replace( `option_value` , 'ldp_', '' );"
);
To use the Options API as follows:
$result = $wpdb->get_results(
"SELECT `option_name`
FROM $wpdb->options
WHERE `option_name` LIKE '%ldp_container_%';"
);
foreach ( $result as $current ) {
$option = get_option($current->option_name);
if (!empty($option) && !empty($option['ldp_model'])) {
$option['ldp_model'] = str_replace('ldp_', '', $option['ldp_model']);
update_option($current->option_name, $option, false);
}
}
So that the serialized objects stays correct, and the Options API takes care of serialization and unserialization.
Lots of learning here for me ;-)
Upvotes: 2