Reputation: 169
I have the following code in php
$test = "\151\163\142\156";
echo utf8_decode($test);
var_dump($test);
and i get the following result:
isbn
string(4) "isbn"
I get some text from a txt file that has the \151\163\142\156 text
$all_text = file_get_contents('test.txt');
var_dump($all_text);
result:
string(16) "\151\163\142\156"
I have the following questions:
how can i utf8 decode the second text so i get the isbn result?
how can i encode the isbn to get \151\163\142\156 ?
EDIT
(from comments)
I tried everything with iconv and encode but nothing worked. The text from the .txt file is string(16) and not string(4) so i can encode it. The txt file is saved from sublime with Western (ISO 8859-1) encoding
Upvotes: 1
Views: 2982
Reputation: 522626
This has absolutely nothing to do with UTF-8 encoding. Forget about that part entirely. utf8_decode
doesn't do anything in your code. iconv
is entirely unrelated.
It has to do with PHP string literal interpretation. The \...
in "\151\163\142\156"
is a special PHP string literal escape sequence:
\[0-7]{1,3}
the sequence of characters matching the regular expression is a character in octal notation, which silently overflows to fit in a byte (e.g. "\400" === "\000")http://php.net/manual/en/language.types.string.php#language.types.string.syntax.double
Which very easily explains why it works when written in a PHP string literal, and doesn't work when reading from an outside source (because the external text read through file_get_contents
is not being interpreted as PHP code). Simply do echo "\151\163\142\156"
and you'll see "isbn" without any other conversions necessary.
To manually convert the individual escape sequences in the string \151\163\142\156
to their character equivalents (really: their byte equivalents):
$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
happens to include this functionality, but it also does a whole lot of other things which may be undesired.
The other way around:
$string = 'isbn';
preg_replace_callback('/./', function ($m) {
return '\\' . decoct(ord($m[0]));
}, $string)
// \151\163\142\156
Upvotes: 1
Reputation: 10391
Try using 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 ) );
?>
Tested with this file :
This is some text :
\151\163\142\156
And this is more text!!!
Next is how to convert chars to codes :
<?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".
?>
Let's make it more general with a function that we can call anywhere :
<?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".
?>
Upvotes: 1