【问题标题】:PHP utf8 encoding and decodingPHP utf8 编码和解码
【发布时间】:2016-06-21 20:11:44
【问题描述】:

我在php中有以下代码

$test = "\151\163\142\156";
echo utf8_decode($test);
var_dump($test);

我得到以下结果:

isbn
string(4) "isbn"

我从包含 \151\163\142\156 文本的 txt 文件中获取一些文本

$all_text = file_get_contents('test.txt');
var_dump($all_text);

结果:

string(16) "\151\163\142\156"

我有以下问题:

  1. 如何对第二个文本进行 utf8 解码,以便获得 isbn 结果?

  2. 如何编码 isbn 以获得 \151\163\142\156 ?

编辑

(来自 cmets)

我用 iconv 和 encode 尝试了所有方法,但没有任何效果。 .txt 文件中的文本是 string(16) 而不是 string(4),所以我可以对其进行编码。 txt 文件是用西方 (ISO 8859-1) 编码从 sublime 中保存的

【问题讨论】:

  • 认真的吗? utf8_decode($all_text);? utf8_encode('WHAT YOU NEED')?
  • 那行不通。我得到相同的文本,而不是编码的文本。如您所见,第一个 $test 是 string(4),第二个是 string(16)
  • 你解码第二个字符串吗?显示 DECODED $all_text 的输出
  • $all_text_utf8_decoded = utf8_decode(file_get_contents('test.txt')); 和 php.net/manual/de/function.utf8-encode.php
  • 这有关系吗,因为file_get_contents 是文件的参考点,而不是数据本身的容器?

标签: php utf-8 decode encode


【解决方案1】:

这与 UTF-8 编码完全无关。完全忘记那部分。 utf8_decode 在您的代码中不做任何事情。 iconv 完全不相关。

这与 PHP 字符串字面解释有关。 "\151\163\142\156" 中的 \... 是一个特殊的 PHP 字符串文字转义序列:

\[0-7]{1,3}
匹配正则表达式的字符序列是八进制表示的字符,它会静默溢出以适应一个字节(例如“\400”===“\000”)

http://php.net/manual/en/language.types.string.php#language.types.string.syntax.double

这很容易解释为什么它在以 PHP 字符串文字编写时有效,而在从外部源读取时无效(因为通过 file_get_contents 读取的外部文本不会被解释为 PHP 代码)。只需执行echo "\151\163\142\156",您将看到“isbn”,无需任何其他转换。

手动将字符串 \151\163\142\156 中的各个转义序列转换为它们的等效字符(实际上:它们的字节等效项):

$string = '\151\163\142\156';  // note: single quotes cause no iterpretation
echo preg_replace_callback('/\\\\([0-7]{1,3})/', function ($m) {
    return chr(octdec($m[1]));
}, $string)
// isbn

stripcslashes 恰好包含此功能,但它还做了很多其他可能不受欢迎的事情。

反过来:

$string = 'isbn';
preg_replace_callback('/./', function ($m) {
    return '\\' . decoct(ord($m[0]));
}, $string)
// \151\163\142\156

【讨论】:

  • 谢谢。这就是我想做的。
【解决方案2】:

尝试使用stripcslashes:

<?php

$test = "\151\163\142\156";
echo utf8_decode( $test );                         // "isbn"
var_dump( $test );

echo "<br/><br/><br/>";

$all_text = file_get_contents( "test.txt" );
echo utf8_decode( $all_text ) .                    // "\151\163\142\156"
     "<br/>" .
     utf8_decode( stripcslashes( $all_text ) );    // "isbn"
var_dump( stripcslashes( $all_text ) );

?>

用这个文件测试过:

这是一些文字:

\151\163\142\156

这是更多的文字!!!

接下来是如何将字符转换为代码:

<?php
$test = "isbn";
$coded = "";
for ( $i = 0; $i < strlen( $test ); $i++ ) // PROCESS EACH CHAR IN STRING.
  $coded .= "\\" . decoct( ord( $test[ $i ] ) ); // CHAR CODE TO OCTAL.

echo $coded .                           // "\151\163\142\156"
     "<br/>" .
     stripcslashes( $coded );           // "isbn".
?>

让我们用一个可以在任何地方调用的函数使其更通用:

<?php
function code_string ( $s )
{ $coded = "";
  for ( $i = 0; $i < strlen( $s ); $i++ )
    $coded .= "\\" . decoct( ord( $s[ $i ] ) );
  return $coded;
}

$x = code_string( "isbn" );
echo $x .                           // "\151\163\142\156"
     "<br/>" .
     stripcslashes( $x );           // "isbn".
?>

【讨论】:

  • 你可以完全摆脱utf8_decode,它在这里没有任何作用。
  • @deceze,我同意,但 OP 似乎喜欢它(文本文件可能带有奇怪的字符)。
  • 我以为你是在试图教育 OP 他们做错了什么和/或误解......!? :-P
  • 谢谢你们。你和@deceze 都是一个很好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 2014-06-23
相关资源
最近更新 更多