I'm trying to use dropzone.js to add an easy drag-and-drop interface for a user to upload up to 10 photos to my server (currently WAMP). I'm using PHP 5.4 on the back end.
Following this tutorial I got the system working enough to upload acceptable file types to an 'Uploads' folder in my root directory, but I'm stuck on how to make the photos instead upload to a unique directory for each user.
By the time the user gets to my photo upload page, they've already created a folder on my server with a unique name, the path to which has been stored in $_SESSION['requestedDirectory'].
Here is the code used to display the Dropzone form:
<form action="<?php echo BASE_URL; ?>photo_uploads.php" class="dropzone" id="photoUploadDropzone"></form>
<script type="text/javascript">
Dropzone.options.photoUploadDropzone = {
paramName: "file",
maxFilesize: 5, // MB
maxFiles: 10,
addRemoveLinks: true,
acceptedFiles: "image/jpeg, image/jpg, image/png, image/gif",
accept: function(file, done) {
done();
}
};
</script>
As you can see, it sends the data to a file called photo_uploads.php, which has the following code:
if (!empty($_FILES)) {
$tempFile = $_FILES['file']['tmp_name'];
$targetPath = $_SESSION['requestedDirectory']; <--HERE'S THE PROBLEM LINE
$targetFile = $targetPath. $_FILES['file']['name'];
move_uploaded_file($tempFile,$targetFile);
}
As mentioned in the comment above, this file doesn't seem to be able to take data out of a session variable, but I'm not sure why. If I change that line to give the full directory (eg $targetPath = 'C://wamp/www/shops/foldername';) it works fine, but then of course I can't change that foldername dynamically based on which user is using the form.
So to clarify, I'd like to know how to upload the file to the path stored in Session?
UPDATE: Solved.
For anyone else with the same problem in future, this is what I changed the form to:
<form action="<?php echo BASE_URL; ?>photo_uploads.php?folder=<?php echo $_SESSION['photosDir']; ?>" class="dropzone" id="photoUploadDropzone"></form>
Like Rizwan suggested, by passing the $_SESSION['photosDir'] value in a GET variable it was accessible after the form posted.
The other change I made was to photo_uploads.php, just to the following line:
$targetPath = $_GET['folder'];
Absolutely no idea why the value wasn't available directly from Session in the first place - I've never heard of Session values going out of scope - but happy to have this problem solved.
You can pass the requestedDirectory as a query string with the form's action attribute. In that way it can be accessible.
Related
This is the ordinary input file with HTML in the form with method POST
<input type="file" name="file" accept="image/png, image/jpeg">
then Ill get that file input with this function written in PHP
function Upload() {
$namefile = $_FILES['file']['name'];
$error = $_FILES['file']['error'];
$tmpName = $_FILES['file']['tmp_name'];
move_uploaded_file($tmpName, 'upload/'.$namefile);
return $namafile;
}
Ya that's success. The file move to folder 'upload'.
But I want to try styling my form input with Filepond.
<input class="filepond" type="file" name="file" accept="image/png, image/jpeg">
With this js
const inputElement = document.querySelector(".filepond");
FilePond.registerPlugin(
FilePondPluginFileValidateType,
FilePondPluginFileValidateSize
)
FilePond.create(inputElement, {
labelIdle: 'Upload Photo<span class="filepond--label-action">Browse</span>',
maxFiles: '1',
maxFileSize: '5MB',
labelMaxFileSizeExceeded: 'Too big bro.',
labelMaxFileSize: 'max {filesize}',
labelFileTypeNotAllowed: 'Meh dont up that type',
fileValidateTypeLabelExpectedTypes: 'just {allTypes}'
})
But when I try to get the file with the same method as before, $_FILES['file'] will just turn null.
Instead of styling your input, filepond may be creating a proxy element with a different name.
Try var_dump($_FILES) and see if it has been named something else.
As browsers cannot update the file input field value the file is stored in a separate field.
This means you either have to encode the file as a base64 string and then upload that with the form submit (and then decode on the server).
Or you have to upload the file asynchronously by setting the FilePond server property to a page on the server that handles the upload.
A third alternative is setting the storeAsFile property to true, FilePond will now update the file input field, but this only works if the browser supports the DataTransfer constructor
today i need some help, i know its not that hard and there is a lot of help for doing this in php in this site but i couldn't find nothing with AJAX, the technology im learning now and i want to master some day.
My code is the following.
$(".descarga").click(function(){
var paquete={idArchivo:$(this).val()};
$.post("includes/descargarPublicacion.php",paquete,procesarDatos);
});
So when a buttom from the "descarga" class i make a "packet", which i use it with the post method to send the data to the php file called descargarPublicacion.php
This is how it looks the php file:
<?php
session_start();
$mysqli = new mysqli("localhost", "root", "", "registroflashback");
if (isset($_GET['idArchivo'])) {
header("Content-type: application/vnd.msword");
header("Cache-Control: must-revalidate,post-check=0, pre-check=0");
header("Content-disposition:attachment;filename=yeaboi.doc");
header("Expires: 0");
$idPubliGet=$_GET['idArchivo'];
$resultadoBusqueda=$mysqli->query("SELECT * FROM publicaciones WHERE idPubli='$idPubliGet'");
if ($resultadoBusqueda->num_rows>0) {
//$resultadoBusqueda['titulo'];
echo 'descarga exitosa';
}else{
echo 'descarga no exitosa';
}
}else{
echo 'descarga no exitosa';
}
?>
I made a little research and people told me to use the headers to convert the file and download it, but it dosnt works for me, it dosnt generates any file, however it executes the "echo descarga exitosa" which i use as return value for the following function in the js file.
function procesarDatos(datos_devueltos){
alert(datos_devueltos);
if(datos_devueltos=="descarga exitosa"){
$("#alertaDescarga").show(1000);
}
if(datos_devueltos!="descarga exitosa"){
$("#alertaDescargaError").show(1000);
}
}
How i could generate a .doc file from html using ajax and jquery? I know i have it almost, it should be some detail but i dont know which one is, thats why im asking some experienced help! Thank you !
I do not understand why you want to to serve the .doc file via ajax. In my opinion it's easier to just provide valid .doc over a normal GET Request.
$(".descarga").click(function(){
//onClick transfer id via Get-Param and download file
window.location = "includes/descargarPublicacion.php?idArchivo="+$(this).val();
});
php part (descargarPublicacion.php)
<?php
if (isset($_GET['idArchivo'])) {
header("Content-type: application/vnd.msword");
header("Cache-Control: must-revalidate,post-check=0, pre-check=0");
header("Content-disposition:attachment;filename=yeaboi.doc");
header("Expires: 0");
//ID is available via GET because we send it as Url Param
$idPubliGet=$_GET['idArchivo'];
//#TODO fetch relevant data with given ID
//#TODO generate valid(!) doc File output
//- just echo'ing something will not result in an valid document for Word
echo $coumentContent;
}
?>
To provide/generate a valid Word document is a little bit more complicated. I would recommend you to look into a libary which does all the work for you.
E.g. https://github.com/PHPOffice/PHPWord
If you instead want to serve just some simple .txt File - change your header Content-Type to text/plain and the filename to yeaboi.txt and print/echo out the text-content
First , i am a french web developer ( sorry for my poor english )
i 'am looking for a bootstrap php image upload with thumbnail.
i would like to make an upload image file like :
[http://www.2ememain.be/inserer/][1]
the Krajee plugin ([http://plugins.krajee.com/file-input][2]) seems to be the one i am looking for..
But i have some problems with the upload..
i get the error message:
item1.png: SyntaxError: Unexpected token e
my form:
<input id="input-700" name="kartik-input-700" type="file" multiple=true class="file-loading">
js:
$("#input-700").fileinput({
uploadUrl: "upload.php",
uploadAsync: true,
maxFileCount: 10});
upload.php:
echo "test";
if (empty($_FILES['input-700'])) {
echo json_encode(['error'=>'No files found for upload.']);
return;
}
// get the files posted
$images = $_FILES['input-700'];
var_dump($images);
More strange:
when i delete echo(test);
i get the error:
No files found for upload
Thanks for your support
if you have another solution , i shall be glad to get it..
Since you have set the uploadUrl parameter you are using the ajax uploads feature (instead of native HTML form submission).
You need to ensure that you return a proper JSON encoded data response from the server action (as set in uploadUrl) else the plugin fails. You can read the plugin documentation for ajax uploads where this is highlighted. For example, even if you do not have any data to send - you can send a empty JSON string like {}.
I have a file upload page in my application. I need to show "Uploading" while file is uploading then show "Processing" while file is processing. Then after completion of script my page got redirected to some url.
I have tried to use PHP SESSIONS in the script. As in code below:
$_SESSION['uploaded']=0;
if (!empty($_FILES)) {
$tempFile = $_FILES['file']['tmp_name'];
$targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds;
$_FILES['file']['name']=date('Ymdhis').$_FILES['file']['name'];
$targetFile = $targetPath. $_FILES['file']['name'];
if(move_uploaded_file($tempFile,$targetFile)){
$_SESSION['uploaded']=1;
//some processing here which takes some 4-5second to complete
}
}
After file upload complete I update session. I am checking session every second by calling following function in javascript:
function countdown(seconds){
console.log(<?php echo $_SESSION['uploaded']; ?>);
if(<?php echo $_SESSION['uploaded']; ?>==0){
setTimeout(function() {
//uploading
seconds--;
countdown(seconds);
}, 1000);
}
else{
//processing
}
}
After searching from google for long time I came to know that in a single script SESSION is locked till script execution completed. Then I used session_write_close(); But it also not works. I am always getting 0 value of SESSION.
Please help me figuring out solution in simplest way. Thanks.
UPDATE
Unable to make it work with Ajax request also. So further tried using the MySQL table.
What I do is create table when upload script is called. Then insert value of status=0 in it using following code:
$session=session_id();
$stmt=$conn->prepare("DROP TABLE IF EXISTS $session");
$stmt->execute();
$stmt=$conn->prepare("CREATE TABLE $session (id INT(11), status INT(11))");
$stmt->execute();
$stmt=$conn->prepare("INSERT INTO $session VALUES(1,0)");
$stmt->execute();
Then after upload completion I update the status to 1 and do the processing on file.
Then after successful completion of script I redirect to result page and drop table using session_id().
But My Ajax script which is checking status every second doesn't respond till the upload.php script ends. I have tried closing connection after every query but in vain. Code on getstatus.php
<?php
session_start();
$session=session_id();
require_once('connect.php');
$stmt=$conn->prepare("SELECT * FROM $session WHERE id=1");
$stmt->execute();
$res=$stmt->fetch(PDO::FETCH_ASSOC);
echo $res['status'];
?>
Unable to find solution for it till now. Help is greatly appreciated. Thanks.
Instead of invoking a PHP process on the server side every second, you could use a static file to check the upload state.
When generating the upload form for the client:
Create a tempnam for a directory that is accessible for the
client.
Write 'uploading' to the temporary file
Store the filename in the session. (Be aware: The user might open multiple upload forms. Store the filenames in an array)
Send the filename to the client as a hidden field.
On the server side after user submitted the form:
Check if filename sent from the client matches a filename stored in the session.
Write 'processing' to the state file
At the end of your upload script write 'finished' to the state file
On the client side after user submits the form, check the upload state by doing ajax requests on the state file.
Remarks
Disable caching for the state file with .htaccess. If this is no option you can achieve the same behavior with a php state script and the upload state saved to a session variable instead of a state file.
To make sure all generated files are deleted register a destroy handler that deletes files generated in the session: http://php.net/manual/en/function.session-set-save-handler.php
<?php echo $_SESSION['uploaded']; ?> is preprocessed by PHP only once, just before this javascript is sent to client. That said, the javascript on client looks like:
function countdown(seconds){
console.log(0);
if(0==0){
setTimeout(function() {
//uploading
seconds--;
countdown(seconds);
}, 1000);
}
else{
//processing
}
}
You should find other way (ajax?) to update information on the client side.
This became too long for a comment.
I'm unsure how you'd respond with progress information with PHP. I tried once and failed.
Socket.io is awesome in Node.js and there is a PHP server emitter. I would potentially give that a go. It should offer near instantaneous communication without waiting for scripts to complete.
Alternatively I would check out Jquery upload, it has a PHP server script. Supports progress bars Jquery Upload. Either implement it directly or check out the source code for how display progress info. I tried having a quick look but couldn't identify how they do it easily.
Why use DATABASE if you can do it on server ?
To save your bandwidth and database traffic you can seperate your process into 2 file
Create upload.php to serve uploading process
$_SESSION['uploaded']=0;
if (!empty($_FILES)) {
$tempFile = $_FILES['file']['tmp_name'];
$targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds;
$_FILES['file']['name']=date('Ymdhis').$_FILES['file']['name'];
$targetFile = $targetPath. $_FILES['file']['name'];
if(move_uploaded_file($tempFile,$targetFile)){
// Save path to session var
$_SESSION['uploaded']=$targetFile;
//You can tell client if the uploading process were done and show 'Processing ...'
// Place some code
exit;
}
}
Next, create a file called progress.php
// check
if(!empty($_SESSION['uploaded'])){
// Do your processing code here
// Remove session
unset($_SESSION['uploaded']);
// Then send response to client after your processing were done
echo 'Done';
exit;
}
You can redirect client using jquery as you tagged it. Good luck
I've read many articles in this site or other sites (Redirect with POST to application/csv without form, jQuery.post(), PHP and redirects, ... ) but without any valuable solutions.
My problem is the following :
in my site (html5, JQuery), there is a table. A feature of the site
is to export the table as a csv file which will be available for
download,
This feature is implemented as follow :
2.1 a javascript is called which extracts the data of the table,
2.2 this JS redirect to a php service and pass as arguments the datas. The code is the
following :
var url= jmcnet.request.getOrigin()+'/commons/php/dt_csv_export.php' ;
location.href = url+"?action=generate&csv_type=export_task&csv_data=" +encodeURIComponent(csv);
2.3 The php script format the input (csv_data parameter), write a temporay file and returns the content of the temporary file. The code is the following :
$h = #fopen($csv_file_name, 'w');
fputcsv($h, $csv_row, ',', '"');
fclose($h);
// export file content to JS
header('Content-Encoding: UTF-8');
header('Content-Type: text/ csv; charset =UTF-8');
header('Content-Disposition: attachment; filename=export-table.csv');
header(' Pragma: no-cache');
echo "\xEF\xBB\xBF"; // UTF-8 BOM
readfile($csv_file_name);
2.4 The php file delete (unlink) the temporary file and exit,
My problem is that when the table is long, the URL called is not valid and the JS call to Php is down.
So, I imagine the 3 following solutions but no one is evident and all leads to other problems :
S1 : dont do a GET but a POST in JS. So the size of the csv_data
doesn't matter anymore. The problem is that I will have the content
of the csv file in JS var after the call succeed and I don't know or
find how to redirect to a page which content is in a JS var ? I
guess I will lose all header information doing this.
S2 : compress in JS the csv_data parameter and decompress it in Php.
I just don't know how to do that and if it possible ....
S3 : call the php with a POST. Modify the Php to return the URL of
the temporary file, and do a redirect in JS to this temporay URL.
The problems are that my Php must generate a file into a dir
directly visible on the Internet, the file name must be unique and
there is no way to simply delete the file after it has been read by
browser (and I hate cron or what else).
I'm sure I'm not the first one to have this problem, so I need your help to see what is the best practice for this problem.
I think you may be over-complicating this just a bit. There is no need for all of the JS redirect stuff, you can just point your forms action attribute to your csv_export php code and use POST to send your data.
if needed, you can modify the max size of a post request by editing the post_max_size option in your php.ini. heres what mine looks like:
; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 8M
as for writing to a temporary file, php has built in I/O streams to handle that. for your purposes you'll probably want to use php://memory or php://temp (more info on those here: http://www.php.net/manual/en/wrappers.php.php)
so you can do something like this:
SAMPLE HTML:
<html>
<head>
<!-- include jquery because you say you are using it -->
<script src="//code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
//just a dummy function to represent your js to extract csv data from a table
function extract_table_data(){
var csv = "field1,field2,field3\n\
value1,value2,value3\n\
value4,value5,value5";
return csv;
}
$( document ).ready(function() {
//export link click handler
$('#export_link').click(function() {
$('#csv_data').val(extract_table_data());
$('#theform').submit();
});
});
</script>
</head>
<body>
<a id='export_link'>Export CSV</a>
<form id='theform' method='post' action='dropcsv.php'>
<input type='hidden' name='csv_data' id='csv_data'/>
</form>
</body>
</html>
dropcsv.php
//filename for our csv attachment
$export_filename = 'thefile.csv';
//grab csv data
$csv_data = $_POST['csv_data'];
//open file in memory
$f = fopen('php://memory', 'w'); //use php://temp if you want a tmp file instead
//load up csv file
fwrite($f, $csv_data);
// go back to the beginning of the file
fseek($f, 0);
header('Content-Type: application/csv');
header('Content-Disposition: attachement; filename="'.$export_filename.'"');
fpassthru($f);
fclose($f);
of course don't forget to add your error checking and sanitize the input.