I am not real good at reading the code for uploading images via php/ajax so i am hoping a php guru can help me out. I am trying to take the image file name and if it has spaces in it then replace those spaces with an underscore "_"
The php code for uploading is this:
$file_name = ( isset($_REQUEST['ax-file-name']) && !empty($_REQUEST['ax-file-name']) )?$_REQUEST['ax-file-name']:'';
$currByte = isset($_REQUEST['ax-start-byte'])?$_REQUEST['ax-start-byte']:0;
if($is_ajax)//Ajax Upload, FormData Upload and FF3.6 php:/input upload
{
//we get the path only for the first chunk
$full_path = ($currByte==0) ? checkFileExits($file_name, $upload_path):$upload_path.$file_name;
//Just optional, avoid to write on exisiting file, but in theory filename should be unique from the checkFileExits function
$flag = ($currByte==0) ? 0:FILE_APPEND;
//formData post files just normal upload in $_FILES, older ajax upload post it in input
$post_bytes = isset($_FILES['Filedata'])? file_get_contents($_FILES['Filedata']['tmp_name']):file_get_contents('php://input');
//some rare times (on very very fast connection), file_put_contents will be unable to write on the file, so we try until it writes
while(#file_put_contents($full_path, $post_bytes, $flag) === false)
{
usleep(50);
}
//delete the temporany chunk
if(isset($_FILES['Filedata']))
{
#unlink($_FILES['Filedata']['tmp_name']);
}
//if it is not the last chunk just return success chunk upload
if($isLast!='true')
{
echo json_encode(array('name'=>basename($full_path), 'size'=>$full_size, 'status'=>1, 'info'=>'Chunk uploaded'));
}
}
else //Normal html and flash upload
{
$isLast = 'true';//we cannot upload by chunks here so assume it is the last single chunk
$full_path = checkFileExits($file_name, $upload_path);
$result = move_uploaded_file(str_replace(" ", "_",$_FILES['Filedata']['tmp_name']), $full_path);//make the upload
if(!$result) //if any error return the error
{
echo json_encode( array('name'=>basename($full_path), 'size'=>$full_size, 'status'=>-1, 'info'=>'File move error') );
return false;
}
}
I've already tried the following (with str_replace(" ", "_", $nameoffile):
$post_bytes = isset($_FILES['Filedata'])? file_get_contents(str_replace(" ", "_",$_FILES['Filedata']['tmp_name'])):file_get_contents('php://input');
That seems to do nothing to rename it. So where am i missing it at?
The problem in your code is , you are trying to rename the temporary name of image file not the actual name
move_uploaded_file(str_replace(" ", "_",$_FILES['Filedata']['tmp_name']), $full_path);//make the upload
So you have to remove the str_replace from temporary name and append this to actual name like this.
move_uploaded_file($_FILES['Filedata']['tmp_name'], str_replace(" ", "_",$full_path));//make the upload
Hope it clarifies your doubt.
Related
Hi i have the following code that uploads videos to a server and updates the database accordingly. This code works fine when i run it with a bunch of images and or small video's. See the code below:
for ($i=0; $i<count($_FILES['images']['error']); $i++) {
if ($_FILES['images']['error'][$i] == UPLOAD_ERR_OK) {
$tmpName = $_FILES['images']['tmp_name'][$i];
$name = $_FILES['images']['name'][$i];
$type = $_FILES['images']['type'][$i];
if (strpos($type, 'image') !== false) {
$type = "img";
}elseif(strpos($type, 'video') !== false){
$type = "vid";
}else{
exit();
}
move_uploaded_file(($tmpName), $dir.$name);
$upload = array(
'name'=>$name,
'type'=>$type
);
$uploads[] = $upload;
}
}
But when my client tries to upload a video bigger than 64mb the program doesnt upload it... I already tried to change the max_file_size and other according parameters to allow bigger files. But my clients hosting provider doesnt allow this.
So are there any other ways of uploading big files to my server via my custom cms?
Thomas
So as said in comments. Reference material is below code examples. Trick is to cut the file into chunks that are less than the upload limit. This method can be extended to the point that when a file upload is interrupted you can continu on the last known part. :-)
Basic JavaScript class to assist in uploading the file, determines the chunks to be sent to a PHP server.
function fileUploader() {
// Called when the file is selected
this.onFileSelected = function() {
// Read file input (input type="file")
this.file = this.fileInput.files[0];
this.file_size = this.file.size;
this.chunk_size = (1024 * 1000);
this.range_start = 0;
this.range_end = this.chunk_size;
this.slice_method = 'slice';
this.request = new XMLHttpRequest();
// Start uploading
this.upload();
};
this.upload = function()
{
var self = this,
chunk;
// Last part reached
if (this.range_end > this.file_size) {
this.range_end = this.file_size;
}
// Chunk the file using the slice method
chunk = this.file[this.slice_method](this.range_start, this.range_end);
// Open a XMLHttpRequest
var endpoint = "/url/to/php/server/for/processing";
this.request.open('PUT', (endpoint));
this.request.overrideMimeType('application/octet-stream');
this.request.send(chunk);
// Make sure we do it synchronously to prevent data corruption
this.request.onreadystatechange = function()
{
if (self.request.readyState == XMLHttpRequest.DONE && self.request.status == 200) {
self.onChunkComplete();
}
}
};
this.onChunkComplete = function()
{
if (this.range_end === this.file_size)
{
// We are done, stop uploading
return;
}
this.range_start = this.range_end;
this.range_end = this.range_start + this.chunk_size;
this.upload();
};
}
And for the PHP bit:
...
$out = fopen("{$filePath}.partial", "a+");
fwrite($out, file_get_contents("php://input"));
fclose($out);
...
Big warning here, make sure to properly validate and take security measures to ensure the safety of your clients upload function. You are writing the raw PHP input to a file.
When the upload is done you can rename the file to it's original name including the correct extension.
Reference material:
http://creativejs.com/tutorials/advanced-uploading-techniques-part-1/index.html
https://secure.php.net/manual/en/wrappers.php.php
In a nutshell.. it's break the file into small chunks using a processor, upload the files using conventional methods (like you would normally upload a file), append the input to a temporarily file. Some pitfalls I encountered were sending extra params and alike to the endpoint, avoid those as it's appended to the file and it will corrupt your file.
I am new for developing.I have opted for php to learn coding.So I might make mistake as I learn by myself, kindly clarify my doubts.
I have problem in uploading files using php to a folder.What I really do is, I upload a file and the file is saved in a folder and the name of the file alone inserted in the database. While uploading the file I do copy the file to another folder which will be used for the editing purpose so that the original file will not be disturbed.Here the problem I get is, the file is uploaded successfully as well as the name too inserted in database. But it take much time to get upload even the size of the file is small.It works good while I test using my local but when I come in real time this issue(slow uploading) I face. What the person incharge in uploading do is, uploading a file and opening a new browser and upload another file. When the new browser is opened the files get uploaded but in the previous browser it is still in process. The code I have written to copy the file to another folder is not executed as the new browser is opened to upload another set of files. I am using xamp cp v3.2.1.To minimize the execution time I have set the default Maximum execution time to 30. But unable to upload file fastly.
Below is my php coding:
<?php
// connect to the database
include('connect-db.php');
if (isset($_POST['submit']))
{
// get form data, making sure it is valid
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
$file_array=($_FILES['file_array']['name']);
// check to make sure both fields are entered
if ($udate == '' || $file_array=='')
{
// generate error message
$error = 'ERROR: Please fill in all required fields!';
// if either field is blank, display the form again
renderForm($udate, $file_array, $error);
}
else
{
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
if(isset($_FILES['file_array']))
{
$name_arrray=$_FILES['file_array']['name'];
$tmp_name_arrray=$_FILES['file_array']['tmp_name'];
for($i=0;$i <count($tmp_name_arrray); $i++)
{
if(move_uploaded_file($tmp_name_arrray[$i],"test_uploads/".str_replace(' ','',$name_arrray[$i])))
{
// save the data to the database
$j=str_replace(' ','',$name_arrray[$i]);
echo $j;
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
$provider = mysql_real_escape_string(htmlspecialchars($_POST['provider']));
$existfile=mysql_query("select ubatch_file from batches");
while($existing = mysql_fetch_array( $existfile)) {
if($j==$existing['ubatch_file'])
echo' <script>
function myFunction() {
alert("file already exists");
}
</script>';
}
mysql_query("INSERT IGNORE batches SET udate='$udate', ubatch_file='$j',provider='$provider',privilege='$_SESSION[PRIVILEGE]'")
or die(mysql_error());
echo $name_arrray[$i]."uploaded completed"."<br>";
$src = 'test_uploads';
$dst = 'copy_test_uploads';
$files = glob("test_uploads/*.*");
foreach($files as $file){
$file_to_go = str_replace($src,$dst,$file);
copy($file, $file_to_go);
/* echo "<script type=\"text/javascript\">
alert(\"CSV File has been successfully Uploaded.\");
window.location = \"uploadbatches1.php\"
</script>";*/
}
} else
{
echo "move_uploaded_file function failed for".$name_array[$i]."<br>";
}
}
}
// once saved, redirect back to the view page
header("Location:uploadbatches1.php");
}
}
?>
It takes much time because, each and everytime all the files are copied to the newfolder. This exceeds the execution time.Only copying the uploaded files makes uploading and copying files fast.
am uploading a Pdf file and passing it to getExtact function to extract pages from file which is being uploaded if any error in extraction we will send the file to decryptPDF function for which the input parameters are filename and filetempname for both the functions but here am using a file upload process i want to use file url like www.domainname.com/docs/1.pdf so that all the functions which are written already can be used : Below is my code
//here for the above variable values are coming from uploaded file here i want to use file url and all the pdf are in my own server
$FileName = $_FILES['inputfile']['name'];
$TempFileName = $_FILES['inputfile']['tmp_name']; $Folderpath='/home/domain/public_html/pdftest/temp';
try {
.
GetExtract($TempFileName,$FileName);
} catch (Exception $e) {
$responce = DecryptPDF($Folderpath,$Filename,$TempFileName);
if($responce == ''){
$Inputfile = $Folderpath.'/un_'.$Filename;
GetExtract($Inputfile,$FileName);
}else{
echo $responce;
}
As per my knowledge,local server $PATH is "/var/www/".Try putting your inputfiles in that location.Then only you can access the files using url.
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.
on a page, i have :
if (!empty($_FILES['logo']['name'])) {
$dossier = 'upload/';
$fichier = basename($_FILES['logo']['name']);
$taille_maxi = 100000;
$taille = filesize($_FILES['logo']['tmp_name']);
$extensions = array('.png', '.jpg', '.jpeg');
$extension = strrchr($_FILES['logo']['name'], '.');
if(!in_array($extension, $extensions)) {
$erreur = 'ERROR you must upload the right type';
}
if($taille>$taille_maxi) {
$erreur = 'too heavy';
}
if(!empty($erreur)) {
// ...
}
}
The problem is, if the users wants to edit information WITHOUT uploading a LOGO, it raises an error : 'error you must upload the right type'
So, if a user didn't put anything in the inputbox in order to upload it, i don't want to enter in these conditions test.
i tested :
if (!empty($_FILES['logo']['name']) and if (isset($_FILES['logo']['name'])
but both doesn't seems to work.
Any ideas?
edit : maybe i wasn't so clear, i don't want to test if he uploaded a logo, i want to test IF he selected a file to upload, because right now, if he doesn't select a file to upload, php raises an error telling he must upload with the right format.
thanks.
You can check this with:
if (empty($_FILES['logo']['name'])) {
// No file was selected for upload, your (re)action goes here
}
Or you can use a javascript construction that only enables the upload/submit button whenever the upload field has a value other then an empty string ("") to avoid submission of the form with no upload at all.
There is a section in php documentation about file handling. You will find that you can check various errors and one of them is
UPLOAD_ERR_OK
Value: 0; There is no error, the file uploaded with success.
<...>
UPLOAD_ERR_NO_FILE
Value: 4; No file was uploaded.
In your case you need code like
if ($_FILES['logo']['error'] == UPLOAD_ERR_OK) { ... }
or
if ($_FILES['logo']['error'] != UPLOAD_ERR_NO_FILE) { ... }
You should consider checking (and probably providing appropriate response for a user) for other various errors as well.
You should use is_uploaded_file($_FILES['logo']['tmp_name']) to make sure that the file was indeed uploaded through a POST.
I would test if (file_exists($_FILES['logo']['tmp_name'])) and see if it works.
Or, more approperately (thanks Baloo): if (is_uploaded_file($_FILES['logo']['tmp_name']))
We Could Use
For Single file:
if ($_FILES['logo']['name'] == "") {
// No file was selected for upload, your (re)action goes here
}
For Multiple files:
if ($_FILES['logo']['tmp_name'][0] == "") {
// No files were selected for upload, your (re)action goes here
}
if($_FILES["uploadfile"]["name"]=="") {}
this can be used
No file was selected for upload, your (re)action goes here in if body
echo "no file selected";
if ($_FILES['logo']['error'] === 0)
is the only right way