পিএইচপি ডমডকুমেন্ট লোড এইচটিএমএল সঠিকভাবে ইউটিএফ -8 এনকোডিং করছে না


194

আমি ডমডকুমেন্টটি ব্যবহার করে কিছু এইচটিএমএল বিশ্লেষণের চেষ্টা করছি, তবে আমি যখন করি তখন হঠাৎ আমার এনকোডিংটি হারাতে থাকে (কমপক্ষে এটি আমার কাছে প্রদর্শিত হয়)।

$profile = "<div><p>various japanese characters</p></div>";
$dom = new DOMDocument();
$dom->loadHTML($profile); 

$divs = $dom->getElementsByTagName('div');

foreach ($divs as $div) {
    echo $dom->saveHTML($div);
}

এই কোডের ফলাফলটি হ'ল আমি জাপানের নয় এমন একাধিক অক্ষর পেয়েছি। তবে, আমি যদি:

echo $profile;

এটি সঠিকভাবে প্রদর্শিত হয়। আমি সেভএইচটিএমএল এবং সেভ এক্সএমএল চেষ্টা করেছি, এবং উভয়ই সঠিকভাবে প্রদর্শন করা যায় না। আমি পিএইচপি 5.3 ব্যবহার করছি।

আমি যা দেখছি:

ã¤ãªãã¤å·ã·ã«ã´ã«ã¦ãã¢ã¤ã«ã©ã³ãç³»ã®å®¶åº­ã«ã9人åå¼ã®5çªç®ã¨ãã¦çã¾ãããå½¼ãå«ãã¦4人ã俳åªã«ãªã£ããç¶è¦ªã¯æ¨æã®ã»ã¼ã«ã¹ãã³ã§ãæ¯è¦ªã¯éµä¾¿å±ã®å®¢å®¤ä¿ã ã£ããé«æ ¡æ代ã¯ã­ã£ãã£ã®ã¢ã«ãã¤ãã«å¤ãã¿ãæè²è³éãåããªããã«ããªãã¯ç³»ã®é«æ ¡ã¸é²å­¦ã

কী প্রদর্শিত হবে:

イリノイ州シカゴにて、アイルランド系の家庭に、9人兄弟の5番目として生まれる。彼を含めて4人が俳優になった。父親は木材のセールスマンで、母親は郵便局の客室係だった。高校時代はキャディのアルバイトに勤しみ、教育資金を受けながらカトリック系の高校へ進学

সম্পাদনা: আমি কোডটি পাঁচটি লাইনে সরল করে দিয়েছি যাতে আপনি নিজেরাই এটি পরীক্ষা করতে পারেন।

$profile = "<div lang=ja><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>";
$dom = new DOMDocument();
$dom->loadHTML($profile);
echo $dom->saveHTML();
echo $profile;

এখানে ফিরে আসা এইচটিএমএল:

<div lang="ja"><p>イリノイ州シカゴã«ã¦ã€ã‚¢ã‚¤ãƒ«ãƒ©ãƒ³ãƒ‰ç³»ã®å®¶åº­ã«ã€</p></div>
<div lang="ja"><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>

এটি আপনাকে সাহায্য করতে পারে। stackoverflow.com/questions/1580543/…
হতাশ

ধন্যবাদ। আমি সেগুলি যাচাই করেছিলাম এবং কিছুই সাহায্য করেনি। আমি পেয়েছি না ????, তবে অন্য কিছু অদ্ভুত লেখা আছে। আমি এটি এখানে আটকানোর চেষ্টা করব, তবে কীভাবে সাইট এটি প্রদর্শিত হবে তা জানি না।
সামান্য A.


কোনও সাফল্য না দিয়ে চেষ্টা করা হয়েছে। আগের মতো একই চরিত্রগুলি ফিরিয়েছে।
সামান্য এ

উত্তর:


513

DOMDocument::loadHTMLআপনার স্ট্রিংটি ISO-8859-1-এ থাকার হিসাবে বিবেচনা করবে যদি আপনি অন্যথায় তা না বলেন। ইউটিএফ -8 স্ট্রিংয়ের ফলাফলগুলি ভুল ব্যাখ্যা করা হচ্ছে।

যদি আপনার স্ট্রিংটিতে একটি এক্সএমএল এনকোডিং ঘোষণা না থাকে তবে আপনি স্ট্রিংটিকে ইউটিএফ -8 হিসাবে বিবেচনা করার জন্য একটি প্রতিশোধ নিতে পারেন:

$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>';
$dom = new DOMDocument();
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $profile);
echo $dom->saveHTML();

যদি আপনি জানতে না পারেন যে স্ট্রিংটিতে ইতিমধ্যে এমন ঘোষণা থাকবে কিনা, স্মার্টডোম ডকুমেন্টে একটি কার্যকারিতা রয়েছে যা আপনাকে সহায়তা করবে:

$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>';
$dom = new DOMDocument();
$dom->loadHTML(mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8'));
echo $dom->saveHTML();

এটি দুর্দান্ত কাজ নয়, তবে যেহেতু সমস্ত চরিত্রগুলি আইএসও -8859-1 (এই কাতানার মতো) তে প্রতিনিধিত্ব করা যায় না, এটি নিরাপদ বিকল্প।


1
হ্যাঁ, এটা এটা করেছে। আপনার সাহায্যের জন্য ধন্যবাদ। আমি সেভএইচটিএমএল, সেভ এক্সএমএল চেষ্টা করেছি, এমন ভাবেনি যে লোড চলাকালীন সমস্যাটি এসেছে।
সামান্য A.

4
Mb_convert_encoding কলটি আমার পক্ষে কাজ করেছে, তবে এনকোডিংয়ের ঘোষণার প্রিপেন্ডিংয়ের কাজ হয়নি। সম্ভবত কারণ নথিতে ইতিমধ্যে একটি বিরোধী ঘোষণা ছিল। অনেক ধন্যবাদ - এটিকে তাড়া করে আমাকে অনেক সময় বাঁচিয়েছে।
পিটার বাগনল

1
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $content);এটি পিএইচপি 7 এ আমার জন্য স্থির করে (তাই এটি এখনও একটি সমস্যা) - এটি সত্যিই বিরক্তিকর সমস্যা কারণ আমি এইচটিএমএল নথিতে utf8 সংজ্ঞায়িত করেছি (সহ <meta charset="UTF-8" />) তবে এর কোনও প্রভাব নেই, এটি <? xML অংশের প্রয়োজন বলে মনে হয়, যা সম্পূর্ণ অপ্রচলিত।
আইকুইটো

11
এখনও 2017 সালে এই উত্তরটি প্রাসঙ্গিক এবং আমার পক্ষেও কাজ করেছে। আমার কাছে আমার ডাটাবেস, মাল্টিবাইট, এইচটিএমএল মেটা ট্যাগ এবং ডিওএম এনকোডিং সমস্ত সেট ছিল utf8 এ এবং এখনও একটি ডওসি থেকে অন্য ডিওকে নোড আমদানিতে খারাপ এনকোডিং ছিল। php.net/manual/en/function.mb-convert-encoding.php ঠিক করা ছিল।
লুই লাউডোগ ট্রটিটিয়ার

6
$dom->loadHTML(mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8'));দুর্দান্ত কাজ! আপনাকে ধন্যবাদ,
ভি

66

সমস্যাটি হচ্ছে saveHTML()এবং সাথেইsaveXML() উভয়ই ইউনিক্সে সঠিকভাবে কাজ করে না। ইউনিক্স-এ ব্যবহার করার সময় তারা ইউটিএফ -8 অক্ষর সঠিকভাবে সংরক্ষণ করে না তবে তারা উইন্ডোজে কাজ করে।

কাজটি খুব সহজ:

আপনি যদি ডিফল্ট চেষ্টা করেন তবে আপনি বর্ণিত ত্রুটিটি পাবেন

$str = $dom->saveHTML(); // saves incorrectly

আপনাকে যা করতে হবে তা নিম্নরূপ সংরক্ষণ করতে হবে:

$str = $dom->saveHTML($dom->documentElement); // saves correctly

কোডের এই লাইনটি আপনার ইউটিএফ -8 টি অক্ষর সঠিকভাবে সংরক্ষণ করতে পাবে। আপনি যদি ব্যবহার করছেন তবে একই রকম ব্যবহার করুন saveXML()


হালনাগাদ

নীচে মন্তব্য বিভাগে " জ্যাক এম " দ্বারা প্রস্তাবিত হিসাবে , এবং " পামেলা " এবং " মার্কো অরেলিও দেলিউ " দ্বারা যাচাই করা হয়েছে , নিম্নলিখিত প্রকরণটি আপনার ক্ষেত্রে কাজ করতে পারে:

$str = utf8_decode($dom->saveHTML($dom->documentElement));

বিঃদ্রঃ

  1. আপনি যখন saveHTML()প্যারামিটার ছাড়াই ব্যবহার করেন তখন ইংরেজি অক্ষরগুলির কোনও সমস্যা হয় না (কারণ ইংরেজি অক্ষরগুলি ইউটিএফ -8 এ একক বাইট অক্ষর হিসাবে সংরক্ষণ করা হয়)

  2. আপনার যখন মাল্টি-বাইট অক্ষর (যেমন চীনা, রাশিয়ান, আরবী, হিব্রু, ... ইত্যাদি) থাকে তখন সমস্যাটি ঘটে happens

আমি এই নিবন্ধটি পড়ার পরামর্শ দিচ্ছি: http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/ । আপনি বুঝতে পারবেন কীভাবে ইউটিএফ -8 কাজ করে এবং কেন আপনার এই সমস্যা রয়েছে। এটি আপনাকে প্রায় 30 মিনিট সময় নেবে, তবে এটি সময় ভালভাবে কাটে।


5
এই সমাধানটি ব্যবহার করার সময় আমাকে utf8_decode করতে হয়েছিল। ধন্যবাদ!
জ্যাক এম।

9
আমার বিশেষ অক্ষরগুলি সংরক্ষণ করার জন্য এটি utf8_decode ($ dom-> saveHTML (dom-> documentElement)) হতে হয়েছিল। অন্যথায়, তারা কেবল অন্য কিছু হয়ে গেছে। এটি অন্য কাউকে সাহায্য করার ক্ষেত্রে কেবল এটির উল্লেখ করা।
জ্যাক এম

4
ধন্যবাদ @ মিঃ জ্যাক অদ্ভুত চরিত্রগুলি ছাড়া এটি প্রদর্শন করতে আমাকেও একই কাজ করতে হয়েছিল$str = utf8_decode($dom->saveHTML($dom->documentElement));
পামেলা

1
utf8_decode($dom->saveHTML($dom->documentElement));এটা আমার জন্য নিখুঁতভাবে করেছে
মার্কো অরেলিও ডেলিউ

2
আপনি এই সঙ্গে আমার জীবন বাঁচাতে। আমি এই উত্তরটি সর্বাবস্থায় চেয়েছিলাম! ধন্যবাদ!
পাওলো হগো

15

আসল উত্স ফাইলটি ইউটিএফ -8 হিসাবে সংরক্ষিত হয়েছে তা নিশ্চিত করুন (আপনি এটি নিশ্চিত করার জন্য ইউটিএফ -8 সহ প্রস্তাবিত অ-প্রস্তাবিত বিওএম চার্সও চেষ্টা করতে পারেন)।

এইচটিএমএলের ক্ষেত্রেও, আপনি metaট্যাগ ব্যবহার করে সঠিক এনকোডিং ঘোষণা করেছেন তা নিশ্চিত করুন :

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

যদি এটি কোনও সিএমএস হয় (যেমন আপনি জুমলার সাথে আপনার প্রশ্নটি ট্যাগ করেছেন) আপনার এনকোডিংয়ের জন্য উপযুক্ত সেটিংস কনফিগার করতে হবে।


আপনি কী বলছেন তা আমি বুঝতে পেরেছি, তবে চরিত্রগুলি প্রদর্শন করতে আমার কোনও সমস্যা নেই। যদি আমি "প্রতিধ্বনি $ প্রোফাইল" করি; এটা ঠিক কাজ করে। ডমডকুমেন্ট এটির ব্যর্থতা পেতে শুরু করে it's
সামান্য A.

2
আপনার মেটা সেভ এইচটিএমএলকে ASCII এর উপরের সমস্ত কিছু সত্তায় এনকোড করা থেকে বিরত রাখে। সমাধানটি আমি সন্ধান করছিলাম :)
সড করুন

2
পার্শ্ব নোট হিসাবে, নতুন <meta charset="UTF-8">ট্যাগটি ডোমডোকামেন্টের সাথে কাজ করে না।
টেলান

10

আপনি utf-8এই জাতীয় এনকোডিং প্রয়োগকারী একটি লাইন উপসর্গ করতে পারেন:

@$doc->loadHTML('<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $profile);

এবং তারপরে আপনি ইতিমধ্যে আপনার কাছে থাকা কোডটি দিয়ে চালিয়ে যেতে পারেন, যেমন:

$doc->saveXML()

10

এটি বের করতে আমার কিছুটা সময় লেগেছে তবে এখানে আমার উত্তর।

ডোমডোকামেন্ট ব্যবহার করার আগে আমি url পুনরুদ্ধার করতে ফাইল_জেট_কন্টেন্টগুলি ব্যবহার করব এবং তারপরে স্ট্রিং ফাংশন দিয়ে তাদের প্রক্রিয়া করব। সম্ভবত সেরা উপায় না কিন্তু দ্রুত। ডোমকে ঠিক তত দ্রুত বিশ্বাস করার পরে আমি নিম্নলিখিতগুলি চেষ্টা করেছিলাম:

$dom = new DomDocument('1.0', 'UTF-8');
if ($dom->loadHTMLFile($url) == false) { // read the url
    // error message
}
else {
    // process
}

যথাযথ মেটা ট্যাগ, পিএইচপি সেটিংস এবং এখানে এবং অন্য কোথাও দেওয়া সমস্ত প্রতিকারের পরেও ইউটিএফ -8 এনকোডিং সংরক্ষণে এটি দর্শনীয়ভাবে ব্যর্থ হয়েছে। এখানে কি কাজ করে:

$dom = new DomDocument('1.0', 'UTF-8');
$str = file_get_contents($url);
if ($dom->loadHTML(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8')) == false) {
}

ইত্যাদি এখন বিশ্বের সাথে ঠিক আছে। আশাকরি এটা সাহায্য করবে.


কেবলমাত্র উপরে আমার উত্তরে যোগ করতে চেয়েছিলাম যে এটির সমাধানের আরও একটি উপায় নীচের সাথে রয়েছে, অন্যত্র পাশাপাশি প্রস্তাবিত: যদি (om dom-> loadHTML ('<? XML encoding = "UTF-8">'। $ Str) = = মিথ্যা)। আমার উত্তর পোস্ট করার পরে আমি একটি উপলক্ষ পেয়েছি যেখানে আমার প্রথম পরামর্শটি ব্যর্থ হয়েছিল তবে দ্বিতীয়টি কাজ করেছিল।
স্যাম

এমনকি প্যারামগুলি ছাড়াই আমার জন্য কাজ করে DomDocument('1.0', 'UTF-8')। তবে আমার ক্ষেত্রে কেবল আংশিক এইচটিএমএল লোড হয়।
JKB

5

আপনাকে অবশ্যই আপনার এইচটিএমএল এর একটি সংস্করণ ডোমডোকামেন্টকে এমন শিরোনাম দিয়ে খাওয়াতে হবে যাতে বোঝা যায়। ঠিক এইচটিএমএল 5 এর মতো।

$profile ='<?xml version="1.0" encoding="'.$_encoding.'"?>'. $html;

আপনার এইচটিএমএলকে যথাসম্ভব বৈধ রাখাই ভাল ধারণা, সুতরাং আপনি যখন কোয়েরি শুরু করবেন তখন আপনি: সমস্যার সমাধান করতে পারবেন না: চারপাশে :-) এবং দূরে থাকুন htmlentities!!!! এটি একটি প্রয়োজনীয় পিছনে এবং সংস্থান সম্পদ নষ্ট করা। আপনার কোড উন্মাদ রাখুন !!!!


5

আমি একটি মাঞ্জারোতে পিএইচপি 7.3.8 ব্যবহার করছি এবং আমি ফারসি বিষয়বস্তু নিয়ে কাজ করছিলাম। এটি আমার সমস্যার সমাধান করেছে:

$html = 'hi</b><p>سلام<div>の家庭に、9 ☆';
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
print $doc->saveHTML($doc->documentElement) . PHP_EOL . PHP_EOL;

এই ঠিক একই পরামর্শ স্যাম বছর আগে এই একই পৃষ্ঠায় দেওয়া হয়েছিল। কোনও অপ্রয়োজনীয় তথ্য পোস্ট করবেন না দয়া করে।
মিকম্যাকুসা

4

আমার জন্য কাজ সন্ধানকারী:

$dom = new \DOMDocument;
$dom->loadHTML(utf8_decode($html));
...
return  utf8_encode( $dom->saveHTML());

2
সাবধান থাকুন, utf8_decode তথ্য হারাতে পারে (একটি দিয়ে প্রতিস্থাপন ?)
jwal

2

সঠিক ফলাফলের জন্য এটি ব্যবহার করুন

$dom = new DOMDocument();
$dom->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $profile);
echo $dom->saveHTML();
echo $profile;

এই অপারেশন

mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8');

এটি খারাপ উপায়, কারণ & lt; এর মতো বিশেষ প্রতীকগুলি; , & জিটি; $ প্রোফাইলে থাকতে পারে এবং তারা mb_convers__coding পরে দুবার রূপান্তর করবে না। এটি এক্সএসএস এবং ভুল এইচটিএমএলের গর্ত।


1

আমার পক্ষে কাজ করা একমাত্র জিনিসটির গৃহীত উত্তর

$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>';
$dom = new DOMDocument();
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $profile);
echo $dom->saveHTML();

যাহোক

এটি <?xml encoding="utf-8" ?>নথির আউটপুট থাকার ক্ষেত্রে নতুন সমস্যা নিয়ে আসে ।

আমার জন্য সমাধানটি তখন করা হয়েছিল

foreach ($doc->childNodes as $xx) {
    if ($xx instanceof \DOMProcessingInstruction) {
        $xx->parentNode->removeChild($xx);
    }
}

কিছু সমাধান আমাকে জানিয়েছিল যে xmlশিরোনামটি সরাতে , আমাকে সম্পাদন করতে হবে

$dom->saveXML($dom->documentElement);

এটি আমার পক্ষে আংশিক দলিল হিসাবে কাজ করেনি (যেমন দুটি <p>ট্যাগ সহ একটি ডক ), <p>যেখানে ফিরে আসা ট্যাগগুলির মধ্যে একটি ।


0

সমস্যাটি হ'ল যখন আপনি ডোমডোকামেন্ট :: সেভ এইচটিএমএল () ফাংশনে প্যারামিটার যুক্ত করেন, আপনি এনকোডিংটি হারাবেন। কয়েকটি ক্ষেত্রে, আপনাকে প্যারামিটারটি ব্যবহার এড়াতে হবে এবং আপনার সন্ধান করা সন্ধানের জন্য পুরানো স্ট্রিং ফাংশন ব্যবহার করতে হবে।

আমি মনে করি পূর্ববর্তী উত্তরটি আপনার পক্ষে কাজ করে, তবে যেহেতু এই কার্যকারিতাটি আমার পক্ষে কাজ করে নি, আমি পিপিএলকে আমার ক্ষেত্রে যারা সাহায্য করতে পারে তার জন্য আমি এই উত্তরটি যুক্ত করছি।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.