PHP. JSON encode utf-8 - php

I want to encode json, but when I use json_encode function I get not UTF-8 string. I added header header('Content-Type: application/json; charset=utf-8'); and data from database comes good. How I could solve the problem?
My code:
foreach($dbh->query('SELECT Event.name, Event.description, Category.name as category FROM Event, Category WHERE Event.category_id = Category.category_id') as $row) {
$event['name'] = utf8_encode($row['name']);
$event['description'] = utf8_encode($row['description']);
$event['category'] = utf8_encode($row['category']);
$events[] = $event;
}
echo json_encode($events);

PHP json_encode needs always UTF8 string despite your charset. You must encode all your strings before.
To clarify, you must use utf8_encode on data extracted from your database if they are not already in utf8.
json_encode(array(
"one" => utf8_encode("super string &éùà"),
"two" => utf8_encode("super string &éùà")
));
Note : utf8_encode is only applicable from ISO 8859-1. If you are using another charset, see iconv()

Related

PHP json encode - Malformed UTF-8 characters, possibly incorrectly encoded [duplicate]

This question already has answers here:
UTF-8 all the way through
(13 answers)
Closed 7 months ago.
I'm using json_encode($data) to an data array and there's a field contains Russian characters.
I used this mb_detect_encoding() to display what encoding it is for that field and it displays UTF-8.
I think the json encode failed due to some bad characters in it like "ра▒". I tried alot of things utf8_encode on the data and it will by pass that error but then the data doesn't look correct anymore.
What can be done with this issue?
The issue happens if there are some non-utf8 characters inside even though most of them are utf8 chars. This will remove any non-utf8 characters and now it works.
$data['name'] = mb_convert_encoding($data['name'], 'UTF-8', 'UTF-8');
If you have a multidimensional array to encode in JSON format then you can use below function:
If JSON_ERROR_UTF8 occurred :
$encoded = json_encode( utf8ize( $responseForJS ) );
Below function is used to encode Array data recursively
/* Use it for json_encode some corrupt UTF-8 chars
* useful for = malformed utf-8 characters possibly incorrectly encoded by json_encode
*/
function utf8ize( $mixed ) {
if (is_array($mixed)) {
foreach ($mixed as $key => $value) {
$mixed[$key] = utf8ize($value);
}
} elseif (is_string($mixed)) {
return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
}
return $mixed;
}
Please, make sure to initiate your Pdo object with the charset iso as utf8.
This should fix this problem avoiding any re-utf8izing dance.
$pdo = new PDO("mysql:host=localhost;dbname=mybase;charset=utf8", 'user', 'password');
With php 7.2, two options allow to manage invalid UTF-8 direcly in json_encode :
https://www.php.net/manual/en/function.json-encode
json_encode($text, JSON_INVALID_UTF8_IGNORE);
Or
json_encode($text, JSON_INVALID_UTF8_SUBSTITUTE);
you just add in your pdo connection charset=utf8
like below line of pdo connection:
$pdo = new PDO("mysql:host=localhost;dbname=mybase;charset=utf8", 'user', 'password');
hope this will help you
Remove HTML entities before JSON encoding. I used html_entity_decode() in PHP and the problem was solved
$json = html_entity_decode($source);
$data = json_decode($json,true);
Do you by any chance have UUIDs in your result set? In that case the following database flag will help:
PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER => true
If your data is well encoded in the database for example, make sure to use the mb_ * functions for string handling, before json_encode. Functions like substr or strlen do not work well with utf8mb4 and can cut your text and leave a malformed UTF8
I know this is kind of an old topic, but for me it was what I needed. I just needed to modify the answer 'jayashan perera'.
//...code
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
for ($i=0; $i < sizeof($result) ; $i++) {
$tempCnpj = $result[$i]['CNPJ'];
$tempFornecedor = json_encode(html_entity_decode($result[$i]['Nome_fornecedor']),true) ;
$tempData = $result[$i]['efetivado_data'];
$tempNota = $result[$i]['valor_nota'];
$arrResposta[$i] = ["Status"=>"true", "Cnpj"=>"$tempCnpj", "Fornecedor"=>$tempFornecedor, "Data"=>"$tempData", "Nota"=>"$tempNota" ];
}
echo json_encode($arrResposta);
And no .js i have use
obj = JSON.parse(msg);

save special characters in database in core php

I want to save special characters like the following string in a database:-
:¦:-•:":•.-:¦:-•EXCELLENT!•-:¦:-•:•-:¦:-•:*''•
Below is the code that I am using.
$Fields ['CommentText']=$CommentText;
$Fields = prepareMySQLi($FieldsNotifications,$linkMysqli);
$insert = mysqli_query($linkMysqli,"INSERT INTO `feeds` SET $Fields");
function prepareMySQLi($MyArray,$linkMysqli) {
foreach($MyArray as $col => $val) {
if($val=='Invalid Request') $val='';
if ($val!='' && !is_array($val)) {
$col = mysqli_real_escape_string($linkMysqli,$col);
$val = mysqli_real_escape_string($linkMysqli,$val);
if(isset($fields)) {
$fields .= ", `$col` = '$val' ";
} else {
$fields = " `$col` = '$val' ";
}
}
}
return $fields;
}
But the above code saves the result like:-
•:¨¨:•.EXCELLENT.•:¨¨:••:¨¨:•.
Can anyone guide me how can I save the string same as it is in the database?
It seems like encoding issue. The encoding of the data that you are receiving should be same as the encoding of database where you are storing it.
General practice would be to use "utf-8" encoding for both.
So check in which encoding the database stores the data, and try to convert received data to that format or vice versa.
You can use utf8_encode function for encoding data to "utf-8".
please check by doing these two simple thing, i hope it helps you:-
the "collation" of the column in which you are going to save this data(special characters), made it "utf-8-bin".
either change type of the column to "blob","text" or "long text".
try in your code:- mysqli_set_charset($linkMysqli, "utf8");
encode and decode process. before saving the text encode it and if you want to show it somewhere then first decode it and then show.
simple thing is change
Collation in db to utf8 -> utf8_unicode_ci
and if you dont used field Type as text than change it to text...
May be this is simple solution.....
Other things may You can check your Mysqli Db class Where
'charset' => 'utf8',
is there or not....??
If you dont find charset than please change to utf8...
At last check your page header
and add
<meta charset="utf-8">
Thats it may u will get something...

parsing xml and output encoding in php

I generate a lot of posts in Wordpress from an XML file. The worry: accented characters.
The header of the stream is:
<? Xml version = "1.0" encoding = "ISO-8859-15"?>
Here is the complete flux : http://flux.netaffiliation.com/rsscp.php?maff=177053821BA2E13E910D54
My site is in utf8.
So I use the function utf8_encode ... but that does not solve the problem, the accents are always misunderstood.
Does anyone have an idea?
EDIT 04-10-2011 18:02 (french hour) :
Here is the complete flux : http://flux.netaffiliation.com/rsscp.php?maff=177053821BA2E13E910D54
Here is my code :
/**
* parse an rss flux from netaffiliation and convert each item to posts
* #var $flux = external link
* #return bool
*/
private function parseFluxNetAffiliation($flux)
{
$content = file_get_contents($flux);
$content = iconv("iso-8859-15", "utf-8", $content);
$xml = new DOMDocument;
$xml->loadXML($content);
//get the first link : http://www.netaffiliation.com
$link = $xml->getElementsByTagName('link')->item(0);
//echo $link->textContent;
//we get all items and create a multidimentionnal array
$items = $xml->getElementsByTagName('item');
$offers = array();
//we walk items
foreach($items as $item)
{
$childs = $item->childNodes;
//we walk childs
foreach($childs as $child)
{
$offers[$child->nodeName][] = $child->nodeValue;
}
}
unset($offers['#text']);
//we create one article foreach offer
$nbrPosts = count($offers['title']);
if($nbrPosts <= 0)
{
echo self::getFeedback("Le flux ne continent aucune offre",'error');
return false;
}
$i = 0;
while($i < $nbrPosts)
{
// Create post object
$description = '<p>'.$offers['description'][$i].'</p><p>'.$offers['link'][$i].'</p>';
$my_post = array(
'post_title' => $offers['title'][$i],
'post_content' => $description,
'post_status' => 'publish',
'post_author' => 1,
'post_category' => array(self::getCatAffiliation())
);
// Insert the post into the database
if(!wp_insert_post($my_post));;
$i++;
}
echo self::getFeedback("Le flux a généré {$nbrPosts} article(s) depuis le flux NetAffiliation dans la catégorie affiliation",'updated');
return false;
}
All the posts are generated but... the accented chars are ugly. You can see the result here: http://monsieur-mode.com/test/
There are plenty difficulties which you have to master when swapping between different encodings. Also, encodings which use more than one byte to encode characters (so-called multibyte-encodings) like UTF-8, which is used by WordPress, deserve special attention in PHP.
First, make sure that all the files you create are saved with the same encoding as they will be served. For example, make sure you set the same encoding as in the "Save as..."-dialog as you use in the HTTP Content-Type header.
Second, you need to verify that the input has the same encoding as the file you want to deliver. In your case, the input file has the encoding ISO-8859-15, so you'll need to convert it to UTF-8 using iconv().
Third, you must know that PHP doesn't natively support multibyte-encodings such as UTF-8. Functions such as htmlentities() will produce strange characters. For many of these functions, there are multibyte-alternatives, which are prefixed with mb_. If your encoding is UTF-8, check your files for such functions and replace them if necessary.
For more information about these topics, see Wikipedia about variable-width encodings, and the page in the PHP-Manual.
By default, most application work with UTF-8 data and output UTF-8 content. Wordpress should definitely not be apart and surely works on a UTF-8 basis.
I would simply not convert at all any information when printing, but instead change your header to UTF-8 instead of ISO-8859-15.
If your incoming XML data is ISO-8859-15, use iconv() to convert it:
$stream = file_get_contents("stream.xml");
$stream = iconv("iso-8859-15", "utf-8", $stream);
mb_convert_encoding()saves my life.
Here is my solution :
$content = preg_replace('/ encoding="ISO-8859-15"/is','',$content);
$content = mb_convert_encoding($content,"UTF-8");

PHP json_encode() making data null

I have this code here:
case 'resource_list':
if(file_exists('content.php')){
include('../ajax/content.php');
} else {
die('does not exist');
}
$html = render_content_page($array[1],$array[2]);
$slate = 'info_slate';
$reply_array = array(
'html' => $html,
'slate' => $slate
);
echo json_encode($reply_array);
break;
i have debugged every level right up until json_encode() is called. But the data i receive back in my ajax is nul for the html key. This code is essentially a copy and paste of another case the just calls a function other than render_content_page() but that works perfectly fine.
$reply_array var_exports to:
array (
'html' => '<ol>
<li unit="quiz" identifier=""><img src="img/header/notifications.png"/>Fran�ois Vase Volute Krater</li>
</ol>',
'slate' => 'info_slate',
)
My initial thought is that special character in Fran�ois Vase Volute Krater, as json_encode only works with UTF-8 encoded data.
Try UTF-8 encoding it before JSON encoding it like so:
json_encode(utf8_encode("Fran�ois Vase Volute Krater"));
Maybe problem is with encoding?
As manual states, json_encode() works only only with utf8 encoded data:
This function only works with UTF-8 encoded data.
http://php.net/json_encode
As documented, json_encode expects its input text in UTF-8. Most likely, your input (the ç) is not in UTF-8.
Use utf8_encode (if you're currently using ISO-8859-1) or mb_convert_encoding (otherwise) to convert input strings to UTF-8.

Encoding Conversion with PHP

Trying to do a Latin1 to UTF-8 conversion for WordPress, had no luck with the tutorial posted in the Codex. I came up with this to check encoding and convert.
while($row = mysql_fetch_assoc($sql)) {
if(!mb_check_encoding($row['post_content'], 'UTF-8')) {
$row = mb_convert_encoding($row['post_content'], 'ISO-8859-1', 'UTF-8');
if(!mb_check_encoding($row['post_content'], 'UTF-8')) {
echo 'Can\'t Be Converted<br/>';
}
else {
echo '<br/>'.$row.'<br/><br/>';
}
}
else {
echo 'UTF-8<br/>';
}
}
This works... sorta. I'm not getting any rows that can't converted but I did notice that Panamá becomes Panam
Am I missing a step? Or am I doing this all wrong?
UPDATE
The data stored within the database is corrupt(á characters are stored). So its looking more like a find and replace job than a conversion. I haven't found any great solutions so far for doing this automagically.
This will help you. http://php.net/manual/en/book.iconv.php
Further more you can set your mysql connection to utf8 this way:
mysql_set_charset ('utf8',$this->getConnection());
$this->getConnection in my code returns the variable which was returned by
mysql_connect(MYSQL_SERVER,DB_LOGIN,DB_PASS);
Refer to the PHP documentation for mb_convert_encoding:
string mb_convert_encoding ( string $str , string $to_encoding [, mixed $from_encoding ] )
Your code is attempting to convert to ISO-8859-1 from UTF-8!

Categories