web-dev-qa-db-fra.com

PHP sortie montrant des petits diamants noirs avec un point d'interrogation

J'écris un programme php qui tire d'une source de base de données. Certains des varchars ont des guillemets qui affichent des diamants noirs avec un point d'interrogation ( , REMPLACEMENT CHARACTER , je suppose à partir du texte Microsoft Word).

Comment puis-je utiliser PHP pour supprimer ces caractères?

66

Si vous voyez ce caractère ( U + FFFD "REPLACEMENT CHARACTER"), cela signifie généralement que le texte lui-même est codé sous une forme de codage à un octet mais interprété dans l'un des codages unicode (UTF8 ou UTF16).

Si c'était l'inverse, cela ressemblerait (généralement) à quelque chose comme ceci: ¤.

Le codage d'origine est probablement ISO-8859-1, également connu sous le nom de Latin-1. Vous pouvez vérifier cela sans avoir à changer votre script: les navigateurs vous donnent la possibilité de réinterpréter une page dans un encodage différent - dans Firefox, utilisez "Affichage" -> "Encodage du caractère". 

Pour que le navigateur utilise le bon codage, ajoutez un en-tête HTTP comme ceci:

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

ou mettre l'encodage dans une balise meta:

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

Vous pouvez également essayer de lire dans la base de données avec un autre codage (UTF-8, de préférence) ou convertir le texte avec iconv() .

66
user3850

C'est un problème de jeu de caractères. En tant que tel, il peut s'être mal passé à différents niveaux, mais très probablement, les chaînes de votre base de données sont codées en utf-8 et vous les présentez sous la forme iso-8859-1. Ou l'inverse.

La bonne façon de résoudre ce problème est d’obtenir vos jeux de caractères. La stratégie la plus simple, puisque vous utilisez PHP, consiste à utiliser iso-8859-1 dans l’ensemble de votre application. Pour ce faire, vous devez vous assurer que:

  • Tous les fichiers source PHP sont enregistrés au format iso-8859-1 (à ne pas confondre avec cp-1252).
  • Votre serveur Web est configuré pour servir les fichiers avec charset=iso-8859-1
  • Alternativement, vous pouvez remplacer les paramètres des serveurs Web depuis le document PHP, en utilisant header .
  • De plus, vous peut insérez une méta-balise dans votre code HTML, qui spécifie la même chose, mais ce n'est pas strictement nécessaire.
  • Vous peut spécifiez également l'attribut accept-charset sur vos éléments <form>.
  • Les tables de base de données sont définies avec le codage latin1
  • La connexion à la base de données entre PHP et la base de données est définie sur latin1

Si vous avez déjà des données dans votre base de données, sachez qu'elles sont probablement déjà foirées. Si vous n'êtes pas encore en phase de production, effacez tout et recommencez. Sinon, vous devrez nettoyer certaines données.

Une note sur les méta-tags, car tout le monde comprend mal ce qu'ils sont:

Lorsqu'un serveur Web sert un fichier (un document HTML), il envoie des informations qui ne sont pas présentées directement dans le navigateur. Ceci est connu sous le nom d'en-tête HTTP. Un tel en-tête est l’en-tête Content-Type, qui spécifie le type MIME du fichier (par exemple, text/html) ainsi que l’encodage (aka charset) . Bien que la plupart des serveurs Web envoient un en-tête Content-Type avec des informations charset, il est facultatif. Si ce n'est pas le cas, le navigateur interprétera les méta-tags avec http-equiv="Content-Type". Il est important de réaliser que la méta-balise est interprétée uniquement si le serveur Web n'envoie pas l'en-tête. En pratique, cela signifie qu’elle n’est utilisée que si la page est enregistrée sur un disque puis ouverte à partir de là.

Cette page a une très bonne explication de ces choses.

41
troelskn

J'ai aussi fait face à ce problème. Entre temps, j'ai eu trois cas où cela s'est produit:

  1. substr () 

    J'utilisais substr() sur une chaîne UTF8 qui coupait les caractères UTF8, ainsi les caractères coupés ne pouvaient pas être affichés correctement. Utilisez mb_substr($utfstring, 0, 10, 'utf-8'); à la place. Crédits

  2. htmlspecialchars () 

    Un autre problème consistait à utiliser htmlspecialchars() sur une chaîne UTF8. Le correctif est d'utiliser: htmlspecialchars($utfstring, ENT_QUOTES, 'UTF-8');

  3. preg_replace () 

    Enfin, j'ai découvert que preg_replace() peut entraîner des problèmes avec UTF. Le code $string = preg_replace('/[^A-Za-z0-9ÄäÜüÖöß]/', ' ', $string);, par exemple, a transformé la chaîne UTF "F (×) = 2 × -3" en "F 2". Le correctif consiste à utiliser mb_ereg_replace() à la place.

J'espère que ces informations supplémentaires aideront à résoudre de tels problèmes.

26
Kai Noack

Comme mentionné dans les réponses précédentes, cela se produit parce que votre texte a été écrit dans la base de données avec le codage iso-8859-1 ou tout autre format.

Il vous suffit donc de convertir les données en utf8 avant de les sortir. 

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

Pour vous assurer que votre connexion MYSQL est définie sur UTF-8 (ou latin1, selon ce que vous utilisez), vous pouvez procéder comme suit:

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

ou utilisez ceci pour vérifier quel charset vous utilisez: 

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

Plus d'infos ici: http://php.net/manual/en/function.mysql-set-charset.php

7
ptwiggerl

Sur la base de votre description du problème, les données de votre base de données sont presque certainement codées sous le nom Windows-1252 et votre page est très certainement affichée sous le nom ISO-8859-1 . Ces deux jeux de caractères sont équivalents, à la différence que Windows-1252 comporte 16 caractères supplémentaires qui ne sont pas présents dans ISO-8859-1, y compris les guillemets bouclés à gauche et à droite.

En supposant que mon analyse soit correcte, la solution la plus simple consiste à diffuser votre page sous Windows-1252. Cela fonctionnera car tous les caractères qui sont dans ISO-8859-1 le sont également dans Windows-1252. Dans PHP, vous pouvez modifier le codage comme suit:

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

Cependant, vous devez vraiment vérifier le codage de caractères que vous utilisez dans vos fichiers HTML et le contenu de votre base de données, et veillez à être cohérent ou à convertir correctement lorsque cela n’est pas possible.

6
Daniel Cassidy

J'ai choisi de retirer ces caractères de la chaîne en faisant ceci - 

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

Essayez ceci s'il vous plaît

mb_substr ($ description, 0, 490, "UTF-8");

3
Vishal P Gothi

Ajoutez cette fonction à vos variables Utf8_encode ($ votre variable);

3
rk_programmer

Ajoutez simplement ces lignes avant les en-têtes.

Le format exact des fichiers .doc/docx sera récupéré:

 if(ini_get('zlib.output_compression'))

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

ce que j’ai finalement fait après avoir corrigé mes tables, c’était de sauvegarder les données et de modifier les paramètres en utf-8, puis j’ai modifié mon fichier de vidage pour que DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci soient mes entrées de jeu de caractères. 

maintenant je n'ai plus de problèmes de jeu de caractères car la base de données et le navigateur sont utf8.

J'ai compris sa cause. C'était la page Web + les effets du navigateur sur la base de données. Sur les terminaux qui sont linux (Ubuntu + firefox), il encodait la base de données en latin1, ce qui correspond aux tabes. Mais sur les terminaux Windows 10 + Edge, les entrées ont été codées de force dans utf8. De plus, j'ai remarqué que windows 10 avait des problèmes avec latin1 et j'ai donc décidé de me pencher avec le vent et de convertir le tout en utf8.

Je pensais que c’était un problème lié à Windows 10, car nous avions commencé à utiliser les terminaux Win 10 . Je ne sais toujours pas pourquoi l’encodage change sur les formulaires, car le navigateur de Windows 10 affiche le jeu de caractères latin1, mais quand il est encodé en utf8, je reçois l’anomalie de données. mais sous linux + firefox, cela ne se fait pas.

1
drtechno

Cela vous aidera. Mettez ceci dans la balise <head>

<meta charset="iso-8859-1">
1
Prasant Kumar

Cela peut être dû à l'unicode ou à une autre incompatibilité de jeu de caractères. Essayez de changer le jeu de caractères dans votre navigateur, dans les paramètres, le texte semblera OK. Ensuite, la question est de savoir comment convertir le contenu de votre base de données en jeu de caractères que vous utilisez pour l'affichage. (Ce qui peut être en fait juste d'ajouter l'instruction utf-8 charset à votre sortie.)

1
che

Utiliser le même jeu de caractères (comme suggéré ici) dans la base de données et le code HTML n’a pas fonctionné pour moi ... Alors, rappelant que le code est généré au format HTML, j’ai choisi d’utiliser le &quot; (code HTML) ou le &#34; -1 code) dans le texte de ma base de données où les guillemets ont été utilisés. Cela a résolu le problème tout en me fournissant un guillemet. Il est étrange de noter qu'avant cette solution, seuls certains des guillemets et des apostrophes ne s'affichaient pas correctement, alors que d'autres le faisaient, cependant, le code spécial fonctionnait dans tous les cas.

0
GrafixGuy

J'ai exécuté le code "détecter l'encodage" après le changement de classement dans phpmyadmin et il se présente maintenant sous la forme Latin_1.

mais voici quelque chose que j'ai rencontré en cherchant une anomalie de données différente dans mon application et comment je l'ai corrigée:

Je viens d'importer une table à codage mixte (avec des points d'interrogation en forme de losange dans certaines lignes et toutes dans la même colonne). Voici donc mon code correctif. J'ai utilisé le processus utf8_decode qui prend un espace réservé non défini et assigne un point d'interrogation simple à la place du "point d'interrogation en forme de diamant", puis j'ai utilisé str_replace pour remplacer le point d'interrogation par un espace entre guillemets. code]

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

        ?>        
0
drtechno

Vous pouvez également modifier le jeu de caractères dans votre navigateur. Juste pour des raisons de débogage.

0
powtac

Il suffit de coller ce code pour commencer au début de la page.

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

Lorsque vous extrayez des données de n’importe où, vous devez utiliser des fonctions avec le préfixe md_FUNC_NAME.

Avait le même problème, il m'a aidé.

Ou vous pouvez trouver le code de ce symbole et utiliser regexp pour supprimer ces symboles.

0
Skylark Roman

Cela s'est passé dans mon cas:

$text = utf8_decode($text)

Je transforme le caractère de diamant noir en point d'interrogation afin que vous puissiez: 

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

À des fins globales.

Au lieu de convertir, codifier, décoder chaque texte, je préfère les laisser tels quels et modifier les paramètres du serveur php .

  1. Laisser les diamants 
  2. Dans le menu de visualisation, sélectionnez "Encodage du texte" et recherchez celui qui vous permet de voir votre texte correctement
  3. Editez votre php.ini et ajoutez:

    default_charset = "ISO-8859-1"

ou au lieu de ISO-8859 celui qui correspond à votre codage de texte.

0
vivoconunxino