I'm trying to create a download link in PHP so you can download the information in a table. I just started writing it and have run into a snag. Here is what I have so far:
<?php
$sql = "SELECT * FROM " . $survey . ";";
$result = mysql_query($sql)
or die(mysql_error());
$row = mysql_fetch_assoc($result);
$something = "This is text";
$myFile = "data.txt";
$fh = fopen($myFile, 'w') or die("can't open file");
$download_data = "";
foreach ($row as $k=>$v){
$download_data .= $k . "=" . $v . "\n";
}
fwrite($fh, $download_data);
fclose($fh);
echo $download_data;
?>
Download
It is just supposed to show something like Code = 1 Name = John etc. When I open the txt file, it simply says Resource id #7. The weird part is, when I echo $download_data, it looks correctly in the web page. Is there something special I have to do with fwrite in order to get the whole string into the text file
(Note: I have used both mysql_fetch_array and mysql_fetch_assoc and both have the same result. Also, if I simply declare a variable like $test = "this is a test"; it works).
Edit:
I have tried commenting out all other code in the script and I get the same result. Printing $download_data shows the right result, but the text file is still only showing Resource id #7. I've even tried deleting the txt file and when it is recreated, it does the same thing.
You're almost certainly not showing us the whole picture with your example code.
You are likely writing one of these things to the file:
The file handle, $fh
The result returned from mysql_query()
Check you're not mixing up $result and $row. Or even better, post all of your code.
Related
In one of my application, users can upload CSV file (| separated fields), after uploading I am storing all the content of file in temporary table (I truncate this table every time for new upload so that it contains the current file data). After that I am iterating over each and every row of that table, and performs some database operation as per the business logic.
The following code will illustrate this:
if(isset($_POST['btn_uploadcsv']))
{
$filename = $_FILES["csvupload"]["name"];
$uploads_dir = 'csvs'; //csv files...
$tmp_name = $_FILES["csvupload"]["tmp_name"];
$name = time();
move_uploaded_file($tmp_name, "$uploads_dir/$name");
$csvpath = "$uploads_dir/$name";
$row = 0;
$emptysql = "TRUNCATE TABLE `temp`";
$connector->query($emptysql);
if (($handle = fopen($csvpath, "r")) !== FALSE) {
$str_ins = "";
while (($data = fgetcsv($handle, 1000, "|")) !== FALSE) {
/*
* Here I am getting the column values to be store in the
* the table, using INSERT command
*/
unset($data);
}
fclose($handle);
}
/*Here I am selecting above stored data using SELECT statement */
for($j=0;$j<count($allrecords);$j++)
{
echo "In the loop";
/*If I use echo statement for debugging it is working fine*/
//set_time_limit(300);
/* I have tried this also but it is not working*/
if(!empty($allrecords[$j]['catid']))
{
// Here is my business logic which mailny deals with
// conditional DB operation
}
echo "Iteration done.";
/*If I use echo statement for debugging it is working fine*/
}
}
The problem is when I execute aboe script on server it is giving server timeout error. But when I test above script on my localhost, is is working fine.
Also as mentioned in the code, if I use echo statements for debugging, then it is working fine, and when I remove that it starts giving connection timeout problem.
I have tried set_time_limit(300), set_time_limit(0), but none of them seems to work.
Any idea, how can I resolve the above problem.
-- Many thanks for your time.
Edit:
I have checked that, files are uploading on the server.
set_time_limit
change to
ini_set("max_execution_time",300);
When max_execution_time is not set in php.ini set_time_limit valid.
I have resolved the issue using flush, to send intermediate output to the browser, while the query is executing in the background.
This is how I modified the code:
for($j=0;$j<count($allrecords);$j++)
{
/*At the end of each iteration, I have added the following code*/
echo " ";
flush();
}
Thanks to the contributors over this link PHP: Possible to trickle-output to browser while waiting for database query to execute?, from where I got inspiration.
I have all my files stored in a mysql database as blobs. I am trying to add a speed limit to the rate at which a user can download them through our PHP website. I have tried to use the "sleep(1);" method, it does not seem to work or i am not doing it right. So if anyone knows a way to limit the speed, i would love your help.
Here is my download code
$query=mysql_query("SELECT * FROM file_servers WHERE id='$file_server_id'");
$fetch=mysql_fetch_assoc($query);
$file_server_ip=$fetch['ip'];
$file_server_port=$fetch['port'];
$file_server_username=$fetch['username'];
$file_server_password=$fetch['password'];
$file_server_db=$fetch['database_name'];
$connectto=$file_server_ip.":".$file_server_port;
if (!$linkid = #mysql_connect($connectto, $file_server_username, $file_server_password, true))
{
die("Unable to connect to storage server!");
}
if (!mysql_select_db($file_server_db, $linkid))
{
die("Unable to connect to storage database!");
}
$nodelist = array();
// Pull the list of file inodes
$SQL = "SELECT id FROM file_data WHERE file_id='$file_id' order by id";
if (!$RES = mysql_query($SQL, $linkid))
{
die("Failure to retrive list of file inodes");
}
while ($CUR = mysql_fetch_object($RES))
{
$nodelist[] = $CUR->id;
}
// Send down the header to the client
header("Content-Type: $data_type");
header("Content-Length: $size");
header("Content-Disposition: attachment; filename=$name");
// Loop thru and stream the nodes 1 by 1
for ($Z = 0 ; $Z < count($nodelist) ; $Z++)
{
$SQL = "select file_data from file_data where id = " . $nodelist[$Z];
if (!$RESX = mysql_query($SQL, $linkid))
{
die("Failure to retrive file node data");
}
$DataObj = mysql_fetch_object($RESX);
echo $DataObj->file_data;
}
One way of doing this may be the combination of flush and sleep:
read part of what you get from database
output some bytes
flush the output to the user
sleep for 1 second
But also take a loot at throttle function:
http://php.net/manual/en/function.http-throttle.php
It also have an example there. I think it is better suited.
it is in the very last echo line in your code where you would like to implement throtling. Im not familiar with whether php supports throtling output.
if not, you can try to split up that content ($DataObj->file_data) you wish to echo, and echo it little piece by little piece with small pauses in between
and be sure to disable outbut buffering. otherwise all that you echo will not be outputted until the entire script is done.
I have the following script which takes some value from a form and appends to a text file each time new values are entered in the form:
$filename = "nic.txt"; #Must CHMOD to 666, set folder to 777
$text = "\n" . str_pad($fname, 30) . "" . str_pad($lname, 30) . "" . str_pad($tdate, 20) . "" . str_pad($ydept, 30) . "" . str_pad($percentage, 0) . "%";
$fp = fopen ($filename, "a"); # a = append to the file. w = write to the file (create new if doesn't exist)
if ($fp) {
fwrite ($fp, $text);
fclose ($fp);
#echo ("File written");
}
else {
#echo ("File was not written");
}
The issue is, instead of writing to a txt file which isn't secured in storing data, how can I let's say append to a php file so user would need authentication before viewing the file on the web?
I would like some sort of authentication (password/username) in place so not everyone can see it. And with txt file I don't think it's possible.
My SQL writing to data file which I commented out until I find the best option is:
// Write to DB
//$conn = new mysqli('host', 'user', 'pass', 'db');
// check connection
//if (mysqli_connect_errno()) {
// exit('Connect failed: '. mysqli_connect_error());
//}
// store the values in an Array, escaping special characters for use in the SQL statement
//$adds['fname'] = $conn->real_escape_string($fname);
//$adds['lname'] = $conn->real_escape_string($lname);
//$adds['tdate'] = $conn->real_escape_string($tdate);
//$adds['ydept'] = $conn->real_escape_string($ydept);
//$adds['percentage'] = $conn->real_escape_string($percentage);
// sql query for INSERT INTO users
//$sql = "INSERT INTO keepScore ('fname', 'lname', 'tdate', 'ydept', 'percentage' ) VALUES ('". $adds['fname']. "', '". $adds['lname']. "', '". $adds['tdate']. "', '". $adds['ydept']. "', '". $adds['percentage']. "')";
// Performs the $sql query on the server to insert the values
//if ($conn->query($sql) === TRUE) {
// echo 'users entry saved successfully';
//}
//else {
// echo 'Error: '. $conn->error;
//}
//$conn->close();
Keep your text file out of the web server's document root, and use a PHP script to provide authentication/authorization when reading the file.
Take a look at readfile().
PHP files are text files. To achieve what you are asking for, just make $filename end in .php (making sure the data people add is just data and not executable code).
… but editing code programatically is not a great idea. Store your data somewhere outside the web root (possibly in a file, but a database is probably better) and then have your script retrieve it when auth/authz is passed).
A simple solution would be to create a directory with a .txt file in it, which is .htpasswd protected. This way a user needs to authenticate to view the contents, and you are not putting yourself at risk for an untold number of security vulnerabilities.
You can store the files with the .php extension and add header information to serve them as plain text instead of html. Then you can insert a php code at the beginning that will cause the user to authenticate themself.
I have some code to upload and download a sound recording from android. The problem i am having is that it appears an extra blank line is appearing in the binary. When this is removed the file plays i would like to know how to stop this line appearing. Below is my upload and download code as well as a print screen of the blank line
Upload code
mysql_select_db ($database);
// Make sure the user actually
// selected and uploaded a file
if (isset($_FILES['image']) && $_FILES['image']['size'] > 0) {
$size = $_FILES['image']['size'];
$type = $_FILES['image']['type'];
// Temporary file name stored on the server
$tmpName = $_FILES['image']['tmp_name'];
// Read the file
$fp = fopen($tmpName, 'r');
$data = fread($fp, filesize($tmpName));
fclose($fp);
$data = trim(addslashes($data));
// Create the query and insert
// into our database.
$query = "INSERT INTO media";
$query .= "(file, file_size, file_type) VALUES ('$data','$size','$type')";
$results = mysql_query($query, $link);
$mediaid = mysql_insert_id();
$gender = $_POST['gender'];
$cat_id = $_POST['cat'];
$name = $_POST['name'];
$lat = $_POST['lat'];
$lon = $_POST['lon'];
$user = $_POST['user'];
$query="INSERT INTO instance (name, gender, cat_id, lon, lat, user_id) VALUES ('$name', '$gender', '$cat_id', '$lon', '$lat', '$user')";
$result=mysql_query($query);
$instanceid = mysql_insert_id();
$query4 = "INSERT INTO media_link";
$query4 .="(media_id, instance_id) Values ('$mediaid','$instanceid')";
$results4 = mysql_query($query4, $link);
}
// Close our MySQL Link
mysql_close($link);
?>
download code
$test2 = #mysql_query("select * from media where media_id = '$media'");
$result2 = mysql_fetch_array($test2);
header('Content-Type: audio/AMR');
header('Content-Disposition: attachment; filename="ifound.amr"');
print $result2['file'];
exit;
?>
Blank line that is appearing
Check if your download code has a blank line before the first <?php . Remember to check any file it gets included from as well.
Also change addslashes to mysql_real_escape_string. It might not cause a problem here, but it is security hole.
If you can't find the root of your problem, you could always try base64_encode / base64_decode. It takes 30% more storage space, but it's a bullet proof way to store binary data in strings.
Just a tip:
$fp = fopen($tmpName, 'r');
$data = fread($fp, filesize($tmpName));
fclose($fp);
could be replaced with
$data = file_get_contents($tmpName)
I also having the same problem on the coding, but after that I found out that actually one of the including files hase empty space like below:
tool.php
line 1
line 2 <?php
line 3 .......
line 4 ?>
line 1 is causing the problem when I include on
<?php
if($_SERVER['REQUEST_METHOD']=="GET"){
if(isset($_GET["ImageID"])){
/* below require file causing the problem */
require_once($_SERVER['DOCUMENT_ROOT'] . "/model/Game/Tools.php");
$image = new ClsGameImage();
$image->Select($_GET["ImageID"]);
header("Content-type: ". $image->MIMEType);
header("Content-length: " . $image->ImageSize);
header("Content-Disposition:attachment;filename=". $image->Name0);
echo $image->Image0;
}
}
?>
It's possible ltrim could help in this situation if the line is being introduced by PHP. There is also a ltrim function for MySQL if it's being introduced in the database.
Also, use mysql_real_escape_string instead of addslashes.
You may want to consider serving media from a media directory instead of storing it in a database. I know this does nothing for replication purposes, but there are things you can do to propagate filesystem changes to multiple computers, if necessary.
This is obviously a preferential choice.
Using the above technologies, I want to create a PDF, store it in my db, and email it. All with the click of one button.
I also want to call it up and have it be able to display with a hyperlink.
I am very new to FPDF. Therefore, I am trying to start off very slowly.
I began with this link stackoverflow Q
I put both parts of his code into the same page and tried with separate pages. I made the suggested changes/additions and even did a line by line comparison.
I still get the message, "format error: not a PDF or corrupted"
If I just $pdf->Output(); I get the pdf to display. It's either the way the string is being Output, or it's the header() function. It's not the storage method, unless my column setup is incorrect. BUt a blob is a blob, right?
If you want, I can upload the sanitized code. Just let me know what would help answer this.
Thanks
JJ
here's the code on request
here's where I enter it in:
<?php
session_start();
include "server.php";//my file to connect to db
require('fpdf.php');
$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World!');
$content = $pdf->Output("", "S"); //return the pdf file content as string
$sql = "update table set table_pdf= '".addslashes($content)."' " .
"where table_id = '188'";
mysql_query($sql);
//here's where I retrieve it
$sql2 = "select table_pdf from table where table_id = '188'";
$result2 = mysql_query($sql2);
$rs = mysql_fetch_assoc($result2);
$content2 = $rs['rdngs_hdr_pdf'];
header('Content-Type: application/pdf');
header("Content-Length: ".strlen(content2));
header('Content-Disposition: attachment; filename=myfile.pdf');
print $content2;
?>
Like I said, I have tried the other ideas on the other question link above. right now it just sits on the version where the addslashes is there.
Thanks for any help.
Give this a try. Instead of using the addslashes to escape the content, try using unpack to get it in a binary represenation:
$content = $pdf->Output("", "S"); //return the pdf file content as string
$data = unpack("H*hex", $content);
$sql = "update table set table_pdf= " . 0x".$data['hex']." . " " .
"where table_id = '188'";
For retrieving the data you should be able to just do a select, and then output the content, just like you are already doing.