php file uploading and storing - php

I want to upload a file on my PHP server. I am currently able to upload it on server using the following code but I don't know how I can store it on the server.
How can I store the file in a specific directory?
I also want the users to be able to download the files but only once they log in not before that.
For example i store the file in directory /myfiles no-one must be able to download it
unless he is logged in
e.g. someone can download the file if he knows the file location
like www.example.com/temp/myfile.txt
I don't want that - user must not be able to download it unless he is logged in.
I have one page B.php in which there will be the download link. When the user clicks on that link he must be able to download the file. In short, he must get a Save as/Open pop up of browser when he clicks my link. How do I do that?

Check the PHP documentation about move_uploaded_file() here: http://de.php.net/manual/en/function.move-uploaded-file.php

function UploadData()
{
$yourpath ="yourfoldername";
createafolder($yourpath ); // if not present then create it (its custom function)
$target_path = $yourpath . basename( $_FILES['fileupload']['name']);
if(move_uploaded_file($_FILES['fileupload']['tmp_name'], $target_path)) {
//write if any processing
}
else echo "Upload sucessful!";
}

Related

hello I wanna use php_move_upload_file in order to move image from my temp folder to a permanent folder

hi this is the function that upload image inside temp location and save location to session for forther use
function uploadPhoto()
{
$rawImage = $_FILES['advPhoto'];
$uploader = new ImageUploader($rawImage);
$uploader->moveToProjectTempFolder();
//1 save the current image in sassion (save the attachment class inside seesion)
$uploader->saveInSession();
// $temperrary = $uploader->CurrentImgTemperraryLocation();
//2 send reponse the current image location
AjaxHelper::sendAjaxResponse("images/temp/" . $uploader->CurrentImgTemperraryLocation());
//create image tag and set the image source the "temp uploaded image path"
// done
//when the mail form is submitted
//loop through session array
//move the user uploaded/approved images to permanent folder
//save image information inside DB
}
here is the function that cause problem I wanna move the picture from temp folder to permanent location but the php_move_uploaded_file() doesn't work in my case I don't really know what is the problem please help me if you know what is the problem thnks .
function saveAdv()
{
$advTitle = $_POST['advTitle'];
$advContent = $_POST['advContent'];
if (!empty($advTitle) && !empty($advContent)) {
if (DataValidation::isOnlyPersianOrEnglish($advTitle) &&
DataValidation::isOnlyPersianOrEnglish($advContent)) {
DBconnection::insertRow('ADVERTISEMENT', ['title', 'Advertisement', 'advDate'],
[$advTitle, $advContent, date('y/m/d h:i:s')]);
// AjaxHelper::sendAjaxResponse("success");
$projectTemp = $_SESSION['ADVERTISEMENT']['Img'];
move_uploaded_file(
$projectTemp,
DOC_ROOT . "/images/advertisementImg/"
);
AjaxHelper::sendAjaxResponse($projectTemp);
}
} else {
AjaxHelper::sendErrorMessage(AjaxHelper::EMPTY_EMAIL_OR_PASSWORD);
}
}
I don't get any error I've already debuged many times but no warning and no errors at all and the location of the folders are completely correct and also there is no permission problems.
The move_uploaded_file() works pretty well at first step that I move image from system temp location to my project temp location, but doesn't work when I wanna move the image from project temp location to permanent location.
move_uploaded_file() is only for moving files which have just been uploaded in a POST request and are stored in the system temp location. As the documentation (https://php.net/manual/en/function.move-uploaded-file.php) states, it first checks whether the file is a valid upload file meaning that it was uploaded via PHP's HTTP POST upload mechanism (that's a direct quote from the docs). If it's not valid by that definition, it fails.
So, if you're trying to use move_uploaded_file() to copy files from other locations (not the system temp location) which have not been directly uploaded to that location in the current request, then it won't work. Use PHP's general file manipulation functionality for moving other files around, using the rename() function (see https://www.php.net/manual/en/function.rename.php for details).

Prevent users to download other files by changing the path in a url query

i have a download function receiving the filename by $_GET and i want to prevent users of downloading other files changing the path and accessing other files in the system.
method:
function actionDownload($arquivo) {
try {
$filepath = \Yii::getAlias('#webroot') . '/files/coordenadas/'. $arquivo;
if (file_exists($filepath)){
return \Yii::$app->getResponse()->sendFile(\Yii::getAlias('#webroot') . '/files/coordenadas/'. $arquivo, $arquivo);
}
}
catch (\Exception $exception) {
throw new NotFoundHttpException("Arquivo não encontrado");
}
}
the route to download the method:
http://example.com/converter-coordenadas/download?arquivo=geografica-utm-20200830171051.xlsx
if someone change the arquivo variable to another valid path it will be able to download other files. How prevent that, but keeping the function receiving the file name in a url param?
the situation that i have is:
the user upload a file through ajax
i convert this file and return the filename
create a download button with the link to the new file.
I don't have any other information to make a relation with the file, like an user id.
As #GetSet explained in the comments, the biggest problem is procedural. One way to do this correctly is as follows:
Upload the file to your server and save the reference in database (you already doing) and generate an unique ID for this file (or for this download). This ID will be saved in a database field, for example with the name: "donwload_id"
Then in the view (when you are creating the link for the download):
Html::a('Download', [Url::to('donwload-action'), 'download_id' => $model- >download_id]);
In your controller, You will know how to find the file by its unique identifier (download_id).
No one knows how you have generated this ID and therefore it is more difficult for anyone to be able to generate it again. Also you can limit the time available to download the file by setting an expiration date to the link.

Generating unique download link to download once only

I wanna create a few unique download link for my users. The reason is that I wanted to let them download once only, so that they can use back the same link to download again.
I've generate a few of the keys (example, qwertyasdfghzxcbn. As in the download link will be like www.xxxxx.com/download.php?qwertyasdfghzxcbn) in the database and flag field where when the user downloaded, it will update 1 to the flag field.
I did a search on the net and found this.
http://www.webvamp.co.uk/blog/coding/creating-one-time-download-links/
But that only works when you go to the page first then only the page will generate the unique link. I've already pre-generate the link inside my database, I don't need to regenerate again, if fact if I generate the key when user go the page, they will able to download multiple times by refreshing the page.
The solution would be to make the link target itself a PHP script.
You'd hide the actual file somewhere inaccessible from the browser (i.e., somewhere where you can reach the file via fopen(), but isn't within the document root), and put a download.php file to download files.
The download script itself would look something like this:
$fileid = $_REQUEST['file'];
$file = file_location($fileid); // you'd write this function somehow
if ($file === null) die("The file doesn't exist");
$allowed = check_permissions_for($file, $fileid) // again, write this
// the previous line would allow you to implement arbitrary checks on the file
if ($allowed) {
mark_downloaded($fileid, $file); // so you mark it as downloaded if it's single-use
header("Content-Type: application/octet-stream"); // downloadable file
echo file_get_contents($file);
return 0; // running a return 0; from outside any function ends the script
} else
die("You're not allowed to download this file");
Any link you point would simply point to download.php?fileid=712984 (whatever the fileid actually is). That would be the actual download link, since that script does transfer the file; but only if the user is allowed to retrieve it. You'd have to write the file_location(), check_permissions_for() and mark_downloaded() functions yourself though.
I would suggest using uniqid() function, and store unique ids with the expiration date in a database, while returning to the user url with something like this: ...?file_id=$id
When the link is being opened, you may delete it from the database or mark it to be deleted 'soon' (just in case user wants to refresh the page.)

PHP - upload and overwrite a file (or upload and rename it)?

I have searched far and wide on this one, but haven't really found a solution.
Got a client that wants music on their site (yea yea, I know..). The flash player grabs the single file called song.mp3 and plays it.
Well, I am trying to get functionality as to be able to have the client upload their own new song if they ever want to change it.
So basically, the script needs to allow them to upload the file, THEN overwrite the old file with the new one. Basically, making sure the filename of song.mp3 stays intact.
I am thinking I will need to use PHP to
1) upload the file
2) delete the original song.mp3
3) rename the new file upload to song.mp3
Does that seem right? Or is there a simpler way of doing this? Thanks in advance!
EDIT: I impimented UPLOADIFY and am able to use
'onAllComplete' : function(event,data) {
alert(data.filesUploaded + ' files uploaded successfully!');
}
I am just not sure how to point THAT to a PHP file....
'onAllComplete' : function() {
'aphpfile.php'
}
???? lol
a standard form will suffice for the upload just remember to include the mime in the form. then you can use $_FILES[''] to reference the file.
then you can check for the filename provided and see if it exists in the file system using file_exists() check for the file name OR if you don't need to keep the old file, you can use perform the file move and overwrite the old one with the new from the temporary directory
<?PHP
// this assumes that the upload form calls the form file field "myupload"
$name = $_FILES['myupload']['name'];
$type = $_FILES['myupload']['type'];
$size = $_FILES['myupload']['size'];
$tmp = $_FILES['myupload']['tmp_name'];
$error = $_FILES['myupload']['error'];
$savepath = '/yourserverpath/';
$filelocation = $svaepath.$name.".".$type;
// This won't upload if there was an error or if the file exists, hence the check
if (!file_exists($filelocation) && $error == 0) {
// echo "The file $filename exists";
// This will overwrite even if the file exists
move_uploaded_file($tmp, $filelocation);
}
// OR just leave out the "file_exists()" and check for the error,
// an if statement either way
?>
try this piece of code for upload and replace file
if(file_exists($newfilename)){
unlink($newfilename);
}
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $newfilename);

Upload files outside of webroot

I'm developing a shopping system where shopmanager should be able to upload files to the system. Those files can the be sold for a fee and should only be accesible through providing a purchase code.
The whole purchase code and uploading thing is working fine. Just have to block the direct access to the file.
Questions:
How can I allow users to upload outside of webroot but not read/download from there?
Or How do I allow users to upload to a directory but no one can read/download from it?
I'm running Apache and use code like this to upload files via a form:
public function upload_file($file='',$post_value='',$path) {
if ($_FILES[$post_value]) {
$uploadext = strtolower(strrchr($_FILES[$post_value]['name'],"."));
if($uploadext=='.jpg' || $uploadext=='.gif' || $uploadext=='.png' || $uploadext=='.swf' || $uploadext=='.jpeg' || $uploadext=='.pdf' || $uploadext=='.doc' || $uploadext=='.xls' || $uploadext=='.docx') {
$destination = $path.$file.$uploadext;
move_uploaded_file($_FILES[$post_value]['tmp_name'], $destination);
} else {
echo PICTURE_ERROR;
}
}
return $file.$uploadext;
}
you can upload where ever you want using the move_uploaded_file function, just make sure the webserver can write in the destination directory.
After you have to create a script that would read the file and pass it to the browser so you can make sure user have paid the file.
exemple
<?php
// insert your logic here to verify the user has access to this file.
// open the file in a binary mode
$name = 'yourfile';
$fp = fopen($name, 'rb');
// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));
// dump the picture and stop the script
fpassthru($fp);
exit;
?>
You have to be careful about the content-type also make sure the user cannot every file of your server if you use a $_GET variable for getting the filename.
That's actually pretty easy. Just create a directory for your files and give apache permissions to write to it. Then when you call move_uploaded_file() function you can just specify the destination to that directory. PHP operates server side so it will be able to access that directory, while users using the browser will be limited to only what Apache will allow them to access.
If you ever need to download these files, just create a script that will parse URL parameter (or something) and take the file from the files directory and push it to the browser.
use a .htaccess file or configure in apache.conf to not allow direct access to the upload dir.
<Directory /path/to/upload/dir>
Order Deny,Allow
Deny from All
</Directory>
It would probably be easiest, in terms of securing the file, to save the files outside your webroot. When somebody wants to download it, you can use http_send_file to send the file back out to them.

Categories