Write binary stream to browser using PHP - java

Background
Trying to stream a PDF report written using iReport through PHP to the browser. The general problem is: how do you write binary data to the browser using PHP?
Working Code
header('Cache-Control: no-cache private');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment, filename=climate-report.pdf');
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');
$path = realpath( "." ) . "/output.pdf";
$em = java('net.sf.jasperreports.engine.JasperExportManager');
$result = $em->exportReportToPdf($pm);
header('Content-Length: ' . strlen( $result ) );
$fh = fopen( $path, 'w' );
fwrite( $fh, $result );
fclose( $fh );
readfile( $path );
Non-working Code
header('Cache-Control: no-cache private');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment, filename=climate-report.pdf');
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');
$path = realpath( "." ) . "/output.pdf";
$em = java('net.sf.jasperreports.engine.JasperExportManager');
$result = $em->exportReportToPdf($pm);
header('Content-Length: ' . strlen( $result ) );
echo $result;
Question
How can I take out the middle step of writing to the file and write directly to the browser so that the PDF is not corrupted?
Update
PDF file sizes:
Working: 594778 bytes
Non-working: 1059365 bytes
Thank you!

I've previously experienced problems writing from Java because it'll use UTF-16. The function outputPDF from http://zeronine.org/lab/index.php uses java_set_file_encoding("ISO-8859-1");. Thus:
java_set_file_encoding("ISO-8859-1");
$em = java('net.sf.jasperreports.engine.JasperExportManager');
$result = $em->exportReportToPdf($pm);
header('Content-Length: ' . strlen( $result ) );
echo $result;

You just write the output. Make sure that:
correct headers have been set
no other character have been accidentally printed before or after the binary (this includes whitespace).

Related

My java Base64 results are not the same as php

I have previously posted a question related to this work link but I am posting a new one because the question is not completely resolved
I am working on converting the completed code into java with php.
It is a function that reads encrypted files, decrypts them by 16 bytes, makes them into a single string, and encodes them with base 64.
php is already on the server and running, and I have to use java to produce the same result.
If you decrypt the read file,
<?xml version="1.0" encoding="utf-8" ?>
<FileInfo>
...
<TextData> (text data) </TextData>
</FileInfo>
(image data)
It is in the format, and the text data in shows php and java exactly the same.
I am trying to encode the image data part into base64, but the result is different from php.
This is the part of the php code I have that decrypts and processes the read file
$fileContentArray = array(16);
$transContentArray = array(16);
$fileRead = fread($fp,16);
for($i = 0 ; $i < strlen($fileRead); $i++){
$fileContentArray[$i] = ord($fileRead[$i]);
}
$seed->SeedDecrypt($fileContentArray,$pdwRoundKey,$transContentArray);
$transStr = call_user_func_array("pack",array_merge(array("C16"),$transContentArray));
$mergeStr .= $transStr;
}
$dataExplode = explode("<TextData>",trim($mergeStr) );
$dataExplode1 = explode("</FileInfo>",trim($dataExplode[1]) );
$dataExplode2 = explode("</TextData>",$dataExplode1[0]);
$textData = iconv("EUC-KR","utf-8",$dataExplode2[0]);
$imageData = base64_encode(trim($dataExplode1[1]));
And this is the same part of the java code I wrote
byte[] fileContentArray=new byte[n];
for(int i=0;i<fileContentArray.length;i++){
fileContentArray[i]=mergeArr[nReadCur+i];
}
seed.SeedDecrypt(fileContentArray, pdwRoundKey, outbuf);
System.arraycopy(outbuf, 0, resultArr, nReadCur, outbuf.length);
nReadCur=nReadCur+fileContentArray.length;
p=p+fileContentArray.length;
if(p>=nFileSize){
fis.close();
break;
}
}//while
mergeStr=new String(resultArr,"MS949");
String[] dataExplode=mergeStr.trim().split("<TextData>");
String[] dataExplode1=dataExplode[1].trim().split("</FileInfo>");
String[] dataExplode2=dataExplode1[0].trim().split("</TextData>");
String textData = "";
String imageData = "";
textData=dataExplode2[0];
imageData=dataExplode1[1];
Encoder encoder=Base64.getEncoder();
Decoder decoder=Base64.getDecoder();
byte[] encArr=encoder.encode(imageData.trim().getBytes("MS949"));
imageData=new String(encArr,"MS949");
As a result of encoding image data into base64
php: R0lGODlhAwNLBPcAAAAAAAAAMwAAZgAAmQAAzAAA/wArAAArMwArZgArmQArzAAr/wBVAABVMwBVZgBVmQBVzABV/wCAAACAMwCAZgCAmQCAzACA/ ... VzpYirO0le55zF0=
java: R0lGODlhAwNLBD8AAAAAAAAAMwAAZgAAPwAAPwAAPwArAAArMwArZgArPwArPwArPwBVAABVMwBVZgBVPwBVPwBVPwA/AAA/MwA/ZgA/PwA/PwA/PwA/ ... DAQEAOz9GPz8/IXY=
As you can see, the result values are output differently.
Is there anything I'm missing? What should I do to make the result of java the same as php?
Also, MergeStr, who has read the file,
java:
GIF89aK? 3 f ? ? ? + +3 +f +? +? +? U U3 Uf U? U? U? ? ?3 ?f ?? ?? ?? ? ?3 챖 첌 ぬ ? ? ?3 ?f ??
...
J뇽杞H?*]苛⒢쬝쥻쒳뎁諾X...
A?h?~?0a?2$ #삁?d?Dd??e ...
...
WC ;홃?뿿!v
php:
GIF89aK? 3 f ? ?  + +3 +f +? +? + U U3 Uf U? U? U 3 f ? ?  ? ? 챖 첌 ぬ ? ? ? ? ? 螂 ?  3 f ? ? ...
A??~?a?$ #삁?d?Dd?e...
...
WC ;홃??v余퍙W:X뒽킉??
Like this, there is a new line text that I didn't put in, and there's a slight difference in result. Is this a simple difference in encoding? And does this affect the base64 conversion?
I tried encoding with UTF-8 and failed again,
and I used this code to load all bytes of the file at once
FileInputStream fis = new FileInputStream(tpf);
fis.read(mergeArr);
Java uses a little bit different encoding for base64 than PHP. You may use these helper functions to make them compatible to the Java version.
function base64url_encode($data)
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode($data, $strict = false)
{
return base64_decode(strtr($data, '-_', '+/'), $strict);
}

Using Select and Update in PHP query

I am new to php .. anyway I have an application that require to provide the vacation information from the database to the supervisor and then allow the supervisor to enter his approval of this vacation ,
To do this, I use 2 php pages:
one to retrieve the employee vacation request information
and the other to insert the supervisor approval into the database
I want the application to insert this approval value in the record of this employeeID that I retrieve his information in this application.
The retrieval of employee information is done correctly, but the insert doesn't work !
I try this query but it didn't work (it didn't return any results when I exceute the query):
<?php
if(! $conn)
{
die('Could not connect: '.mysql_error());
}
mysql_select_db("a2202757_OURDATA",$conn);
$flag['code']=0;
if($r = mysql_query ("UPDATE request_vacation SET VacationApprove='".$_POST['Approval']."' WHERE IDEmployee=$id",$conn));
{
$flag['code']=1;
}
print(json_encode($flag));
mysql_close($conn);
?>
What is the problem ?
What happens is that you assign a variable ( = is an assignment for comparison you use == or ===) in an if statement.
When you want to check and assign at the same time use this:
if(false !== $r = $mysql_query("UPDATE .......") {
echo 'Update successfull';
}
else {
echo 'Update failed with error ' . mysql_error();
}
It is difficult to solve the problem if you do not provide any error message about the database connection. Please use the following code and using your host and username password to let php to print out the error message. It would be useful if you can provide further error information.
$conn = mysql_connect('localhost','username','password');
if(! $conn)
{
die('Could not connect: '.mysql_error());
}
$db_selected = mysql_select_db("a2202757_OURDATA",$conn);
if (!$db_selected) {
die ('Can\'t use foo : ' . mysql_error());
}
$flag['code']=0;
$r = mysql_query ("UPDATE request_vacation SET VacationApprove='".$_POST['Approval']."' WHERE IDEmployee=$id",$conn);
if (!$r) {
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $query;
die($message);
}
if($r != null);
{
$flag['code']=1;
}
print(json_encode($flag));
mysql_close($conn);
Try this
<?php
if (isset ( $_POST ['Approval'] )/* && isset ( $_POST ['IDEmployee'] )*/) {
mysql_connect ( 'server', 'username', 'password' ) or die ( mysql_error () );
mysql_select_db ( 'a2202757_OURDATA' );
// mysql_query ( "UPDATE request_vacation SET VacationApprove='" . $_POST ['Approval'] . "' WHERE IDEmployee= '" . $_POST ['IDEmployee'] . "'" ) or die ( mysql_error () );
// Hey, What is $id, I leave it up to you.
mysql_query ( "UPDATE request_vacation SET VacationApprove='" . $_POST ['Approval'] . "' WHERE IDEmployee= '" . $id . "'" ) or die ( mysql_error () );
if (mysql_affected_rows () != - 1) {
// some rows has affected
echo mysql_affected_rows () . 'rows has affected';
} else {
// No row has affected
}
} else {
die ( 'Approval '/* . 'and/or IDEmployee'*/ . ' are not properly set' );
}
?>
and, please give some more detail
I think your code formatting is somehow broken on stackexchange.
Below is an example of how to use queries, because you code seems to be fairly broken and nonsense.
Attention: Don't use that in a production environment because it includes some SQLInjection vulnerabilities.
$id = $_POST["IDEmployee"];
// this sets the VacationApprove clumn of request_vacation
// to the $_POST['Approval'] variable where IDEmployee matches
// the previously selected $id
$insRes = mysql_query("UPDATE request_vacation SET VacationApprove = '".$_POST['Approval']."' WHERE IDEmployee = '".$id."'")
I don't know what you are trying to achieve. Please be more specific about your problem.

Multiple values from a SQL Database in php through to Java as separate variables

I'm attempting to retrieve multiple values from a database through php to my android java in eclipse.
I'm managing to get all variations of json arrays except the one i need.
My database is:
**Aircraft** **Status**
A870_870 1
A870_871 1
A870_872 1
A870_873 1
A870_874 1
A870_875 1
A870_876 2
A870_877 1
A870_878 2
A870_879 2
A870_880 2
A870_881 0
A870_882 0
A870_883 0
A870_884 0
A870_885 0
The format I need so that my android app reads it is:
{"A70_870":"1","A70_871":"1","A70_872":"1","A70_873":"1","A70_874":"1",
"A70_875":"1","A70_876":"2","A70_877":"1","A70_879":"2","A70_878":"2",
"A70_880":"2","A70_881":"0","A70_882":"0","A70_883":"0","A70_884":"0",
"A70_885":"0"}
I've been attempting different 'while' loops all sorts of other variations and manage to get all sorts of combinations except the one i need. Surely there is a way...?
My closest PHP attemp is below:
<?php
$con = mysqli_connect("localhost","root","", "mytestdatabase");
if (mysqli_connect_errno()) {
echo 'Database connection error: ' . mysqli_connect_error();
exit();
}
$userdetails = mysqli_query($con, "SELECT *FROM aircraft_status");
$row = mysqli_fetch_row($userdetails) ;
$result_data = array(
'A70_870'=>$row[1],
'A70_871'=>$row[1],
'A70_872'=>$row[1],
'A70_873'=>$row[1],
'A70_874'=>$row[1],
'A70_875'=>$row[1],
'A70_876'=>$row[1],
'A70_877'=>$row[1],
'A70_879'=>$row[1],
'A70_878'=>$row[1],
'A70_880'=>$row[1],
'A70_881'=>$row[1],
'A70_882'=>$row[1],
'A70_883'=>$row[1],
'A70_884'=>$row[1],
'A70_885'=>$row[1],);
echo json_encode($result_data);
?>
It gives the correct format, but obviously only reads row 1. I can't access 3,5,7 etc..
If anyone can assist me in this it would be great!! :) I'm sure its something simple I'm not doing right....
I might be missing something but is it not just wrapping result extraction in a while loop:
$userdetails = mysqli_query($con, "SELECT *FROM aircraft_status");
$result_data = array();
if ($userdetails) {
while($row = mysql_fetch_array($userdetails)) {
// $row[0] being aircraft and $row[1] being status
array_push($result_data , $row[0], $row[1]);
}
}
else {
echo mysql_error();
}
echo json_encode($result_data);
My PHP is very rusty, so might need adjustments. Hope this gets you on the way.

Whitespaces in Java/PHP

Spaces not changing to underscored when sent from Java-->PHP-->SQL
Java code:
String urlString = "http://www.mysite.com/auth/verifyuser.php?name="+name.toLowerCase().replace(" ","_");
PHP code:
$name = mysql_real_escape_string($_GET['name']);
$name = str_replace(' ', '_', $name);
$query = "select * from authinfo where name LIKE '$name'";
mysql_query($query);
$num = mysql_affected_rows();
if ($num > 0) {
echo '1';
} else {
echo '0';
}
when I implement a test log on the SQL database, it somehow still seems to show up with spaces instead of underscores(even though I replace it in Java and PHP) and the PHP file returns '0' rather than '1'. I've heard the issue might be whitespaces? It seems to happen to only certain users, mostly mac users.
If your php file is returning a 0, that means your query is not getting executed. Where are you establishing a connection with the database before executing the query?
Remark: where name = '$name'
mysql_affected_rows concerns INSERT, UPDATE and DELETE.
$r = mysql_query($query);
$num = mysql_num_rows($r);
It's unsafe to pass raw name into URL without encoding it.
String urlString = "http://www.example.com/auth/verifyuser.php?name=" + URLEncoder.encode(name.toLowerCase(), "UTF-8");
In PHP you can obtain data:
$name = urldecode($_GET['name']);

Recognizing a character to be Chinese and get Chinese "pinyin" phonetics from simplified characters?

Is it possible to
A. find out if a character is Chinese (simplified) and in that case
B. get the pinyin? example: 你好 => nǐhǎo using java or php?
Cheers
A)
Yes. All characters represented in unicode have a unique numeric index called a codepoint.
If you know the range of codepoints for simplified Chinese and you know how to get the unicode codepoint of a given character, a simple comparison will tell you if the given character is within the simplified Chinese range.
An existing question has a solution for getting the unicode codepoint for a character in PHP:
How to get code point number for a given character in a utf-8 string?
In Java, the static java.lang.Character::codePointAt() method will give you what you need.
B)
Converting a simplified Chinese character, or string, to Pinyin would most likely require some form of map with the unicode code point as the key and the corresponding pinyin as the value.
An example of this in PHP is shown at http://kingphp.com/108.html.
A simple Google search for [java pinyin] reveals a range of options, two of which being Chinese to pinyin libraries at http://kiang.org/jordan/software/pinyinime/ and http://pinyin4j.sourceforge.net/.
Bit late, but solved!
<?php
function curl($url,$params = array(),$is_coockie_set = false)
{
if(!$is_coockie_set){
/* STEP 1. let¡¯s create a cookie file */
$ckfile = tempnam ("/tmp", "CURLCOOKIE");
/* STEP 2. visit the homepage to set the cookie properly */
$ch = curl_init ($url);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec ($ch);
}
$str = ''; $str_arr= array();
foreach($params as $key => $value)
{
$str_arr[] = urlencode($key)."=".urlencode($value);
}
if(!empty($str_arr))
$str = '?'.implode('&',$str_arr);
/* STEP 3. visit cookiepage.php */
$Url = $url.$str;
$ch = curl_init ($Url);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec ($ch);
return $output;
}
function Translate($word,$from,$to)
{
$word = urlencode($word);
$url = 'http://translate.google.com/translate_a/t?client=t&text='.$word.'&hl=' . $from . '&sl=' . $from . '&tl=' . $to . '&ie=UTF-8&oe=UTF-8&multires=1&otf=2&pc=1&ssel=0&tsel=0&sc=1';
$name_en = curl($url);
$name_en = explode('"',$name_en);
return $name_en[1];
}
function pinyin($word)
{
$word = urlencode($word);
$url = 'http://translate.google.com/translate_a/t?client=t&text='.$word.'&hl=zh&sl=zh&tl=zh&ie=UTF-8&oe=UTF-8&multires=1&otf=2&pc=1&ssel=0&tsel=0&sc=1';
$name_en = curl($url);
$name_en = explode('"',$name_en);
return str_replace(" ", "", strtolower($name_en[5]));
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<?php
echo pinyin(urldecode($_GET['phrase']));
?>
</body>
</html>
If you put this at http://www.example.com/foo.php, type in http://www.example.com/foo.php?phrase=你好, and it will give you the pinyin.
Tested, and works.
If you are using utf-8 to interpret your files and calls to the DB, i guess a simple
$new_text = preg_replace(array('/你好/',...), array('nǐhǎo',...), $old_text);
should do the trick.
Where are you getting your string from?

Categories

Resources