Jump to content

WireCache question about storing JSON strings


baronmunchowsen
 Share

Recommended Posts

I have found that if I store a JSON string in wirecache https://processwire.com/api/ref/wire-cache/, I get an array, not a string back...

$response = $this->cache->get('mycache', 60, function() {
    return '{
        "glossary": {
            "title": "example glossary",
            "GlossDiv": {
                "title": "S",
                "GlossList": {
                    "GlossEntry": {
                        "ID": "SGML",
                        "SortAs": "SGML",
                        "GlossTerm": "Standard Generalized Markup Language",
                        "Acronym": "SGML",
                        "Abbrev": "ISO 8879:1986",
                        "GlossDef": {
                            "para": "A meta-markup language, used to create markup languages such as DocBook.",
                            "GlossSeeAlso": ["GML", "XML"]
                        },
                        "GlossSee": "markup"
                    }
                }
            }
        }
    }';
});

First call, when the cache is set, returns a string (expected). Subsequent calls to retrieve cached data do not return a string, but an array (unexpected).

Any thoughts? Am I missing something?

Thanks

 

Link to comment
Share on other sites

WireCache tries to be smart (too smart) when it finds a valid json string because it uses json to serialize array data for storing. So any string that look like json gets json_decode()ed into an array. It's kind of a known bug because there is currently only a part of a fix implemented in WireCache.

A workaround can be to prefix your string to break WireCache's json recognition and strip it after retrieval, like this:

$response = substr($this->cache->get('mycache', 60, function() {
    return 'JSON{
        "glossary": {
            "title": "example glossary",
            "GlossDiv": {
                "title": "S",
                "GlossList": {
                    "GlossEntry": {
                        "ID": "SGML",
                        "SortAs": "SGML",
                        "GlossTerm": "Standard Generalized Markup Language",
                        "Acronym": "SGML",
                        "Abbrev": "ISO 8879:1986",
                        "GlossDef": {
                            "para": "A meta-markup language, used to create markup languages such as DocBook.",
                            "GlossSeeAlso": ["GML", "XML"]
                        },
                        "GlossSee": "markup"
                    }
                }
            }
        }
    }';
}), 4);

 

  • Like 2
Link to comment
Share on other sites

Thanks for confirming what I had suspected. 

For anyone interested here's the method https://github.com/processwire/processwire/blob/master/wire/core/WireCache.php#L1229 which is implemented in various places in the WireCache module.

For what it's worth (not much likely!) I'd agree that this is indeed being too clever, and suggest that ideally you'd get out of the cache exactly what you put into it, not an interpretation of that data.

Cheers,

 

  • Like 1
Link to comment
Share on other sites

@baronmunchowsen A little trick I use when I need to store JSON is to add two methods $cache->saveRaw and $cache->getRaw through hooks, which just add the prefix to bypass the JSON encoding. See my reply here, which is a slight modification of LostKobrokai's code. Same result as @BitPoet's code above, just feels a bit cleaner than manually prefixing the JSON wherever you need it.

  • Like 1
Link to comment
Share on other sites

5 hours ago, BitPoet said:

There's already a github issue about this. Perhaps give it an upvote?

Exactly - this bug was introduced in July last year (it worked just fine prior to that) and it's still an issue that I am working around by prepending a "~" and then later stripping it, similar to @BitPoet's suggestion above.

Link to comment
Share on other sites

  • 1 year later...
On 3/10/2020 at 6:01 PM, BitPoet said:

WireCache tries to be smart (too smart) when it finds a valid json string because it uses json to serialize array data for storing. So any string that look like json gets json_decode()ed into an array. It's kind of a known bug because there is currently only a part of a fix implemented in WireCache.

I always have a problem with writing JSON data to wire ('cache') with this.
It would be good if the documentation warned about such behavior.
I think the cache should always return data in the format you sent it to.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...