I have a simple PHP upload script I have started. I am not the best to PHP. Just looking for some suggestions.
I want to limit my script to only .JPG, .JPEG, .GIF and .PNG
Is this possible?
<?php
/*
Temp Uploader
*/
# vars
$mx=rand();
$advid=$_REQUEST["advid"];
$hash=md5(rand);
# create our temp dir
mkdir("./uploads/tempads/".$advid."/".$mx."/".$hash."/", 0777, true);
# upload dir
$uploaddir = './uploads/tempads/'.$advid.'/'.$mx.'/'.$hash.'/';
$file = $uploaddir . basename($_FILES['file']['name']);
// I was thinking of a large IF STATEMENT HERE ..
# upload the file
if (move_uploaded_file($_FILES['file']['tmp_name'], $file)) {
$result = 1;
} else {
$result = 0;
}
sleep(10);
echo $result;
?>
Yes, quite easily. But first off, you need some extra bits:
// never assume the upload succeeded
if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
die("Upload failed with error code " . $_FILES['file']['error']);
}
$info = getimagesize($_FILES['file']['tmp_name']);
if ($info === FALSE) {
die("Unable to determine image type of uploaded file");
}
if (($info[2] !== IMAGETYPE_GIF) && ($info[2] !== IMAGETYPE_JPEG) && ($info[2] !== IMAGETYPE_PNG)) {
die("Not a gif/jpeg/png");
}
Relevant docs: file upload errors, getimagesize and image constants.
File path isn't necessarily the best way to check if an image really is an image. I could take a malicious javascript file, rename it to have the .jpg extension, and upload it. Now when you try to display it in your website, I may have just compromised your site.
Here is a function to validate it really is an image:
<?php
function isImage($img){
return (bool)getimagesize($img);
}
?>
try this:
<?php
function isimage(){
$type=$_FILES['my-image']['type'];
$extensions=array('image/jpg','image/jpe','image/jpeg','image/jfif','image/png','image/bmp','image/dib','image/gif');
if(in_array($type, $extensions)){
return true;
}
else
{
return false;
}
}
if(isimage()){
//do codes..
}
?>
Or take a look at: http://php.net/manual/en/function.pathinfo.php
if (substr($_FILES["fieldName"]["name"], strlen($_FILES["fieldName"]["name"])-4) == ".jpg")
{
if(move_uploaded_file($_FILES["fieldName"]["tmp_name"],$path."/".$_FILES['fieldName']['name']))
{
echo "image sucessfully uploaded!";
}
}
similarly you can check for other image formats too.
Related
I am a newbie to programming, and this is my first exposure to PHP. I am building a mobile web app where users can upload pictures to the site while at the social event.
I used the PHP script from W3schools (don't hate me please, but it works for my limited knowledge).
Because it is a mobile app I need to add extra functionality but cannot figure out how with the multitude of scripts and my lack of knowledge.
Before the image is uploaded in the script, I would like first do the following.
1) Reduce the dimension to 500px wide and 'auto' the height to retain picture ratio.
2) Compress the file so it is more appropriately filesized for resolution on mobile devices (it will never be printed) and to speed up the upload over cell network.
3) Ensure that the display is correct by way of EXIF data. Right now, iOS, Android and Windows all display portrait and landscape images differently,...I need consistency
Here is my code,...I have remarked where I think it should go but I am not entirely sure.
This code comes up in a pop-up div tag over the page that displays the images.
<?php
$target_dir = "uploads/";
$target_dir = $target_dir . basename( $_FILES["uploadFile"]["name"]);
$target_dir1 = $target_dir . basename( $_FILES["uploadFile"]["tmp_name"]);
$fileTmpLoc = $_FILES["uploadFile"]["tmp_name"];
$uploadOk=1;
// Check if Upload is done without file.
if (!$fileTmpLoc) { // if file not chosen
echo '<script language="javascript">';
echo 'alert("Please browse for a file before clicking the upload button")';
echo '</script>';
echo '<script language="javascript">';
echo 'window.history.back()';
echo '</script>';
}
// Check if file already exists
if (file_exists($target_dir . $_FILES["uploadFile"]["name"])) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}
// Check file size
if ($uploadFile_size > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
//Check no php files
if ($uploadFile_type == "text/php") {
echo "Sorry, no PHP files allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk==0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
//Reduce file to 500px wide
//Compress file
//Rotate file with EXIF data to properly display.
if (move_uploaded_file($_FILES["uploadFile"]["tmp_name"], $target_dir1)) {
echo header( 'Location: gallery.php' ) ;
} else {
echo "Sorry, there was an error uploading your file.";
}
}
?>
Thanks for any help and as mentioned this is my first exposure to PHP.
There is a free utility called SimpleImage.php, available at http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php that will handle resizing and compression and might be a good starting point. There are great examples on their page on how to use it, below is an example of how I use it to resize uploaded images to a certain width:
require_once("SimpleImage.php");
function createThumbnail($cat_code) {
// Check for full size product image
$fname = $this->getImageFilename($cat_code);
if($fname === "") {
echo "<b>createThumbnail: No image file found for " . $cat_code . "!</b><br>";
return false;
}
$thumb = "images/t/" . $cat_code . ".100.jpg";
if($fname !== "") {
$image = new SimpleImage();
$image->load($fname);
$image->resizeToWidth(100);
$image->save($thumb);
}
return true;
}
function process_upload($file, $cat_code, $format, $price=NULL) {
$imageFileExtensions = array('jpg', 'gif', 'png');
$target_path = "uploads/";
$target_path1 = $target_path . basename($file['name']);
$path_info1 = pathinfo($target_path1);
$ext = $path_info1['extension'];
if(move_uploaded_file($file['tmp_name'], $target_path1)) {
if(rename($target_path1, $main_path1)) {
echo "File ". $file['name'] . " verified and uploaded.<br>";
//Create thumbnail if this is an image file
if(in_array($ext, $imageFileExtensions))
$createThumbnail($cat_code);
} else {
echo "<b>ERROR renaming " . $file['name'] . "</b><br>";
}
}
else
echo "<b>move_uploaded_file(" . $file['tmp_name'] . ", $target_path1) failed</b><br>\n";
}
To do a rotate just add another function to the SimpleImage class that uses imagerotate(), for example the following:
function rotate($angle, $bgd_color, $ignore_transparent=0) {
imagerotate($this->image, $angle, $bgd_color, $ignore_transparent);
}
The php.net page for imagerotate has more details on the function parameters.
To work with EXIF data, I use another free utility called PelJpeg.php, available at http://lsolesen.github.io/pel/. There are many examples on how to use this if you google PelJpeg.php. It can get kind of complicated, because as you mention, every platform handles images and meta data a little differently, so you have to do a lot of testing to see what things are handled the same on various platforms, what things are different, and how to bridge across those gaps.
The code below is uploading and displaying files on the upload.php page and it's working fine. The problem I have is that it's not displaying the files if I copy and paste the url of the upload.php page into a new webpage.
upload.php code
<?php
if (isset($_FILES['file_upload'])) {
$file = $_FILES['file_upload'];
$name = $file['name'];
$type = $file['type'];
$tmp_location = $file['tmp_name'];
$upload = 'uploads';
$final_destination = $upload.'/'.$name;
$error = $file['error'];
$max_upload_size = 2097152;
$size = $file['size'];
$allowedImageTypes = array( 'image/png', 'image/jpeg', 'image/gif', );
function imageTypeAllowed($imageType){
global $allowedImageTypes;
if(in_array($imageType, $allowedImageTypes)){
return true;
}
else{
return false;
}
}
//Check for errors
if($error > 0 || is_array($error)){
die("Sorry an error occured");
}
//Check if file is image
//Only required if image is only whjat we need
if(!getimagesize($tmp_location)){
die("Sorry, you can only upload image types");
}
if(!imageTypeAllowed($type)){
die("Sorry, file type is not allowed");
}
if(file_exists($final_destination)){
$final_destination = $upload.'/'.time().$name;
}
if(!move_uploaded_file($tmp_location, $final_destination)){
die("Cannot finish upload, something went wrong");
}
$handle = opendir('uploads');
if($handle){
while(($entry = readdir($handle)) !== false){
if($entry != '.' && $entry != '..'){
echo "$entry<br>";
}
}
closedir($handle);
}
}
?>
<h2>File Successfully uploaded!</h2>
If you indent your code to be human-readable, you'll find that the entire server-side code block is wrapped in this conditional:
if (isset($_FILES['file_upload'])) {
// all of your code
}
This means that all of that server-side code will execute only if a file_upload value is POSTed to the form. When you copy/paste the URL into a new browser window and invoke that request, you're invoking a GET request with no form values. Since you're not uploading a file in this request, the isset() condition evaluates to false and your code isn't executed.
You should separate your functionality into two groups:
Handling the upload.
Displaying the current state of the data.
The code for handling the upload should execute only when an upload is present. The code for displaying the data should execute always.
If I'm reading your code correctly, all you should need to do is split out the last few parts:
if (isset($_FILES['file_upload'])) {
// the rest of your code
}
$handle = opendir('uploads');
if($handle){
while(($entry = readdir($handle)) !== false){
if($entry != '.' && $entry != '..'){
echo "$entry<br>";
}
}
closedir($handle);
}
the following piece of code recognizes the image through getimagesize() but then when i try to move the file to an uploaded folder it moves the file there but says it's an array? im confused because im not setting any variables as an array?
<?php
//simple image check using getimagesize() instead of extensions
if($_FILES){
$empty_check = getimagesize($_FILES['file']['tmp_name']);
if(empty($empty_check)){
echo 'this is not an image';
}
else{
echo 'you have uploaded ' . explode('.',$_FILES['file']['name'])[0].'
and it is a ' . explode('.',$_FILES['file']['name'])[1].'.';
//an example of how i would extract the extension
$target = "C:\\xampp\\htdocs";
move_uploaded_file($_FILES['file']['tmp_name'], $target.'\\'.$_FILES['file']);
}
}
?>
$_FILES['file']
is an array, you're trying to use it as the target filename;
comment of deceze.
Echo the file you want to move/save, then you should see what he mentioned..
When using move_uploaded_file you get to pick the filename, so you can pick anything you want.
When you upload the file, its put into a temporary directory with a temporary name, move_uploaded_file() allows you to move that file and in that you need to set the name of the file as well.
Use this coding for multiple file uploading....
//For Multiple file uploading
if (isset($_FILES['photo']) != "") {
$errors = array();
foreach($_FILES['photo']['tmp_name'] as $key = > $tmp_name) {
$file_name = $_FILES['photo']['name'][$key];
$file_size = $_FILES['photo']['size'][$key];
$file_tmp = $_FILES['photo']['tmp_name'][$key];
$file_type = $_FILES['photo']['type'][$key];
//change the image extension as png
$fileExt = "png";
$photorename[$key] = strtolower($property_code.
'_'.$key.
'.'.$fileExt);
if ($file_size > 2097152) {
$errors[] = 'File size must be less than 2 MB';
}
//Path of Uploading file
$target = "images_property";
if (empty($errors) == true) {
if (is_dir($target) == false) {
mkdir("$target", 0700); // Create directory if it does not exist
}
if (file_exists("$target/".$photorename[$key])) {
unlink("$target/".$photorename[$key]);
}
move_uploaded_file($file_tmp, "$target/".$photorename[$key]);
} else {
print_r($errors);
}
}
if (empty($errors)) {
echo "Success";
}
}
This is a script that Upload a file in all directory. But when i run it, its only upload One time and then fail to upload . whats wrong in this code ?
function read_directory($p_pathname)
{
$d = dir ($p_pathname);
$target = $p_pathname;
if(move_uploaded_file($_FILES['uploaded']['tmp_name'], $target.$_FILES['uploaded']['name']))
{
echo $target. "Done<br>";
}
else
{
echo $target."Sorry<br>";
}
while (($file = $d->read()) !== false)
{
if (($file != ".") and ($file != ".."))
{
$filetype = filetype ("{$d->path}/{$file}");
if ($filetype == "dir")
{
read_directory ("{$d->path}/{$file}");
}
else
{
// echo "\tFILE: {$d->path}/{$file}\n";
}
}
}
$d->close;
}
Use copy() instead of move_uploaded_file(). move_uploaded_file() deletes the source file when it's done, so you can't use it multiple times on the same file. copy() leaves the original file alone, so you can do it as many times as you want.
When the script exits, PHP automatically removes the temp file that was uploaded if it doesn't get moved by the script.
in the first time your moving the file... not copying ... so only next time that file not in the temp directory, so you can't move again..
I am trying out PHP my first actual script, most of it from tutorial :(
Anyway's
I am having a problem on this part
// This is our limit file type condition
if (!($uploaded_type=="text/java")||!($uploaded_type=="file/class")||!($uploaded_type=="file/jar")) {
echo "You may only upload Java files.<br>";
$ok=0;
}
Basically it doesn't allow any files, even those up there
help!
I want the Java files to be allowed only!
EDIT:
Here is the full code
<?php
$target = "upload/";
$target = $target . basename( $_FILES['uploaded']['name']) ;
$uploaded = basename( $_FILES['uploaded']['name']) ;
$ok=1;
//This is our size condition
if ($uploaded_size > 350000) {
echo "Your file is too large.<br>";
$ok=0;
}
// This is our limit file type condition
if (!($uploaded_type=="text/java")||!($uploaded_type=="file/class")||! ($uploaded_type=="file/jar")) {
echo "You may only upload Java files.<br>";
$ok=0;
}
echo $ok; //Here we check that $ok was not set to 0 by an error
if ($ok==0) {
echo "Sorry your file was not uploaded";
}else {
if(move_uploaded_file($_FILES['uploaded']['tmp_name'], $target)) {
echo "The file ". $uploaded ." has been uploaded";
} else {
echo "Sorry, there was a problem uploading your file.";
}
}
?>
You're using an OR... that means the whole statement evaluates as TRUE if ANY of its member arguments are true. Since a file can only be of one type, you're excluding ALL files. What you want is an 'and' match:
if (!($uploaded_type == 'text/java') && !($uploaded_type == ....)) {
^^---boolean and
Pretending that we're working with a file/class file type, then you version reads:
if the (file is not text/java) OR the (file is not file/class) OR the (file is not file/jar)
TRUE FALSE TRUE
TRUE or FALSE or TRUE -> TRUE
Switchign to AND gives you
TRUE and FALSE and TRUE -> FALSE
Only one of your three conditions could possibly be true, so that you end up with:
if (!false || !false || !true)
Which becomes:
if (true || true || false)
So you should either use an && in place of the OR, or use a nicer function to check for multiple things from a set:
if (!in_array($uploaded_type, array("text/java", "file/class","file/jar")) {
So the if will succeed if neither of the allowed values is found.
You can make this more flexible using in_array():
$allowed_types = array("text/java", "file/class", "file/jar");
if(!in_array($uploaded_type, $allowed_types)) {
echo "You're not allowed to upload this kind of file.<br />";
$ok = 0;
}
This makes it very easy to allow more file types later on. If you want to allow "text/html", you just need to add it to the array and do not need to create so many checks. You could even store the allowed types in a config file or a table in a database and create the array $allowed_types dynamically.
For client file format limit, refer to this Limit file format when using ?
<input type="file" accept="image/*" /> <!-- all image types -->
<input type="file" accept="audio/*" /> <!-- all audio types -->
For server, you can filter the uploaded file by this,
if(in_array(mime_type($file_path),$allowed_mime_types)){
// save the file
}
$allowed_mime_types = array(
'image/jpeg',
'image/jpg',
'image/png',
'image/gif',
'video/mp4'
);
/*
For PHP>=5.3.0, you can use php's `finfo_file`([finfo_file](https://www.php.net/manual/en/function.finfo-file.php)) function to get the file infomation about the file.
For PHP<5.3.0, you can use your's system's `file` command to get the file information.
*/
function mime_type($file_path)
{
if (function_exists('finfo_open')) {
$finfo = new finfo(FILEINFO_MIME_TYPE, null);
$mime_type = $finfo->file($file_path);
}
if (!$mime_type && function_exists('passthru') && function_exists('escapeshellarg')) {
ob_start();
passthru(sprintf('file -b --mime %s 2>/dev/null', escapeshellarg($file_path)), $return);
if ($return > 0) {
ob_end_clean();
$mime_type = null;
}
$type = trim(ob_get_clean());
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
$mime_type = null;
}
$mime_type = $match[1];
}
return $mime_type;
}