1

I have a search feature set up that is fairly expensive and I want to cache the results, based on the $_get string, like: ?search_type=product&relation=or&date=all&s=tagsearch&merchcat=cotton&brand=brandx&color=blue&etc=morestuff

So, i'm trying to cache the array of posts that I get:

if (false === ( $products = get_transient($name) ) ) {
    $products = getproducts();
    set_transient($name, $products, 60*60*12);
}

for the transient name, I've been trying various things like

$name= base64_encode(serialize($_GET));

But, I'm running into the problem of the option name getting truncated and possibly encoded, slashed, etc.

How would you go about solving this?

  • 1
    Have you tried md5($_SERVER['QUERY_STRING']); or md5(implode('|', ksort($_GET)))? – gmazzap Sep 19 '13 at 19:08
4

Take a look at the relevant bits of the database description for that table.

Field           Type        
option_name     varchar(64)      
option_value    longtext                  

The key is 64 characters max. The value is longtext which should be more than you need.

To have you caching work, you need a unique value for the key, but it doesn't have to be readable. My suggestion would be to hash the GET string. It should be unique and well shy of 64 characters.

Instead of this: $name= base64_encode(serialize($_GET));

Try this: $name= wp_hash($_GET);

Proof of concept using the sample GET string above:

$str = '?search_type=product&relation=or&date=all&s=tagsearch&merchcat=cotton&brand=brandx&color=blue&etc=morestuff';
var_dump(base64_encode(serialize($str)));
// vs
var_dump(wp_hash($str));

Edit based on the discussion below (thanks @G-M):

The order of the arguments in the GET string could effect the hash values. The safe thing to do is to normalize the array. The following should do that:

$str = $_GET;
ksort($str);
$str = add_query_arg($str,'');
$str = wp_hash($str);
var_dump($str);

All arguments are preserved, even the empty ones, which seem to be what the OP wants, though I personally believe that running the array through array_filter to remove empty values would actually provide better caching.

$str = $_GET;
$str = array_filter($str);
ksort($str);
$str = add_query_arg($str,'');
var_dump(wp_hash($str));

No data validation/sanitization was attempted.

When you save that key to the database, I would also suggest prepending a string to make it identifiable-- something like $str = 'my_plugin_slug'.$str before saving it.

  • Problem with this is that same arguments in different order will result in different hash, even if the query is the same. – gmazzap Sep 19 '13 at 19:24
  • 3
    @G-M : Yes. Presumably there is a form or something generating the query so the order should be fairly reliable but to be sure you'd have to normalize the array, certainly. I should include that in the answer. Thanks. – s_ha_dum Sep 19 '13 at 19:41
  • parse_str($_SERVER['QUERY_STRING'], $newget); ksort($newget); $str = http_build_query($newget); $name = wp_hash($str); Should normalize the array, yes? – Doug Cassidy Sep 19 '13 at 19:47
  • I am unsetting $_GET['s'] in some cases, which is why I went thru the string->array->string process. I just want to be sure I'm getting the whole querystring. – Doug Cassidy Sep 19 '13 at 20:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.