Json_encode एक रिक्त स्ट्रिंग क्यों लौटाएगा


107

मेरे पास 3 नेस्टेड सरणियों के साथ एक साधारण php संरचना है।

मैं विशेष वस्तुओं का उपयोग नहीं करता हूं और मैं खुद को 2 नेस्टेड छोरों के साथ सरणियों का निर्माण करता हूं।

यहाँ उस सरणी के var_dump का एक नमूना है जिसे मैं Json में बदलना चाहता हूँ।

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

एक अन्य स्क्रिप्ट में मेरे पास एक समान संरचना है और json_encodeठीक काम करता है। इसलिए मुझे समझ नहीं आया कि json_encodeयहां काम क्यों नहीं होगा।

संपादित करें: एन्कोडिंग के साथ एक समस्या प्रतीत होती है। जब mb_detect_encodingASCII देता है, तो json_encodeकाम करता है, लेकिन जब वह UTF8 लौटाता है, तो वह काम नहीं करता है।

Edit2: json_last_error()रिटर्न JSON_ERROR_UTF8जिसका मतलब है: विकृत UTF-8 वर्ण, संभवतः गलत तरीके से एन्कोड किया गया


PHP मैनुअल कहता This function only works with UTF-8 encoded data.है कि एन्कोडिंग के साथ कोई समस्या नहीं होनी चाहिए।
महानगर

13
इससे पहले कि आप स्ट्रिंग को सौंपें, utf8_encode()अपने nameसरणी फ़ील्ड पर उपयोग करने का प्रयास करें json_encode()
महानगर

धन्यवाद ! मैं खुद इस समाधान के लिए आया था जिसने मेरी समस्या को हल किया।
मैथ्यू रीगलर

हाँ, जवाब देखा। सौभाग्य।
महानगर

3
समस्या को देखने के लिए JSON_PARTIAL_OUTPUT_ON_ERRORविकल्प का उपयोग करें (जैसे UTF8 के साथ फ़ील्ड शून्य होगा)।
पीटर क्रस

जवाबों:


255

खुदाई के 2 घंटे बाद (cf संपादन)

मुझे निम्नलिखित पता चला:

  • मेरे मामले में यह एक एन्कोडिंग समस्या है
  • mb_detect_encoding रिटर्न शायद एक दोषपूर्ण प्रतिक्रिया है, कुछ तार शायद UTF-8 नहीं थे
  • utf8_encode()उन स्ट्रिंग का उपयोग करने से मेरी समस्या हल हो गई, लेकिन नीचे नोट देखें

यहाँ एक पुनरावर्ती कार्य है जो किसी सरणी में निहित UTF-8 में परिवर्तित होने के लिए मजबूर कर सकता है:

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;
}

इसे इस तरह से प्रयोग करें:

echo json_encode(utf8ize($data));

नोट: utf8_encode () ISO-8859-1 स्ट्रिंग को UTF-8 में डॉक्स के अनुसार एनकोड करता है, इसलिए यदि आप इनपुट एन्कोडिंग iconv () या mb_convert_encoding () के बारे में अनिश्चित हैं तो टिप्पणियों और अन्य समाधानों में उल्लेखित बेहतर विकल्प हो सकते हैं।


4
अपने समाधान ... फिर भी, एक तरफ ध्यान दें के लिए धन्यवाद: बदलें } else {करने के लिए } else if (is_string ($d)) {; अन्यथा आप तार के लिए सब कुछ बदल जाएगा (जैसे INTबन जाएगा STRING)।
पॉल पीलेन

3
आपने मेरी जान बचा ली। जब तक मुझे यह फंक्शन नहीं मिला, मैं सब कुछ खत्म करने वाली थी !! धन्यवाद।
सिल्वरसुन्थर

2
WTF! अपना समाधान साझा करने के लिए धन्यवाद। मैं देख सकता हूं कि यह पता लगाने के लिए बहुत सारी खुदाई हुई होगी, और ऐसा करने और साझा करने के लिए मैं आपका आभारी हूं।
kris

1
डिबगिंग के तीन दिनों के बाद, मैं आपको अभी चुंबन सकता है।
एजेबी

2
यदि डेटाबेस से पढ़ने के लिए बस उपयोग करते हैं, तो $ con-> set_charset ("utf8");
एंड्रयू ब्रिग्स

36

Matthieu Riegler ने वास्तव में अच्छा समाधान प्रस्तुत किया लेकिन मुझे वस्तुओं को संभालने के लिए इसे थोड़ा संशोधित करना पड़ा:

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;
}

एक और नोट: json_last_error () json_encode () / json_encode () फ़ंक्शन को डीबग करने में सहायक हो सकता है।


elseifइसके बजाय नहीं होना चाहिए else if? (अर्थात कोई कोरा नहीं)।
ऊवे कीम

2
@UweKeim PHP डॉक्यूमेंट के अनुसार "इस्तिफ और फिर अगर केवल घुंघराले कोष्ठक का उपयोग करते समय बिल्कुल वैसा ही माना जाएगा" जिसका अर्थ है कि वे समतुल्य हैं जब तक आप बृहदान्त्र संकेतन का उपयोग नहीं करते हैं जैसेif(): elseif:
एडम बुबेला

1
बहुत बढ़िया। PHP कचरा है और आप जैसे लोग इसे डंप पर जाने से रोकते हैं।
लोनी बेस्ट

आपको else if(is_int($d)||is_bool($d)) return $d;अंतिम कारण से पहले सम्मिलित करना चाहिए , क्योंकि:{"success":true, "message":"Ⲃⲟⲟ𝓵ⲉⲁⲛ ⲁⲛⲇ Ⲓⲛϯⲉ𝓰ⲉꞅ𝛓"}
डेविड रेफौ

जैसे @ पार्थ-रीगलर को सुझाए गए @ पॉल-छीलन: अंतिम elseको बदलें else if(is_string ($d)); अन्यथा आप तार के लिए सब कुछ बदल जाएगा (जैसे INTबन जाएगा STRING)।
ब्रूनो सेरानो

30

मेरे लिए, charset=utf8मेरे पीडीओ कनेक्शन में इस समस्या का जवाब सेट हो रहा था ।

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

2
या mysqli फ़ंक्शन में: mysqli_set_charset ($ कनेक्शन, "utf8");
15

यह मेरे समाधान का संकेत था। Msqli कनेक्शन का थोड़ा अलग कारण। बस $mysqli->set_charset("utf8");अपने डेटाबेस हैंडलिंग करने के बाद कॉल करें ।
मग्गसुक

कृपया utf8mb4हाल के MySQL संस्करणों में उपयोग करें । utf8अप्रचलित है।
19

10

एडम बुबेला ने भी वास्तव में अच्छा समाधान प्रस्तुत किया जिसने मेरी समस्या को हल करने में मदद की, और यहां सरलीकृत कार्य किया गया है:

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

    return $d;
}

1
मुझे यह पसंद है क्योंकि यह कुंजियों को संरक्षित करता है।
dev0

7

मुझे PHP 5.6 पर ठीक यही समस्या है। मैं विंडोज 7 पर ओपन सर्वर + नग्नेक्स का उपयोग करता हूं । सभी चार्ट यूटीएफ -8 में सेट हैं। सिद्धांत रूप में, आधिकारिक दस्तावेज के अनुसार , ध्वज

JSON_UNESCAPED_UNICODE

इसे हल करना चाहिए। दुर्भाग्य से यह मेरा मामला नहीं है। मुझे नहीं पता क्यों। ऊपर दिए गए सभी स्निपेट्स मेरी समस्या का समाधान नहीं करते हैं, इस प्रकार मैंने अपना कार्यान्वयन पाया है। मेरा मानना ​​है कि यह किसी की मदद कर सकता है। कम से कम, रूसी पत्र परीक्षण पास करते हैं।

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;
}

4

यह स्वीकृत उत्तर कार्य है। लेकिन यदि आप MySQL से अपना डेटा प्राप्त कर रहे हैं (जैसा कि मैं था) एक आसान तरीका है।

एक बार जब आप डेटाबेस खोलते हैं, तो क्वेरी करने से पहले आप mysqli का उपयोग करके वर्ण सेट को निम्नानुसार सेट कर सकते हैं:

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

या

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

लिंक: http://php.net/manual/en/mysqli.set-charset.php


4

मैं PHP (5.2) के पुराने संस्करण को चलाने वाले सर्वर पर इस मुद्दे में भाग गया। मैं JSON_FORCE_OBJECT ध्वज का उपयोग कर रहा था, और जाहिर है कि 5.3 तक समर्थित नहीं है

इसलिए यदि आप उस ध्वज का उपयोग कर रहे हैं तो अपने संस्करण की जांच करना सुनिश्चित करें!

एन्कोडिंग से पहले किसी ऑब्जेक्ट पर केवल एक कास्टिंग डाली जाती है, जैसे:

json_encode((object)$myvar);

3

mb_detect_encodingहो सकता है कि वापसी सही न हो:

$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'))
);

डिफ़ॉल्ट पता लगाने के आदेश के आधार पर, उपरोक्त विभिन्न परिणाम दे सकता है, इसलिए एन्कोडिंग को UTF-8 के रूप में गलत बताया जा रहा है। ( यहां एक बड़ा उदाहरण है ।)

यह संभावना है कि आपका डेटा UTF-8 के रूप में एन्कोडेड नहीं है, इसलिए json_encodeवापस लौट रहा है false। JSON-एन्कोडिंग से पहले आपको अपने स्ट्रिंग्स को UTF-8 में परिवर्तित करना चाहिए:

$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

मैं ob_get_clean () से डेटा प्राप्त कर रहा था और उसी समस्या थी, लेकिन उपरोक्त समाधान मेरे लिए काम नहीं करते हैं। मेरे मामले में समाधान यह था, शायद यह किसी की मदद करेगा।

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

2

उन स्ट्रिंग पर utf8_encode () का उपयोग करने से मेरी समस्या हल हो गई।


1

मैंने एडम बुबेला के जवाब में सुधार किया है। मैं इसे नफरत करता हूं जब ब्लॉक {और} द्वारा बंद नहीं किए जाते हैं। यह क्लीनर है और आप बग का परिचय नहीं देते हैं या शायद यह है कि मैंने अतीत में पर्ल का उपयोग किया था :)

<?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;
    }
}

?>

0

यदि आपको यह डेटा किसी डेटाबेस से mysqli_set_charset($connection, "utf8");मिलता है, तो डेटाबेस से परमेस प्राप्त करते समय कनेक्शन में उपयोग करें


0

यह समस्या कभी-कभी आती है - आप हेडर एक्सेस कंट्रोल पास नहीं कर रहे हैं।

मेरे मामले में अगर मुझे json_encode से पहले कोई इको जोड़ा गया था। यह परिणाम दिखा रहा था अन्यथा खाली पृष्ठ आ रहा था।

मैंने कहा

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

और मेरी समस्या हल हो गई।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.