PHP AJAX image upload - I need to limit quota to a folder - php

I am using Ajax PHP to upload images to a folder, but I want to limit that space to 50 MB. I think I'm on the right track, but the code does not work for me. If you can help me.
I think the error should be in "if ($ size> 52428800) {"
Thank you
/*** Calling from ajax to add the gallery new an image****/
public function Addgallery() {
$size = 0;
$files= glob($directory.$folder_gallery.'/*');
foreach($files as $path){
is_file($path) && $size += filesize($path);
is_dir($path) && get_dir_size($path);
}
return $size;
if ($size > 52428800 ) {
echo alert("Your quota on disk does not allow the upload of images. Please erase images that you do not use.");
} else {
$this->_upload_file($this->_base_path .'/images/gallery/', array( '.png', '.jpg', '.jpeg', '.gif' ), 'addgallery');
}
}

You are returning $size on line 9. Everything below the return statement will be skipped.
If you move return $size below the else, your code should work.
/*** Calling from ajax to add the gallery new an image****/
public function Addgallery() {
$size = 0;
$files = glob($directory.$folder_gallery.'/*');
foreach($files as $path){
is_file($path) && $size += filesize($path);
is_dir($path) && get_dir_size($path);
}
if ($size > 52428800){
echo alert("Your quota on disk does not allow the upload of images. Please erase images that you do not use.");
} else {
$this->_upload_file($this->_base_path .'/images/gallery/', array( '.png', '.jpg', '.jpeg', '.gif' ), 'addgallery');
}
return $size;
}
Note: alert() is not a PHP function, just in case you didn't create that function

Related

PHP - Detecting image filesize before saving image

I am using the following code to save an image from a URL but sometimes the image URL is bad and there is no image there, OR there is an issue with the image and it saves a zero size file.
<?php
file_put_contents ("/var/www/html/images/" . $character . ".jpg",
file_get_contents($image));
I need to try and find a way to stop this happening as this creates a problem (saving zero size files).
I have tried this, but it still seems to be happening:
$filesize = file_put_contents ("/var/www/html/images/" . $character . ".jpg",
file_get_contents($image));
if (($filesize < 10) || ($filesize == "")) {
echo "Error";
}
Could anyone recommend a more reliable way to do this?
Imagick package has methods for doing this
Imagick::getImageGeometry() - returns width and height of an image, or throws an exception.
function isValidImage($filename)
{
if (!fileexists($filename) return false;
if (filesize($filename) == 0) return false;
$image = new imagick($filename);
$img=$image->getImageGeometry();
return ($img['width'] > 0 && $img['height'] > 0);
}
EDIT: I have updated my answer with more checks
I have tried to get an image size by URL. I have get_headers() function to get the image size. Here is an example which is given below:
function checkImageSize($imageUrl){
if(!empty($imageUrl)){
$file_headers = #get_headers($imageUrl, 1); // it gives all header values .
// for image size, we use **Content-Length** for size.
$sizeInKB = round($file_headers['Content-Length'] / 1024, 2));
return $sizeInKB;
} else {
return 0;
}
}
$imageSize =checkImageSize($imageUrl);
if($imageSize<=$conditionalSize){
// upload code
} else {
// error msg
}

Issue when uploading image to tmp folder, resize and then upload to S3 bucket

I've spend all day figuring out how to store an image in tmp, change its size and then upload it to my S3 bucket. The S3 bucket works fine and i am able to upload images when i don't resize. The resize function is the createThumbnail function and works fine when not combined with S3 probably because it's a wrong format or something. The second file "init.php" contains all the functions. The images are uploaded to the temp folder but when i run the script it doesn't get uploaded after it's resized. I don't get any error logs on localhost and when i upload the code to my AWS instance it just returns a internal server error but the error log in my instance is oddly empty... I need some fresh eyes on this issue.
banner_image.php
<?php
include "init.php";
if (#session($_SESSION["buddy"])){
$valid_file_formats = array("jpg","png","jpeg");
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST" && !empty($_FILES['banner_image']['tmp_name']) && !empty($_FILES['banner_image']['name'])){
$folder = usernameFromEmail($_SESSION["user"]); // session based on users email
$buddy = $_SESSION["user"];
$name = $_FILES['banner_image']['name'];
$size = $_FILES['banner_image']['size'];
$path = $folder."/cover/"; // path to image folder
$temp = explode(".", $name);
$newfilenameKey = round(microtime(true)); // generating random file name
$newfilename = $newfilenameKey . "." . "png"; // always using png
if(strlen($newfilename) && strlen($name)) {
$ext = explode(".", $name);
$ext = end($ext);
if(in_array($ext,$valid_file_formats)) { // valid file format array check
if($size<=(10485760)) { // size check in bits
$tmp = $_FILES['banner_image']['tmp_name'];
$file_name = $path.$newfilename; // full path including file name
if(putS3IMG($bucket, $file_name, $tmp)){ // upload untouched image to S3 bucket
list($width, $height) = getimagesize($tmp);
$type = 2;
$w = 300;
$h = 300 * ($height / $width);
// getting new dimensions for the new image
if(createThumbnail(1,$tmp,$w,$h,$path,$file_name) == 1){ // function for smaller image
return json_encode(array("succ" => 1));
}
}
}
}
}
}
}
?>
here is my init.php file included in the banner_image.php file which contains my functions.
<?php
// connection to S3Client .... $client
function createThumbnail($type,$image_name,$new_width,$new_height,$uploadDir,$moveToDir){
global $bucket;
//$type: defines the name of the new file
//image_name: tmp name
//uploadDir: path
//moveToDir: files new path incl. file name
$mime = getimagesize($image_name);
if($mime['mime']=='image/png') {
$src_img = imagecreatefrompng($image_name);
} else if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
$src_img = imagecreatefromjpeg($image_name);
}
$old_x = imageSX($src_img);
$old_y = imageSY($src_img);
$thumb_w = $new_width;
$thumb_h = $new_height;
$dst_img = ImageCreateTrueColor($thumb_w,$thumb_h);
$background = imagecolorallocate($dst_img, 0, 0, 0);
imagecolortransparent($dst_img, $background);
imagealphablending($dst_img, false);
imagesavealpha($dst_img, true);
imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);
$image_name_new = explode(".", $moveToDir);
if ($type == 1){
$new_image_name = $image_name_new[0] . "_thumb." . $image_name_new[1];
} else if ($type == 2){
$new_image_name = $image_name_new[0] . "_image." . $image_name_new[1];
}
$tmpPath = tempnam(sys_get_temp_dir(), $new_image_name); // getting temporary directory
if($mime['mime']=='image/png') {
imagepng($dst_img,$tmpPath,8);
} else if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
imagejpeg($dst_img,$tmpPath,80);
}
imagedestroy($dst_img);
imagedestroy($src_img);
if(putS3IMG($bucket, $image_name, $tmpPath)){ // this part does not work
return 1;
} else {
return 2;
}
}
function putS3IMG($bucket, $file_name, $tmp){ // function uploading to my bucket
//file_name is with directories
//tmp is $_FILES tmp_name
global $client;
$result = $client->putObject([
'Bucket' => $bucket,
'Key' => $file_name,
'SourceFile' => $tmp
]);
if ($result){
return true;
}
return false;
}
SOLUTION:okay, so eventually i ended up using AWS lambda which solved the issue but it isn't a free solution. So, if any of you come up with a solution that allow you to resize without using third party tools feel free to comment it in order to make life easier for the next programmers viewing this question.

cannot upload and save large image files on PHP server

I have written the php upload image files to php server.
When small images within 100kB, it is success.
But when over 500KB, it is failed and said no data received on server.
I also do not know why. No file saved in php server of this uploading.
Do you know how to solve??
function uploadImages($input, $file)
{
if($input == null || $input == "")
{
return false;
}
$stringVal = $input;
$value = str_replace('data:image/png;base64,', '', $stringVal);
if ($this->check_base64_image($value) == false) {
return false;
}
$actualFile = base64_decode($value);
$img = imagecreatefromstring($actualFile);
$imgSize = getimagesize('data://application/octet-stream;base64,' . base64_encode($actualFile));
if ($img == false) {
return false;
}else
{
/*** maximum filesize allowed in bytes ***/
$max_file_length = 100000;
log_message('debug', 'PRE UPLOADING!!!!!!!!');
if (isset($img)){
log_message('debug', 'UPLOADING!!!!!!!!');
// check the file is less than the maximum file size
if($imgSize['0'] > $max_file_length || $imgSize['1'] > $max_file_length)
{
log_message('debug', 'size!!!!!!!!'.print_r($imgSize));
$messages = "File size exceeds $max_file_size limit";
return false;
}else if (file_exists($file)) {
return false;
}else
{
file_put_contents($file, $actualFile);
return true;
}
}
}
}
try this,
ini_set('post_max_size',52428800); // 50 MB
ini_set('upload_max_filesize',52428800) // 50 MB

resize multiple images while uploading

Hi im trying to resize multiple image while uploading i have the function that resize but its only work for one image so please can anyone shom me how to loop this for multiple file upload
if( $_FILES['image']['size']< $max_file_size ){
// get file extension
$ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
// $ext = pathinfo($_FILES['files']['name'][$f], PATHINFO_EXTENSION);
if (in_array($ext, $valid_exts)) {
/* resize image */
foreach ($sizes as $w => $h) {
$files[] = resize($w, $h);
}
} else {
$msg = 'Unsupported file';
}
} else{
$msg = 'Please upload image smaller than 200KB';
}
This is untested, but might give you an idea.
The way this works is by looping through all of the $_FILES of the variable $iname which is 'image'. I set this since it's used multiple times, so if you ever change it, its easier.
I create a new variable called $image which will be the variables for that specific image. I do this by looping through all of the variables of $_FILES[$iname]. I set the $image variable to the $key and the new value, which will be an array. We reference the correct array using the $i variable.
Next I simply use your existing code. Since the resize() function only calls for width and height, I am unsure what happens here. Another parameter should be passed to reference the image you want to resize, which will be $image.
From the visible code I typed, not knowing what resize() is, this code is insecure. You should really check more than just the file extension since it can easily be changed. I usually use exif to check the image header. I also never store the data users upload unless I re-encode it using a GDI function in PHP.
Hopefully this will get you started.
$i = 0;
$iname = 'image';
for($i = 0; $i < count($_FILES[$iname]['size']); $i++) {
// Create new Image Array
$image = array();
foreach($_FILES[$iname] as $key => $val) {
$image[$key] = $val[$i];
}
if( $image['size'] < $max_file_size ) {
$ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
if (in_array($ext, $valid_exts)) {
foreach ($sizes as $w => $h) {
// How is resize getting the $_FILES?
// Should pass a variable of $image and use it instead
$files[] = resize($w, $h);
}
} else {
$msg = 'Unsupported file';
}
} else{
$msg = 'Please upload image smaller than 200KB';
}
}

valums ajax-upload broken script after xhr.send(file) - sometimes works, and sometimes does not

I searched for solution to this the better part of the day and I'm still in the dark. For a client of mine I created a simple web gallery for uploading images and I'm using valums file uploader. Till now I didn't have any problems with it on any other site I created, except miss-configuration which I solved some time ago.
So, what is the problem?
When I upload a image with filesize below 260KB it works fine. But, when I'm uploading a bigger image, it doesn't throw me back any error. I just get an empty thumbnail, because image wasn't uploaded.
When I open Chrome Console, this is what I see:
POST http://designflowstudio.com/gallery2/include/upload.php?url=uploads%2Fe558c4dfc2a0f0d60f5ebff474c97ffc&fid=7&qqfile=316267269718409738080100.jpg 403 (Forbidden) fileuploader.js:1463
POST http://designflowstudio.com/gallery2/include/upload.php?url=uploads%2Fe558c4dfc2a0f0d60f5ebff474c97ffc&fid=7&qqfile=3.jpg 403 (Forbidden) fileuploader.js:1463
On some occasions I got 413 error "Request entity too large".
Let me say that this problem really annoys me because the script works well on my local web server (apache) and on my web server. Here I can upload as may and as big images as I can find, but on the client's web server...
If anyone have time and will to help me, here is the JavaScript that I use to call the valums uploader:
function createUploader(){
var uploader = new qq.FileUploaderBasic({
debug: true,
multiple: true,
allowedExtensions: [<?php $tmp=".";foreach($allowedExt as $ext){$tmp.="'$ext', ";}echo substr($tmp,1,strlen($tmp)-3);?>],
button: document.getElementById('uploadDiv'),
action: '<?php echo$home;?>include/upload.php',
sizeLimit: <?php echo$sizeLimit;?>,
forceMultipart: true,
params: {'url':'uploads/<?php echo$g['path'];?>','fid':'<?php echo$g['id'];?>'},
onSubmit: function(id, fName){$('#upload-list').append('<div id="upload-list-'+id+'" class="gallery" rel="'+fName+'"><div class="progress'+id+'"></div>');$('.progress'+id).progressbar({value:0})},
onProgress: function(id, fName, loaded, total){
var p = 0;
p = parseFloat(loaded/total*100);
if(isNaN(p)) p = '';
$('.progress'+id).progressbar("option","value",p);
},
onComplete: function(id,fName,json){
if(json.error){
$('#upload-list-'+id).html(fName+'<br />'+json.error);
}else{
$('#upload-list-'+id)
.attr("rel",json.fname)
.html('<img class="cmd" id="deleteImg" rel="'+json.id+'" src="<?php echo$home;?>images/delete.png" title="Delete picture" /><img class="img" src="<?php echo$home;?>uploads/<?php echo$g['path'];?>/th_'+json.fname+'" /><input class="ut" type="text" name="name" value="'+json.name+'" /><input class="ud" type="text" name="desc" /><div class="cl"></div>')
.attr("id",json.id);
}
},
onError: function(id,fName,error){
console.log(id+' '+fName+' '+error);
}
});
}
window.onload = createUploader;
And here is my PHP for server processing the file:
require("config.php");
require("SimpleImage.php");
ini_set("log_errors" , "1");
ini_set("error_log" , "php-errors-upload.log");
ini_set("display_errors" , "1");
/**
* Handle file uploads via XMLHttpRequest
*/
class qqUploadedFileXhr {
/**
* Save the file to the specified path
* #return boolean TRUE on success
*/
function save($path) {
$input = fopen("php://input", "r");
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
if ($realSize != $this->getSize()){
return false;
}
$target = fopen($path, "w");
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
return true;
}
function getName() {
return $_GET['qqfile'];
}
function getSize() {
if (isset($_SERVER["CONTENT_LENGTH"])){
return (int)$_SERVER["CONTENT_LENGTH"];
} else {
throw new Exception('Getting content length is not supported.');
}
}
}
/**
* Handle file uploads via regular form post (uses the $_FILES array)
*/
class qqUploadedFileForm {
/**
* Save the file to the specified path
* #return boolean TRUE on success
*/
function save($path) {
if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
return false;
}
return true;
}
function getName() {
return $_FILES['qqfile']['name'];
}
function getSize() {
return $_FILES['qqfile']['size'];
}
}
class qqFileUploader {
private $allowedExtensions = array();
private $sizeLimit = 20485760;
private $file;
function __construct(array $allowedExtensions = array(), $sizeLimit = 20485760){
$allowedExtensions = array_map("strtolower", $allowedExtensions);
$this->allowedExtensions = $allowedExtensions;
$this->sizeLimit = $sizeLimit;
$this->checkServerSettings();
if (isset($_GET['qqfile'])) {
$this->file = new qqUploadedFileXhr();
} elseif (isset($_FILES['qqfile'])) {
$this->file = new qqUploadedFileForm();
} else {
$this->file = false;
}
}
private function checkServerSettings(){
$postSize = $this->toBytes(ini_get('post_max_size'));
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
}
}
private function toBytes($str){
$val = trim($str);
$last = strtolower($str[strlen($str)-1]);
switch($last) {
case 'g': $val *= 1024;
case 'm': $val *= 1024;
case 'k': $val *= 1024;
}
return $val;
}
/**
* Returns array('success'=>true) or array('error'=>'error message')
*/
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
chdir("../");
if(!file_exists($uploadDirectory)){
foreach(explode("/",$uploadDirectory) as $val){
if(empty($val2)){$val2=$val."/";}else{$val2.=$val."/";}
if($val<>""){if(!file_exists($val2)){mkdir($val2);}}
}
}
if (!is_writable($uploadDirectory)){
return array('error' => "Server error. Upload directory isn't writable.");
}
if (!$this->file){
return array('error' => 'No files were uploaded.');
}
$size = $this->file->getSize();
if ($size == 0) {
return array('error' => 'File is empty');
}
if ($size > $this->sizeLimit) {
return array('error' => 'File is too large');
}
$pathinfo = pathinfo($this->file->getName());
$filename = md5($pathinfo['filename'].mt_rand());
//$filename = md5(uniqid());
$ext = strtolower($pathinfo['extension']);
if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
$these = implode(', ', $this->allowedExtensions);
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
}
if(!$replaceOldFile){
/// don't overwrite previous files that were uploaded
while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
$filename .= rand(10, 99);
}
}
if ($this->file->save($uploadDirectory .'/'. $filename . '.' . $ext)){
global $sql_images;
$md=md5($filename);
$tmp=mysql_query("SELECT `order` FROM `$sql_images` WHERE `gid`='{$_REQUEST['fid']}' ORDER BY `order` DESC");
if($tmp&&mysql_num_rows($tmp)>0){$i=mysql_result($tmp,0);$i++;}else{$i=0;}
mysql_query("INSERT INTO `$sql_images` (`order`,`gid`,`name`,`path`) VALUES ('$i','{$_REQUEST['fid']}','{$pathinfo['filename']}','$filename.$ext')");
$image = new SimpleImage();
$image->load($uploadDirectory.'/'.$filename.'.'.$ext);
$image->resizeToWidth(150);
$image->save($uploadDirectory.'/th_'.$filename.'.'.$ext);
return array('success'=>true,'fname'=>$filename.".".$ext,'name'=>$pathinfo['filename'],'id'=>mysql_insert_id());
} else {
return array('error'=> 'Could not save uploaded file.' .
'The upload was cancelled, or server error encountered');
}
}
}
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
$allowedExtensions = array();
// max file size in bytes
$sizeLimit = 20*1024*1024;
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
$result = $uploader->handleUpload($_REQUEST['url']);
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
Let me say again, all the calls to MySQL, files with require() are valid. The scripts work on two other servers, but on this one, not.
Thank you for your time and will to help.
You have some configuration issues on your server if it is choking due to the content-type header. Instead of commenting out this line, to work around this messed up server, you should perhaps try to set the forceMultipart option to true, assuming your server can handle multipart-encoded requests correctly. This all assumes you are using the 2.1-SNAPSHOT version of the uploader, as the option I mentioned first appeared in this version.

Categories