Висновок PHP, що показує маленькі чорні діаманти зі знаком питання


81

Я пишу PHP-програму, яка бере з джерела бази даних. Деякі з варчарів мають цитати, які відображаються у вигляді чорних діамантів із знаком запитання ( , ЗАМІННИЙ ХАРАКТЕР , я припускаю з тексту Microsoft Word).

Як я можу використовувати php для вилучення цих символів?


1
Не роздягайте їх, фіксуйте час. Див. Також "чорний діамант" у stackoverflow.com/questions/38363566/…
Рік Джеймс,

Відповіді:


75

Якщо ви бачите цей символ ( U + FFFD "ЗАМІННИЙ ХАРАКТЕР"), це зазвичай означає, що сам текст закодований у певній формі однобайтового кодування, але інтерпретований в одному з кодувань Unicode (UTF8 або UTF16).

Якби це було навпаки, це (зазвичай) виглядало б приблизно так: ä.

Ймовірно, оригінальним кодуванням є ISO-8859-1, також відомий як Latin-1. Ви можете перевірити це, не змінюючи сценарій: браузери дають вам можливість повторно інтерпретувати сторінку в іншому кодуванні - у Firefox використовуйте "Перегляд" -> "Кодування символів".

Щоб браузер використовував правильне кодування, додайте заголовок HTTP наступним чином:

header("Content-Type: text/html; charset=ISO-8859-1");

або помістіть кодування в метатег:

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

Крім того, ви можете спробувати прочитати з бази даних в іншому кодуванні (бажано UTF-8) або перетворити текст за допомогою iconv().


Поки це найближче рішення. Однак зараз у мене є мета: <meta http-equiv = "Content-Type" content = "text / html; charset = UTF-8"> і я використовую iconv для перетворення з iso-8859-1 на utf- 8, символи тепер відображаються у вигляді коробки з 0096 та 0092, що стосуються спеціальних ('або -) будь-яких інших думок?

так, у мене є інша думка: зробіть домашнє завдання ... ви, мабуть, використали неправильне кодування джерела. 0x92 та 0x96 - це "вигнута одинарна лапка" та "тире" у Windows-1252. чи може це бути правильним? ви пробували трюк браузера?

Заголовок PHP виправив для мене речі при використанні класу PDF2Text.
Джеймс П.

Не повинно header("Content-Type: text/plain; charset=ISO-8859-1");бути header("Content-Type: text/html; charset=ISO-8859-1");?
j08691

@ j08691: ну, це зараз залежить від типу вмісту, чи не так?

41

Це питання кодування. Таким чином, це може помилитися на багатьох різних рівнях, але, швидше за все, рядки у вашій базі даних закодовані utf-8, і ви представляєте їх як iso-8859-1. Або навпаки.

Правильний спосіб вирішити цю проблему - це виправити набори символів. Найпростіша стратегія, оскільки ви використовуєте PHP, полягає у використанні iso-8859-1 у всій програмі. Для цього потрібно переконатися, що:

  • Усі вихідні файли PHP зберігаються як iso-8859-1 (не плутати з cp-1252).
  • Ваш веб-сервер налаштований на обслуговування файлів charset=iso-8859-1
  • Крім того, ви можете замінити налаштування веб-серверів у PHP-документі, використовуючи header.
  • Крім того, ви можете вставити мета-тег у свій HTML, який вказує те саме, але це не є суворо необхідним.
  • Ви також можете вказати accept-charsetатрибут для своїх <form>елементів.
  • Таблиці баз даних визначаються з кодуванням як latin1
  • З'єднання з базою даних між PHP і базою даних встановлено на latin1

Якщо у вашій базі даних уже є дані, вам слід пам’ятати, що вони, ймовірно, вже переплутані. Якщо ви ще не у фазі виробництва, просто витріть все це і починайте спочатку. В іншому випадку вам доведеться зробити деяке очищення даних.

Примітка про мета-теги, оскільки всі неправильно розуміють, що вони собою представляють:

Коли веб-сервер обслуговує файл (HTML-документ), він надсилає деяку інформацію, яка не відображається безпосередньо у браузері. Це відоме як HTTP-заголовки. Одним із таких заголовків є Content-Typeзаголовок, який вказує тип mime файлу (Напр. text/html), А також кодування (він же набір символів). Хоча більшість веб-серверів надсилатимуть Content-Typeзаголовок з charsetінформацією, це необов’язково. Якщо його немає, браузер замість цього інтерпретує будь-які мета-теги за допомогою http-equiv="Content-Type". Важливо розуміти, що мета-тег інтерпретується лише в тому випадку, якщо веб-сервер не надсилає заголовок. На практиці це означає, що він використовується лише в тому випадку, якщо сторінка зберігається на диску, а потім відкривається звідти.

На цій сторінці дуже добре пояснено ці речі.


38

Я також стикався з цим питанням. Тим часом я натрапив на три випадки, коли це сталося:

  1. substr ()

    Я використовував substr()на рядку UTF8, який вирізав символи UTF8, тому символи вирізання не можуть відображатися правильно. Використовуйте mb_substr($utfstring, 0, 10, 'utf-8');замість цього. Кредити

  2. htmlspecialchars ()

    Іншою проблемою було використання htmlspecialchars()на рядку UTF8. Виправлення полягає у використанні:htmlspecialchars($utfstring, ENT_QUOTES, 'UTF-8');

  3. preg_replace ()

    Нарешті я з’ясував, що preg_replace()може призвести до проблем з UTF. Наприклад, код $string = preg_replace('/[^A-Za-z0-9ÄäÜüÖöß]/', ' ', $string);перетворив рядок UTF "F (×) = 2 × -3" у "F 2 ". Виправлення полягає у використанні mb_ereg_replace()замість цього.

Сподіваюся, ця додаткова інформація допоможе позбутися таких проблем.


2
Саме з цією проблемою я стикався. Не знав про функції рядка mb.
Ren

1
Це траплялося і для strtolowerфункції. Усі функції, що стосуються посібника PHP
micaball

13

Як згадувалося у попередніх відповідях, це відбувається тому, що ваш текст було записано до бази даних у iso-8859-1кодуванні або будь-якому іншому форматі.

Отже, вам просто потрібно перетворити дані, utf8перш ніж їх виводити.

$text = “string from database”;
$text = utf8_encode($text);
echo $text;

11

Щоб переконатися, що для вашого з’єднання MYSQL встановлено значення UTF-8 (або latin1, залежно від того, що ви використовуєте), ви можете зробити це, щоб:

$con = mysql_connect("localhost","username","password");    
mysql_set_charset('utf8',$con);

або скористайтеся цим, щоб перевірити, яку кодировку ви використовуєте:

$con = mysql_connect("localhost","username","password");   
$charset = mysql_client_encoding($con);
echo "The current character set is: $charset\n"; 

Більше інформації тут: http://php.net/manual/en/function.mysql-set-charset.php


Це було дуже корисно і вирішило проблему мого кодування котирувань у даних, що надходять із віддаленої бази даних MySQL, дякую!
трибулант

@ptwiggerl це дуже допомогло.
unixmiah

Я переніс веб-сайт на інший сервер і зіткнувся з цією проблемою, mysql_set_charset ('utf8', $ con); вирішив!
Рафаель Моні

5

На основі вашого опису проблеми, дані у вашій базі даних майже напевно кодуються як Windows-1252 , а ваша сторінка майже напевно обслуговується як ISO-8859-1 . Ці два набори символів еквівалентні, за винятком того, що Windows-1252 містить 16 зайвих символів, яких немає у ISO-8859-1, включаючи ліві та праві фігурні лапки.

Вважаючи мій аналіз правильним, найпростішим рішенням є обслуговування вашої сторінки як Windows-1252. Це спрацює, оскільки всі символи, що містяться в ISO-8859-1, також є в Windows-1252. У PHP ви можете змінити кодування наступним чином:

header('Content-Type: text/html; charset=Windows-1252');

Тим не менш, ви дійсно повинні перевірити, яке кодування символів ви використовуєте у своїх HTML-файлах та вмісті вашої бази даних, і подбати про послідовність або правильно перетворювати там, де це неможливо.


Проблема цієї пропозиції полягає в тому, що на даний момент дані, швидше за все, є поєднанням різних наборів символів. Якщо ви точно не знаєте, що пішло не так, це просто стає ще більш заплутаним, якщо ви просто кинете сюди-туди випадкові виправлення.
troelskn

Я згоден. Я кілька відредагував свою публікацію, щоб засвідчити, що це рішення не замінює знання того, що ти робиш. Однак я дійшов висновку, що більшість розробників або не здатні зрозуміти цю проблему, або просто не байдужі. Здається, це принаймні раз на місяць з’являється там, де я працюю.
Даніель Кассіді,

Це майже моє спостереження теж. За те, що я дбаю, вони жнуть, коли сіють. Але ти, мабуть, маєш рацію; Швидше за все, його дані справді є cp-1252 .. Принаймні деякі з них є.
troelskn

Я спробував купу рішень того самого питання. Цей був негайно ефективний з найменшими зусиллями
шестиструнний

4

Я вирішив вилучити цих символів із рядка, виконавши це -

ini_set('mbstring.substitute_character', "none"); 
$text= mb_convert_encoding($text, 'UTF-8', 'UTF-8');

1
Це чудово, це працювало для мене, спробував utf8_encode та ut8_decode також - не працював. Але це рішення спрацювало в моєму випадку. Дякую.
Санджеєв Шетті

4

Додайте цю функцію до своїх змінних utf8_encode ($ ваша змінна);


Будь ласка, детальніше опишіть цю відповідь.
ppovoski

1
це функція, яка дозволяє вилучити спеціальний символ і повертає вам стандарт utf8 символу google.com/…
rk_programmer

Це працювало з дробами, які відображались неправильно.
Рог

На мою думку, це має бути прийнятою відповіддю; це єдиний метод, який у мене спрацював, я спробував усі.
квантм

4

Просто вставте цей код, починаючи з початку сторінки.

<?php
header("Content-Type: text/html; charset=ISO-8859-1");
?>

Будь ласка, додайте коротке пояснення того, що робить код.
Зал КТ

1
Цей PHP-код дозволяє дозволити набір символів "ISO-8859-1", і в цьому наборі символів цей символ відображається як символ.
Harshil Kaneria



1

Це може бути спричинено невідповідністю Unicode або іншим кодом. Спробуйте змінити набір символів у вашому браузері, в налаштуваннях текст буде виглядати нормально. Тоді питання про те, як перетворити вміст бази даних у набір символів, який ви використовуєте для відображення. (Що насправді може бути просто додаванням оператора коду коду utf-8 до вашого виводу.)


1

що я врешті-решт зробив після того, як я зафіксував свої таблиці, це зробити його резервну копію та змінити налаштування на utf-8, потім я змінив свій файл дампа так, що DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci є моїми наборами символів

тепер у мене більше не виникає проблем із набором символів, оскільки база даних та браузер є utf8.

Я зрозумів, що це спричинило. Це була веб-сторінка + ефекти браузера на БД. На терміналах, які є Linux (ubuntu + firefox), він кодував базу даних латиницею1, що і встановлюється в таблицях. Але на терміналах вікон 10 + краю записи були закодовані в utf8. Також я помітив, що у Windows 10 виникають проблеми з латиною1, тому я вирішив нахилитися вітром і перетворити все на utf8.

Я зрозумів, що це проблема Windows 10, тому що ми почали використовувати термінали win 10. тому ще раз помилки Microsoft викликають проблеми. Я все ще не знаю, чому кодування змінюється на формах, оскільки браузер у Windows 10 показує набір символів latin1, але коли він переходить у кодування utf8, і я отримую аномалію даних. але в linux + firefox він цього не робить.


1

У моєму випадку це спрацювало:

$text = utf8_decode($text)

Я перетворюю символ чорного діаманта на знак запитання, щоб ви могли:

$text = str_replace('?', '', utf8_decode($text));

1
попередження про $text = розділ: це змінить всі знаки запитання всередині рядка, а не тільки діамант
treyBake

1

Просто додайте ці рядки перед заголовками.

.doc/docxБуде отримано точний формат файлів:

 if(ini_get('zlib.output_compression'))

   ini_set('zlib.output_compression', 'Off');
 ob_clean();

0

Ви також можете змінити набір символів у своєму браузері. Просто з причин налагодження.


0

Використання одного і того ж коду (як пропонується тут) як в базі даних, так і в HTML мені не вдалося ... Тому, пам’ятаючи, що код генерується як HTML, я вирішив використовувати &quot;(HTML-код) або &#34;(ISO Latin-1 код) у моєму тексті бази даних, де використовувались лапки. Це вирішило проблему, одночасно надавши мені лапки. Дивно зауважити, що до цього рішення лише деякі лапки та апострофи відображалися неправильно, тоді як інші, проте, спеціальний код працював у всіх випадках.


0

Я запустив код "виявлення кодування" після моєї зміни зіставлення в phpmyadmin, і тепер він виглядає як Latin_1.

але ось щось я натрапив, дивлячись на іншу аномалію даних у своєму додатку та як я це виправив:

Я щойно імпортував таблицю зі змішаним кодуванням (із алмазними знаками запитання в деяких рядках, і всі вони були в одному стовпці.), Отже, ось мій код виправлення. Я використовував процес utf8_decode, який займає невизначений заповнювач і призначає простий знак питання замість "алмазного знака питання", тоді я використовував str_replace, щоб замінити знак питання пробілом між лапками. ось [код]

    include 'dbconnectfile.php';

  //// the variable $db comes from my db connect file
   /// inx is my auto increment column
   /// broke_column is the column I need to fix

      $qwy = "select inx,broke_column from Table ";
      $res = $db->query($qwy); 

      while ($data = $res->fetch_row()) {
      for ($m=0; $m<$res->field_count; $m++) {
           if ($m==0){ 
           $id=0;
           $id=$data[$m];
       echo $id;
           }else if ($m==1){ 
             $fix=0;
             $fix=$data[$m];


             $fix = utf8_decode($fix);
             $fixx =str_replace("?"," ",$fix);

        echo $fixx;

        ////I echoed the data to the screen because I like to see something as I execute it :)
            }
            }
         $insert= "UPDATE Table SET broke_column='".$fixx."'  where inx='".$id."'";
          $insresult= $db->query($insert);
      echo"<br>";
        }

        ?>        

наведений вище код виправляє мою таблицю. але я б рекомендував коментувати заяви про оновлення, щоб ви спочатку побачили, чи збирається це вирішити проблему.
drtechno

0

Для глобальних цілей.

Замість перетворення, кодифікації, декодифікації кожного тексту я волію залишати їх такими, якими вони є, і замість цього змінювати налаштування php сервера. Так,

  1. Нехай діаманти

  2. У браузері в меню перегляду виберіть «кодування тексту» та знайдіть той, який дозволить вам правильно бачити ваш текст.

  3. Відредагуйте файл php.ini та додайте:

    default_charset = "ISO-8859-1"

або замість ISO-8859 той, який відповідає кодуванню тексту.


0

Коли ви видобуваєте дані з будь-якого місця, вам слід використовувати функції з префіксом md_FUNC_NAME.

Була та сама проблема, і це мені допомогло.

Або ви можете знайти код цього символу та використати регулярний вираз для видалення цих символів.


-2

Перейдіть до свого phpmyadmin і виберіть свою базу даних і просто збільште довжину / значення поля цієї таблиці до 500 або 1000, і це вирішить вашу проблему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.