Heim > Artikel > Backend-Entwicklung > Detaillierte Erklärung von PHP-Dateien und Zeichenkodierung
Mein anfänglicher Zweifel war: Was ist der Unterschied zwischen Textdateien und Binärdateien? Warum kann der eine den Inhalt anzeigen, der andere jedoch oft nicht normal (mit einem Texteditor)?
Dieser Schulungshinweis der University of Maryland erklärt deutlich den Unterschied zwischen den beiden: Textdateien sind eine Art Binärdatei, und der zugrunde liegende Speicher ist ebenfalls 0 und 1. Textdateien sind lesbar und portierbar, aber Ausdruck Die Anzahl der Zeichen ist begrenzt; die Datenspeicherung in Binärdateien ist kompakt und unterliegt keinen Einschränkungen bei der Zeichenkodierung. Textdateien können grundsätzlich nur Inhalte speichern, die aus begrenzten Zeichen wie Zahlen, Text, Satzzeichen usw. bestehen. Binärdateien unterliegen keinen Zeichenbeschränkungen und können Bilder, Audio- und Videodaten sowie andere Daten nach Belieben speichern.
Am Beispiel der Speicherung von Zahlen können Sie den Unterschied im Speicherinhalt von Textdateien und Binärdateien anschaulich erkennen. Um beispielsweise die Zahl 1234567890 zu speichern, muss die Textdatei die ASCII-Codes der zehn Zahlen 0-9 speichern. Die entsprechende hexadezimale Darstellung ist:, die 10 Bytes einnimmt; die entsprechende binäre Darstellung von 1234567890 ist „. 31 32 33 34 35 36 37 38 39 30
“, belegt 4 Bytes (Binärdarstellung ist 32 Bit, ein Byte ist 8 Bit), und die in der Datei gespeicherte Hexadezimaldarstellung ist (Big Endian): 0100 1001 1001 0110 0000 0010 1101 0010
. 49 96 02 D2
Zeichen und Binärdateien speichern Inhalte in Bytes. Dies ist der wichtigste Unterschied zwischen den beiden Dateien. Aus dieser Eigenschaft lassen sich einige allgemeine Schlussfolgerungen ableiten: Binärdateien sind oft kompakter als Textdateien und nehmen weniger Platz ein. Textdateien sind benutzerfreundlicher und können im WYSIWYG-Stil bearbeitet werden offen usw. .
Wenn ich auf den Texteditor zurückblicke, sind Binärdateien oft verstümmelt. Eine Binärdatei speichert beispielsweise eine Ganzzahl 1234 (vier Bytes), die hexadezimal ausgedrückt wird als:. Nachdem Sie den Texteditor geöffnet und ihn Zeichen für Zeichen interpretiert haben, werden Sie feststellen, dass diese Bytes keine anzeigbaren Zeichen darstellen können und Sie sie daher als Kauderwelsch behandeln müssen. Der Grund für die verstümmelten Zeichen liegt darin, dass der Texteditor den Bytestrom nicht richtig analysieren kann, weshalb Binärdateien mit spezieller Software geöffnet werden müssen. Beispielsweise muss eine JPG-Datei mit einer Bildbetrachtungssoftware geöffnet werden. Wenn sie mit einem Musikplayer geöffnet wird, ist es vorbei! Videodateien müssen mit einem Player und einer Komprimierungssoftware geöffnet werden, also legen wir los! 00 00 04 D2
Nachdem wir den Unterschied zwischen Textdateien und Binärdateien verstanden haben, schauen wir uns das Dateiformat an. Wir wissen, dass Windows das Dateiformat anhand der Dateierweiterung erkennt und das entsprechende Programm zum Öffnen der Datei aufruft. In (ähnlichen) Unix-Systemen ist die Erweiterung optional. Woher wissen Sie also, welches Format die Datei hat?
Glücklicherweise gibt es den Dateibefehl, der uns sagen kann, in welchem Format die Datei vorliegt. Der wesentliche Unterschied im Dateiformat ist nicht die Dateierweiterung, sondern der Inhalt. Ändern Sie a.zip in a.txt/a.jgp/a.mp3, egal wie der Dateiname lautet, die Datei zeigt ihre ursprüngliche Form: Zip archive data, at least v1.0 to extract
.
Nachdem wir über die Datei gesprochen haben, sprechen wir über die Kodierung im Dateiinhalt. Es gibt 127 gängige ASCII-Zeichen. Es gibt jedoch keine entsprechende Kodierung. Allerdings sind fast alle Kodierungsmethoden damit kompatibel. Doppelbyte- und Multibyte-Zeichen, Kodierungsmethoden und Bytereihenfolge sind die Probleme, die Programmierern zu schaffen machen. Für ein chinesisches Zeichen erfordert die GBK-Codierung zwei Bytes, und die Endianness des lokalen Computers muss berücksichtigt werden, um die endgültige Speicherform während der Netzwerkkommunikation zu bestimmen. Sie muss in die Netzwerk-Byte-Reihenfolge (Big Endian) konvertiert werden, damit der Empfänger dies tun kann Analysieren Sie es normal. Wenn Entwickler mit der Zeichenkodierung nicht vertraut sind und während der Kommunikation auf verstümmelte Zeichen stoßen, wird das Debuggen schwierig.
Die Formulierung des UCS-Standards (Universal Multiple Octet Coded Character Set) ermöglicht es Entwicklern, verwirrende Multibyte-Zeichensätze zu vermeiden. Im UCS-Standard haben alle Zeichen eindeutige Codepunkte, und die entsprechenden Zeichen können anhand der Codepunkte gefunden werden. UCS verwendet zwei Bytes zur Darstellung eines Codepunkts (der UCS-4-Standard sind 4 Bytes), der einem Zeichen entspricht. Da es zwei Bytes verwendet, kann es 2^16-1 (6w+) Zeichen aufnehmen, was im Wesentlichen den in verschiedenen Ländern häufig verwendeten Zeichen entspricht (UCS-4 kann theoretisch bis zu 2 Milliarden Zeichen aufnehmen und nimmt derzeit mehr als 16W Zeichen auf). Beachten Sie, dass es sich bei UCS lediglich um einen Standard handelt, der die Eins-zu-eins-Entsprechung zwischen Codepunkten und Zeichen festlegt, jedoch nicht definiert, wie diese im Computer gespeichert werden.
Die Festlegung der Speichermethode für Unicode-Zeichen wird durch UTF (Unicode Transformation Format) vervollständigt. Die am häufigsten verwendeten Lösungen sind UTF-16 und UTF-8. UTF-16 verwendet zwei Bytes zur Darstellung eines Zeichens. Die Standardzeichenkodierungsschemata für Windows-, MacOS- und Java-Plattformen sind UTF-16. Da es zwei Bytes gibt, gibt es zwei Schemata: Big-Endian und Little-Endian. Bei Dateien, die nur ASCII-Zeichen enthalten, führt die Verwendung der UTF-16-Kodierung zu einer erheblichen Platzverschwendung (Verschwendung von 50 % des Speichers). Das von Ken Thompson (Erfinder der C-Sprache) und Robe Pike (Erfinder der Go-Sprache) vorgeschlagene UTF-8-Kodierungsschema. Es wurde schnell populär. UTF-8 ist ein Einzelbyte-Stream, es gibt kein Problem mit der Bytereihenfolge und es ist keine Stückliste erforderlich. UTF-8 ist derzeit der gängige Webstandard.
Der Wertebereich von USC-2 ist U+0000~U+FFFF, und die Korrespondenz mit UTF-8 ist wie folgt:
十六进制 | 二进制 |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
从编码可以看出,与二进制相比,浪费了很多空间。不过这也没办法,可显示的字符更容易阅读和理解,人类很难抗拒这个诱惑。
UTF-8转换规则为: 1. 如果某字节第一位是 0 ,那么判定为 ASCII 字节,除了 0 外余下的 7 位是 ASCII 码,所以 UTF-8 是兼容 ASCII 码的; 2. 如果第一个字节是 1 ,那么连续的几个 “1” 代表从这个字符开始,后面连续的几个字节其实是一个字位,且后面的字节都要以10开头。
了解如上规则,我们的程序便可轻松的处理UTF-8编码的字节流。例如要找出“中”的UTF-8编码,则可以这样处理(注意文件是UTF-8编码):
$char = "中"; $length = strlen($char); $bytes = pack("a" . $length, $char);echo "UTF-8:" . bin2hex($bytes) . "\n"; // 或者echo "UTF-8:";for ($index = 0; $index < $length; ++ $index) { echo bin2hex($char{$index}); }echo PHP_EOL;
也可以写出针对UTF-8编码的strlen函数:
function myStrlen(string $string){ $slen = strlen($string); $mlen = 0; $maxByteLength = 4; $maxOffset = 7; for ($i = 0; $i < $slen; ++ $i) { $byte = ord($string{$i}); // 从01xxxxxx开始对比,直到11110xxxx 10xxxxxx 10xxxxxx 10xxxxxx。只需要对比第一个字节即可 for ($offset = 0; $offset < $maxByteLength; ++ $offset) { $result = $byte & (1 << ($maxOffset - $offset)); if ($result === 0) { $i += $offset; ++ $mlen; break; } } } return $mlen; } $string = "Coder不是工程师!";echo "mb_strlen:" . mb_strlen($string) . "\n";echo "mStrlen:" . myStrlen($string) . "\n";
相关推荐:
Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung von PHP-Dateien und Zeichenkodierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!