Predis: Predis serialisiert keine Objekte

Erstellt am 19. Mai 2011  ·  6Kommentare  ·  Quelle: predis/predis

Das scheint fehlgeschlagen zu sein:

// Set Array
$redis->set( 'key', array(1,2,3) );

Dies ist bei einer so vollständigen Bibliothek nicht zu erwarten. Wo ist der beste Ort, um einen Objekt-/Array-Serializer für alle Reids-Befehle zu platzieren?

documentation

Hilfreichster Kommentar

Dies ist ein beabsichtigtes Verhalten: Predis handhabt (und wird niemals) irgendeine Art von Serialisierung, es liegt vollständig bei den Entwicklern, wie die in Redis übergebenen oder gespeicherten Werte serialisiert oder deserialisiert werden. Hinter den Kulissen Ihres Beispiels wird der an SET übergebene Wert in eine Zeichenfolge (string) array(1,2,3) , was zum Zeichenfolgenwert Array führt.

Wenn Sie die (De-)Serialisierung für bestimmte Operationen wirklich transparent für den Code der Anwendung handhaben möchten, sollten Sie sich auf die Erweiterbarkeit von Predis verlassen und Ihre eigenen Befehle wie im folgenden Beispiel definieren (ich verwende json als Serialisierungsformat, Sie können jedoch alles auswählen, was am besten zu Ihrer Anwendung passt):

<?php

require 'autoload.php';

class StringSetJson
    extends Predis\Commands\StringSet {

    protected function filterArguments(Array $arguments) {
        $arguments[1] = json_encode($arguments[1]);
        return $arguments;
    }
}

class StringGetJson
    extends Predis\Commands\StringGet {

    public function parseResponse($data) {
        return json_decode($data);
    }
}

$client = new Predis\Client();

$profile = $client->getProfile();
// If you want, you can override SET or GET just like any other command, but I 
// think it's better to use different names for your serialization-aware commands:
$profile->defineCommand('jsonset', 'StringSetJson');
$profile->defineCommand('jsonget', 'StringGetJson');

$client->jsonset("json_key", array(1,2,3,4));
$value = $client->jsonget("json_key");

Auf diese Weise haben Sie die vollständige Kontrolle darüber, welche Art von Serialisierungsstrategie Sie verwenden (z. B. _Igbinary_) und wie sie in Abhängigkeit von den Daten funktionieren soll. Es lohnt sich wahrscheinlich, dies in die FAQ-Datei und die neue Dokumentation aufzunehmen, die vorbereitet wird, sobald Predis v0.7 veröffentlicht wird.

Alle 6 Kommentare

Vielmehr liegt das Problem beim Lesen mit einem GET-Befehl:

// Get Array
$data = $redis->get('key');

Empfehlungen?

Dies ist ein beabsichtigtes Verhalten: Predis handhabt (und wird niemals) irgendeine Art von Serialisierung, es liegt vollständig bei den Entwicklern, wie die in Redis übergebenen oder gespeicherten Werte serialisiert oder deserialisiert werden. Hinter den Kulissen Ihres Beispiels wird der an SET übergebene Wert in eine Zeichenfolge (string) array(1,2,3) , was zum Zeichenfolgenwert Array führt.

Wenn Sie die (De-)Serialisierung für bestimmte Operationen wirklich transparent für den Code der Anwendung handhaben möchten, sollten Sie sich auf die Erweiterbarkeit von Predis verlassen und Ihre eigenen Befehle wie im folgenden Beispiel definieren (ich verwende json als Serialisierungsformat, Sie können jedoch alles auswählen, was am besten zu Ihrer Anwendung passt):

<?php

require 'autoload.php';

class StringSetJson
    extends Predis\Commands\StringSet {

    protected function filterArguments(Array $arguments) {
        $arguments[1] = json_encode($arguments[1]);
        return $arguments;
    }
}

class StringGetJson
    extends Predis\Commands\StringGet {

    public function parseResponse($data) {
        return json_decode($data);
    }
}

$client = new Predis\Client();

$profile = $client->getProfile();
// If you want, you can override SET or GET just like any other command, but I 
// think it's better to use different names for your serialization-aware commands:
$profile->defineCommand('jsonset', 'StringSetJson');
$profile->defineCommand('jsonget', 'StringGetJson');

$client->jsonset("json_key", array(1,2,3,4));
$value = $client->jsonget("json_key");

Auf diese Weise haben Sie die vollständige Kontrolle darüber, welche Art von Serialisierungsstrategie Sie verwenden (z. B. _Igbinary_) und wie sie in Abhängigkeit von den Daten funktionieren soll. Es lohnt sich wahrscheinlich, dies in die FAQ-Datei und die neue Dokumentation aufzunehmen, die vorbereitet wird, sobald Predis v0.7 veröffentlicht wird.

nein,

Danke für die Hilfe. Dies ist enttäuschend, da Memcache-Clients die Serialisierung automatisch unterstützen. PHP4+ unterstützt Objektserialisierung: http://www.php.net/manual/en/function.serialize.php

Hallo,

Ich verstehe nicht, was mit dem Profil-Ding in einer OO-Welt ist.

Warum nicht eine Proxy-Klasse über der Client-Klasse bereitstellen, um alle Get-Set-Aufrufe abzufangen und nach Bedarf zu serialisieren?

abstract class Predis\ProxyClient extends Predis\Client
    abstract method decode(string)
    abstract method encode(mixed)

    method get(string key)
        return $this->decode(parent::get(key))

Wenn Sie Ihre Verbindungsklasse trennen, würde dies funktionieren und unterschiedliche Clienttypen für eine Verbindung zulassen.

Ich denke, das Ärgerliche an der hier vorgeschlagenen Lösung für mich ist, dass sie sehr granular ist, da die PHP-Redis-Erweiterung uns den Serializer global einstellen lässt (nur problematisch für Strings, da er ein paar Bytes hinzufügt).

Was Sie haben, sieht aus wie Abhängigkeitsinjektion, aber aus dem Beispiel sehe ich es in diesem Fall nicht als so bequem an, wie es sein könnte.

Danke.

@joeyhub Sie können tatsächlich Predis\Client erweitern und sowohl get() - als auch set() -Methoden implementieren, damit sie Dinge serialisieren / deserialisieren, aber diese Lösung würde nicht mit Pipelines, Transaktionen und Clustering funktionieren Aufgrund der internen Struktur von Predis arbeiten diese Funktionen direkt gegen die zugrunde liegende Verbindung.

Was ist mit einer optionalen (wie Präfix) Variante, um alle in redis gespeicherten Werte automatisch zu serialisieren (jsonify)?

$options = ['serialize' => 'json']
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen