downloaded file cannot open(damage) codeigniter - php

i have a file with extension PDF and DOCX, and when i download it from my server, the file cannot opened and the size become 1kb, when in my server folder it has 199kb size. iam using database to store the file path and filename, here is my view to download the file
View
<?php echo $details->FILE_NAME; ?>
and my controller
Admin_Controls.php
function download_proposal($id_pemesanan) {
$this->load->helper('download');
$this->load->model('gedung/gedung_model');
$temp_id = substr($id_pemesanan, 7); //i cut the string because it content prefix string
$data = $this->gedung_model->get_proposal_by_id($temp_id);
$path = file_get_contents($data->PATH.$data->FILE_NAME);
$file_name = $data->FILE_NAME;
force_download($file_name, $data);
}
my model
Gedung_Model.php
public function get_proposal_by_id($id_pemesanan) {
$sql = "SELECT * FROM pemesanan_details WHERE ID_PEMESANAN = $id_pemesanan";
$query = $this->db->query($sql);
$hasil = $query->row();
return $hasil;
}
my problem is just after i download the file, it becomes corrupted and cannot open, like i say the size become 1kb. all works well from user click to download until the download process
Thanks in advice

I would like to check the path . You can use absolute path of the file for testing purpose instead of dynamic generated path .

Related

Converting files to binary code using php and saving it in database

I am creating something like google drive or some cloud using PHP and HTML where you can save your files but i have problem with saving files to binary code and uploading it to database. I mean i want to do something like that:
User is uploading file by form in html -> converting file to binary -> saving it in database.
User can download his file by some button or smh like that -> file is converting from binary to file.
I tried with doing a script what will save bin code in my database but when i am trying to send some files i am getting error like that:
Fatal error: Uncaught TypeError: fopen(): Argument #1 ($filename) must be of type string, array given in C:\xampp\htdocs\fileshub\src\send_file.php:12 Stack trace: #0 C:\xampp\htdocs\fileshub\src\send_file.php(12): fopen(Array, 'rb') #1 {main} thrown in C:\xampp\htdocs\fileshub\src\send_file.php on line 12
This is my form in html:
<form class="upload-form" action="./src/send_file.php" method="post" enctype="multipart/form-data"><br>
<input type="text" name="filename" id="filename" placeholder="File name">
<input type="file" name="file" id="file"><br>
<button type="sumbit" class="submit">Submit</button>
</form>
And this is my script in php:
<?php
session_start();
include "../src/db_conn.php";
if(isset($_SESSION['id'])) {
$id = $_SESSION['id']; // id usera
$filename = $_POST['filename']; // nazwa pliku
$file = $_FILES['file'];
$data = fopen ($file, 'rb');
$size = filesize ($file);
$contents = fread ($data, $size);
fclose ($data);
$binfile = base64_encode($contents);
if(!$filename|| !$file) {
header("Location: ../index.php?error=Enter your data!");
exit();
} else {
$check = "SELECT bin_code FROM files WHERE user_id = '$id' AND bin_code = '$binfile' AND file_name = '$filename'";
$result = mysqli_query($conn, $check);
if(mysqli_num_rows($result) === 1){
header("Location: ../index.php?error=Your file exsist.");
exit();
}else {
$save = "INSERT INTO files (user_id, file_name, bin_code) values('$id', '$filename', $binfile)";
$saveresult = mysqli_query($conn, $save);
$saveresult;
header("Location: ../index.php?error=Your file has been saved");
exit();
}
}
}
?>
db_conn:
<?php
$server = "localhost";
$user ="root";
$password = "";
$db = "fileshub";
$conn = mysqli_connect($server, $user, $password, $db);
?>
If you know any solutions for my problem please help :)
Files table
Users table and example user
I believe you know that uploading an image to a directory is a more efficient way to store it.
Please note that $_FILES['file'] is an array containing all sorts of information of the uploaded file, for your case you have to use the filename of the uploaded file. (which is "tmp_name")
So change
$file = $_FILES['file'];
$data = fopen ($file, 'rb');
to
$file = $_FILES['file']["tmp_name"];
$data = fopen ($file, 'rb');
On the other hand, an alternative way is to use file_get_contents instead of fopen, fread, etc.
$contents = file_get_contents($_FILES['file']["tmp_name"]);
So firstly you need to ensure you have a directory that PHP has access and has permissions on but that is not publicly accessible. Usually, on web hosts the web root folder is a sub folder of the home directory, so you can create a new folder there for file storage. Eg:
/home/myuser/public_html/ <-- might be the web root (some installations differ eg: htdocs or html or httpdocs)
/home/myuser/files/ <-- Create this folder for storing files.
Alternatively, if youre web server is Apache, you can create a folder inside your web root, and protect that folder using a .htaccess file
The easiest way then to store an uploaded file on the file server is to use the move_uploaded_file command that PHP provides, here is how I would achieve this:
$postname = 'file';
$root = '/home/myuser/files';
//cleanse the filename to prevent SQL injections when saving to DB
$filename = preg_replace("/[^a-zA-Z0-9\.]/","_",$_FILES[$postname]['name']);
$path = "$root/$filename";
//Create the files folder if it doesnt already exist...
if(!file_exists($root)) if(!mkdir($root,0775,true)) die("Failed to create root folder $root");
//Store the uploaded file in the files folder
if(!move_uploaded_file($_FILES[$postname]['tmp_name'],$path)) die('Failed to move uploaded file into asset storage');
//Store the file location in the database...
$saveresult = mysqli_query($conn,"INSERT INTO `files` (`filename`,`path`) VALUES ('$filename','$path')");

Mysql file upload and pdf browser viewer failing to work

I am trying to build an interface with between my Wordpress page and my practice management software. When I upload files directly to my practice management software a physical copy shows up in the patient file. When browsing files within the software, on first click, I am able to view them in a browser based pdf viewer. If I click again on the file link, the file downloads and opens on my PC's PDF software.
PROBLEM: currently my file uploads to the server and a physical file is placed in the patient file. When browsing files it will not show up in my PDF viewer. It downloads to my PC on the first click and opens into my PDF software. However, the same file, when uploaded directly to the software behaves as expected.
I see no difference in the two files. So I assume there must be a problem with the $contents variable in my query. I am only working with PDF files. To upload attachments in my private messaging software I am using the following code:
function action_getmsgup($uploadid) {
global $wpdb, $out;
$query = $wpdb->prepare("SELECT ID, post_mime_type, guid FROM {$wpdb->prefix}posts WHERE ID = %d", array($uploadid));
$rows = $wpdb->get_results($query, ARRAY_A);
foreach ($rows as $row) {
$url = $row['guid'];
$filename = basename($url);
$path = parse_url($url, PHP_URL_PATH); // just the path part of the URL
$parts = explode('/', $path); // all the components
$parts = array_slice($parts, -6); // the last six
$path = implode('/', $parts);
$filepath = ABSPATH . $path;
// Get file contents and make a blob.
$tmpfile = fopen($filepath, "r");
$contents = fread($tmpfile, filesize($filepath));
$out['filename'] = $filename;
$out['mimetype'] = $row['mimetype'];
$out['contents'] = $contents;
}
}
QUESTION: Is there a problem with my upload method that is not filling $contents correctly?

Downloading uploaded file php

I'm new to yii framework and we have a project in school about uploading and downloading files and I kind of need some assistance...
I followed this link as a sample exactly as it is and it really does upload to the uploads folder in yii but now I'm trying to download it using this code in my view:
$id= $_GET['id'];
$media = Document::model()->findByPk($id);
$path = Yii::app()->basePath . '/../uploads';
$name = $media->doc_file;
Yii::app()->request->sendFile($name, file_get_contents($path."/".$name));
but when it downloads, it wont open because the file format is not supported... any idea how I can
I did a little modification on your code. Pass the id through the url on the view and that will hit the download action inside your controller. You should be good to go with this
public function actionDownload($id)
{
$media = Document::model()->findByPk($id);
$path = Yii::app()->request->baseURL . '/uploads';
$file = $path . '/'.$media->doc_file;
if (file_exists($file)) {
return Yii::app()->getRequest()->sendFile($name, #file_get_contents($path));
}else{
//throw an error here
}
}

CodeIgniter - error trying to view uploaded pdf files

I'm having difficulty trying to view a pdf file outside of the webroot folder.
This is the view file - I'm grabbing the file id from the URL and then querying the db to get all the file info stored from the upload.
$fid = $_GET['fid'];
$query = $this->db->query("SELECT * FROM files WHERE FID = $fid");
$fileinfo = $query->result();
foreach ($fileinfo as $row)
{
$fname = $row->file_name;
$ftype = $row->file_type;
$fpath = $row->file_path;
$full_path = $row->full_path;
$raw_name = $row->raw_name;
$client_name = $row->client_name;
$file_ext = $row->file_ext;
$file_size = $row->file_size;
$is_image = $row->is_image;
$width = $row->image_width;
$height = $row->image_height;
$img_type = $row->image_type;
$img_size = $row->image_size_str;
$orig_name = $row->orig_name;
$created = $row->created;
}
Then I'm taking that info and passing it to the File_viewer_model using the following:
$this->load->model('File_viewer_model');
$this->File_viewer_model->getFileInfo($fname,$ftype);
The function in the model that receives the data is as follows:
function getFileInfo($fname,$ftype){
$path = '/home/sitename/uploads/' . $fname;
header('Content-Type: ' . $ftype);
header('Content-Length: ' . filesize($path));
readfile($path);
}
The problem is when I click on the link to open a new tab and try to display the file, I get the following error:
File does not begin with '%PDF-'.
The file is in a 777 permissions directory called uploads right outside of the webroot - I've been all over the web and there seems to be several methods to display a pdf file, none of which seem to work for me. Any help would be appreciated. Thanks!
Solved: The problem was I was passing a header_view page in the controller before the $this->load->view('file_viewer_view'); section.
The PDF viewer was trying to parse the header_view first before the header('Content-Type: application/pdf') code in the file_viewer_view and thus generating the error.
I removed everything from the controller before the $this->load->view('file_viewer_view'); and it works like a champ!
Hopefully, this will save someone several hours of banging your head against the wall like I experienced!

PHP Foreach and jQuery

I am working on a piece of code that I am wanting to "spice" up with jQuery but I can't think of a way to actually make it work. I am sure its simple, I just need a little advice to get me going.
I am wanting to create a piece of code that makes an Ajax request out to start a big loop that will download files and then upload them to an S3 bucket of mine. The place where I am stuck is I am wanting to send back a request back to the browser everytime a file is uploaded and output a string of text to the screen upon completion.
I don't have any of the frontend code working... just trying to get my head wrapped around the logic first... any ideas?
PHP Backend Code:
<?php
public function photos($city) {
if(isset($city))
$this->city_name = "{$city}";
// grab data array from Dropbox folder
$postcard_assets = $this->conn->getPostcardDirContent("{$this->city_name}", "Photos", TRUE);
$data = array();
foreach($postcard_assets['contents'] as $asset) {
//only grab contents in root folder... do not traverse into sub folders && make sure the folder is not empty
if(!$asset['is_dir'] && $asset['bytes'] > 0) {
// get information on file
$file = pathinfo($asset['path']);
// download file from Dropbox
$original_file = $this->conn->downloadFile(str_replace(" ", "%20", $asset['path']));
// create file name
$file_name = $this->cleanFileName($file['basename']);
// write photo to TMP_DIR ("/tmp/photos/") for manipulation
$fh = fopen(self::TMP_DIR . $file_name, 'w');
fwrite($fh, $original_file);
fclose($fh);
// Resize photo
$this->resize_photo($file_name);
// hash file name
$raw_file = sha1($file_name);
// create S3 hashed name
$s3_file_name = "1_{$raw_file}.{$file['extension']}";
// Upload manipulated file to S3
$this->s3->putObject($s3_file_name, file_get_contents(self::TMP_DIR . $file_name), $this->photo_s3_bucket, 'public-read');
// check to see if file exists in S3 bucket
$s3_check = $this->s3->getObjectInfo($s3_file_name, $this->photo_s3_bucket);
// if the file uploaded successully to S3, load into DB
if($s3_check['content-length'] > 0) {
$data['src'] = $s3_file_name;
$data['width'] = $this->width;
$data['height'] = $this->height;
Photo::create_postcard_photo($data, "{$this->city_name}");
// Now that the photo has been uploaded to S3 and saved in the DB, remove local file for cleanup
unlink(self::TMP_DIR . $file_name);
echo "{$file_name} uploaded to S3 and resized!<br />";
}
}
}
// after loop is complete, kill script or nasty PHP header warnings will appear
exit();
}
?>
The main problem is that with PHP, the output is buffered so it won't return a line at a time. You can try and force the flush but it's not always reliable.
You could add an entry to the DB for each file that is exchanged and create a seperate API to get the details of what has completed.
Generally, Jquery will wait till the request has finished before it allows you to manipulate data from a HTTP request.

Categories