We are using some third-party php library functions and have some difficulties converting utf-8 strings.
After some experiment, this is what we got so far:
(1) The following will print the correct unicode word (it's 'one' word) in browser(we use Firefox):
$s = "\345\244\247";
echo $s;
大 <-- (prints out a correct unicode word)
(2) However, the library function will return something like this:
$s2 = "\\345\\244\\247";
echo $s2;
\345\244\247 <-- the print out will contain escape character so the unicode isn't showing correctly
(3) So the question is, is there a php function capable of doing this, converting $s2 to the correct unicode form (like $s)?
Thanks.
The environment is PHP 5.3.
Something like http://ideone.com/Owl2a3 :
function _conv($oct) {
return chr(octdec($oct[1]));
}
$es = "\\345\\244\\247";
$es = preg_replace_callback('#\\\\(\d{3})#', '_conv', $es);
echo $es;
outputs 大
the problem is, that you're escaping the slashes!
use this:
$s2 = str_replace("\\","\",$s2);
Related
Since some days I read about Character-Encoding, I want to make all my Pages with UTF-8 for Compability. But I get stuck when I try to convert User-Input to UTF-8, this works on all Browsers, expect Internet-Explorer (like always).
I don't know whats wrong with my code, it seems fine to me.
I set the header with char encoding
I saved the file in UTF-8 (No BOM)
This happens only, if you try to access to the page via $_GET on the internet-Explorer myscript.php?c=äüöß
When I write down specialchars on my site, they would displayed correct.
This is my Code:
// User Input
$_GET['c'] = "äüöß"; // Access URL ?c=äüöß
//--------
header("Content-Type: text/html; charset=utf-8");
mb_internal_encoding('UTF-8');
$_GET = userToUtf8($_GET);
function userToUtf8($string) {
if(is_array($string)) {
$tmp = array();
foreach($string as $key => $value) {
$tmp[$key] = userToUtf8($value);
}
return $tmp;
}
return userDataUtf8($string);
}
function userDataUtf8($string) {
print("1: " . mb_detect_encoding($string) . "<br>"); // Shows: 1: UTF-8
$string = mb_convert_encoding($string, 'UTF-8', mb_detect_encoding($string)); // Convert non UTF-8 String to UTF-8
print("2: " . mb_detect_encoding($string) . "<br>"); // Shows: 2: ASCII
$string = preg_replace('/[\xF0-\xF7].../s', '', $string);
print("3: " . mb_detect_encoding($string) . "<br>"); // Shows: 3: ASCII
return $string;
}
echo $_GET['c']; // Shows nothing
echo mb_detect_encoding($_GET['c']); // ASCII
echo "äöü+#"; // Shows "äöü+#"
The most confusing Part is, that it shows me, that's converted from UTF-8 to ASCII... Can someone tell me why it doesn't show me the specialchars correctly, whats wrong here? Or is this a Bug on the Internet-Explorer?
Edit:
If I disable converting it says, it's all UTF-8 but the Characters won't show to me either... They are displayed like "????"....
Note: This happens ONLY in the Internet-Explorer!
Although I prefer using urlencoded strings in address bar but for your case you can try to encode $_GET['c'] to utf8. Eg.
$_GET['c'] = utf8_encode($_GET['c']);
An approach to display the characters using IE 11.0.18 which worked:
Retrieve the Unicode of your character : example for 'ü' = 'U+00FC'
According to this post, convert it to utf8 entity
Decode it using utf8_decode before dumping
The line of code illustrating the example with the 'ü' character is :
var_dump(utf8_decode(html_entity_decode(preg_replace("/U\+([0-9A-F]{4})/", "&#x\\1;", 'U+00FC'), ENT_NOQUOTES, 'UTF-8')));
To summarize: For displaying purposes, go from Unicode to UTF8 then decode it before displaying it.
Other resources:
a post to retrieve characters' unicode
I'm trying to check if a string is start with '€' or '£' in PHP.
Below are the codes
$text = "€123";
if($text[0] == "€"){
echo "true";
}
else{
echo "false";
}
//output false
If only check a single char, it works fine
$symbol = "€";
if($symbol == "€"){
echo "true";
}
else{
echo "false";
}
// output true
I have also tried to print the string on browser.
$text = "€123";
echo $text; //display euro symbol correctly
echo $text[0] //get a question mark
I have tried to use substr(), but the same problem occurred.
Characters, such as '€' or '£' are multi-byte characters. There is an excellent article that you can read here. According to the PHP docs, PHP strings are byte arrays. As a result, accessing or modifying a string using array brackets is not multi-byte safe, and should only be done with strings that are in a single-byte encoding such as ISO-8859-1.
Also make sure your file is encoded with UTF-8: you can use a text editor such as NotePad++ to convert it.
If I reduce the PHP to this, it works, the key being to use mb_substr:
<?php
header ('Content-type: text/html; charset=utf-8');
$text = "€123";
echo mb_substr($text,0,1,'UTF-8');
?>
Finally, it would be a good idea to add the UTF-8 meta-tag in your head tag:
<meta charset="utf-8">
I suggest this as the easiest solution to you. Convert the symbols to their unicode identifiers using htmlentities().
htmlentities($text, ENT_QUOTES, "UTF-8");
Which will either give you £ or €. Now that allows you to run a switch() {case:} statement to check. (Or your if statements)
$symbols = explode(";", $text);
switch($symbols[0]) {
case "£":
echo "It's Pounds";
break;
case "&euro":
echo "It's Euros";
break;
}
Working Example
This happens because you’re using a multi-byte character encoding (probably UTF-8) in which both € and £ are recorded using multiple bytes. That means that "€" is a string of three bytes, not just one.
When you use $text[0] you're getting only the first byte of the first character, and so it doesn't match the three bytes of "€". You need to get the first three bytes instead, to check whether one string starts with another.
Here’s the function I use to do that:
function string_starts_with($string, $prefix) {
return substr($string, 0, strlen($prefix)) == $prefix;
}
The question mark appears because the first byte of "€" isn’t enough to encode a whole character: the error is indicated by ‘�’ when available, otherwise ‘?’.
Given a string of UTF-8 data in PHP, how can I convert and save it to a UTF-16LE file (this particular file happens to be destined for Indesign - to be placed as a tagged text document).
Data:
$copy = "<UNICODE-MAC>\n";
$copy .= "<Version:8><FeatureSet:InDesign-Roman><ColorTable:=<Black:COLOR:CMYK:Process:0,0,0,1>>\n";
$copy .= "A bunch of unicode special characters like ñ, é, etc.";
I am using the following code, but to no avail:
file_put_contents("output.txt", pack("S",0xfeff) . $copy);
You can use iconv:
$copy_utf16 = iconv("UTF-8", "UTF-16LE", $copy);
file_put_contents("output.txt", $copy_utf16);
Note that UTF-16LE does not include a Byte-Order-Marker, because the byte order is well defined. To produce a BOM use "UTF-16" instead.
Using the following code, I have found a solution:
this function changes the byte order (from http://shiplu.mokadd.im/95/convert-little-endian-to-big-endian-in-php-or-vice-versa/):
function chbo($num) {
$data = dechex($num);
if (strlen($data) <= 2) {
return $num;
}
$u = unpack("H*", strrev(pack("H*", $data)));
$f = hexdec($u[1]);
return $f;
}
used with a utf-8 to utf-16LE conversion, it creates a file that will work with indesign:
file_put_contents("output.txt", pack("S",0xfeff). chbo(iconv("UTF-8","UTF-16LE",$copy));
Alternatively, you could use mb_convert_encoding() as follows:
$copy_UTF16LE = mb_convert_encoding($copy,'UTF-16LE','UTF-8');
let us say that the string is
$uni_str="06280628002006280628";
In Arabic,it is: بب بب
so , how can i convert it in php without using html like:
for($i=0; $i<strlen($uni_str); $i+=4)
{
$text_str .= "&#x".substr($uni_str,$i,4).";";
}
as this code just solves the problem of viewing the result in html page ,
but i want to but the result in php variable .
as the result of the code above was like
بب بب
I found the solution , hope to help:
function uni2arabic($uni_str)
{
for($i=0; $i<strlen($uni_str); $i+=4)
{
$new="&#x".substr($uni_str,$i,4).";";
$txt = html_entity_decode("$new", ENT_COMPAT, "UTF-8");
$All.=$txt;
}
return $All;
}
variable $All contains the arabic string
Use hex2bin to decode the hex into a sequence of bytes, and then you can unpack each pair of bytes as a UTF-16 code unit (which is what I assume your string represents).
Assuming you are producing UTF-8 text output:
iconv('UTF-16BE', 'UTF-8', hex2bin('06280628002006280628'))
The following code allows you to decode the characters as well as re-encode them if necessary
Code :
if (!function_exists('codepoint_encode')) {
function codepoint_encode($str) {
return substr(json_encode($str), 1, -1);
}
}
if (!function_exists('codepoint_decode')) {
function codepoint_decode($str) {
return json_decode(sprintf('"%s"', $str));
}
}
How to use :
header('Content-Type: text/html; charset=utf-8');
var_dump(codepoint_encode('ඔන්ලි'));
var_dump(codepoint_encode('සින්ග්ලිෂ්'));
var_dump(codepoint_decode('\u0d94\u0db1\u0dca\u0dbd\u0dd2'));
var_dump(codepoint_decode('\u0dc3\u0dd2\u0db1\u0dca\u0d9c\u0dca\u0dbd\u0dd2\u0dc2\u0dca'));
Output :
string(30) "\u0d94\u0db1\u0dca\u0dbd\u0dd2"
string(60) "\u0dc3\u0dd2\u0db1\u0dca\u0d9c\u0dca\u0dbd\u0dd2\u0dc2\u0dca"
string(15) "ඔන්ලි"
string(30) "සින්ග්ලිෂ්"
If you want more complex functionality, see How to get the character from unicode code point in PHP?.
I use the following lines of code:
$revTerm = "". strrev($limitAry["term"]);
$revTerm = utf8_encode($revTerm);
The $revTerm contains Norwegian characters as ø æ å. However, it is shown correctly. I need to reverse them before displaying, so I use the first line.
When I display them this way, I get an error of bad xml format - used to fill a grid.
When I try to use the second line, I don't get an error but the characters are not shown correctly. Could there be any other way to solve that?
If it may help, I use jqGrid to fill those data in.
strrev, like most PHP string functions, is not safe for multi-byte encodings.
try this example
$test = 'А роза упала на лапу Азора ウィキ';
$test = iconv('utf-8', 'utf-16le', $test);
$test = strrev($test);
// キィウ арозА упал ан алапу азор А
echo iconv('utf-16be', 'utf-8', $test);
(russian)
http://bolknote.ru/2012/04/02/~3625#56
Try this:
$revTerm = utf8_decode($limitAry["term"]);
$revTerm = strrev($revTerm);
$revTerm = utf8_encode($revTerm);
For using strrev you have to decode your string to a non-multibyte string.