Delphi and PHP UTF-8 Returned Data - php

I have a PHP application that calculate all my data and return answers to HTML page with AJAX and JQuery.
in top of my PHP code I add
header("Content-Type: text/html; charset=utf-8");
and return data with
echo json_encode($returndata);
and also i save my file with UTF-8 Format
all things work good with HTML but when i get PHP response with a another program for example Delphi IDHTTP then arabic character show like :\u06f2 \u0634\u0647\u0631\u06cc\u0648\u0631 \u06f1\u06f3\u06f9\u06f9 \u06f1\u06f4:\u06f1\u06f3
i run PHP on server with IIS
here is my Delphi code
try
RespJson := IdHTTP1.Post
('http://192.168.0.6:1000/allcalculate.php',data);
finally
data.Free;
end;
delete(RespJson,length(RespJson),1);
delete(RespJson,1,1);
RespJson := StripChars(RespJson,['"']);
arrresp:= splitstring(RespJson,',');
arrresp:=splitstring(arrresp[30],':');
advedit48.Text:=arrresp[1];
how can i fix this problem
thank you and sorry for bad english

Related

Binary Data from PHP to Angular 6 via http

the goal is to make a http request (empty) from Angular 7 to PHP to receive binary data in Angular for the use with protobuf3.
More specifically, the binary data (encoded like described here: https://developers.google.com/protocol-buffers/docs/encoding) in PHP (source) is encapsulated in a string, while the goal in Angular is a Uint8Array.
Therefore, I currently have the following working code:
PHP Code (a simple ProcessWire root template):
header('Content-Type: application/b64-protobuf');
…
echo base64_encode($response->serializeToString());
Angular:
let res = this.httpClient.get(`${this.API_URL}`, { responseType: 'text' });
res.subscribe((data) => {
let binary_string = atob(data);
let len = binary_string.length;
let bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
let parsedResponse = pb.Response.deserializeBinary(bytes)
})
As you can see I encode the data as base64 before sending it. So, it is not as efficient as it could be, because base64 reduces the amount of information per character. I tried already quite a lot to get binary transmission working, but in the end the data always gets corrupted, i.e. the variable bytes is not identical to the argument of base64_encode.
But still, according to some sources (e.g. PHP write binary response, Binary data corrupted from php to AS3 via http (nobody says it would not be possible)) it should be possible.
So my question is: What must change to directly transfer binary data? Is it even possible?
What have I tried?
using different headers, such as
header('Content-Type:binary/octet-stream;'); or using Blob in Angular.
I also tried to remove base64_encode from the PHP Code and atob
from the Angular Code. The result: the content of the data is modified between serializeToString and deserializeBinary(bytes), which is not desired.
I checked for possible characters before <?php
Specifications:
PHP 7.2.11
Apache 2.4.35
Angular 7.0.2
If further information is needed, just let me know in the comments. I am eager to provide it. Thanks.

PHP passthru: unable to get full response from python script

I'm trying to get data from Python script:
import pymorphy2
import json
import sys
morph = pymorphy2.MorphAnalyzer()
butyavka = morph.parse(sys.argv[1])[0]
for item in butyavka.lexeme:
print(item.word)
PHP code:
<?php
chdir('C:\\Users\Michael-PC\AppData\Local\Programs\Python\Python35-32');
$out;
passthru('python WordAnalizator.py "слово"', $out);
echo($out);
?>
If I use console, it make correct response, like:
But in PHP I have only first word:
Whats wrong?
This is obvious encoding problem (Russian letters become unreadable). So, try to set (i.e. change default) encoding in the PHP code, e.g. add to header usage of Unicode:
header('Content-Type: text/html; charset=utf-8');
If charset=utf-8 does not help, try charset=windows-1251 instead.
UPDATE:
Do not forget to save your file (PHP code in UTF encoding for utf-8, or ANSI for windows-1251)

PHP's base64_decode returns wrong result working in IIS

I'm trying to show a jpg that was previously encoded in a WCF web service using:
<?php
require_once '../inc/config.php';
[...]
header("Content-type: image/jpg");
echo base64_decode($doc['BDATA']);
But I'm getting a
Can't display the image because it contains errors.
I've decoded the base64 string in this web app www.opinionatedgeek.com/dotnet/tools/base64decode/ and the result is right, but different that the one I'm getting with base64_decode, which is wrong.
Edit: I have two enviroments using the same code: Test and Production. It works fine in Test, but not in Production, so I'm thinking in some configuration problem.
I'm working with PHP 5.5.9 in Microsoft IIS.
An example of a string that base64_decode isn't decoding well:
/9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKAP/2Q==
Any ideas?
Edit 2: If I comment this line
require_once '../inc/config.php';
and copy the code from config.php to my actual file, it works fine. What could be happening?
From base_64_decode manual comments
php <= 5.0.5's base64_decode( $string ) will assume that a space is
meant to be a + sign where php >= 5.1.0's base64_decode( $string )
will no longer make that assumption
To fix this behavior try this code
$encodedData = str_replace(' ','+',$encodedData);
$decocedData = base64_decode($encodedData);
As this is no't your case then you have to check this answer
Because every thing work fine for me here on (WAMP)
EDIT:
As in our below conversation
There are a lot of things that may corrupt header for example , if
your file encoding is UTF-8 then you should save it as UTF-8 Without
bom you can do this using notepad ++ , also make sure if you use FTP
that your client didn't any chars to your file , rather than that
every thing should work fine
base64 encoding is not completely standardised.
Some implementations use different characters, so you'll have to replace those characters before you run your decode.
further details

ANSI <--> UTF-8 charset issue, when displaying images from the database (PHP)

I am loading images from a MySQL database, to display them in an Web GUI.
This is pretty standard and worked pretty well, till I tried to install the software in russia...
Here a example of the code that loads the image:
// Load overview image
if ($global_mode == 'overview') {
// Load the image from the database.
mysql_select_db("$db_x");
$sql = "SELECT $db_x.sensor_images.image
FROM $db_x.sensor_images
WHERE $db_x.sensor_images.image_id = '" . $global_image_id . "'";
$sql = mysql_query($sql);
$row = mysql_fetch_assoc($sql);
// Image output.
header('Content-type: image/jpeg');
echo $row['image'];
}
I installed the software on many european based laptops and I never had the problem, that images were not displayed...
Apparently on russian laptops (Windows 7, XAAMP, MySQL) this was not the case, images were not displayed.
I started to do some research and found out (on my laptop, where images get displayed...), that if I change the Encoding of the php file (in this case the show_image.php), I could replicate the error I had on russian laptops.
If the encoding is set to ANSI, the images get displayed...
Here I have disabled the header, so the browser displays the binary data (the encoding of the PHP file is set to ANSI)...
EXAMPLE A
Now I set the Encoding of the PHP file to UTF-8
By doing this images do not get displayed any more...
This is the output when I try to display the data without the header...
EXAMPLE B
As you can see, the output is different...
On my laptop (european):
ANSI: images get displayed, the data (without header) looks like EXAMPLE A
UTF-8: images get not displayed, the data (without header) looks like EXAMPLE B
On russian laptops:
ANSI: images get not displayed, the data (without header) looks like EXAMPLE B
UTF-8: images get not displayed, the data (without header) looks like EXAMPLE B
I still don't understand why changing the encoding of a php file has an impact on the output of binary data, respectively an image...
On the russian laptops the PHP files get always interpreted as if the encoding was set to UTF-8, no matter if I set it to ANSI or something else...
Please help!
Thx.
In your IDE you see "UTF-8" and "UTF-8 without BOM". You're choosing UTF-8, which in this case means with BOM. The BOM is prepended to the file and is the first thing that's output. This may a) break the output of your header, thereby breaking the data display, and b) giving the browser a clue that the following data is supposedly UTF-8 encoded, hence the browser is interpreting the data as UTF-8, which results in a lot of UNICODE REPLACEMENT CHARACTERS �. Check your error logs, you should see PHP complain about Headers already sent.
The data you're sending is always the same, it's just interpreted in different encodings depending on the machine's default and the presence or absence of a UTF-8 BOM.
The only reason it breaks at all under any circumstances is that you're outputting the wrong headers and/or are sending additional content before or after the image data. Check with a low-level tool like curl what exactly is output, and find and remove anything that doesn't belong.
Save the php File that sends out the picture as "UTF-8 w/o BOM".If there are any files inlcuded, it is mandatory that they are saved as either "ANSI" or "UTF-8 w/o BOM", too. There also must be no space nor any text before the <?php -Tag.
If you want to send any text, e.g. an error message because the picture file is non-existent, you need to send the header("Content-Type: charset=utf-8"); right before the text in order to display all characters correctly - but not in combination with the image:
<?php
include "/someSafeDir/utils.inc.php";
$pic= secureGet($_GET['pic']);
$imagePath=/somePath/
$picture=$imagePath.$pic;
if (file_exists($picture)){
if ($fd = fopen ($picture, "r")) {
$fsize = filesize($picture);
header ("Content-type: image/jpeg");
header ("Content-length: $fsize");
readfile($picture);
} else
echo "File \"$pic\" could not be opened.\n";
fclose ($fd);
} else {
header("Content-Type: text/html; charset=utf-8");
echo "File \"$pic\" not existent";
}
?>
It could be that your PHP server charset is not the correct one.
In your php.ini file, try having the following directive:
default_charset = "UTF-8"
And restart your server.

fwrite() and UTF8

I am creating a file using php fwrite() and I know all my data is in UTF8 ( I have done extensive testing on this - when saving data to db and outputting on normal webpage all work fine and report as utf8.), but I am being told the file I am outputting contains non utf8 data :( Is there a command in bash (CentOS) to check the format of a file?
When using vim it shows the content as:
Donâ~#~Yt do anything .... Itâ~#~Ys a
great site with
everything....Weâ~#~Yve only just
launched/
Any help would be appreciated: Either confirming the file is UTF8 or how to write utf8 content to a file.
UPDATE
To clarify how I know I have data in UTF8 i have done the following:
DB is set to utf8 When saving data
to database I run this first:
$enc = mb_detect_encoding($data);
$data = mb_convert_encoding($data, "UTF-8", $enc);
Just before I run fwrite i have checked the data with Note each piece of data returns 'IS utf-8'
if (strlen($data)==mb_strlen($data, 'UTF-8')) print 'NOT UTF-8';
else print 'IS utf-8';
Thanks!
If you know the data is in UTF8 than you want to set up the header.
I wrote a solution answering to another tread.
The solution is the following: As the UTF-8 byte-order mark is \xef\xbb\xbf we should add it to the document's header.
<?php
function writeStringToFile($file, $string){
$f=fopen($file, "wb");
$file="\xEF\xBB\xBF".$file; // this is what makes the magic
fputs($f, $string);
fclose($f);
}
?>
You can adapt it to your code, basically you just want to make sure that you write a UTF8 file (as you said you know your content is UTF8 encoded).
fwrite() is not binary safe. That means, that your data - be it correctly encoded or not - might get mangled by this command or it's underlying routines.
To be on the safe side, you should use fopen() with the binary mode flag. that's b. Afterwards, fwrite() will safe your string data "as-is", and that is in PHP until now binary data, because strings in PHP are binary strings.
Background: Some systems differ between text and binary data. The binary flag will explicitly command PHP on such systems to use the binary output. When you deal with UTF-8 you should take care that the data does not get's mangeled. That's prevented by handling the string data as binary data.
However: If it's not like you told in your question that the UTF-8 encoding of the data is preserved, than your encoding got broken and even binary safe handling will keep the broken status. However, with the binary flag you still ensure that this is not the fwrite() part of your application that is breaking things.
It has been rightfully written in another answer here, that you do not know the encoding if you have data only. However, you can validate data if it validates UTF-8 encoding or not, so giving you at least some chance to check the encoding. A function in PHP which does this I've posted in a UTF-8 releated question so it might be of use for you if you need to debug things: Answer to: SimpleXML and Chinese look for can_be_valid_utf8_statemachine, that's the name of the function.
//add BOM to fix UTF-8 in Excel
fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
I find this piece works for me :)
The problem is your data is double encoded. I assume your original text is something like:
Don’t do anything
with ’, i.e., not the straight apostrophe, but the right single quotation mark.
If you write a PHP script with this content and encoded in UTF-8:
<?php
//File in UTF-8
echo utf8_encode("Don’t"); //this will double encode
You will get something similar to your output.
$handle = fopen($file,"w");
fwrite($handle, pack("CCC",0xef,0xbb,0xbf));
fwrite($handle,$file);
fclose($handle);
I know all my data is in UTF8 - wrong.
Encoding it's not the format of a file. So, check charset in headers of the page, where you taking data from:
header("Content-type: text/html; charset=utf-8;");
And check if data really in multi-byte encoding:
if (strlen($data)==mb_strlen($data, 'UTF-8')) print 'not UTF-8';
else print 'utf-8';
There is some reason:
first you get information from database it is not utf-8.
if you sure that was true use this ,I always use this and it work :
$file= fopen('../logs/logs.txt','a');
fwrite($file,PHP_EOL."_____________________output_____________________".PHP_EOL);
fwrite($file,print_r($value,true));
The only thing I had to do is add a UTF8 BOM to the CSV, the data was correct but the file reader (external application) couldn't read the file properly without the BOM
Try this simple method that is more useful and add to the top of the page before tag <body> :
<head>
<meta charset="utf-8">
</head>

Categories