web-dev-qa-db-de.com

Warum würde json_encode eine leere Zeichenfolge zurückgeben?

Ich habe eine einfache PHP-Struktur mit 3 verschachtelten Arrays. 

Ich verwende keine speziellen Objekte und ich baue mir die Arrays mit 2 verschachtelten Schleifen. 

Hier ist ein Beispiel für den var_dump des Arrays, das ich in Json konvertieren möchte. 

array (size=2)
  'tram B' => 
    array (size=2)
      0 => 
        array (size=3)
          'name' => string 'Ile Verte' (length=9)
          'distance' => int 298
          'stationID' => int 762
      1 => 
        array (size=3)
          'name' => string 'La Tronche Hôpital' (length=18)
          'distance' => int 425
          'stationID' => int 771
  16 => 
    array (size=4)
      0 => 
        array (size=3)
          'name' => string 'Bastille' (length=8)
          'distance' => int 531
          'stationID' => int 397
      1 => 
        array (size=3)
          'name' => string 'Xavier Jouvin' (length=13)
          'distance' => int 589
          'stationID' => int 438

In einem anderen Skript habe ich eine ähnliche Struktur und json_encode funktioniert gut. Ich verstehe nicht, warum json_encode hier nicht funktioniert.

Edit: Es scheint ein Problem mit der Kodierung zu geben. Wenn mb_detect_encoding ASCII zurückgibt, funktioniert json_encode, aber wenn UTF8 zurückgegeben wird, funktioniert es nicht mehr. 

Edit2: json_last_error() gibt JSON_ERROR_UTF8 zurück. Dies bedeutet: Falsch formatierte UTF-8-Zeichen, möglicherweise falsch codiert .

90

Gut nach 2 stunden graben (vgl. Bearbeitungen) 

Ich habe folgendes herausgefunden: 

  • In meinem Fall handelt es sich um ein Codierungsproblem
  • mb_detect_encoding gibt wahrscheinlich eine fehlerhafte Antwort zurück, einige Zeichenfolgen waren wahrscheinlich nicht UTF-8 
  • mit utf8_encode() für diese Zeichenfolge wurde mein Problem gelöst. 

Hier ist eine rekursive Funktion, die die Umwandlung aller in einem Array enthaltenen Zeichenfolgen in UTF-8 erzwingen kann:

function utf8ize($d) {
    if (is_array($d)) {
        foreach ($d as $k => $v) {
            $d[$k] = utf8ize($v);
        }
    } else if (is_string ($d)) {
        return utf8_encode($d);
    }
    return $d;
}

Verwenden Sie es einfach so:

echo json_encode(utf8ize($data));
213

Matthieu Riegler präsentierte eine wirklich gute Lösung, jedoch musste ich sie leicht modifizieren, um auch mit Objekten umgehen zu können: 

function utf8ize($d) {
    if (is_array($d)) 
        foreach ($d as $k => $v) 
            $d[$k] = utf8ize($v);

     else if(is_object($d))
        foreach ($d as $k => $v) 
            $d->$k = utf8ize($v);

     else 
        return utf8_encode($d);

    return $d;
}

Noch eine Anmerkung: json_last_error () kann beim Debuggen von json_encode ()/json_encode () - Funktionen hilfreich sein.

34
Adam Bubela

Für mich war die Antwort auf dieses Problem das Setzen von charset = utf8 in meiner PDO-Verbindung.

beispiel: $dbo = new PDO('mysql:Host=localhost;dbname=yourdb;charset=utf8', $username, $password);

23
fayd

Adam Bubela präsentierte auch eine wirklich gute Lösung, die mir geholfen hat, mein Problem zu lösen. Hier ist die vereinfachte Funktion:

function utf8ize($d)
{ 
    if (is_array($d) || is_object($d))
        foreach ($d as &$v) $v = utf8ize($v);
    else
        return utf8_encode($d);

    return $d;
}
7
Alex

Dieses Problem ist auf einem Server aufgetreten, auf dem eine ältere Version von PHP (5.2) ausgeführt wird. Ich habe das Flag JSON_FORCE_OBJECT verwendet, und das wird anscheinend bis 5.3 nicht unterstützt

Wenn Sie dieses Flag verwenden, überprüfen Sie Ihre Version!

Eine Problemumgehung scheint nur ein Casting auf ein Objekt zu sein, z. B .:

json_encode((object)$myvar);
4
Shane N

Diese akzeptierte Antwort funktioniert. Falls Sie jedoch Ihre Daten von MySQL erhalten (wie ich es war), gibt es einen einfacheren Weg.

Nachdem Sie Ihre Datenbank geöffnet haben, können Sie vor der Abfrage den Zeichensatz mit mysqli wie folgt festlegen:

/* change character set to utf8 | Procedural*/
if (!mysqli_set_charset($link, "utf8")) {
    printf("Error loading character set utf8: %s\n", mysqli_error($link));
    exit();
}

OR

/* change character set to utf8 | Object Oriented*/
if (!$mysqli->set_charset("utf8")) {
        printf("Error loading character set utf8: %s\n", $mysqli->error);
        exit();
 }

LINK: http://php.net/manual/de/mysqli.set-charset.php

3
Kholofelo

Die Rückgabe von mb_detect_encoding ist möglicherweise nicht korrekt:

$data = iconv('UTF-8', 'ISO-8859-1', 'La Tronche Hôpital');
var_dump(
    mb_detect_encoding($data),
    mb_detect_encoding($data, array('ISO-8859-1', 'UTF-8'))
);

Abhängig von der Standarderkennungsreihenfolge kann das obige Ergebnis andere Ergebnisse liefern, sodass die Kodierung fälschlicherweise als UTF-8 gemeldet wird. ( Hier ist ein größeres Beispiel .)

Es ist wahrscheinlich, dass Ihre Daten nicht als UTF-8 codiert sind. json_encode gibt false zurück. Vor dem JSON-Encoding sollten Sie sich die Konvertierung Ihrer Zeichenfolgen in UTF-8 ansehen:

$fromEncoding = 'ISO-8859-1'; // This depends on the data

array_walk_recursive($array, function (&$value, $key, $fromEncoding) {
    if (is_string($value)) {
        $value = iconv($fromEncoding, 'UTF-8', $value);
    }
}, $fromEncoding);
3
cmbuckley

mit utf8_encode () für diese Zeichenfolge wurde mein Problem gelöst. 

2
mobizen

Ich habe genau das gleiche Problem auf PHP 5.6 . Ich benutze Open Server + Nginx unter Windows 7. Alle Zeichensätze sind auf UTF-8 ..__ eingestellt. Theoretisch laut offizielle Dokumentation , Flagge 

JSON_UNESCAPED_UNICODE

sollte das lösen. Leider ist dies nicht mein Fall. Keine Ahnung warum. Alle obigen Ausschnitte lösen mein Problem nicht, daher habe ich meine eigene Implementierung gefunden. Ich glaube es könnte jemandem helfen. Zumindest bestehen russische Buchstaben den Test.

function utf8ize($d) {
    if (is_array($d) || is_object($d)) {
        foreach ($d as &$v) $v = utf8ize($v);
    } else {
        $enc   = mb_detect_encoding($d);

        $value = iconv($enc, 'UTF-8', $d);
        return $value;
    }

    return $d;
}
2

Ich habe die Antwort von Adam Bubela verbessert. Ich hasse es einfach, wenn Blöcke nicht durch {und} geschlossen werden. Es ist sauberer und man führt keine Fehler ein, oder vielleicht habe ich Perl in der Vergangenheit benutzt :)

<?php

class App_Updater_String_Util {    
    /**
     * Usage: App_Updater_String_Util::utf8_encode( $data );
     *
     * @param mixed $d
     * @return mixed
     * @see http://stackoverflow.com/questions/19361282/why-would-json-encode-returns-an-empty-string
     */
    public static function utf8_encode($d) {
        if (is_array($d)) {
            foreach ($d as $k => $v) {
                $d[$k] = self::utf8_encode($v);
            }
        } elseif (is_object($d)) {
            foreach ($d as $k => $v) {
                $d->$k = self::utf8_encode($v);
            }
        } elseif (is_scalar($d)) {
            $d = utf8_encode($d);
        }

        return $d;
    }
}

?>
1

Ich erhielt Daten von ob_get_clean () und hatte das gleiche Problem, aber oben genannte Lösungen funktionieren für mich nicht. In meinem Fall war dies die Lösung, vielleicht hilft sie jemandem.

$var = mb_convert_encoding($var, 'UTF-8');
1
zdeniiik

dieses Problem tritt manchmal auf - Sie übergeben keine Headerzugriffskontrolle.

In meinem Fall, wenn ich ein Echo vor json_encode hinzugefügt habe. Es wurde das Ergebnis angezeigt, ansonsten kam eine leere Seite.

Ich fügte hinzu

header('Access-Control-Allow-Origin: *'); 

und mein problem gelöst.

0
Anup

Wenn Sie diese Daten aus einer Datenbank beziehen, verwenden Sie mysqli_set_charset($connection, "utf8"); in Verbindung, wenn Sie die Parameter aus der Datenbank abrufen