Fehler in SymconMisc/SzenenSteuerung

Hallo zusammen,

das o.g. Modul wollte ich gerade benutzen. Für Dimmerwerte ungleich 0 oder 1 funktioniert bei mir das Abrufen von Szenen nicht korrekt.

Nach etwas Suchen bin ich auf den vermutlichen Fehler gestoßen: Das Modul serialisiert die Variablenwerte nach XML und verwendet dabei Kommata für den Prozentwert zwischen 0 und 1. Beim Deserialisieren wird jedoch (zumindest bei mir) vermutlich ein Punkt erwartet und somit beispielsweise 0,9 auf 0 deserealisiert.

Gibt es eine Möglichkeit, dies zu beheben?

Danke und Gruß
micheljarre

Moin micheljarre!

Wir konnten das Problem leider nicht nachstellen.

Ich möchte dich bitten mal dieses Skript bei dir laufen zu lassen und die Ausgabe hier hin zu kopieren.

<?

$data = array();
$data[1] = 0.01;
$data[2] = 0.50;
$data[3] = 0.99;

var_dump($data);
var_dump($wddx = wddx_serialize_value($data));
var_dump(wddx_deserialize($wddx));

?>

Grüße
Pio

Hallo Pio,

danke für die Hilft. Leider ergibt sich das erwartete (unschöne) Ergebnis:

array(3) {
  [1]=>
  float(0,01)
  [2]=>
  float(0,5)
  [3]=>
  float(0,99)
}
string(200) "0,010,50,99"
array(3) {
  [1]=>
  int(0)
  [2]=>
  int(0)
  [3]=>
  int(0)
}

Auf dem Rückweg werden aus den Strings Integer gebildet.

Irgendwas mit Regionaleinstellungen (wäre mir nicht bewusst, etwas geändert zu haben)?

Gruß
micheljarre

Wenn ich die Werte direkt als String serialisiere, funktioniert es interessanterweise:

$v1 = 1.1;
echo "v1: " . $v1 . PHP_EOL;
$v2 = wddx_serialize_value($v1);
echo "v2: " . $v2 . PHP_EOL;
$v3 = wddx_deserialize($v2);
echo "v3: " . $v3 . PHP_EOL; 

Ausgabe:

v1: 1,1
v2: 1,1
v3: 1

Im Vergleich dazu:

$v1 = "1.1";
echo "v1: " . $v1 . PHP_EOL;
$v2 = wddx_serialize_value($v1);
echo "v2: " . $v2 . PHP_EOL;
$v3 = wddx_deserialize($v2);
echo "v3: " . $v3 . PHP_EOL; 

Ausgabe:

v1: 1.1
v2: 1.1
v3: 1.1

Gruß,
micheljarre

Gibt es etwas, das ich zur Problemsuche oder Behebung noch machen kann? Würde das Modul gerne benutzen.

Danke und Gruß
micheljarre

Aus meiner Sicht entsteht das Problem bereits beim Serialisieren:

15.12.2016 12:42:27*| VariableManager*| [Programme\Szenen\Treppenhauslicht DG\Scene1Data] = <wddxPacket version='1.0'><header/><data><struct><var name='21352'><number>0,5</number></var></struct></data></wddxPacket>

Hier wird der Variablenwert mit einem Komma serialisert. Verändere ich diesen String manuell und setze einen Punkt ein (also 0.5), wird der Dimmerwert korrekt deserialisiert und gesetzt.

Habe mir jetzt mangels Antworten selber beholfen.

Ursache ist wohl ein unangenehmer Seiteneffekt in der PHP Umgebung. Der Aufruf

setlocale(LC_ALL, 'en_US.utf8');

in einem beliebigen Skript hat bei mir dazu geführt, dass die Gleitkommazahlen vom Modul nun mit einem Punkt als Trennzeichen serialisiert werden. Jetzt funktioniert das Abrufen von Szenen.

(siehe auch http://php.net/manual/de/function.setlocale.php, insbesondere den dortigen Abschnitt „Warnung“).

Allerdings wäre mir nicht bewusst, diese Einstellung jemals geändert zu haben. Außerdem: wenn die PHP Umgebung mit Komma serialisiert, warum kann sie dann nicht auch mit Komma deserialiseren?

Gruß
micheljarre

Eine Float in PHP hat immer eine Punkt als Trennzeichen, wenn das mit Komma geht ist das eher Zufall. Auch wenn im Deutschen ein Komma als Trennzeichen benutzt wird so wird in PHP eben ein . benutzt dann ist man auch immer auf der sicheren Seite. Das gilt auch für JSON Encode und Decode hier muss auch ein Float mit . geschrieben werden ansonsten ist es kein Float.

Eben. Daher sehr seltsam, dass PHP so serialisiert.

Dummerweise ist die Änderung nach einem Neustart weg und ich muss erst wieder setlocale irgendwo aufrufen, damit das Modul funktioniert.

Vielleicht hat ja doch noch jemand eine Idee, woher das Problem kommen könnte und wie es sich systematisch beseitigen ließe.

Danke und Gruß
micheljarre

Ich würde einfach kein serialize benutzten statt dessen JSON dann funktioniert das auch zuverlässig. Also wenn das ein Problem ist am besten in der module.php abändern.


$data = array(); 
$data[1] = 0.01; 
$data[2] = 0.50; 
$data[3] = 0.99; 

var_dump($data); 
$datajson = json_encode($data);
var_dump($datajson);
$data = json_decode($datajson, true);
var_dump($data); 

Ich musste erst mal nachlesen was wddx überhaupt ist [emoji5]
Jetzt muss ich mal testen ob es sich mit dem ‚normalen‘ serialize genauso verhält.
Das nutzte ich ausgiebig um Daten mittels eines String zu verarbeiten.
Michael

Das geht:


 $data = array(); 
$data[1] = 0.01; 
$data[2] = 0.50; 
$data[3] = 0.99; 


var_dump($data); 

// serialize
$dataserialize = serialize($data);
var_dump($dataserialize);
$data = unserialize($dataserialize);
var_dump($data);

Wobei imho finde das JSON besser lesbar ist als die Ausgabe von serialize und kürzer.

JSON:

{"1":0.01,"2":0.5,"3":0.99}

Serialize:

a:3:{i:1;d:0.01;i:2;d:0.5;i:3;d:0.98999999999999999;}

$data = array(); 
$data[1] = 0.01; 
$data[2] = 0.50; 
$data[3] = 0.99; 


var_dump($data); 
$datajson = json_encode($data);
var_dump($datajson);
$data = json_decode($datajson, true);
var_dump($data); 


Ja, das mit dem Float ist schon cool :slight_smile:
Aber ich nutzte es eh meistens für Objekte, somit ist es die beste Wahl, da automatisch __sleep und __wakeup ausgeführt wird.
Hast du den es auch mit setlocal getestet ?
Michael

Hier meine Ergebnisse, zur Übersicht nur die serialisierten Strings:

wddx_serialize_value:

string(200) „0,010,50,99“

serialize:

string(53) „a:3:{i:1;d:0.01;i:2;d:0.5;i:3;d:0.98999999999999999;}“

json_encode:

string(27) „{„1“:0.01,„2“:0.5,„3“:0.99}“

Bei unserialize und json_decode lande ich bei den richtigen Ergebnissen, auch ohne locale Änderungen.

Für mich spricht das eindeutig für einen Bug in wddx. Wenn ich ein Float plattform- und länderneutral serialisiere, muss ich mich auf ein Format einigen, und das dürfte korrekterweise mit einem Punkt sein, so wie bei serialize und json auch.

Stimmt das hatte ich noch gar nicht auf dem Schirm, ist dann ja aber nur für Klassen relevant.

Also durch ein einfaches Ersetzen der Serialisierung durch json_encode und json_decode in den Methoden SaveValues und LoadValues scheint bei mir das Problem behoben zu sein.

@Symcon Team: Wäre es möglich, das generell so ins Modul SymconMisc einzupflegen?

Danke und Gruß
micheljarre

Ich befürchte das ist ein PHP Bug. Habe dies mal eingereicht und wir warten ab: PHP :: Bug #73793 :: WDDX uses wrong decimal seperator

paresy

Also durch ein einfaches Ersetzen der Serialisierung durch json_encode und json_decode in den Methoden SaveValues und LoadValues scheint bei mir das Problem behoben zu sein.

Danke für den Tip, hab die 2 Stellen im Modul ersetzt und schon funktioniert es auch mit den Dimmern.:slight_smile:

Die Jungs von PHP haben den Bug zu PHP 7.2 korrigiert :wink:

paresy