Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I find it very difficult to comprehend why one of my pages is taking long before displaying its content. The code on the page is as follows.
Please, advise what could be wrong and if the code is secure. If not how to fix it.
<?php
//open database
include("includes/db_connect.php");
//require("includes/mysql_conn.php");
// Check to see if the type of file uploaded is a valid image type .........................
function is_valid_type($file)
{
// This is an array that holds all the valid image MIME types
// These are the same for all file upload boxes
$valid_types = array("image/jpg", "image/jpeg", "image/bmp", "image/gif");
// This is an array that holds all valid image extensions
// These are the same for all file upload boxes
$valid_exts = array('jpg', 'jpeg', 'bmp', 'gif');
// This check is optional
if(!in_array($file['type'], $valid_types))
return 0;
// Get the extension from the uploaded filename
$upload_ext = pathinfo($file['name'], PATHINFO_EXTENSION);
// This check is essential for security
if(!in_array($upload_ext, $valid_exts))
return 0;
return 1;
}
//...................................................................................................
// Just a short function that prints out the contents of an array in a manner that's easy to read
// I used this function during debugging but it serves no purpose at run time for this example
function showContents($array)
{
echo "<pre>";
print_r($array);
echo "</pre>";
}
// Set some constants
// This variable is the path to the image folder where all the images are going to be stored
// Note that there is a trailing forward slash
$TARGET_PATH = "images/";
// Get our POSTed variables
$ctitle = $_POST['ctitle'];
$csubject = $_POST['csubject'];
$creference = $_POST['creference'];
$cyear = $_POST['cyear'];
$cobjecttype = $_POST['cobjecttype'];
$cmaterial = $_POST['cmaterial'];
$ctechnic = $_POST['ctechnic'];
$cwidth = $_POST['cwidth'];
$cheight = $_POST['cheight'];
$cperiod = $_POST['cperiod'];
$cmarkings = $_POST['cmarkings'];
$cdescription = $_POST['cdescription'];
$csource = $_POST['csource'];
$cartist = $_POST['cartist'];
$image = $_FILES['image'];
// Build our target path full string. This is where the file will be moved do
// i.e. images/picture.jpg
$target_path_1 = $TARGET_PATH . $image['name'];
// Sanitize our inputs
$ctitle = mysql_real_escape_string($ctitle);
$csubject= mysql_real_escape_string($csubject);
$creference = mysql_real_escape_string($creference);
$cyear = mysql_real_escape_string($cyear);
$cobjecttype = mysql_real_escape_string($cobjecttype);
$cmaterial = mysql_real_escape_string($cmaterial);
$ctechnic = mysql_real_escape_string($ctechnic);
$cwidth = mysql_real_escape_string($cwidth);
$cheight = mysql_real_escape_string($cheight);
$cperiod = mysql_real_escape_string($cperiod);
$cmarkings = mysql_real_escape_string($cmarkings);
$cdescription = mysql_real_escape_string($cdescription);
$csource = mysql_real_escape_string($csource);
$cartist = mysql_real_escape_string($cartist);
$image['name'] = mysql_real_escape_string($image['name']);
// Make sure all the fields from the form have inputs
if ( $ctitle == "" || $csubject == "" || $creference == "" || $cyear == "" || $cobjecttype == "" || $cmaterial == "" || $ctechnic == "" || $cwidth == "" || $cheight == "" || $cperiod == "" || $cmarkings == "" || $cdescription == "" || $csource == "" || $cartist == "" || $image['name'] == "")
{
echo "All fields are required";
exit;
}
// Check to make sure that our file is actually an image
// You check the file type instead of the extension because the extension can easily be faked
if (!is_valid_type($image))
{
echo "You must upload a jpeg, gif, or bmp";
exit;
}
// Here we check to see if a file with that name already exists
// You could get past filename problems by appending a timestamp to the filename and then continuing
if (file_exists($target_path_1))
{
echo "A file with that name already exists";
exit;
}
// Lets attempt to move the file from its temporary directory to its new home
if (
move_uploaded_file($image['tmp_name'], $target_path_1)
)
{
// NOTE: This is where a lot of people make mistakes.
// We are *not* putting the image into the database; we are putting a reference to the file's location on the server
$sql = "insert into collections (ctitle, csubject, creference, cyear, cobjecttype, cmaterial, ctechnic, cwidth, cheight, cperiod, cmarkings, cdescription, csource, cartist, cfilename) values ('$ctitle', '$csubject', '$creference', '$cyear', '$cobjecttype', '$cmaterial', '$ctechnic', '$cwidth', '$cheight', '$cperiod', '$cmarkings', '$cdescription', '$csource', '$cartist', '" . $image['name'] . "')";
$result = mysql_query($sql) or die ("Could not insert data into DataBase: " . mysql_error());
exit;
}
else
{
// A common cause of file moving failures is because of bad permissions on the directory attempting to be written to
// Make sure you chmod the directory to be writeable
echo "Could not upload file. Check read/write persmissions on the directory";
exit;
}
?>
And my database connection code:
<?php
//set connection variables
$host = "localhost";
$username = "joseph";
$password = "";
$db_name = "collectionsdb"; //database name
//connect to mysql server
$mysqli = new mysqli($host, $username, $password, $db_name);
//check if any connection error was encountered
if(mysqli_connect_errno()) {
echo "Error: Could not connect to database.";
exit;
}
?>
Thanx.
Joseph
Seems fine to me.
There are three stages.
Time to upload the data(depends on filesize and connection speed)
connect to the database(depends on the load on your database server)
and the moving of the file on the server(depends on the load of your server) ...
If you are on a local test system there could be the virus scan interfering as well. First filtering the post data then scanning the file and scanning the file again when moved(yes, they can be pretty paranoid...).
Advice: Put some "print_r(microtime());" in there and take a look.
The code is not necessarily secure. Sql injection is on thing that I is easily spotted. Do not pass the variables into the query string like that. Although you are using mysql_real_escape_string() there are scenarios where this is not adequate.
Please use parametrized queries. Also you should worry about html markup inserted into your db that could be used for XSS.
Another point to keep in mind is the permissions for you upload folder. Make sure you don't have everyone read and write.
Hope it helps.
See my comment for additional info about the root cause of your slow loads.
Related
I am quite new to PHP, but i'm having a problem with my thought process around some code i am writing.
I am trying to get the below to work so that a user can upload two images in a form, which uploads to the server, and updates the field in SQL, but i'm having a hard time working out how to make it so that the SQL field isn't updated unless an image is uploaded - I've managed to make it work with one image using;
$uploadArtwork = $_FILES['asset_name']['tmp_name'];
if($uploadArtwork == null) {
$sql = "";
}
else {
$sql = "";
}
I am struggling to work out, how i can do it for two images (and eventually more than two images?)
Tried a lot of googling, but without much luck yet!
$uploadArtwork1 = $_FILES['asset_name1']['tmp_name'];
$uploadArtwork2 = $_FILES['asset_name2']['tmp_name'];
// Image1 and/or image2 was uploaded successfully
if(($uploadArtwork1 != null) || ($uploadArtwork2 != null)) {
$sql = "";
// No images were selected, or there were problems uploading them
} else {
$sql = "";
}
Though it would be better to check $_FILES['asset_name']['error'] == UPLOAD_ERR_OK to determine if an image was uploaded successfully:
$uploadArtwork1 = $_FILES['asset_name1']['error'];
$uploadArtwork2 = $_FILES['asset_name2']['error'];
// Image1 and/or image2 was uploaded successfully
if(($uploadArtwork1 == UPLOAD_ERR_OK) || ($uploadArtwork2 == UPLOAD_ERR_OK)) {
// Do something with $_FILES['asset_name1']['tmp_name'] and $_FILES['asset_name2']['tmp_name']
$sql = "";
// No images were selected, or there were problems uploading them
} else {
$sql = "";
}
Update:
require_once("Inc/classCloud.php");
$sql = "UPDATE assets SET asset_title='$post_asset_title'";
if ($uploadArtwork != null) {
$getImageID= $res['data'];
$sql .= ", asset_name='$getImageID'";
}
if ($uploadMock != null) {
$getImageID2= $res2['data'];
$sql .= ", product_artwork='$getImageID2'";
}
$sql .= " WHERE asset_id='$post_asset_id'";
Here is a basic structure to work with.
Basically looping through all uploaded files and if they have been found then move them to a new location on the server and write the entry to database.
This code has not been tested.
<?php
// Loops through all possible file uploads.
foreach ($_FILES as $file) {
// Checks a file has been chosen.
if (isset($file['tmp_name']) && !empty($file['tmp_name'])) {
// Checks the uploaded (object) is a file.
if (is_file($file['tmp_name'])) {
// The filepath for the uploaded file.
$destination = 'LOCATION TO MOVE THE UPLOADED FILE TO';
/*
* Perform SQL Write here
*/
if (WRITE WAS SUCCESSFUL) {
// Move FIle
move_uploaded_file($file['tmp_name'], $destination);
}
}
}
}
I'm making a file uploader using PHP and want to restrict it to PDFs and Microsoft Word files. However, it's currently allowing uploads from all file types to the database. How can I restrict it to only allowing PDFs and Microsoft Word files?
Here is my code:
<?php
# Check if a file has been uploaded
if (isset($_FILES['uploaded_file']))
# Make sure the file was sent without errors
if ($_FILES['uploaded_file']['error'] == 0) {
# Connect to the database
$dbLink = mysql_connect("localhost", "root") or die(mysql_error());
mysql_select_db("webproject", $dbLink) or die(mysql_error());
/* if(mysql_connect()) {
die("MySQL connection failed: ". mysql_error());
} */
# Gather all required data
$filename = mysql_real_escape_string($_FILES['uploaded_file']['name']);
$filemime = mysql_real_escape_string($_FILES['uploaded_file']['type'] == "application/pdf" || $_FILES["uploaded_file"]["type"] == "application/msword");
$size = $_FILES['uploaded_file']['size'];
$data = mysql_real_escape_string(file_get_contents($_FILES ['uploaded_file']['tmp_name']));
$subjects = $_POST['subjects'];
$name = $_POST['name'];
$phone = $_POST['phone'];
$email = $_POST['email'];
# Create the SQL query
$query = "
INSERT INTO file(
Filename, Filemime, Filesize, Filedata, subjects, name, email, phone, Created
)
VALUES (
'{$filename}', '{$filemime}', {$size}, '{$data}', '{$subjects}','{$name}','{$email}','{$phone}', NOW()
)";
# Execute the query
$result = mysql_query($query, $dbLink);
# Check if it was successfull
if ($result) {
echo "Success! Your file was successfully added!";
} else {
echo "Error! Failed to insert the file";
echo "<pre>" . mysql_error($dbLink) . "</pre>";
}
} else {
echo "Error!
An error accured while the file was being uploaded.
Error code: " . $_FILES['uploaded_file']['error'];
}
# Close the mysql connection
mysql_close($dbLink);
# Echo a link back to the mail page
echo "<p><a href='index.html'>Click here to go back home page!.</a></p>";
?>
I am not sure how your code actually works, but if you replace your second if at the top by this, the program will run only if the type is pdf or word, other files will cause this error: "Error! An error accured while the file was being uploaded. Error code: ". $_FILES['uploaded_file']['error'];" to occur
if($_FILES['uploaded_file']['error'] == 0 && ($_FILES['uploaded_file']['type']=='application/pdf' || $_FILES['uploaded_file']['type']=='application/msword' || $_FILES["uploaded_file"]["type"] == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'))
Your first if: if (isset($_FILES['uploaded_file'])) has no braces... that's not a very good practice.
Here is a extract from a function I sometimes use:
function CheckFile ($file){
$mimeTypes = array(
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/excel",
"application/vnd.ms-excel",
"application/x-excel",
"application/x-msexcel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
$fileExtensions = array("pdf", "doc", "docx", "xls", "xlsx");
if (in_array($file['type'], $mimeTypes) &&
in_array(end(explode(".", $file["name"])), $fileExtensions)) {
return true;
}
}
Call it with CheckFile($_FILES['uploaded_file']) It will return true if the doc is a pdf word or excel file
Edit:
One way to use it would be like so:
if (!CheckFile($_FILES['uploaded_file'])){
?>
<p>Sorry, your file was not of the correct type</p>
<?php
exit();
}
I want to upload images to mysql server using php.
I have created html and sql connectivity but the image upload shows error.
I cant upload the image, it shows error of valid image i.e. you must upload jpeg,bmp,gif; and read/write in directory.
Can any1 help me solving this problem
the php file is
<?php
//Start session
session_start();
//Array to store validation errors
$errmsg_arr = array();
//Validation error flag
$errflag = false;
// Check to see if the type of file uploaded is a valid image type
function valid($file)
{
// This is an array that holds all the valid image MIME types
$valid_types = array("image/jpg", "image/jpeg", "image/bmp", "image/gif");
//echo $file['type'];
if (in_array($file['type'], $valid_types))
return 1;
return 0;
}
// Build our target path full string. This is where the file will be moved do
// i.e. images/picture.jpg
$TARGET_PATH = "image/";
$TARGET_PATH = $TARGET_PATH . basename( $_FILES['image']['name']);
$pimage = $_FILES['image']['name'];
// Check to make sure that our file is actually an image
// You check the file type instead of the extension because the extension can easily be faked
if (!valid($pimage))
{
$_SESSION['ERRMSG_ARR'] = array('You must upload a jpeg, gif, or bmp');
header("Location: admin.php");
exit;
}
// Here we check to see if a file with that name already exists
// You could get past filename problems by appending a timestamp to the filename and then continuing
if (file_exists($TARGET_PATH))
{
$_SESSION['ERRMSG_ARR'] = array('A file with that name already exists');
header("Location: admin.php");
exit;
}
// Lets attempt to move the file from its temporary directory to its new home
if (move_uploaded_file($_FILES['image']['tmp_name'], $TARGET_PATH))
{
// NOTE: This is where a lot of people make mistakes.
// We are *not* putting the image into the database; we are putting a reference to the file's location on the server
$sql = "insert into people (p_category, p_name, p_quantity, p_desc, p_image) values ('$pcategory', '$pname','$pquantity','pdesc', '" . $pimage['name'] . "')";
$result = mysql_query($sql);
//Check whether the query was successful or not
if($result) {
$_SESSION['ERRMSG_ARR'] = array('Product added');;
$_SESSION['MSG_FLAG'] = 0;
session_write_close();
header("location: admin.php");
exit();
}else {
die("Query failed: ".mysql_error());
}
}
else
{
// A common cause of file moving failures is because of bad permissions on the directory attempting to be written to
// Make sure you chmod the directory to be writeable
$_SESSION['ERRMSG_ARR'] = array('Could not upload file. Check read/write persmissions on the directory');
header("Location: admin.php");
exit;
}
?>
I think
$pimage = $_FILES['image']['name'];
should be
$pimage = $_FILES['image'];
You probably missed this because your code is quite inconsistent - sometimes you use $pimage, while elsewhere you reference the $_FILES array directly. This makes it harder to maintain should the file field's name change. You could also type hint the valid() function to make PHP complain if $file isn't an array:
function valid(array $file) { ... }
What level of error reporting do you have set? It would highlight errors like trying to access undefined array keys.
See you are passing the image type in the line if (!valid($pimage))
But in the valid() function you are again trying to get the type of image $file['type'].
What George said should also work, but since you are making variables for the image type $ptype and name $pimage, you can use them itself.
So the changes should be $file['type'] becomes $file and $file['type'] & in the insert query $pimage['name'] becomes $pimage
I'm sure this solves it, Bahua ;)
I want people to upload photos on my website, and save each photo as a random file name. I created the upload form. and this is the uploading php function:
if($_FILES['myprofilepicture']['type']!='image/jpeg' && $_FILES['photo']['type']!='image/jpg' && $_FILES['photo']['type']!='image/png'){header("location:wrongfile.php");}else{
$info = pathinfo($_FILES['photo']['name']);
$randomfile = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"),0,$length);
$target = 'picture/'.$randomfile; $now=time();
move_uploaded_file( $_FILES['myprofilepicture']['tmp_name'], $target);
mysql_query("Insert into photos(name,photo,date)values('$myname','$randomfile','$now')")or die('database error occured');
header("location:home.php");
the problem is, if there was a picture uploaded with the same filename before, it will get overwritten, I want to improve the code so that
if no photo was uploaded with the same file name before->save photo
if a photo was uploaded with the same file name before->generate another random string and continue this loop until no photo was previously uploaded with the same name and then save the photo
any help?
Use file_exists() function to check if a file exists:
if($_FILES['myprofilepicture']['type'] != 'image/jpeg' &&
$_FILES['photo']['type'] != 'image/jpg' &&
$_FILES['photo']['type'] != 'image/png')
{
header("location: wrongfile.php");
}
else
{
$info = pathinfo($_FILES['photo']['name']);
$randomfile = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"),0,$length);
$target = 'picture/'.$randomfile;
if(!file_exists($target)) //if file doesn't exist
{
$now = time();
move_uploaded_file( $_FILES['myprofilepicture']['tmp_name'], $target);
mysql_query("Insert into photos(name,photo,date)values('$myname','$randomfile','$now')")or die('database error occured');
header("location:home.php");
}
}
The if conditional statement in the above piece of code will check if the file already exists, and if not, execute the statements in the block. However, if you want to repeat the process until a unique file path is found, you can use a loop instead:
while(!file_exists($target))
{
# code ...
}
As a sidenote: you're currently inserting user input directly into your SQL query. This is a very bad practice and it makes your query vulnerable to SQL injection. You should stop using the deprecated mysql_* functions and start using PDO or MySQLi.
I have the following PHP code to display the content of a directory in my website:
<?php
$conn = ftp_connect("host") or die("Could not connect");
ftp_login($conn,"username","password");
if ($_GET['dir'] != null) {
ftp_chdir($conn, "logs/{$_GET['dir']}");
}
else
{
ftp_chdir($conn, "logs");
}
$files = ftp_nlist($conn,"");
foreach($files as $value) {
echo "{$value}";
}
ftp_close($conn);
?>
This is my webpage
When I click on the subdirectory1 or subdirectory2, I get the content of it (some images). Then when I click on one of the images, I get the content of the root directory of my website.
How can I display only the image when a visitor clicks on it? Note that I don't want to download it or anything - I just want to display it in the browser when a visitor clicks on it.
You need to establish which of the returned items are files and which are directories. For that you are better of using ftp_rawlist as it allows to extract more data. Then create links for each case and so you can process them appropriately. Here's a possible implementation:
$ftpHost = 'hostname';
$ftpUser = 'username';
$ftpPass = 'password';
$startDir = 'logs';
if (isset($_GET['file'])) {
// Get file contents (can also be fetched with cURL)
$contents = file_get_contents("ftp://$ftpUser:$ftpPass#$ftpHost/$startDir/" . urldecode($_GET['file']));
// Get mime type (requires PHP 5.3+)
$finfo = new finfo(FILEINFO_MIME);
$mimeType = $finfo->buffer($contents);
// Set content type header and output file
header("Content-type: $mimeType");
echo $contents;
}
else {
$dir = (isset($_GET['dir'])) ? $_GET['dir'] : '';
$conn = ftp_connect($ftpHost) or die("Could not connect");
ftp_login($conn, $ftpUser, $ftpPass);
// change dir to avoid ftp_rawlist bug for directory names with spaces in them
ftp_chdir($conn, "$startDir/$dir");
// fetch the raw list
$list = ftp_rawlist($conn, '');
foreach ($list as $item) {
if(!empty($item)) {
// Split raw result into pieces
$pieces = preg_split("/[\s]+/", $item, 9);
// Get item name
$name = $pieces[8];
// Skip parent and current dots
if ($name == '.' || $name == '..')
continue;
// Is directory
if ($pieces[0]{0} == 'd') {
echo "<a href='?dir={$dir}/{$name}'><strong>{$name}</strong></a><br />";
}
// Is file
else {
echo "<a href='?file={$dir}/{$name}'>{$name}</a><br />";
}
}
}
ftp_close($conn);
}
You'll need to add a function which checks which type of file we're handling.
If it's a directory show the regular link (the one you're using now) and if it's an image
show a link with the path of the image.
Because $value contains the name of the file you can use end(explode('.',$value)); to find the ext. of the file (php , jpg , gif , png).
Use another condition with the piece of information and you can identify if it's a picture or not.
In order to build the path of the image you'll need to use the $_GET['dir'] variable's value.
For instance:
<a href='<?=$_GET['dir']?>/Flower.gif'>Flower.gif</a>
I hope you got the idea.