text encoding in php response - php

i'm trying to print a JSON in Hebrew and only get utf-8 encoded string. how can I make sure the client's browser shows the string in Hebrew?
the code is:
<html>
<head>
<meta charset=utf-8" />
</head>
<body>
<?php
header('Content-Type: text/html; charset=utf-8');
$response = array();
require_once __DIR__.'/db_connect.php';
$db = new DB_CONNECT();
$result = mysql_query(" SELECT * FROM stores") or die(mysql_error());
if (mysql_num_rows($result)>0){
$response["stores"]=array();
while($row = mysql_fetch_array($result)){
$store = array();
$store["_id"]=$row["_id"];
$store["name"]=$row["name"];
$store["store_type"]=$row["store_type"];
array_push($response["stores"],$store);
}
$response["success"] = 1;
$string = utf8_encode(json_encode($response));
echo hebrevc($string);
}else{
$response["success"]=0;
$response["message"]="No stores found";
echo utf8_encode(json_encode($response));
}
?>
</body>
</html>
and the response is:
{{"stores":[{"_id":"1","name":"\u05d7\u05ea\u05d5\u05dc\u05d9","store_type":"\u05de\u05e1\u05e2\u05d3\u05ea \u05d1\u05e9\u05e8\u05d9\u05dd"},{"_id":"2","name":"\u05de\u05e2\u05d3\u05e0\u05d9 \u05de\u05d0\u05de\u05d9","store_type":"\u05de\u05e1\u05e2\u05d3\u05d4 \u05dc\u05e8\u05d5\u05e1\u05d9\u05dd"}],"success":1

A nice constant was added in PHP 5.4: JSON_UNESCAPED_UNICODE
Using it will not escape your Hebrew characters.
echo json_encode($response, JSON_UNESCAPED_UNICODE);
Check out the json_encode reference.

The result looks like a UCS-2 string. Try setting the charset of the Mysql Connection:
mysql_set_charset('utf8', $conn)
then remove the utf8_encode statements

Related

SQL result not english characters

I always work with MySQL but in but I am forced now to work with SQL Server and I am lost. I just want to get a row in spanish and I can't make it work. Here is the code, hopefully everything makes sense.
$connection = odbc_connect("Driver={SQL Server Native Client 11.0};Server=$server;Database=$database;", $user, $password);
$sql="SELECT * FROM my_table";
$res=odbc_exec($connection,$sql)or die(exit("Error en odbc_exec"));
while($arr = odbc_fetch_array($res)) {
$var = $arr["OkRef"];
echo "1.- ".iconv("Windows-1256", "UTF-8", "$var")."<br />";
echo "2.- ".iconv("CP437", "UTF-8", $var)."<br />";
echo "3.- ".iconv("CP850", "UTF-8", $var)."<br />";
echo "4.- ".utf8_decode($arr["OkRef"])."<br />";
echo "5.- ".utf8_encode($arr["OkRef"])."<br />";
echo "6.- ".$arr["OkRef"]."<br />";
echo "7.- ".mb_convert_encoding($arr["OkRef"], "utf-8", "windows-1251")."<br />";
echo "8.- ".htmlspecialchars( iconv("iso-8859-1", "utf-8", $var) );
}
}
I get this as result:
1.- ér àçHه¬´§d_meta_packet1Y³§0ت.122) ¸ؤ
2.- Θr ατHσ¼┤ºd_meta_packet1Y│º0╩.122) ╕─
3.- Úr ÓþHÕ¼┤ºd_meta_packet1Y│º0╩.122) ©─
4.- ?r ??H????d_meta_packet1Y??0?.122) ??
5.- ér àçH嬴§d_meta_packet1Y³§0Ê.122) ¸Ä
6.- �r ��H����d_meta_packet1Y��0�.122) ��
7.- йr азH嬴§d_meta_packet1Yі§0К.122) ёД
8.- ér àçH嬴§d_meta_packet1Y³§0Ê.122) ¸Ä
I tried also to add the following (not at once obviously) to make it work as it is:
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
header('Content-Type: text/html;charset=utf-8');
header('Content-Type: text/html;charset=iso-8859-1');
ini_set('mssql.charset', 'UTF-8');
The server is a Microsoft SQL Server Enterprise Edition, and the server Collation is Modern_Spanish_CI_AS.
I know, that this answer is posted too late, but I am in similar situation these days, so I want to share my experience.
My configuration is almost the same - database and table columns with Cyrillic_General_CS_AS collation. Note, that I use PHP Driver for SQL Server, not build-in ODBC support.
The steps below have helped me to resolve my case. I've used collation from your example.
Database:
CREATE TABLE [dbo].[MyTable] (
[TextInSpanish] [varchar](50) COLLATE Modern_Spanish_CI_AS NULL,
[NTextInSpanish] [nvarchar](50) COLLATE Modern_Spanish_CI_AS NULL
)
INSERT [dbo].[MyTable] (TextInSpanish, NTextInSpanish)
VALUES ('Algunas palabras en español', N'Algunas palabras en español')
PHP:
Set default_charset = "UTF-8" in your php.ini file.
Encode your source files in UTF-8. I use Notepad++ for this step.
Read data from database:
With default connection encoding. For reading data from database use $data = iconv('CP1252', 'UTF-8', $data);
Note, that by default data is returned in 8-bit characters as specified in the code
page of the Windows locale that is set on the system. Any
multi-byte characters or characters that do not map into
this code page are substituted with a single-byte question
mark (?) character. This is the default encoding.
With UTF-8 connection encoding.
Column must be of type 'nchar' or 'nvarchar'.
HTML:
Use: <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Working Example:
test.php (PHP 7.1, PHP Driver for SQL Server 4.3, file test.php is UTF-8 encoded):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta charset="utf-8">
<?php
// Connection settings
$server = '127.0.0.1\instance,port';
$database = 'database';
$user = 'username';
$password = 'password';
$cinfo = array(
"CharacterSet"=>SQLSRV_ENC_CHAR,
#"CharacterSet"=>"UTF-8",
"Database"=>$database,
"UID"=>$user,
"PWD"=>$password
);
$conn = sqlsrv_connect($server, $cinfo);
if ($conn === false)
{
echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
exit;
}
// Query
$sql = "SELECT * FROM MyTable";
$res = sqlsrv_query($conn, $sql);
if ($res === false) {
echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
exit;
}
// Results
while ($arr = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC)) {
# Use next 2 lines with "CharacterSet"=>SQLSRV_ENC_CHAR connection setting
echo iconv('CP1252', 'UTF-8', $arr['TextInSpanish'])."</br>";
echo iconv('CP1252', 'UTF-8', $arr['NTextInSpanish'])."</br>";
# Use next 2 lines with "CharacterSet"=>"UTF-8" connection setting
#echo $arr['TextInSpanish']."</br>";
#echo $arr['NTextInSpanish']."</br>";
}
// End
sqlsrv_free_stmt($res);
sqlsrv_close($conn);
?>
</head>
<body></body>
</html>
Oh my gosh, this did it:
"$data = iconv('CP1252', 'UTF-8', $data);"
Or in my case:
$specialnost = $_POST['specialnost'];
$specialnost = iconv('CP1251', 'UTF-8', $specialnost);
I have been searching for the last three days for a solution! Thank you Zhorov!

Result from URL request returning weird characters instead of accents

My problem is that the accents are not displayed in the output of print_r().
Here is my code:
<?php
include('./lib/simple_html_dom.php');
error_reporting(E_ALL);
if (isset($_GET['q'])){
$q = $_GET['q'];
$keyword=urlencode($q);
$url="https://www.google.com/search?q=$keyword";
$html=file_get_html($url);
$results=$html->find('li.g');
$G_tot = sizeof($results)-1;
for($g=0;$g<=$G_tot;$g++){
$results=$html->find('li.g',$g);
$array_ttl_google[]=$results->find('h3.r',0)->plaintext;
$array_desc_google[]=$results->find('span.st',0)->plaintext;
$array_href_google[]=$results->find('cite',0)->plaintext;
}
print_r($array_desc_google);
}
?>
Here is the result of print_r:
Array ( [0] => �t� m (plural �t�s)...
What is the resolution in your opinion?
3 basic things you can do:
Set the page encoding to UTF-8 - Add at the very begining of your page: header('Content-Type: text/html; charset=utf-8');
Make sure your code file is saved as UTF-8 (without BOM).
Add a function to translate the parsed string to UTF-8 (in case some other sites are using different encodings)
Your code should look something like that (Tested - working great tried with english and hebrew results):
<?php
header('Content-Type: text/html; charset=utf-8');
include('simple_html_dom.php');
error_reporting(0);
if (isset($_GET['q'])){
$q = $_GET['q'];
$keyword=urlencode($q);
$url="https://www.google.com/search?q=$keyword";
$html=file_get_html($url);
//Make sure we received UTF-8:
$encoding = #mb_detect_encoding($html);
if ($encoding && strtoupper($encoding) != "UTF-8")
$html = #iconv($encoding, "utf-8//TRANSLIT//IGNORE", $html);
//Proceed with your code:
$results=$html->find('li.g');
$G_tot = sizeof($results)-1;
for($g=0;$g<=$G_tot;$g++){
$results=$html->find('li.g',$g);
$array_ttl_google[]= $results->find('h3.r',0)->plaintext;
$array_desc_google[]= $results->find('span.st',0)->plaintext;
$array_href_google[] = $results->find('cite',0)->plaintext;
}
print_r($array_desc_google);
} else {
echo "You forgot to set the 'q' variable in your url.";
}
?>

Cannot get the correct utf-8 text from Access

When I tried to get chinese characters from the database, I got weird text.
I tried almost everything, like html_entity_decode, htmlentities, save the file using utf-8, encode in utf-8, but I can't seem to get it right.
How do i get the right text?
Here's my code:
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<?php
header('Content-Type: text/html; charset=utf-8');
$conn=odbc_connect('vocab','','');
$rs1=odbc_exec($conn,"SELECT MAX(ID) AS MaxId FROM vocab");
$NewMaxID=odbc_result($rs1,"MaxId");
$rand=rand(1,$NewMaxID);
$sql="SELECT word,part_of_speech,chinese FROM vocab WHERE ID=".$rand.";";
$rs=odbc_exec($conn,$sql);
$i=1;
odbc_fetch_row($rs);
$a=(odbc_result($rs,1));
$b=(odbc_result($rs,2));
$c=(odbc_result($rs,3));
//$c="鎮";
//$d=html_entity_decode($c);
//$c=htmlentities($d, ENT_NOQUOTES , "UTF-8");
$rows=array("first"=>$a,"second"=>$b,"third"=>$c);
echo json_encode($rows);
?>
ps: I am using Traditional Chinese version of MS Office.
I encountered this issue a while ago and the only way I could get it to work was to write the HTML into an ADODB.Stream object, save it to a file, and then echo the file:
<?php
define("TEMP_FOLDER", "C:\\__tmp\\");
header('Content-Type: text/html; charset=utf-8');
$stm = new COM("ADODB.Stream") or die("Cannot create COM object.");
$stm->Type = 2; // adTypeText
$stm->Charset = 'utf-8';
$stm->Open();
$stm->WriteText('<html>');
$stm->WriteText('<head>');
$stm->WriteText('<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />');
$stm->WriteText('<title>ADODB test</title>');
$stm->WriteText('</head>');
$stm->WriteText('<body>');
$con = new COM("ADODB.Connection");
$con->Open(
"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" .
"Dbq=C:\\Users\\Public\\Database1.accdb");
$rst = $con->Execute("SELECT word FROM vocab WHERE ID=3");
$stm->WriteText($rst->Fields("word"));
$rst->Close();
$con->Close();
$stm->WriteText('</body>');
$stm->WriteText('</html>');
$tempFile = TEMP_FOLDER . uniqid("", TRUE) . ".txt";
$stm->SaveToFile($tempFile, 2); // adSaveCreateOverWrite
$stm->Close();
echo file_get_contents($tempFile);
unlink($tempFile);
?>

PHP Script not Working: error on line 1 column 538

I have no idea of what is going wrong, i was using this same script to get another XML and it was working just fine.
This is the script:
<?php
header("Content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"LATIN-1\"?>";
echo "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
echo "<plist version=\"1.0\">";
function getXML($sql="SELECT IDCargo FROM database.table"){
$conn = mysql_connect ("myserverurl.com", "user", "psw");
$db = mysql_select_db("database");
$result = mysql_query($sql, $conn);
$column = "";
echo "<array>";
while($row = mysql_fetch_assoc($result)){
$column .= "<dict>";
foreach ($row as $key => $value){
$column .= "<key>$key</key>";
$column .= "<string>$value</string>";
}
$column .= "</dict>";
}
echo $column;
echo "</array>";
echo "</plist>";
}
getXML("SELECT IDCargo as ID_CARGO, SequencialDoCandidato as NUMERO_SEQ_CANDIDATO, NomeDoCandidato AS NOME_CANDIDATO, NumeroDoCandidato as NUMERO_CANDIDATO, NomeDoPartido AS SIGLA_PARTIDO, Estado as SIGLA_ESTADO,IDUnidadeEleitoral AS ID_CIDADE_CANDIDATO, UnidadeEleitoral AS CIDADE_CANDIDATO FROM database.table");
mysql_close();
?>
It brings this error:
This page contains the following errors:
error on line 1 at column 538: Encoding error
Below is a rendering of the page up to the first error.
ID_CARGO11NUMERO_SEQ_CANDIDATO10000002965NOME_CANDIDATOAGRECINO DE SOUSANUMERO_CANDIDATO13SIGLA_PARTIDOPTSIGLA_ESTADOACID_CIDADE_CANDIDATO1120CIDADE_CANDIDATO
Can anyone see anything? Give me some help here, please.
I got the script from one that was working just fine.
If I read your code, I can see :
echo "<?xml version=\"1.0\" encoding=\"LATIN-1\"?>";
So I guess you want to output LATIN-1 charset. You need to specify this charset everywhere :
1/ You can try to specify the encoding on the http header :
header("Content-type: text/xml; charset=ISO-8859-1");
2/ And you can also set the charset on the DB client :
mysql_set_charset('latin1', $db);
Your output most likely contains a character or characters in an encoding not supported in the default encoding.
Either update the encoding you use, or escape any characters that does not fit the encoding. The htmlentities php function would be a good start.

Use php for Output Buffering and jQuery to send ob_get_contents

I am trying to capture the contents of my php page using output buffering:
<?php
function connect() {
$dbh = mysql_connect ("localhost", "user", "password") or die ('I cannot connect to the database because: ' . mysql_error());
mysql_select_db("PDS", $dbh);
return $dbh;
}
session_start();
if(isset($_SESSION['username'])){
if(isset($_POST['entryId'])){
//do something
$dbh = connect();
$ide = $_POST['entryId'];
$usertab = $_POST['usertable'];
$answertable = $usertab . "Answers";
$entrytable = $usertab . "Entries";
$query = mysql_query("SELECT e.date, q.questionNumber, q.question, q.sectionId, a.answer FROM $answertable a, Questions q, $entrytable e WHERE a.entryId = '$ide' AND a.questionId = q.questionId AND e.entryId = '$ide' ORDER BY q.questionNumber ASC;") or die("Error: " . mysql_error());
if($query){
//set variables
$sectionOne = array();
while($row=mysql_fetch_assoc($query)){
$date = $row['date'];
$sectionOne[] = $row;
}
}else{
//error - sql failed
}
}
?>
<?php
ob_start();
?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script src = "jQuery.js"></script>
<script>
$(document).ready(function(){
$("#export").click(function(e){
//post to html2pdfconverter.php
$("#link").val("<?php echo(ob_get_contents()); ?>"); //THIS DOESN'T WORK
$("#nm").val("Entry Report.pdf");
$("form#sendanswers").submit();
});
});
</script>
<title>Personal Diary System - Entry Report - <?php echo($date); ?></title>
</head>
<body>
<h1>Entry Report - <?php echo($date); ?></h1>
<div id = "buttons">
<form id = "sendanswers" name = "sendanswers" action="html2pdfconverter.php" method="post">
<input type = "hidden" name = "link" id = "link" value = "">
<input type = "hidden" name = "nm" id = "nm" value = "">
<input type = "button" name = "export" id = "export" value = "Export As PDF"/>
</form>
</div>
<h3>Biological Information</h3>
<?php
echo('<p>');
$i = 0;
foreach($sectionOne as &$value){
if($i == 1 || $i == 3){
$image = "assets/urine".$i.".png";
echo("<br/>");
echo($value['question']." <br/> "."<img src = \"$image\"/>");
echo("<br/>");
}else{
echo($value['question'].' : '.$value['answer']);
}
echo("<br/>");
$i++;
}
echo('</p>');
?>
</body>
</html>
<?php
}
$contents = ob_get_contents(); //THIS WORKS
ob_end();
?>
I assign the contents of ob to $contents using ob_get_contents(); This works, and echoing $contents duplicates the html page.
However, in my jQuery, I am trying to assign this to a hidden text field ('link') using:
$("#link").val("<?php echo($contents); ?>");
This doesn't work however..And I have a feeling its because I am accessing $contents too eraly but not too sure...any ideas?
$("#link").val("<?php echo(ob_get_contents()); ?>"); //THIS DOESN'T WORK
at the point you do that ob_get_contents call, you've only output about 10 lines of javascript and html. PHP will NOT reach back in time and magically fill in the rest of the document where you do this ob_get_contents().
You're basically ripping the page out of the laser printer the moment the page starts emerging, while the printer is still printing the bottom half of the page.
I fail to see why you want to embed the contents of your page into an input field. If you want to somehow cache the page's content in an input field, you can just use JS to grab the .innerHTML of $('body').
Well, you have two problems.
The first is what you suspect. You can't access that stuff until later. The second problem which you may not realize is that you will have quoting issues in JavaScript even if you manage to find a way to reorder this and make it work. It's recursive, in a bad way.
What you should do instead is change your $('#export').click handler to do an Ajax call, render the HTML you need to appear in the link on the server in a separate PHP script (no output buffering necessary) and then have your code inject the result of that call into the page the way you're trying to do in your click handler now.

Categories