[wp-trac] [WordPress Trac] #20004: Fix NULL and FALSE in WP_Object_Cache and make found/not-found unambiguous.

WordPress Trac wp-trac at lists.automattic.com
Thu Feb 9 21:54:28 UTC 2012


#20004: Fix NULL and FALSE in WP_Object_Cache and make found/not-found unambiguous.
--------------------------+------------------------------------
 Reporter:  andy          |      Owner:
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Cache         |    Version:
 Severity:  normal        |   Keywords:  has-patch dev-feedback
--------------------------+------------------------------------
 ```WP_Object_Cache``` mistreats ```NULL``` as a stored value by converting
 it to ```""```. To handle it correctly, the existence check must not use
 ```isset()```:

 {{{
 $cache[ $key ] = NULL;
 isset( $cache[ $key ] ); // false
 array_key_exists( $key, $cache ); // true
 }}}

 The attached patch corrects the treatment of ```NULL``` by storing it as-
 is and using ```array_key_exists()``` to test the existence of a key.

 As a value returned from ```wp_cache_get```, ```FALSE``` is ambiguous. It
 could mean that the value stored and retrieved was literally ```FALSE```
 or that the key was not found.

 The attached patch moves the found/not-found information to a pass-by-
 reference parameter, ```$found```, which is set to ```TRUE``` after a
 cache hit or ```FALSE``` after a cache miss. This allows storage and
 retrieval of ```FALSE``` without ambiguity and reduces the temptation to
 use confusing patterns such as ```!$value```, ```$value === false```, and
 ```empty( $value )```.

 The attached patch permits a clearer coding style:

 {{{
 $found = null;
 $value = wp_cache_get( $key, $group, false, $found );
 if ( ! $found ) {
     $value = $wpdb->get_results( $query );
     wp_cache_set( $key, $value, $group );
 }
 }}}

 (Assigning ```$found = null;``` prevents "Notice: Undefined variable".)

 However, because object cache drop-ins may lag behind core in adding
 support for the ```$found``` parameter, the following pattern may be
 preferred for backwards compatibility:

 {{{
 $found = null;
 $value = wp_cache_get( $key, $group, false, $found );
 if ( ! $value && ! $found ) {
     $value = $wpdb->get_results( $query );
     wp_cache_set( $key, $value, $group );
 }
 }}}

 I also added a function, ```wp_cache_found()```, to determine whether the
 previous retrieval was a hit or a miss.

 {{{
 $value = wp_cache_get( $key, $group );
 if ( ! wp_cache_found() ) {
     $value = $wpdb->get_results( $query );
     wp_cache_set( $key, $value, $group );
 }
 }}}

 Again, this function may not be present in drop-ins. Until such time as
 old drop-ins are forced into obsolescence, use ```function_exists```
 before calling ```wp_cache_found``` in core code.

 It would behoove us to devise a drop-in API versioning and update system
 to assist with this.

-- 
Ticket URL: <http://core.trac.wordpress.org/ticket/20004>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software


More information about the wp-trac mailing list