سؤال

لدي بعض ملفات json التي أحتاج إلى فك تشفيرها وتعديلها ثم تشفيرها دون العبث بأي أحرف.

إذا كان لدي حرف Unicode في سلسلة json فلن يتم فك تشفيره.لست متأكدًا من السبب حيث أن json.org يقول أن السلسلة يمكن أن تحتوي على: any-Unicode-character- except-"-or-\-or- control-character.لكنها لا تعمل في بايثون أيضًا.

{"Tag":"Odómetro"}

يمكنني استخدام utf8_encode الذي سيسمح بفك تشفير السلسلة باستخدام json_decode، ولكن الحرف يتشوه إلى شيء آخر.هذه هي النتيجة من print_r لمصفوفة النتائج.شخصيتان.

[Tag] => Odómetro

عندما أقوم بتشفير المصفوفة مرة أخرى، أفلت الحرف إلى ascii، وهو صحيح وفقًا لمواصفات json:

"Tag"=>"Od\u00f3metro"

هل هناك طريقة ما يمكنني من خلالها الهروب من هذا؟لا يوفر json_encode مثل هذا الخيار، ويبدو أن utf8_encode لا يعمل أيضًا.

يحرر أرى أن هناك خيار unescaped_unicode لـ json_encode.ومع ذلك فهو لا يعمل كما هو متوقع.يا إلهي، إنه موجود فقط على php 5.4.سيتعين علي استخدام بعض التعبيرات العادية لأن لدي 5.3 فقط.

$json = json_encode($array, JSON_UNESCAPED_UNICODE);
Warning: json_encode() expects parameter 2 to be long, string ...
هل كانت مفيدة؟

المحلول

بالنظر إلى كل ما قلته، يبدو أنه الأصلي Odómetro السلسلة التي تتعامل معها مشفرة بـ ISO 8859-1، وليس UTF-8.

لهذا السبب أعتقد ذلك:

  • json_encode أنتجت مخرجات قابلة للتحليل بعد تشغيل سلسلة الإدخال من خلالها utf8_encode, ، والذي يتحول من ISO 8859-1 إلى UTF-8.
  • لقد قلت أنك حصلت على مخرجات "مشوهة" عند الاستخدام print_r بعد القيام utf8_encode, ، لكن المخرجات المشوهة التي حصلت عليها هي في الواقع بالضبط ما سيحدث عند محاولة تحليل نص UTF-8 كـ ISO 8859-1 (ó هو \x63\xb3 في UTF-8، ولكن هذا التسلسل ó في ISO 8859-1.
  • لك htmlentities نجح حل الاختراق. htmlentities يحتاج إلى معرفة ما هو ترميز سلسلة الإدخال للعمل بشكل صحيح.إذا لم تحدد واحدًا، فإنه يفترض ISO 8859-1.(html_entity_decode, ، من المربك أن الإعداد الافتراضي هو UTF-8، لذلك كان لطريقتك تأثير التحويل من ISO 8859-1 إلى UTF-8.)
  • لقد قلت إن لديك نفس المشكلة في بايثون، والتي يبدو أنها تستبعد PHP من كونها المشكلة.

سوف يستخدم PHP \uXXXX الهروب، ولكن كما لاحظت، هذا هو JSON صالح.

لذا، يبدو أنك بحاجة إلى تهيئة اتصالك بـ Postgres بحيث يمنحك سلاسل UTF-8.يشير دليل PHP إلى أنك ستفعل ذلك عن طريق إلحاق options='--client_encoding=UTF8' إلى سلسلة الاتصال.هناك أيضًا احتمال أن تكون البيانات المخزنة حاليًا في قاعدة البيانات بترميز خاطئ.(يمكنك ببساطة استخدام utf8_encode, ، ولكن هذا لن يدعم سوى الأحرف التي تشكل جزءًا من ISO 8859-1).

أخيرًا، كما تمت الإشارة إلى إجابة أخرى، فأنت بحاجة إلى التأكد من أنك تعلن عن مجموعة الأحرف المناسبة، باستخدام رأس HTTP أو غير ذلك (بالطبع، ربما كانت هذه المشكلة بالذات مجرد قطعة أثرية من البيئة التي قمت فيها بعملك print_r اختبارات).

نصائح أخرى

لقد وجدت الطريقة التالية لإصلاح هذه المشكلة ...آمل أن يكون هذا يمكن أن تساعدك.

json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);

JSON_UNESCAPED_UNICODE تمت إضافته في PHP 5.4 لذا يبدو أنك بحاجة إلى ترقية إصدار PHP الخاص بك للاستفادة منه.5.4 لم يصدر بعد!:(

هناك 5.4 مرشح إطلاق ألفا على ضمان الجودة على الرغم من أنك إذا كنت تريد اللعب على جهاز التطوير الخاص بك.

طريقة مخترقة للقيام بـ JSON_UNESCAPED_UNICODE في PHP 5.3.محبط حقًا بسبب دعم PHP json.ربما هذا سوف يساعد شخص آخر.

$array = some_json();
// Encode all string children in the array to html entities.
array_walk_recursive($array, function(&$item, $key) {
    if(is_string($item)) {
        $item = htmlentities($item);
    }
});
$json = json_encode($array);

// Decode the html entities and end up with unicode again.
$json = html_entity_decode($rson);

حاول ضبط utf-8 الترميز في صفحتك:

header('content-type:text/html;charset=utf-8');

هذا يعمل بالنسبة لي:

$arr = array('tag' => 'Odómetro');
$encoded = json_encode($arr);
$decoded = json_decode($encoded);
echo $decoded->{'tag'};
$json = array('tag' => 'Odómetro'); // Original array
$json = json_encode($json); // {"Tag":"Od\u00f3metro"}
$json = json_decode($json); // Od\u00f3metro becomes  Odómetro
echo $json->{'tag'}; // Odómetro
echo utf8_decode($json->{'tag'}); // Odómetro

لقد كنت قريبًا، فقط استخدم utf8_decode.

جرب استخدام:

utf8_decode() and utf8_encode

لتشفير مصفوفة تحتوي على أحرف خاصة، من ISO 8859-1 إلى UTF8.(إذا لم يكن utf8_encode وutf8_decode هو ما يناسبك، فقد يكون هذا أحد الخيارات)

يجب تحويل كل ما هو موجود في ISO-8859-1 إلى UTF8:

$utf8 = utf8_encode('이 감사의 마음을 전합니다!'); //contains UTF8 & ISO 8859-1 characters;    
$iso88591 = mb_convert_encoding($utf8, 'ISO-8859-1', 'UTF-8');
$data = $iso88591;

يجب أن يعمل التشفير بعد ذلك:

$encoded_data = json_encode($data);

تحويل UTF-8 من وإلى ISO 8859-1

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top