PHP-Ausgabe mit kleinen schwarzen Diamanten und Fragezeichen

80

Ich schreibe ein PHP-Programm, das aus einer Datenbankquelle zieht. Einige der Varchars haben Anführungszeichen, die als schwarze Diamanten mit einem Fragezeichen angezeigt werden ( , ERSATZZEICHEN , nehme ich aus Microsoft Word-Text an).

Wie kann ich PHP verwenden, um diese Zeichen zu entfernen?

hakre
quelle
1
Zieh sie nicht aus, fixiere die Zeit. Siehe auch "schwarzer Diamant" in stackoverflow.com/questions/38363566/…
Rick James

Antworten:

74

Wenn Sie dieses Zeichen sehen ( U + FFFD "REPLACEMENT CHARACTER"), bedeutet dies normalerweise, dass der Text selbst in einer Form von Einzelbyte-Codierung codiert, aber in einer der Unicode-Codierungen (UTF8 oder UTF16) interpretiert wird.

Wenn es umgekehrt wäre, würde es (normalerweise) ungefähr so ​​aussehen: ¤.

Wahrscheinlich ist die ursprüngliche Codierung ISO-8859-1, auch bekannt als Latin-1. Sie können dies überprüfen, ohne Ihr Skript ändern zu müssen: Browser bieten Ihnen die Möglichkeit, eine Seite in einer anderen Codierung neu zu interpretieren. Verwenden Sie in Firefox "Ansicht" -> "Zeichencodierung".

Fügen Sie einen HTTP-Header wie folgt hinzu, damit der Browser die richtige Codierung verwendet:

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

oder fügen Sie die Codierung in ein Meta-Tag ein:

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

Alternativ können Sie versuchen, in einer anderen Codierung (vorzugsweise UTF-8) aus der Datenbank zu lesen oder den Text mit zu konvertieren iconv().

Teufelsjunge
quelle
Bisher ist dies die naheliegendste Lösung. Jetzt habe ich jedoch ein Meta: <meta http-equiv = "Content-Type" content = "text / html; charset = UTF-8"> und ich verwende iconv, um von iso-8859-1 nach utf- zu konvertieren. 8, zeigen die Charaktere jetzt als Box mit 0096 und 0092 jeweils spezielle ('oder -) irgendwelche anderen Gedanken?
Ja, ich habe noch einen Gedanken: Mach ein paar Hausaufgaben ... du hast wahrscheinlich die falsche Quellcodierung verwendet. 0x92 und 0x96 sind in Windows-1252 "gebogenes einfaches Anführungszeichen" und "Bindestrich". könnte das der richtige sein? Hast du den Browser-Trick ausprobiert?
Der PHP-Header hat für mich Probleme behoben, wenn ich die PDF2Text-Klasse verwendet habe.
James P.
Sollte nicht header("Content-Type: text/plain; charset=ISO-8859-1");sein header("Content-Type: text/html; charset=ISO-8859-1");?
j08691
@ j08691: Nun, das hängt jetzt von der Art des Inhalts ab, nicht wahr?
41

Dies ist ein Zeichensatzproblem. Als solches kann es auf vielen verschiedenen Ebenen schief gegangen sein, aber höchstwahrscheinlich sind die Zeichenfolgen in Ihrer Datenbank utf-8-codiert und Sie präsentieren sie als iso-8859-1. Oder umgekehrt.

Der richtige Weg, um dieses Problem zu beheben, besteht darin, Ihre Zeichensätze zu korrigieren. Die einfachste Strategie, da Sie PHP verwenden, ist die Verwendung von ISO-8859-1 in Ihrer gesamten Anwendung. Dazu müssen Sie Folgendes sicherstellen:

  • Alle PHP-Quelldateien werden als ISO-8859-1 gespeichert (nicht zu verwechseln mit CP-1252).
  • Ihr Webserver ist für die Bereitstellung von Dateien konfiguriert charset=iso-8859-1
  • Alternativ können Sie die Webserver-Einstellungen im PHP-Dokument mit überschreiben header.
  • Darüber hinaus Sie können einen Meta-Tag in Sie einfügen HTML, dass die gleiche Sache gibt, aber dies nicht unbedingt erforderlich ist.
  • Sie können das accept-charsetAttribut auch für Ihre <form>Elemente angeben .
  • Datenbanktabellen werden mit der Codierung latin1 definiert
  • Die Datenbankverbindung zwischen PHP und Datenbank ist auf latin1 eingestellt

Wenn Sie bereits Daten in Ihrer Datenbank haben, sollten Sie sich bewusst sein, dass diese wahrscheinlich bereits durcheinander sind. Wenn Sie sich noch nicht in der Produktionsphase befinden, wischen Sie einfach alles ab und beginnen Sie von vorne. Andernfalls müssen Sie einige Daten bereinigen.

Ein Hinweis zu Meta-Tags, da jeder falsch versteht, was er ist:

Wenn ein Webserver eine Datei (ein HTML-Dokument) bereitstellt, sendet er einige Informationen, die nicht direkt im Browser angezeigt werden. Dies wird als HTTP-Header bezeichnet. Ein solcher Header ist der Content-TypeHeader, der den Mimetyp der Datei (z. B. text/html) sowie die Codierung (auch als Zeichensatz bezeichnet) angibt. Während die meisten Webserver einen Content-TypeHeader mit charsetInformationen senden , ist dies optional. Wenn es nicht vorhanden ist, interpretiert der Browser stattdessen alle Meta-Tags mit http-equiv="Content-Type". Es ist wichtig zu wissen, dass das Meta-Tag nur interpretiert wird, wenn der Webserver den Header nicht sendet. In der Praxis bedeutet dies, dass es nur verwendet wird, wenn die Seite auf der Festplatte gespeichert und von dort aus geöffnet wird.

Diese Seite enthält eine sehr gute Erklärung dieser Dinge.

troelskn
quelle
36

Ich war auch mit diesem Problem konfrontiert. In der Zwischenzeit bin ich auf drei Fälle gestoßen, in denen es passiert ist:

  1. substr ()

    Ich habe substr()eine UTF8-Zeichenfolge verwendet, die UTF8-Zeichen schneidet, sodass die geschnittenen Zeichen nicht korrekt angezeigt werden konnten. Verwenden Sie mb_substr($utfstring, 0, 10, 'utf-8');stattdessen. Credits

  2. htmlspecialchars ()

    Ein weiteres Problem war die Verwendung htmlspecialchars()einer UTF8-Zeichenfolge. Das Update ist zu verwenden:htmlspecialchars($utfstring, ENT_QUOTES, 'UTF-8');

  3. preg_replace ()

    Zuletzt habe ich herausgefunden, dass preg_replace()dies zu Problemen mit UTF führen kann. Der Code $string = preg_replace('/[^A-Za-z0-9ÄäÜüÖöß]/', ' ', $string);transformierte beispielsweise die UTF-Zeichenfolge "F (×) = 2 × -3" in "F 2 ". Das Update ist mb_ereg_replace()stattdessen zu verwenden .

Ich hoffe, dass diese zusätzlichen Informationen dazu beitragen, solche Probleme zu beseitigen.

Kai Noack
quelle
2
Das war genau das Problem, mit dem ich konfrontiert war. Wusste nichts über die MB-String-Funktionen.
Ren
1
Es geschah auch für die strtolowerFunktion. Alle Funktionen im PHP-Handbuch
Micaball
13

Wie in früheren Antworten erwähnt, geschieht dies, weil Ihr Text in iso-8859-1Codierung oder einem anderen Format in die Datenbank geschrieben wurde .

Sie müssen die Daten also nur konvertieren, utf8bevor Sie sie ausgeben.

$text = “string from database”;
$text = utf8_encode($text);
echo $text;
Weiler Kraskian
quelle
11

Um sicherzustellen, dass Ihre MYSQL-Verbindung auf UTF-8 (oder latin1, je nachdem, was Sie verwenden) eingestellt ist, können Sie Folgendes tun:

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

oder verwenden Sie diese Option, um zu überprüfen, welchen Zeichensatz Sie verwenden:

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

Weitere Informationen hier: http://php.net/manual/en/function.mysql-set-charset.php

ptwiggerl
quelle
Dies war sehr nützlich und löste mein Problem mit der Codierung von Zitaten in Daten, die aus einer entfernten MySQL-Datenbank stammen. Vielen Dank!
Tribulant
@ptwiggerl das hat sehr geholfen.
Unixmiah
Ich habe eine Website auf einen anderen Server migriert und war mit diesem Problem konfrontiert: mysql_set_charset ('utf8', $ con). Ich habe es gelöst!
Rafael Moni
5

Basierend auf Ihrer Beschreibung des Problems werden die Daten in Ihrer Datenbank mit ziemlicher Sicherheit als Windows-1252 codiert , und Ihre Seite wird mit ziemlicher Sicherheit als ISO-8859-1 bereitgestellt . Diese beiden Zeichensätze sind äquivalent, außer dass Windows-1252 16 zusätzliche Zeichen enthält, die in ISO-8859-1 nicht vorhanden sind, einschließlich linker und rechter geschweifter Anführungszeichen.

Vorausgesetzt, meine Analyse ist korrekt, besteht die einfachste Lösung darin, Ihre Seite als Windows-1252 bereitzustellen. Dies funktioniert, da alle Zeichen in ISO-8859-1 auch in Windows-1252 enthalten sind. In PHP können Sie die Codierung wie folgt ändern:

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

Sie sollten jedoch unbedingt überprüfen, welche Zeichenkodierung Sie in Ihren HTML-Dateien und im Inhalt Ihrer Datenbank verwenden, und darauf achten, dass Sie konsistent sind, oder ordnungsgemäß konvertieren, wenn dies nicht möglich ist.

Daniel Cassidy
quelle
Das Problem bei diesem Vorschlag ist, dass die Daten zu diesem Zeitpunkt höchstwahrscheinlich eine Mischung aus verschiedenen Zeichensätzen sind. Wenn Sie nicht genau wissen, was schief gelaufen ist, wird es nur noch chaotischer, wenn Sie hier und da nur einige zufällige Korrekturen vornehmen.
Troelskn
Genau. Ich habe meinen Beitrag etwas bearbeitet, um zu berücksichtigen, dass diese Lösung kein Ersatz dafür ist, zu wissen, was Sie tun. Ich bin jedoch zu dem Schluss gekommen, dass die meisten Entwickler dieses Problem entweder nicht verstehen können oder sich einfach nicht darum kümmern. Es scheint mindestens einmal im Monat zu kommen, wo ich arbeite.
Daniel Cassidy
Das ist so ziemlich auch meine Beobachtung. Was mir wichtig ist, ernten sie, wenn sie säen. Aber du hast wahrscheinlich recht; Die Chancen stehen gut, dass seine Daten tatsächlich cp-1252 sind. Zumindest einige davon.
Troelskn
Ich habe eine Reihe von Lösungen für das gleiche Problem ausprobiert. Dieser war sofort mit der geringsten Anstrengung wirksam
Sixstring
4

Ich habe mich dazu entschlossen, diese Zeichen aus der Zeichenfolge zu entfernen -

ini_set('mbstring.substitute_character', "none"); 
$text= mb_convert_encoding($text, 'UTF-8', 'UTF-8');
DropHit
quelle
1
Das ist großartig, es hat bei mir funktioniert, utf8_encode ausprobiert und ut8_decode auch - hat nicht funktioniert. Aber diese Lösung hat in meinem Fall funktioniert. Vielen Dank.
Sanjeev Shetty
4

Fügen Sie diese Funktion Ihren Variablen hinzu utf8_encode ($ your variable);

rk_programmer
quelle
Bitte erläutern Sie diese Antwort.
ppovoski
1
Dies ist die Funktion, mit der Sie das Sonderzeichen entfernen und den utf8-Standard des Zeichens google.com/…
rk_programmer
Dies funktionierte mit Brüchen, die nicht korrekt angezeigt wurden.
Rog
Meiner Meinung nach sollte dies eine akzeptierte Antwort sein; Dies ist die einzige Methode, die für mich funktioniert hat. Ich habe alles ausprobiert.
Quantme
4

Fügen Sie diesen Code einfach am Anfang der Seite ein.

<?php
header("Content-Type: text/html; charset=ISO-8859-1");
?>
Harshil Kaneria
quelle
Bitte fügen Sie eine kurze Erklärung der Funktionsweise des Codes bei.
CT Hall
1
Dieser PHP-Code erlaubt den Zeichensatz von "ISO-8859-1" und in diesem Zeichensatz wird dieses Symbol als Zeichen angezeigt.
Harshil Kaneria
3

Versuchen Sie dies bitte

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

Vishal P Gothi
quelle
3

Das wird dir helfen. Setzen Sie dieses innere <head>Etikett

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

Dies kann durch Unicode- oder andere Zeichensatz-Fehlanpassungen verursacht werden. Versuchen Sie, den Zeichensatz in Ihrem Browser zu ändern. In den Einstellungen sieht der Text OK aus. Dann geht es darum, wie Sie Ihren Datenbankinhalt in einen Zeichensatz konvertieren, den Sie für die Anzeige verwenden. (Dies kann tatsächlich nur das Hinzufügen einer utf-8-Zeichensatzanweisung zu Ihrer Ausgabe sein.)

che
quelle
1

Am Ende, nachdem ich meine Tabellen repariert hatte, war es, sie zu sichern und die Einstellungen auf utf-8 zurückzusetzen. Dann änderte ich meine Dump-Datei so, dass DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci meine Zeichensatzeinträge sind

Jetzt habe ich keine Probleme mit dem Zeichensatz mehr, da die Datenbank und der Browser utf8 sind.

Ich habe herausgefunden, was es verursacht hat. Es war die Webseite + Browser-Effekte auf die DB. Auf den Linux-Terminals (Ubuntu + Firefox) wurde die Datenbank in Latin1 codiert, wobei die Registerkarten festgelegt sind. Auf den Windows 10 + Edge-Terminals wurden die Einträge jedoch zwangsweise in utf8 codiert. Außerdem habe ich festgestellt, dass Windows 10 Probleme mit latin1 hat, also habe ich mich entschlossen, mich dem Wind zu beugen und alles auf utf8 umzustellen.

Ich dachte, es sei ein Windows 10-Problem, weil wir angefangen haben, Win 10-Terminals zu verwenden. Microsoft-Fehler verursachen also erneut Probleme. Ich weiß immer noch nicht, warum sich die Codierung in den Formularen ändert, da der Browser in Windows 10 den latein1-Zeichensatz anzeigt, aber wenn er in seiner utf8-Codierung angezeigt wird und ich die Datenanomalie erhalte. Aber unter Linux + Firefox funktioniert das nicht.

drtechno
quelle
1

Das hat in meinem Fall funktioniert:

$text = utf8_decode($text)

Ich verwandle das schwarze Diamantzeichen in ein Fragezeichen, damit Sie:

$text = str_replace('?', '', utf8_decode($text));
JacobRossDev
quelle
1
Warnung über den $text = Abschnitt: Dies ändert alle Fragezeichen innerhalb der Zeichenfolge, nicht nur den Diamanten
treyBake
1

Fügen Sie diese Zeilen einfach vor den Überschriften hinzu.

Das genaue Format der .doc/docxDateien wird abgerufen:

 if(ini_get('zlib.output_compression'))

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

Sie können den Zeichensatz auch in Ihrem Browser ändern. Nur aus Debug-Gründen.

powtac
quelle
0

Die Verwendung des gleichen Zeichensatzes (wie hier vorgeschlagen) sowohl in der Datenbank als auch im HTML hat bei mir nicht funktioniert ... Da ich mich daran erinnere, dass der Code als HTML generiert wird, habe ich mich für den &quot;(HTML-Code) oder den &#34;(ISO Latin-1) entschieden Code) in meinem Datenbanktext, in dem Anführungszeichen verwendet wurden. Dies löste das Problem und gab mir ein Anführungszeichen. Es ist merkwürdig zu bemerken, dass vor dieser Lösung nur einige der Anführungszeichen und Apostrophe nicht korrekt angezeigt wurden, während andere dies taten. Der spezielle Code funktionierte jedoch in allen Fällen.

GrafixGuy
quelle
0

Ich habe den Code "Codierung erkennen" nach meiner Änderung der Sortierung in phpmyadmin ausgeführt und jetzt wird er als Latin_1 angezeigt.

Aber hier ist etwas, bei dem ich auf eine andere Datenanomalie in meiner Anwendung gestoßen bin und wie ich sie behoben habe:

Ich habe gerade eine Tabelle mit gemischter Codierung importiert (mit Diamant-Fragezeichen in einigen Zeilen und alle in derselben Spalte). Hier ist also mein Fixcode. Ich habe den utf8_decode-Prozess verwendet, der den undefinierten Platzhalter verwendet und anstelle des "Diamant-Fragezeichens" ein einfaches Fragezeichen zuweist. Dann habe ich str_replace verwendet, um das Fragezeichen durch ein Leerzeichen zwischen Anführungszeichen zu ersetzen. Hier ist der [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>";
        }

        ?>        
drtechno
quelle
Der obige Code repariert meine Tabelle. Ich würde jedoch empfehlen, die Update-Anweisungen zu kommentieren, damit Sie zuerst sehen können, ob das Problem dadurch behoben wird.
Drtechno
0

Für globale Zwecke.

Anstatt jeden Text zu konvertieren, zu kodieren, zu dekodieren, lasse ich sie lieber so wie sie sind und ändere stattdessen die PHP-Einstellungen des Servers. Damit,

  1. Lass die Diamanten

  2. Wählen Sie im Browser im Ansichtsmenü "Textcodierung" und suchen Sie diejenige, mit der Sie Ihren Text richtig sehen können.

  3. Bearbeiten Sie Ihre php.ini und fügen Sie hinzu:

    default_charset = "ISO-8859-1"

oder anstelle von ISO-8859 diejenige, die zu Ihrer Textcodierung passt.

javier_domenech
quelle
0

Wenn Sie Daten von irgendwoher extrahieren, sollten Sie Funktionen mit dem Präfix verwenden md_FUNC_NAME.

Hatte das gleiche Problem, es hat mir geholfen.

Oder Sie finden den Code dieses Symbols und löschen diese Symbole mit regulärem Ausdruck.

Lerche Roman
quelle
-2

Gehen Sie zu Ihrem phpmyadmin und wählen Sie Ihre Datenbank aus. Erhöhen Sie einfach die Länge / den Wert des Felds dieser Tabelle auf 500 oder 1000, um Ihr Problem zu lösen.

Dheeraj Verma
quelle