Issue with image uploading PHP - php

I'm trying to create a form where users can select an image and set their profile picture. After this I want to get this specific information and display it within HTML.
I have the following code inside profile.php;
if(isset($_POST['submit']) ){
$fileName = $_FILES["avatar"]["name"];
$fileTmpLoc = $_FILES["avatar"]["tmp_name"];
$fileType = $_FILES["avatar"]["type"];
$fileSize = $_FILES["avatar"]["size"];
$fileErrorMsg = $_FILES["avatar"]["error"];
$mysql->setUserAvatar($fileName, $fileTmpLoc, $fileType, $fileSize, $fileErrorMsg, $s_email);
}
I have the following code inside mysql.php (this code is inside a class name mysql):
function setUserAvatar($fileName, $fileTmpLoc, $fileType, $fileSize, $fileErrorMsg, $s_email){
$kaboom = explode(".", $fileName);
$fileExt = end($kaboom);
list($width, $height) = getimagesize($fileTmpLoc);
if($width < 10 || $height < 10){
echo "Image is too small";
exit();
}
$db_file_name = rand(100000000000,999999999999) . "." . $fileExt;
echo $db_file_name;
if($fileSize > 1048576) {
echo "Image can't be larger than 1MB";
exit();
} else if (!preg_match("/\.(gif|jpg|png)$/i", $fileName) ) {
echo "The file extension should be .gif, .jpg or .png";
exit();
} else if ($fileErrorMsg == 1) {
echo "An unknown error occurred";
exit();
}
$sql = "SELECT avatar FROM users WHERE email='$s_email' LIMIT 1";
$query = mysqli_query($this->db, $sql);
$row = mysqli_fetch_row($query);
$avatar = $row[0];
if($avatar != ""){
$picurl = "../user/$s_email/$avatar";
if (file_exists($picurl)) { unlink($picurl); }
}
$moveResult = move_uploaded_file($fileTmpLoc, SITE_ROOT . "/../user/$s_email/". $db_file_name);
if ($moveResult != true) {
echo "File upload failed";
exit();
}
$sql = "UPDATE users SET avatar='$db_file_name' WHERE email='$s_email' LIMIT 1";
$query = mysqli_query($this->db, $sql);
}
After this is done, I want to do something like:
<img src="user/" . $s_email . "/" . $data['avatar'] . " />
How ever, when I try to reach the avatar element from the MySQL database, I always get the same number, which is: 2147483647 (but in the user folder everything went right). So there is a problem with the value that is getting inserted into the database. Any suggestions what this problem might be?
EDIT: I've fixed the issue by decreasing the length of the random number. However, the problem is still that the value in the database hasn't receive the extension? The column datatype of avatar is VARCHAR.
It's this line:
$db_file_name = rand(100000,999999) . "." . $fileExt;

Yes, a nice feature of most random number generators is that they produce repeatable results unless you tell them not to.
In the case of PHP you tell it not to start at the same place using srand()

Your number is to big. and not very random.
$db_file_name = rand(100000000000,999999999999)
Your min and max are very close to each other/in wrong order, and to large because the number your getting 2147483647 = 2^30 -1 is most likely the size limit for the type of column input you decided to use for the name.
rand documentation http://php.net/manual/en/function.rand.php
Change your column type to something like varchar(40)
I'd also recommend not using random numbers greater than php's signed 32 bit integer rand(0,2147483647);

Related

Orient image according to EXIF orientation before upload with PHP

I know that this topic is probably easy for most of you but i've been fighting over this for the last 2 days without any progress.
I'm doing a web app for myself, no security needed as it is non production intended.
Following scripts work fine, the problem remains when i upload picture directly from camera using:
<input
id="photoBox"
type="file"
class="form-control-file"
accept="image/*"
capture="camera"
name="photo"/>
When i upload from browser everything works fine, however from smartphone the server does not respect EXIF orientation therefore images are wrongly rotated.
As per upload i am using the following script: (pastebin provided as well).
https://pastebin.com/mvgah9Ud
function photoPlant($pID){
// db
include "includes/dbConfig.php";
// init
$out = null;
// gen hash
$varA = microtime();
$varB = time();
$varC = $varA . $varB;
$hash = md5($varC);
// prepare upload
$currentDir = getcwd();
$uploadDirectory = "/gallery/";
$errors = []; // Store all foreseen and unforseen errors here
$fileExtensions = ['jpeg','jpg','png', '']; // Get all the file
extensions, including empty for mobile
// reformat empty file extension
if ($fileExtension === ""){
$fileExtension = "jpg";
}
$fileName = $_FILES['photo']['name'];
$fileTmpName = $_FILES['photo']['tmp_name'];
$fileSize = $_FILES['photo']['size'];
$fileType = $_FILES['photo']['type'];
$fileExtension = strtolower(end(explode('.',$fileName)));
// reformat filename
$fileName = $hash . "." . $fileExtension;
$uploadPath = $currentDir . $uploadDirectory . basename($fileName);
if (! in_array($fileExtension,$fileExtensions)) {
$errors[] = "This file extension is not allowed. Please upload a
JPEG or PNG file";
}
if ($fileSize > 8000000) {
$errors[] = "This file is more than 8MB. Sorry, it has to be less
than or equal to 8MB";
}
if (empty($errors)) {
$didUpload = move_uploaded_file($fileTmpName, $uploadPath);
if ($didUpload) {
$out .= "ok"; // everything is ok give feedback ok
} else {
$out .= "An error occurred somewhere. Try again or contact the
admin";
}
} else {
foreach ($errors as $error) {
$out .= $error . "These are the errors" . "\n";
}
}
// store img on db
// prepare data
$timeStamp = time();
// query
$query = mysqli_query($con, "INSERT INTO photo_table
(photo_parent_id, photo_name, photo_timestamp) VALUES ($pID,
'$fileName', $timeStamp)");
// run query
if (!$query){
$out = mysqli_error($con);
}
// return
return $out;
}
My intentions are clear. Rotate img BEFORE upload according to EXIF orientation and then proceed to store it on the disk.
If possible i intend to do it in the very same photoPlant(arg) function.
Thanks.
Well. After a few unexplained downvotes and a very useful comment from DinoCoderSaurus this is the answer i was looking for.
I had to install and enable Imagick for PHP7.
It was not a plain simple job but there are a few guides available to google. Depending on your version / os installation notes are different so proceed with care.
My upload function (from original post) changed on the upload part.
Where it says:
if (empty($errors)){
// old code here.
}
It was changed for the following validation:
if (empty($errors)) {
// this is my new validation code.
$img = new Imagick($fileTmpName);
$orient = $img->getImageOrientation();
if($orient === 6){
// we need to rotate it 90deg
$img->rotateImage("rgba(255, 255, 255, 0.0)", 90);
}
if ($orient === 3){
// we need to rotate it 180deg
$img->rotateImage("rgba(255, 255, 255, 0.0)", 180);
}
// Note that imagick does the storage for me as well!
$img->writeImage("gallery/" . $fileName);
}
else{
$out .= "Errors on upload";
}
This fixed ALL of my issues with a reasonably good response time.
Hopefully some newbies like me will take some skill profit from this post.
As a farewell note i need to add... If you downvote a post, comment the reason why you did that, because this topic was already discussed here countless times, but after 2 days researching on SO old posts i didn't manage to find WHY it was not working!
A special thanks to DinoCoderSaurus who sent me in the right direction with around 10 words.

value recorded in the database differs from the value of the variable

I am trying to save a file in php, and the name of the file is being changed using the date, time and a random number. The same name of the file is being recorded in a database, however the name of the record in the database differs always of a few digits from the one being generated and used for the file upload. It looks like when the operation of uploading of the file occurs, the random number is being regenerated...:( but a that should be happening.
<?php
$id = intval($_REQUEST['id']);
include 'conn.php';
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
$today = date('y-m-j');
$time1 = date('H-i', time()); // 12:50:29
$temp = mt_rand ( 0 , 200 );
$newfilename = $today.'_'.$temp.'_'.$time1.'.zip'; //generates a random name based on time for the
$DBnewfilename="http://localhost/purchasesystem/uploads/".$newfilename;
$sql = "update PURCHASE_REQUESTS set URL='$DBnewfilename' where id=$id";
$result = #mysql_query($sql);
if(move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], "uploads/".$newfilename)){
echo "The file ". basename($_FILES["fileToUpload"]["name"]). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
the database record URL is set as TEXT (however I have tried also varchar with no results) :(
thanks a lot for any advise you could possibly give me.
Kele

Any way to generate random file name when uploading?

I have created a website that uploads anything. The problem I have is that I'm new to all this. I have tried every code that generates random strings but I have nothing. Here is the code anyway:
<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
echo "ERROR: Please browse for a file before clicking the upload button.";
exit();
}
if(move_uploaded_file($fileTmpLoc, "uploads/$fileName")) {
echo '<a href="uploads/'.$fileName.'"><input type="button" class="button"
value="Download" /></a>';
} else {
echo "move_uploaded_file function failed";
}
?>
Could there be a way to generate random file names so that when someone uploads the same name as a file already on the server, it does not overwrite the existing file?
$fileName = "image_".uniqid();
The uniqid() function generates a unique ID based on the microtime
(current time in microseconds).
About uniqid function: http://www.php.net/manual/en/function.uniqid.php
You can use md5(microtime()) to get unique file name even you uploading more than one file at a time
you can use microtime time to make sure file name is unique.
$file_name = "custom_name_" . microtime();
Because a folder is limited to 65535 files, you need to create subfolders. This technique creates 3 subfolders (with 3 characters each) depending on the timestamp then creates a random filename.
For more randomness and future-proofness (because using time() and microtime() is weak if you have multiple users uploading at the same time) :
//Get the extension of the file
$fileExtension = end(explode(".", $_FILES['item']['name']));
$randOctalName = openssl_random_pseudo_bytes(5);
$randName = bin2hex($randOctalName).".".$fileExtension;
//Save it into uploads/123/456/789/
$path = "";
$timestamp = time();
$path = substr($timestamp,0,3)."/".substr($timestamp,3,3)."/".substr($timestamp,6,3)."/";
$relativePath = './uploads/'.$path;$timestamp = time();
$path = substr($timestamp,0,3)."/".ubstr($timestamp,3,3)."/".substr($timestamp,6,3)."/";
$relativePath = './uploads/'.$path;
_r_mkdir($relativePath);
And the mkdir recursive function :
private function _r_mkdir($path, $mode = 0755, $recursive = true)
{
if(empty($path)){
return false;
}
if($recursive) {
$toDo = substr($path, 0, strrpos($path, '/'));
if($toDo !== '.' && $toDo !== '..'){
_r_mkdir($toDo, $mode);
}
}
if(!is_dir($path)){
mkdir($path, $mode);
}
return true;
}
use the timestamp (or microtime), so you know it is necessarily different every time
$fileName = "image_".time();
TimeStamp
Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).
Microtime
microtime() returns the current Unix timestamp with microseconds. This function is only available on operating systems that support the gettimeofday() system call.
//you can use both random and time function to get more unique no count:
$fileName = 'mypic'.mt_rand(100000, 999999).'_'.time(). $_FILES["file1"]["name"];
use are:-
mt_rand(100000, 999999)// for randm no.
time()// for timestring
$_FILES["file1"]["name"]//also you can give your file name
Study this code thoroughly. This is all you need.
<?php
if (isset($_FILES["avatar"]["name"]) && $_FILES["avatar"]["tmp_name"] != "")
{
$fileName = $_FILES["avatar"]["name"];
$fileTmpLoc = $_FILES["avatar"]["tmp_name"];
$fileType = $_FILES["avatar"]["type"];
$fileSize = $_FILES["avatar"]["size"];
$fileError = $_FILES["avatar"]["error"];
$kaboom = explode(".",$fileName);
$fileExt = end($kaboom);
list($width,$height) = getimagesize($fileTmpLoc);
if($width < 10 || $height < 10)
{
header("location: ../message.php?msg=ERROR: That image has no dimensions");
exit();
}
$db_file_name = rand(100000000000,999999999999).".".$fileExt;
if($fileSize > 5048576)
{
header("location: ../message.php?msg=ERROR: Your image file was larger than 1mb");
exit();
}
else if (!preg_match("/\.(gif|jpg|png)$/i", $fileName) )
{
header("location: ../message.php?msg=ERROR: Your image file was not jpg, gif or png type");
exit();
}
else if ($fileErrorMsg == 1)
{
header("location: ../message.php?msg=ERROR: An unknown error occurred");
exit();
}
$sql = "SELECT avatar FROM users WHERE username='$log_username' LIMIT 1";
$query = mysqli_query($db_conx,$sql);
$row = mysqli_fetch_row($query);
$avatar = $row[0];
if($avatar != "")
{
$picurl = "../user/$log_username/$avatar";
if (file_exists($picurl))
unlink($picurl);
}
$moveResult = move_uploaded_file($fileTmpLoc,"../user/$log_username/$db_file_name");
if ($moveResult != true)
{
header("location: ../message.php?msg=ERROR: File upload failed");
exit();
}
include_once("../php_includes/image_resize.php");
$target_file = "../user/$log_username/$db_file_name";
$resized_file = "../user/$log_username/$db_file_name";
$wmax = 200;
$hmax = 300;
img_resize($target_file, $resized_file, $wmax, $hmax, $fileExt);
$sql = "UPDATE users SET avatar='$db_file_name' WHERE username='$log_username' LIMIT 1";
$query = mysqli_query($db_conx, $sql);
mysqli_close($db_conx);
header("location: ../user.php?u=$log_username");
exit();
}
?>
try this
$now=date('d/m/y');
if(move_uploaded_file($fileTmpLoc, "uploads/$now.$fileName"))
it will add date infront of the filename

Fileupload — Add random name and set max-size, how to do it?

Hi,
Today I have a file upload script.
The problem is that it does not rename file names, and has a maximum file upload size.
How can I add this to my current script?
$Filename=$_POST['Filename'];
$Name=$_POST['Name'];
$pic=($_FILES['Filename']['name']);
if (isset($_POST['save']) && !empty($_POST['Name']) && !empty($_POST['Category']) && !empty($_POST['Time'])){
$sql = "INSERT INTO View SET MergeID='{$_GET['id']}', Name='{$_POST['Name']}', Category='{$_POST['Category']}', Media='$pic', Time='{$_POST['Time']}'";
mysql_query($sql) or die(mysql_error());
GetFileUpload();
}
function GetFileUpload() {
if (file_exists("Media/" . $_FILES["Filename"]["name"])) {
echo $_FILES["Filename"]["name"] . " file already exist ";
} else {
move_uploaded_file($_FILES["Filename"]["tmp_name"], "Media/" . $_FILES["Filename"]["name"]);
// echo "File: ". basename( $_FILES['Filename']['name']). " has been created.";
}
}
if ($_FILES["Filename"]["size"] < 2000000)
{
if ($_FILES["Filename"]["error"] > 0)
{
echo "Return Code: " . $_FILES["Filename"]["error"] . "<br>";
}
else
{
$rand =rand(1000,9999);
$fname=$rand."-".$_FILES["Filename"]["name"];
move_uploaded_file($_FILES["Filename"]["tmp_name"], "Media/" .$rand );
}
For Ramdon name you can use timestamp along with the filename that will make it unique
use the DateTime() function of php.
If you are not using any framework you can set the fileupload limit from php.ini file
or use this
// You should also check filesize here.
if ($_FILES['upfile']['size'] > 1000000) {
throw new RuntimeException('Exceeded filesize limit.');
}
reference http://www.php.net/manual/en/features.file-upload.php
$_FILES['Filename']['size'] will return you the size of the file in bytes, make a check on it accordingly to your maximum allowed size.
As for the renaming file, I use this piece of function:
function rename_file($file_to_rename)
{
$actual_name = pathinfo($file_to_rename,PATHINFO_FILENAME);
$original_name = $actual_name;
$extension = pathinfo($file_to_rename, PATHINFO_EXTENSION);
$name = $actual_name.".".$extension;
$i = 1;
while(file_exists("Media/".$actual_name.".".$extension))
{
$actual_name = (string)$original_name.'_'.$i;
$name = $actual_name.".".$extension;
$i++;
}
return $name; //For example, if file name is 1.jpg, this returns 1.jpg if that file doesn't exist else keeps incrementing like 1_1.jpg, 1_2.jpg etc.
}
function GetFileUpload($new_name) {
move_uploaded_file($_FILES["Filename"]["tmp_name"], "Media/" . $new_name);
// echo "File: ". basename( $_FILES['Filename']['name']). " has been created.";
}
$new_file_name = rename_file($_FILES['Filename']['name']);
GetFileUpload($new_file_name);
Edited:
Your GetFileUpload changed to match with the rename_file function.

Photo Upload getimagesize() warning - filename cannot be empty

I've run into a conundrum and was wondering if anyone might be able to give me a straight answer. So I built a photo upload script using PHP/MySQL. Within the script photos are re-sized and given a temporary name while being uploaded. I tested it using several pictures (file size 220 KB | 960 x 720) and everything was working just fine. Then I attempted to upload several pictures from my digital camera (file size 2.47 MB | 3000 x 4000) and all of a sudden I got this error:
Warning: getimagesize() [function.getimagesize]: Filename cannot be empty in /php_parsers/photo_system.php on line 94
Warning: Cannot modify header information - headers already sent by (output started at /php_parsers/photo_system.php:94) in /php_parsers/photo_system.php on line 96
I checked stackoverflow for a post with a similar issue and came upon one however it didn't seem to apply to the scenario I'm experiencing.
Here is the applicable code for "photo_system.php". I have commented the offending lines 94 and 96. Any help/ideas you could give would be greatly appreciated!
<?php
if (isset($_FILES["photo"]["name"]) && isset($_POST["gallery"])){
$sql = "SELECT COUNT(id) FROM photos WHERE user='$log_username'";
$query = mysqli_query($db_conx, $sql);
$row = mysqli_fetch_row($query);
if($row[0] > 79){
header("location: ../message.php?msg=The system allows only 80 pictures total");
exit();
}
$gallery = preg_replace('#[^a-z 0-9,]#i', '', $_POST["gallery"]);
$fileName = $_FILES["photo"]["name"];
$fileTmpLoc = $_FILES["photo"]["tmp_name"];
$fileType = $_FILES["photo"]["type"];
$fileSize = $_FILES["photo"]["size"];
$fileErrorMsg = $_FILES["photo"]["error"];
$kaboom = explode(".", $fileName);
$fileExt = end($kaboom);
$db_file_name = date("DMjGisY")."".rand(1000,9999).".".$fileExt; // WedFeb272120452013RAND.jpg
list($width, $height) = getimagesize($fileTmpLoc); //Offending Line 94
if($width < 10 || $height < 10){
header("location: ../message.php?msg=ERROR: That image has no dimensions"); //Offending Line 96
exit();
}
if($fileSize > 4194304) {
header("location: ../message.php?msg=ERROR: Your image file was larger than 4mb");
exit();
} else if (!preg_match("/\.(gif|jpg|png)$/i", $fileName) ) {
header("location: ../message.php?msg=ERROR: Your image file was not jpg, gif or png type");
exit();
} else if ($fileErrorMsg == 1) {
header("location: ../message.php?msg=ERROR: An unknown error occurred");
exit();
}
$moveResult = move_uploaded_file($fileTmpLoc, "../user/$log_username/$db_file_name");
if ($moveResult != true) {
header("location: ../message.php?msg=ERROR: File upload failed");
exit();
}
include_once("../php_includes/image_resize.php");
$wmax = 800;
$hmax = 600;
if($width > $wmax || $height > $hmax){
$target_file = "../user/$log_username/$db_file_name";
$resized_file = "../user/$log_username/$db_file_name";
img_resize($target_file, $resized_file, $wmax, $hmax, $fileExt);
}
$sql = "INSERT INTO photos(user, gallery, filename, uploaddate) VALUES ('$log_username','$gallery','$db_file_name',now())";
$query = mysqli_query($db_conx, $sql);
mysqli_close($db_conx);
header("location: ../photos.php?u=$log_username");
exit();
}
?><?php
if (isset($_POST["delete"]) && $_POST["id"] != ""){
$id = preg_replace('#[^0-9]#', '', $_POST["id"]);
$query = mysqli_query($db_conx, "SELECT user, filename FROM photos WHERE id='$id' LIMIT 1");
$row = mysqli_fetch_row($query);
$user = $row[0];
$filename = $row[1];
if($user == $log_username){
$picurl = "../user/$log_username/$filename";
if (file_exists($picurl)) {
unlink($picurl);
$sql = "DELETE FROM photos WHERE id='$id' LIMIT 1";
$query = mysqli_query($db_conx, $sql);
}
}
mysqli_close($db_conx);
echo "deleted_ok";
exit();
}
?>
OK everyone. I figured out what the issue was. Hopefully this will help someone in the future. So I checked my phpinfo() and found that upload_max_filesize was only set to 2M. I added php.ini to the directory of the offending file and included:
upload_max_filesize = 250M
post_max_size = 250M
max_execution_time = 300
date.timezone = "America/Los_Angeles"
I had to add the date.timezone because my system didn't like the fact that I didn't have it defined. Anyway this has resolved the issue.

Categories