I was trying to write a PHP code that uploads all images to mysql db and shows the images metadata in columns. in my code it uploads the images but does not show the metadata. for example I tried to insert the width of the image, I made a column for that and when I upload the image the width is always 0. can someone check my code and help me find a solution for than?
<?php
// Include the database configuration file
include_once 'dbconfig.php';
if(isset($_POST['submit'])){
// File upload configuration
$targetDir = "C:\\xampp\\htdocs\\uploaded\\";
$allowTypes = array('jpg','png','jpeg','gif');
$statusMsg = $errorMsg = $insertValuesSQL = $errorUpload = $errorUploadType = '';
$fileNames = array_filter($_FILES['files']['name']);
if(!empty($fileNames)){
function getExif( $filename, $key1, $key2) {
$width = 0;
$allowedFiletypes = array("jpg","jpeg","tif","tiff");
if(in_array(strtolower(substr($filename, -3)),$allowedFiletypes)) {
if(exif_read_data($filename) == true) {
$exif = exif_read_data($filename, 0, true);
foreach ($exif as $key => $section) {
foreach ($section as $name => $val) {
if($key === $key1 AND $name === $key2){
$width = $val;
}
}
}
}
return $width;
} else {
print "filetype not supported";
}
}
$key1 = "IFD0";
$key2 = "ImageWidth";
foreach($_FILES['files']['name'] as $key=>$val){
// File upload path
$fileName = basename($_FILES['files']['name'][$key]);
$width = getExif( $fileName, $key1, $key2);
$targetFilePath = $targetDir . $fileName;
// Check whether file type is valid
$fileType = pathinfo($targetFilePath, PATHINFO_EXTENSION);
if(in_array($fileType, $allowTypes)){
// Upload file to server
if(move_uploaded_file($_FILES["files"]["tmp_name"][$key], $targetFilePath)){
// Image db insert sql
$insertValuesSQL .= "('".$fileName."', NOW(), '".$width."'),";
}else{
$errorUpload .= $_FILES['files']['name'][$key].' | ';
}
}else{
$errorUploadType .= $_FILES['files']['name'][$key].' | ';
}
}
// Error message
$errorUpload = !empty($errorUpload)?'Upload Error: '.trim($errorUpload, ' | '):'';
$errorUploadType = !empty($errorUploadType)?'File Type Error: '.trim($errorUploadType, ' | '):'';
$errorMsg = !empty($errorUpload)?'<br/>'.$errorUpload.'<br/>'.$errorUploadType:'<br/>'.$errorUploadType;
if(!empty($insertValuesSQL)){
$insertValuesSQL = trim($insertValuesSQL, ',');
// Insert image file name into database
$insert = $db->query("INSERT INTO images(file_name, uploaded_on, image_width) VALUES $insertValuesSQL");
if($insert){
$statusMsg = "Files are uploaded successfully.".$errorMsg;
}else{
$statusMsg = "Sorry, there was an error uploading your file.";
}
}else{
$statusMsg = "Upload failed! ".$errorMsg;
}
}else{
$statusMsg = 'Please select a file to upload.';
}
}
?>
<form action="upload1.php" method="post" enctype="multipart/form-data">
Select Image Files to Upload:
<input type="file" name="files[]" multiple >
<input type="submit" name="submit" value="UPLOAD">
</form>
my goal is to upload images with all their metadata
You are incorrectly passing in the filename rather than the file itself - and a name does not have any EXIF data attributes. One other issue that you will encounter with EXIF perhaps is that not every camera adds the same details so there ar eno guarantees that a particular property will exist within a particular section so forking the processing logic around that is needed.
You can simplify the getExif function using array_key_exists rather than the nested loops which can be prone to issues. For example, a bare-bones piece of PHP without the SQL portion.
The getExif below either returns exactly the item requested or the entire exif response which can be used to fork the logic as mentioned. In testing I found just one image that contained both the section and required parameter ($key1,$key2- renamed for clarity)
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
Select Image Files to Upload:
<input type="file" name="files[]" multiple />
<input type="submit" />
</form>
<?php
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );
function uploaderror( $error ){
switch( $error ) {
case UPLOAD_ERR_INI_SIZE: return "The uploaded file exceeds the upload_max_filesize directive in php.ini";
case UPLOAD_ERR_FORM_SIZE: return "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form";
case UPLOAD_ERR_PARTIAL: return "The uploaded file was only partially uploaded";
case UPLOAD_ERR_NO_FILE: return "No file was uploaded";
case UPLOAD_ERR_NO_TMP_DIR: return "Missing a temporary folder";
case UPLOAD_ERR_CANT_WRITE: return "Failed to write file to disk";
case UPLOAD_ERR_EXTENSION: return "File upload stopped by extension";
default: return "Unknown upload error";
}
}
function getExif( $filename, $section=false, $param=false ) {
if( $section & $param ){
$exif = #exif_read_data( $filename,0, true );
if( array_key_exists( $section, $exif ) && array_key_exists( $param, $exif[ $section ] ) )return $exif[ $section ][ $param ];
return $exif;
}
return false;
}
if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_FILES['files'] ) ){
$exts = array('jpg','jpeg','tif','tiff');
$files=(object)$_FILES['files'];
foreach( $files->name as $i => $void ){
$name = $files->name[$i];
$size = $files->size[$i];
$type = $files->type[$i];
$tmp = $files->tmp_name[$i];
$error= $files->error[$i];
$errors=array();
if( !$error == UPLOAD_ERR_OK )$errors[]=uploaderror( $error );
if( empty( $errors )){
$ext = strtolower( pathinfo( $name, PATHINFO_EXTENSION ) );
$targetDir = __DIR__ . '/uploads';
$targetFile = sprintf('%s/%s',$targetDir,$name);
if( in_array( $ext, $exts )){
/*
What you wish to find in the exif...
*/
$section = "IFD0";
$param = "ImageWidth";
/*
find and process...
*/
$result = getExif( $tmp, $section, $param );
if( !is_numeric( $result ) or is_array( $result ) ){
$errors[]=sprintf('Unable to locate property "%s" within designated section: "%s"',$param,$section);
$errors[]=$result;
}else{
# just to show the data...
printf('<pre>%s</pre>',print_r( $result, true ) );
/*
save file to disk...
*/
$status=move_uploaded_file( $tmp, $targetFile );
if( !$status )$errors[]='Failed to save file';
/*
sql... use a Prepared Statement!
*/
$sql='insert into images( `file_name`, `uploaded_on`, `image_width` ) values (?,?,?)';
/*
$stmt=$db->prepare($sql);
$args=array(
$name,
date('Y-m-d H:i:s'),
$result
);
$stmt->bind_param('sss',...$args);
$stmt->execute();
*/
}
}else{
$errors[]='unknown file extension: '.$ext;
}
}
if( !empty( $errors ) )printf('<pre>%s</pre>',print_r($errors,true));
}
}
?>
</body>
</html>
Related
I am new here, nice to meet you.
I'm trying create a clean copy of a picture uploaded by a user after security checks, and to save this copy in a designated folder and in my DB. I'm working with XAMPP on Windows 10 and I granted the right permissions for the said folder. My code is below:
/*bit of code for picture addition, in a function for album publication*/
if($_FILES['albumCover']['error'] === 0) {
$covType;
$createCover;
$covName = guidv4();
$imgRegex = '/^[a-z\d][^.]*\.(jpe?g$)|\.(png$)/i';
$covInfo = finfo_open(FILEINFO_MIME_TYPE);
$covMime = finfo_file($covInfo, $_FILES['albumCover']['tmp_name']);
finfo_close($covInfo);
if(!preg_match($imgRegex, $_FILES['albumCover']['name']) ||
str_contains($_FILES['albumCover']['name'], ' ') ||
in_array($_FILES['albumCover']['type'], ['image/jpeg','image/png'])||
strpos($covMime, 'image/') !== 0)
{
$addMessages['errors'][] = 'Caractère autorisé pour le nom d\'image : lettres sans
accent / sans trémas / sans cédille, chiffres, tirets et underscores. Fichiers
autorisés : images .jpg, .jpeg ou .png.';
}
if(empty($addMessages['errors'])) {
if(preg_match($imgRegex, $_FILES['albumCover']['name'])
&& $_FILES['albumCover']['type'] == 'image/jpeg'
&& strpos($covMime, 'image/') !== 0)
{
$covType = 'jpeg';
$createCover = imagecreatefromjpeg($_FILES['albumCover']['tmp_name']);
imagejpeg($createCover,
self::COV_SECURE_PATH.$covName.'.'.pathinfo($_FILES['albumCover']['name'],
PATHINFO_EXTENSION)
);
move_uploaded_file($_FILES['albumCover']['tmp_name'],
self::COV_SECURE_PATH.'/'.$_FILES['albumCover']['name']);
} elseif(preg_match($imgRegex, $_FILES['albumCover']['name'])
&& $_FILES['albumCover']['type'] == 'image/png'
&& strpos($covMime, 'image/') !== 0)
{
$covType = 'png';
$createCover = imagecreatefrompng($_FILES['albumCover']['tmp_name']);
imagepng($createCover,
self::COV_SECURE_PATH.$covName.'.'.pathinfo($_FILES['albumCover']['name'],
PATHINFO_EXTENSION));
move_uploaded_file($_FILES['albumCover']['tmp_name'],
self::COV_SECURE_PATH.'/'.$_FILES['albumCover']['name']);
}
}
}
A few more details: the bit of code above is part of a class method. The constant COV_SECURE_PATH is declared in the class, before the method. And the guidv4() function for the picture name is in the same file, before the declaration of the class.
I have no PHP error messages, my prints display the right name and extension of each file and I declared the attribute enctype="multipart/form-data" in my HTML form. The pictures are saved in my DB (I will add the code regarding the DB if needed), but they won't be saved in my folder and I don't know what I'm missing. So far I haven't found an answer when searching in any site, any help will be very appreciated.
Well, I have finally fixed everything. My error was: if(preg_match($imgRegex, $_FILES['albumCover']['name']) && $_FILES['albumCover']['type'] == 'image/jpeg' && strpos($covMime, 'image/') !== 0) {
instead of if(preg_match($imgRegex, $_FILES['albumCover']['name']) && $_FILES['albumCover']['type'] == 'image/jpeg' && strpos($covMime, 'image/') === 0) {
And I also realised that I hadn't activated GD in my php.ini, now it's done.
Thanks to everyone who answered me!
take a look at my image validation...
//connecting to the database
$mysqli = mysqli_connect( 'localhost', 'root', '', 'img_validation' )
or
die( 'Database connection error => '.mysqli_connect_error() );
//errors and success message handling
$errors = array();
$success = array();
//imgs dir
$imgs_dir = './assets/imgs/';
//if upload button is pressed...
if ( isset( $_POST['upload'] ) ) {
//get image info...
$imgName = $_FILES['image']['name'];
$imgTmp = $_FILES['image']['tmp_name'];
$imgSize = $_FILES['image']['size'];
//image validation
if ( $imgName ) {
//get extension info
$imgExt = strtolower( pathinfo( $imgName, PATHINFO_EXTENSION ) );
//allowed image extensions
$allowExt = array( 'jpg', 'jpeg', 'png' );
//create new random image name
$uploadedPic = 'user-upload-'.rand( 100000, 999999 ).'.'.$imgExt;
//validate image extension
if ( in_array( $imgExt, $allowExt ) ) {
//max image upload size 3MB
if ( $imgSize < 3000000 ) {
//move image file to designated directory/folder
move_uploaded_file( $imgTmp, $imgs_dir.$uploadedPic );
} else {
array_push( $errors, "Image too large. Max. upload size 3MB." );
}
} else {
array_push( $errors, "<script type='text/javascript'>
alert('JPG, JPEG and PNG formats required.\\nMax. upload size 3MB.');</script>" );
array_push( $errors, "Please select a valid image." );
}
} else {
$uploadedPic;
}
//if found no errors...
if ( count( $errors ) == 0 ) {
//insert new record in `user_uploads` table in the database...
$admin = mysqli_query( $mysqli, "INSERT INTO user_uploads (image) VALUES ('$uploadedPic');" );
if ( $admin == 1 ) {
//success message
array_push( $success, "Image uploaded successfully." );
//redirect to profile after 2 seconds...
header( 'refresh: 2; url=http://localhost/img-validation/' );
} else {
array_push( $errors, mysqli_error() );
}
}
}
When I was at the early learning stage of PHP, I write this code and hope this will work for you : )
This question already has an answer here:
How to upload multiple image with rename in php mysql?
(1 answer)
Closed 1 year ago.
I wanted to upload multiple pictures at once using PHP but I am new to PHP so I don't understand how to do it. I want to upload a lot of pictures for one model. Like the picture below:
Here is my PHP code:
<?php
include_once('inc/header.php');
if (isset($_REQUEST['add'])) {
try {
$name = $_REQUEST['name'];
$category = $_REQUEST['category'];
$age = $_REQUEST['txt_age'];
$height = $_REQUEST['height'];
$haircolor = $_REQUEST['haircolor'];
$eyecolor = $_REQUEST['eyecolor'];
$bust = $_REQUEST['bust'];
$waist = $_REQUEST['waist'];
$about = $_REQUEST['about'];
$image_file = $_FILES["image"]["name"];
$type = $_FILES["image"]["type"]; //file name "txt_file"
$size = $_FILES["image"]["size"];
$temp = $_FILES["image"]["tmp_name"];
$path="../img/model_images/".$image_file; //set upload folder path
if (empty($name)) {
$errorMsg="Please Enter Name";
} elseif (empty($image_file)) {
$errorMsg="Please Select Image";
} elseif ($type=="image/jpg" || $type=='image/jpeg' || $type=='image/png' || $type=='image/gif') { //check file extension
if (!file_exists($path)) { //check file not exist in your upload folder path
if ($size < 5000000) { //check file size 5MB
move_uploaded_file($temp, "../img/model_images/" .$image_file); //move upload file temperory directory to your upload folder
} else {
$errorMsg="Your File To large Please Upload 5MB Size"; //error message file size not large than 5MB
}
} else {
$errorMsg="File Already Exists...Check Upload Folder"; //error message file not exists your upload folder path
}
} else {
$errorMsg="Upload JPG , JPEG , PNG & GIF File Formate.....CHECK FILE EXTENSION"; //error message file extension
}
if (!isset($errorMsg)) {
$insert_stmt=$connect->prepare('INSERT INTO tbl_model(model_name,model_category,model_image,model_age,model_height,model_haircolor,model_eyecolor,model_bust,model_waist,model_description) VALUES(:name,:category,:image,:txt_age,:height,:haircolor,:eyecolor,:bust,:waist,:about)'); //sql insert query
$insert_stmt->bindParam(':name', $name);
$insert_stmt->bindParam(':category', $category);
$insert_stmt->bindParam(':image', $image_file);
$insert_stmt->bindParam(':txt_age', $age);
$insert_stmt->bindParam(':height', $height);
$insert_stmt->bindParam(':haircolor', $haircolor);
$insert_stmt->bindParam(':eyecolor', $eyecolor);
$insert_stmt->bindParam(':bust', $bust);
$insert_stmt->bindParam(':waist', $waist);
$insert_stmt->bindParam(':about', $about);
if ($insert_stmt->execute()) {
echo $insertMsg="Model Added Successfully!"; //execute query success message
}
} else {
echo $errorMsg;
}
} catch (PDOException $e) {
echo $e->getMessage();
}
}
?>
But with this code I can only upload one picture but I want to upload many pictures.
This is my html code
<div class="form-group col-12">
<label for="slideImages" class="col-form-label">Model Image</label>
<input type="file" name="image" class="dropify" multiple>
</div>
In html you miss '[]' after name as you have to send array when you upload images and also make sure you write enctype in form tag as shown below
The form tag must contain the following attributes.
method="post"
enctype="multipart/form-data"
The input tag must contain type="file[]" and multiple attributes.
<form action="/action_page_binary.asp" method="post" enctype="multipart/form-data">
<div class="form-group col-12">
<label for="slideImages" class="col-form-label">Model Image</label>
<input type="file" name="image[]" class="dropify" multiple>
</div>
</form>
after this just you have to write for loop or foreach loop in php file as shown below in your code you use single column to store multiple image so apply this loop after you $about
if (isset($_REQUEST['add'])) {
try {
$name = $_REQUEST['name'];
$category = $_REQUEST['category'];
$age = $_REQUEST['txt_age'];
$height = $_REQUEST['height'];
$haircolor = $_REQUEST['haircolor'];
$eyecolor = $_REQUEST['eyecolor'];
$bust = $_REQUEST['bust'];
$waist = $_REQUEST['waist'];
$about = $_REQUEST['about'];
//$path="../img/model_images/".$image_file; //set upload folder path
$path = '';
if (empty($name)) {
$errorMsg="Please Enter Name";
exit;
}
foreach($_FILES["image"]["name"] as $key => $value){
$image_file = implode(',', $_FILES["image"]["name"]);
$image_name = $_FILES["image"]["name"][$key];
$type = $_FILES["image"]["type"][$key]; //file name "txt_file"
$size = $_FILES["image"]["size"][$key];
$temp = $_FILES["image"]["tmp_name"][$key];
if (empty($image_file)) {
$errorMsg="Please Select Image";
exit;
} else if (
($type=="image/jpg" ||
$type=='image/jpeg' ||
$type=='image/png' ||
$type=='image/gif')
) { //check file extension
if (!file_exists($path)) { //check file not exist in your upload folder path
if ($size < 5000000) { //check file size 5MB
move_uploaded_file($temp, "images/" .$image_name); //move upload file temperory directory to your upload folder
} else {
$errorMsg="Your File To large Please Upload 5MB Size"; //error message file size not large than 5MB
exit;
}
} else {
$errorMsg="File Already Exists...Check Upload Folder"; //error message file not exists your upload folder path
exit;
}
} else {
$errorMsg="Upload JPG , JPEG , PNG & GIF File Formate.....CHECK FILE EXTENSION"; //error message file extension
exit;
}
}
echo $name.$category.$age.$height.$haircolor.$eyecolor.$bust.$waist.$about.$image_file;
exit;
after this just bind above $image_file in your query
when you want to fetch display image use explode
$explode_images = explode(",", $images_file);
its gives you array then use foreach loop and key to access image name url or whatever you store in that column.
Hope this help .
if you need explanation of implode and explode check this out Implode Explode
I m creating a one form in PHP for upload image in server, That image should upload in 2 folder, in 1st folder image name will go from M1.jpg to M5.jpg, if I upload a 6th image the image name again should be M1.jpg and if I upload 1 more image the name is M2.jpg, etc.
In 2nd folder whatever the image name it should upload with the name and current time.
Now what I have done is that image is upload in both folders, in 1st folder image name upload with M1.jpg to M5.jpg, if upload 6th or 7th image it will replace only 1st image.
How it is possible, that really i don't know.
Please help out some one Thanks in advance.
Form.php
<div class="sm-col-5">
<form action="upload.php" method="post" enctype="multipart/form-data">
<h2>OFFER IMG</h2>
<input type="file" name="file">
</br></br>
<input type="submit" value="Upload" >
</form>
</div>
<?php
$upimg=null;
if(isset($_GET['upimg'])){
if ($_GET['upimg']=='' ){
echo "Please Upload New Image";
}
else{
$upimg=$_GET['upimg'];
//scan "uploads" folder and display them accordingly
echo "<img src=\"http://notify/P_Log/".$upimg."\" alt=\"".$upimg."\" >";
}
}
?>
Upload.php
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$folder = "P_Logss";
$results = scandir('images');
unset($results[1]);
$mcount = count($results);
if($mcount <=5){
$mname = "M".$mcount++.'.jpg';
}
else {
$mname = 'M1.jpg';
$mcount++;
}
//$id=uniqid();
$name = $_FILES['file']['name'];
$tmpName = $_FILES['file']['tmp_name'];
$error = $_FILES['file']['error'];
$size = $_FILES['file']['size'];
$ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
switch ($error) {
case UPLOAD_ERR_OK:
$valid = true;
if ( !in_array($ext, array('jpg','jpeg','png','gif')) ) {
$valid = false;
$response = 'Invalid file extension.';
}
if ( $size/2048/2048 > 2 ) {
$valid = false;
$response = 'File size is exceeding maximum allowed size.';
}
if ($valid) {
$targetPath = dirname( __FILE__ ) . DIRECTORY_SEPARATOR. 'P_Logss' . DIRECTORY_SEPARATOR.$name;
$targetPath1 = dirname( __FILE__ ) . DIRECTORY_SEPARATOR. 'images' . DIRECTORY_SEPARATOR. $mname;
$upimg=$name;
move_uploaded_file($_FILES['file']['tmp_name'],$targetPath);
copy($targetPath,$targetPath1);
$targetPath = dirname( __FILE__ ) . DIRECTORY_SEPARATOR. 'images' . DIRECTORY_SEPARATOR. $mname;
header('Location: http://'.$_SERVER['HTTP_HOST'].'/notify/uploadimg.php?upimg='.$upimg);
exit;
}
break;
case UPLOAD_ERR_INI_SIZE:
$response = 'The uploaded file exceeds the upload_max_filesize directive in php.ini.';
break;
case UPLOAD_ERR_PARTIAL:
$response = 'The uploaded file was only partially uploaded.';
break;
case UPLOAD_ERR_NO_FILE:
$response = 'No file was uploaded.';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$response = 'Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3.';
break;
case UPLOAD_ERR_CANT_WRITE:
$response = 'Failed to write file to disk. Introduced in PHP 5.1.0.';
break;
default:
$response = 'Unknown error';
break;
}
echo $response;
}
?>
The problem is how you are getting the image name, when the count is bigger than 5 you always use 'M1.jpg', you need to use the modulus operator:
$mcount = count($results);
$mname = "M".((($count-1) % 5)+1).'.jpg';
In this way if $mcount is <=5 you just get that value, if the count is 6 you get 1, with 7 you get 2 and so on.
Note also that $mcount++ is not needed because you don't have a loop in your code, your code get executed once for each file uploaded and the value is reset in the next execution of the script.
Edit: online example
My assignment is to make a php file for uploading files to a directory. The user should only be able to upload a file if the file size is less than 512kb and the file type is txt, zip or jpg. My code is not working properly as it ignores the output if file is not relevant and it also does not check the file type properly. Can anyone help please?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Files</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="dat">
<input type="submit" value="Upload">
<div>(max. size: 512kb, Type: jpg,txt,zip)</div>
</form>
<?php
if(isset($_FILES["dat"])){
$file=$_FILES["dat"];
$name=$file["name"];
$size=$file["size"];
$location=$file["tmp_name"];
$location_file=$location . basename($name);
if($size>512000 or $location_file!="txt" or $location_file!="zip" or $location_file!="jpg"){
echo "The file is too big or the format is not correct...";
}
else{
move_uploaded_file($location,"files/".$name);
}
}
?>
</body>
</html>
In html side
<input type="file" name="dat" accept=".txt, .zip, .jpg">
In server side :
<?php
$extension = array_pop(explode(".", $_FILES["dat"]["name"])); // return file extension
if(in_array($extension, array("zip", "txt", "jpg"))) // check if extension is valid
{
if($_FILES['dat']['size'] > 512*1024) // check file size is above limit
{
echo "File size above limit";
}
else
{
move_uploaded_file($_FILES['dat']['tmp_name'],"files/".$_FILES['dat']['name']); // moving uploaded file
}
}
else
{
echo "Invalid file type";
}
First try to debug your uploaded file. Secondly don't rely on the name of the file since it can be spoofed easily.
tmp_name gives you the files temporary location, which will be a random string.
Your best option is to call getimagesize on tmp_name, for images, and finfo_open or new finfo for other file types to compare its mime type, you could also explode the name and use end which will give you an extension as well. maybe define an array of accepted extensions and use in_array to check if extension is valid.
Will provide example code after I get to a PC.
LE: as promised a more complex check with comments and security concepts
<?php
// you can make sure you have every variable set
// then procced further
if(
isset(
$_FILES['dat'], $_FILES['dat']['tmp_name'],
$_FILES['dat']['name'], $_FILES['dat']['size'],
$_FILES['dat']['error']
)
){
$accepted = array(
'image/jpeg' => 'jpg',
'text/plain' => 'txt',
'application/zip' => 'zip',
);
$file = $_FILES['dat'];
$maxSize = 512 * 1024; // 512 KB
// check if any upload error occured
if( UPLOAD_ERR_OK !== $file['error'] ){
// http://php.net/manual/en/features.file-upload.errors.php
echo 'Upload error: ', $file['error'], '<br/>';
// check if file size is bigger than $maxSize
} elseif( $file['size'] > $maxSize ){
// if filesize is bigger than upload_max_filesize directive in php.ini
// script may timeout without any error
// post_max_size and upload_max_filesize need to be high enough
echo 'Error: File size is to big!<br/>';
// can proceed further
} else {
// you will need to have the fileinfo enabled in php ini to use these
$finfo = finfo_open( FILEINFO_MIME );
$mime = finfo_file( $finfo, $file['tmp_name'] );
// finfo may give you charset info as well
// text/plain; charset=utf-8 or image/jpeg; charset=binary
$mime = array_shift( explode( ';', $mime ) );
// change uploaded file name do to security reasons
// google "php null char upload"
// nice read http://resources.infosecinstitute.com/null-byte-injection-php/
$filename = md5( time() . $file['name'] ) . '.';
// if mime is accepted
if( ! array_key_exists( $mime, $accepted ) /* or use isset: ! isset( $accepted[ $mime ] ) */ ){
echo 'Error: Unsupported file type!<br/>';
// you could check if file is image and check min-max width & height
// for now move the uploaded file
} elseif( ! #move_uploaded_file( $file['tmp_name'], 'files/' . $filename . $accepted[ $mime ] ) ){
echo 'Unable to save uploaded image to <strong>',
htmlspecialchars( 'files/' . $filename . $accepted[ $mime ] ),
'</strong>';
} else {
echo '<a href="files/', htmlspecialchars( $filename . $accepted[ $mime ] ), '" target="_blank">',
htmlspecialchars( $filename . $accepted[ $mime ] ),
'</a>';
}
}
}
For format you will need to take out the extension from the file name like this:
$explode = explode(".", $name);
$extension = $explode[sizeof($explode)-1]; //return "txt", "zip" or whatever
if(!in_array($extension, ["zip","txt", "jpg", "jpeg"])){
//format error: not in correct format
} else {
//format OK
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['dat']['tmp_name']);
$allowed_mime_types = [
"image/jpg",
"image/jpeg",
"application/zip",
"plain/text"
];
if(!in_array($mime, $allowed_mime_types)){
//error format
} else {
//format OK
}
}
I'm trying to upload multiple files and it uploads them well. But I am also checking for errors (type and size) and catch errors in an array variable. When I select, lets say, 3 images and one of them has some error (more size than allowed and/or type not allowed) and its the first image then the other two images also don't get uploaded. If the file with error is second one then only first one gets uploaded, and when error image is last one the first two get uploaded. What I'm trying to do is even if there is error in one or more images then other valid images should get uploaded no matter the order in which they are selected.
Here is my script:
function filesupload($files) // here files is $_FILES array
{
$i = 0;
$errors = array();
$maxfilesize = 1*1024*1024; // 1 MB
$num = count($files['name']);
$allowed_types = array('image/jpeg', 'image/png');
foreach($files['tmp_name'] as $key=>$tmp_name)
{
$tmpname = $files['tmp_name'][$key]; // file temp name
$fsize = $files['size'][$key]; // file size
if(!empty($files['name'][$key]))
{
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$ftype = finfo_file($finfo, $files['tmp_name'][$key]); // file mime type
}
//validations for file type and size
// no file selected
if(empty($files['name'][$key]))
{
$errors[] = 'Select at least one file for uploading';
}
// file type not allowed
if(in_array($ftype, $allowed_types) === false)
{
$errors[] = 'One or more files have invalid file extension';
}
// file size validation
if($fsize > $maxfilesize)
{
$errors[] = 'Size of one or more files is more than allowed';
}
// if no errors uploaded file(s)
if(empty($errors))
{
$path = 'images/';
$newfilename = time().'_'.rand(100000, 999999).'_'.$files['name'][$key];
$move = move_uploaded_file($tmpname, $path.$newfilename);
if($move)
{
$i = $i + 1;
if($i == $num)
{
$msg = 'Files uploaded';
return $msg;
}
}
}
elseif(!empty($errors))
{
return $errors;
}
}
}
In the loop you have checked $error[]. So when the error is in first file so that array will not be blank and other images will not upload.
Try as below :
function filesupload($files) // here files is $_FILES array
{
$i = 0;
$errors = array();
$maxfilesize = 1*1024*1024; // 1 MB
$num = count($files['name']);
$allowed_types = array('image/jpeg', 'image/png');
foreach($files['tmp_name'] as $key=>$tmp_name)
{
$tmpname = $files['tmp_name'][$key]; // file temp name
$fsize = $files['size'][$key]; // file size
if(!empty($files['name'][$key]))
{
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$ftype = finfo_file($finfo, $files['tmp_name'][$key]); // file mime type
}
//validations for file type and size
// no file selected
if(empty($files['name'][$key]))
{
$errors[$key] = 'Select at least one file for uploading';
}
// file type not allowed
if(in_array($ftype, $allowed_types) === false)
{
$errors[$key] = 'One or more files have invalid file extension';
}
// file size validation
if($fsize > $maxfilesize)
{
$errors[$key] = 'Size of one or more files is more than allowed';
}
// if no errors uploaded file(s)
if(!isset($errors[$key]))
{
$path = 'images/';
$newfilename = time().'_'.rand(100000, 999999).'_'.$files['name'][$key];
$move = move_uploaded_file($tmpname, $path.$newfilename);
if($move)
{
$i = $i + 1;
if($i == $num)
{
$msg = 'Files uploaded';
return $msg;
}
}
}
}
if(!empty($errors))
{
return $errors;
}
}
I have changed error message array from $errors[] to $errors[$key] and checked the same. So if you have 4 file input and 1st and 3rd are having error then 2nd and 4th will upload and you will get error in 0th and 2nd index of array.