file exist in php download - php

I'm download file but i want. IF file exist from drive C i can download,
ELSE IF file exist automatic can donwload file from drive D . Else "File Not Found"
i'm confused :(
This is my quoute script
$id = $_GET['id'];
$query = "SELECT * FROM upload WHERE id = '$id'";
$jl = mysql_query($query);
$data = mysql_fetch_array($jl);
header("Content-Disposition: attachment; filename=".$data['name']);
header("Content-length: ".$data['size']);
header("Content-type: ".$data['type']);
$filename = $data['name'];
if (file_exists($filename)) {
$fp = fopen("d:/result/".$data['name'], 'r');
$content = fread($fp, filesize('d:/result/'.$data['name']));
fclose($fp);
}
else if (file_exists($filename)) {
$fp = fopen("c:/result/".$data['name'], 'r');
$content = fread($fp, filesize('c:/result/'.$data['name']));
fclose($fp);
}
else {
echo "File Not Found";
}
// show file download
echo $content;
exit;

You could specify the list of paths in an array.
$paths ['c:/result/', 'd:/result/];
then you loop through these paths:
foreach($paths as $path){
if(file_exists($path.$data['name'])){
print file_get_contents($path.$data['name']);
}
}
Full solution for you:
//prevent sql injection
$data = mysql_fetch_array(mysql_query("SELECT * FROM upload WHERE id = '".intval($_GET['id'])."'"));
//now you can add as much paths as you like
$paths = [
'd:/result/',
'c:/result/'
];
foreach ($paths as $path) {
if (file_exists($path . $data['name'])) {
header("Content-Disposition: attachment; filename=" . $data['name']."; ".
"Content-length: " . $data['size']."; ".
"Content-type: " . $data['type']);
print file_get_contents($path . $data['name']);
exit;
}
}
echo "File not found";
exit;

Your code is backwards. You've output your content headers already, so if the file doesn't exist, your user will be downloading a file whose contents are "File Not Found". That'd just confuse them when they double-click on their pdf/word/whatever file and get a "file is corrupted" error.
Your code should be more like:
$c_source = 'C:/...';
$d_source = 'D:/...';
if (is_readable($c_source)) {
header(...); // <--do this only if you found a file
readfile($c_source);
} else if (is_readable($d_source)) {
header(...); // do this only if you found a file
readfile($d_source);
} else {
die("File not found");
}

Related

How to make a safe file function in PHP?

This method receives a foldername and filename. It should make sure that the filename actually really exists in the folder path before doing anything. If so then it can proceed to get the file, send headers and send the response content. Is there a better and more secure way to to do this?
public function is_file_in_path($filename, $filepath)
{
if (file_exists($filepath)) {
$filename = realpath($filepath);
}
if ($filename) {
$image_mime = get_mime_by_extension($filename);
header('Content-Type: ' . $image_mime);
header('Content-Length: ' . filesize($filename));
echo file_get_contents($filename);
} else {
show_error('No image found.', 404);
}
}
To make the function to have higher compatibility and cleaner:
consider removing the word "public"
remove the 1st parameter, which is a bit redundant
change get_mime_by_extension to mime_content_type
change "No image found" to "No File found" (because this function can also be used if you supply a PDF file as parameter).
<?php
function is_file_in_path($filepath)
{
if (file_exists($filepath)) {
$filename = realpath($filepath);
}
if ($filename) {
$file_mime = mime_content_type($filename);
header('Content-Type: ' . $file_mime);
header('Content-Length: ' . filesize($filename));
echo file_get_contents($filename);
} else {
// show_error('No image found.', 404);
echo "No File Found";
}}
// is_file_in_path("./photo.jpg");
is_file_in_path("./ess.pdf");
?>

How can I remove duplicates and add a new unique file?

I have on my website to grab 5 random files from all the files in my directory and all is going well but about %50 of the time I get a duplicate. I would like to:
1) Remove duplicate
2) Replace with new unique file
.. or maybe I can prevent duplicates in an easier manner all together? I tried to find a function for this without asking a question of here but I have not found one. Any ideas? Thanks!!
<?php
//define stuff
$dir = "uploads/";
$allfiles = array_diff(scandir($dir), array('.', '..'));
echo '<pre>';
print_r("all files ready for access");
echo '<pre>';
// create zip
$zip = new ZipArchive();
$zip_name = "zipfile.zip";
if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE){
$error .= "* Sorry ZIP creation failed at this time";
}
else {
echo '<pre>';
print("created zip");
echo '<pre>';
}
// array of random files
$n=1;
while ($n<=6){
$n ++;
$file = array_rand($allfiles);
$randomfile = $allfiles[$file];
echo '<pre>';
print_r($randomfile);
echo '<pre>';
if (file_exists($dir.$randomfile)) {
$content = $dir.$randomfile;
echo '<pre>';
print_r($content);
echo '<pre>';
$zip->addfile($content,$randomfile);
echo 'ok';
} else {
echo 'failed';
}
}
//present for download
$zip->close();
ob_get_clean();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=" . basename($zip_name) . ";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($zip_name));
readfile($zip_name);
if(file_exists($zip_name))
{
unlink('zipfile.zip');
}
?>
Just check if you already found this file. And if you already found it, get a new one by continuing without incrementing $n.
Look at this:
// array of random files
$n = 1;
$myfiles = [];
while ($n<=6){
$file = array_rand($allfiles);
$randomfile = $allfiles[$file];
if(!in_array($randomfile, $myfiles)) { // this line checks if you already got this file
$myfiles[] = $randomfile;
} else {
continue; // if you already got it, continue (http://php.net/manual/de/control-structures.continue.php)
}
echo '<pre>';
print_r($randomfile);
echo '<pre>';
if (file_exists($dir.$randomfile)) {
$content = $dir.$randomfile;
echo '<pre>';
print_r($content);
echo '<pre>';
$zip->addfile($content,$randomfile);
echo 'ok';
} else {
echo 'failed';
}
$n++; // increment in the end
}
You can pass a second parameter to the array_randfunction:
$my_files = array_rand($allfiles, 5);
or shuffle the array and get -for example- the first five items:
shuffle($allfiles);
// now $allfiles[0...4] are 5 different files.
create a an array for the files already added to the zip :
$added = //array
$zip->addfile($content,$randomfile);
array_push($added,$randomfile)
and check any new file in the above array before inserting:
if(!in_array($randomfile, $added)){
//add the file to zip
}

ZipArchive not opening file - Error Code: 19

Im having issues with my code being able to open a zip file that i have uploaded and moved into a folder, the zip file uploads fine and you can open it in any Zip program however, when i attempt to open it with ZipArchive to extract the data it errors.
$path = "../"; // Upload directory
$count = 0;
foreach ($_FILES['files']['name'] as $f => $name) {
if(move_uploaded_file($_FILES["files"]["tmp_name"][$f], $path . $name))
$count++; // Number of successfully uploaded file
}
$kioskFile = $_FILES['files']['name'][0];
$kioskFile = explode(".", $kioskFile);
$kioskFile = $kioskFile[0];
$zipFile = "../" . $kioskFile . ".zip";
$zip = new ZipArchive;
$res = $zip->open($zipFile);
if ($res === true) {
$zip->extractTo("./");
$zip->close();
} else {
echo "Error Cannot Open Zip File - Error Code: ";
}
When i run the code it shows me a Error Code 19
ZIPARCHIVE::ER_NOZIP - 19
This is the error im getting, however the file exists and if i use zip_open, it returns that it can open the zip file.
Any help would be very greatful
EDIT1
If i upload a zip file that i manually create (using a zip program) then the upload works fine. However if i use a ZipArchive created zip file, then it instantly errors with a error 19.
EDIT2
I have now added a check to make sure the file exists in the right directory and also put a print of the location also, both match, however still the same issue. Error 19
$path = "../"; // Upload directory
$count = 0;
foreach ($_FILES['files']['name'] as $f => $name) {
if(move_uploaded_file($_FILES["files"]["tmp_name"][$f], $path . $name))
$count++; // Number of successfully uploaded file
}
$kioskFile = $_FILES['files']['name'][0];
$kioskFile = explode(".", $kioskFile);
$kioskFile = $kioskFile[0];
$realpath = realpath("../");
$zipFile = $realpath . "\\" . $kioskFile . ".zip";
if (file_exists($zipFile)) {
$extract = zip_extract($zipFile, "../");
if ($extract === TRUE) {
} else {
echo "The file " . $zipFile . " cannot be opened";
}
} else {
echo "The file " . $zipFile . " does not exist";
die();
}
UPDATE1
So i think ive narrowed it down to either this bit of code, or the download script that i use to download the .zip file from the system, if i leave the zip on the system and use the exact same bit of code it works fine.
Here is my download code, maybe ive missed something on this that is causing the issue.
$fileID = $_GET['id'];
$backupLoc = "backups/";
$sql = "SELECT * FROM backups WHERE id = '" . addslashes($fileID) . "' LIMIT 1";
$res = mysql_query($sql);
$row = mysql_fetch_array($res);
$backupFile = $row['backupFile'];
$zipFile = $backupLoc . "/" . $backupFile . ".zip";
$zipSize = filesize($zipFile);
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="' . basename($zipFile). '"');
ob_end_flush();
readfile($zipFile);
exit;
die();
Open the archive with a text or hex editor and make sure you have the 'PK' signature at the start of the file.
If you have any HTML before that signature, it would suggest that your buffers are not being cleaned or are being flushed when they should not be, meaning that PHP ZipArchive will assume an invalid archive.
It was the download.php file that was causing the issue, here is the solution. which was to do a OB CLEAN rather than a Flush
///echo "<div style='padding: 50px;'>Please Wait .....</div>";
$fileID = $_GET['id'];
$backupLoc = "backups/";
$sql = "SELECT * FROM backups WHERE id = '" . addslashes($fileID) . "' LIMIT 1";
$res = mysql_query($sql);
$row = mysql_fetch_array($res);
$backupFile = $row['backupFile'];
$zipFile = $backupLoc . "/" . $backupFile . ".zip";
$zipSize = filesize($zipFile);
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="' . basename($zipFile). '"');
//ob_end_flush();
ob_end_clean();
readfile($zipFile);
exit;
die();

Error FileType after inserting a file as Blob - PHPMySQL

I made a simple script to insert files as BLOB (mediumblob) in MySQL Database.
The script works fine, the file is uploaded and saved into the table but when I download the file and I try to open it, it says: "File type HTML document (text/html) is not supported"!
This means there was an error while saving the file's type!
Here is my code, please tell me what can be wrong in it:
upload.php :
if (isset($_POST['upload']))
{
if(isset($_POST['upload']) && $_FILES['userfile']['size'] > 0)
{
$fileName = $_FILES['userfile']['name'];
$tmpName = $_FILES['userfile']['tmp_name'];
$fileSize = $_FILES['userfile']['size'];
$fileType = $_FILES['userfile']['type'];
$fp = fopen($tmpName, 'r');
$content = fread($fp, filesize($tmpName));
$content = addslashes($content);
fclose($fp);
if(!get_magic_quotes_gpc())
{
$fileName = addslashes($fileName);
}
$p = $cnx->prepare('INSERT INTO commandes (name, size, type, content) VALUES(:name, :size, :type, :content)');
$p->execute(array('name'=>$fileName, 'size'=>$fileSize, 'type'=>$fileType, 'content'=>$content));
echo "<br>File $fileName uploaded<br>";
}
}
Download.php :
$p = $cnx->prepare('SELECT cmd_id, name FROM commandes');
$p->setFetchMode(PDO::FETCH_OBJ);
$p->execute();
if($p->rowCount() == 0)
{
echo "0 Element <br />";
}
else
{
while($data = $p->fetch())
{
?>
<?php echo $data->name;?> <br>
<?php
}
}
if(isset($_GET['id']))
{
$id = $_GET['id'];
$q = $cnx->prepare('SELECT * FROM commandes WHERE cmd_id = :cmd_id');
$q->setFetchMode(PDO::FETCH_OBJ);
$q->execute(array('cmd_id'=>$id));
while($getFile = $q->fetch())
{
header("Content-length: $getFile->size");
header("Content-type: $getFile->type");
header("Content-Disposition: download; filename=$getFile->name");
echo $getFile->pdf;
exit;
}
}
Thank you!
What is the output for the response headers?
Can you ensure that "Content-type" is "Content-Type"
Also, using a debugger to inspect the response is really valuable.
http://fiddler2.com/get-fiddler

PHP UTF-8 to GB2312

Part of our web app has a little Ajax method that will load a page in an iFrame or allow you to download it.
We store a bunch of search results from search engines and we have script opens the file containing our info and the search html. We strip out the stuff we don't need from the top (our info) and then we serve that up either by echo'ing the $html variable or putting it in a temporary file and dishing it off to download.
The problem: I load the page in the iFrame and it's loaded in UTF-8 because everything else is. If I download the file manually it is fine and FF tells me the endoding is x-gbk.
I've tried using mb_convert_encoding to no avail. We are using PHP4 on this server.
Thoughts?
EDIT: Code that drives this
f(!isset($_GET['file']) || $_GET['file'] == '')
{
header("location:index.php");
}
$download = false;
if(!isset($_GET['view']) || $_GET['view'] != 'true')
{
$download = true;
}
$file = LOG_PATH . $_GET['file'];
$fileName = end(explode("/", $file));
$fh = fopen($file, "rb");
if(!$fh)
{
echo "There was an error in processing this file. Please retry.";
return;
}
// Open HTML file, rip out garbage at top, inject "http://google.com" before all "images/"
$html = fread($fh, filesize($file));
fclose($fh);
// Need to trim off our headers
$htmlArr = explode("<!", $html, 2);
$htmlArr[1] = "<!" . $htmlArr[1];
if(strstr($file, "google"))
{
$html = str_replace('src="/images/', 'src="http://google.com/images/', $htmlArr[1]);
$html = str_replace('href="/', 'href="http://google.com/', $html);
}
else if(strstr($file, "/msn/"))
{
$html = str_replace('src="/images/', 'src="http://bing.com/images/', $htmlArr[1]);
$html = str_replace('href="/', 'href="http://www.bing.com/', $html);
}
else
{
$html = $htmlArr[1];
}
if(strstr($file, "baidu"))
{
$html = mb_convert_encoding($html, 'utf-8'); // Does not work
}
if($download)
{
// Write to temporary file
$fh = fopen("/tmp/" . $fileName, 'w+');
fwrite($fh, $html);
fclose($fh);
$fh = fopen("/tmp/" . $fileName, "rb");
header('Content-type: application/force-download;');
header("Content-Type: text/html;");
header('Content-Disposition: attachment; filename="' . $fileName . '"');
fpassthru($fh);
fclose($fh);
unlink("/tmp/" . $fileName);
}
else // AJAX Call
{
echo $html;
}
You may want to try iconv() instead of mb_convert_encoding()--it has support for a much broader set of encodings.

Categories