i'm using this code to upload and attach an image through a form, and send it to a mail (as html not as smtp).
once i enter this (the code) page in the web, i can see the output just fine, i can click the "choose file" and choose a file from some directory.
but, i can see as well right away when enterind the page the echo "invalid file" probably because an image didn't upload yet by me, but the code runs and not waiting for me to choose something.
am i missing some triger that will submit my choise and than send it?
when configuring it to be sent as an html like i did, does $mail->Send() is enough and when the code reaches to that command the mail with the attach will be sent?? or i need some other triger to send it?
thank you,
<?php
include_once("functions.php");
// Process
$action = isset($_POST["action"]) ? $_POST["action"] : "";
if (empty($action))
{
$output = "<form action='#'>
<h1>header: </h1>
<label for='image'>upload: </label>
<input type='file' id='image' name='image' maxlength=50 >";
}
echo $output;
$image = $_POST["image"];
uploadImage($image);
require("class.phpmailer.php");
$Email_to = "some#gmail.com"; // the one that recieves the email
$email_from = "someone#someone.net";
$dir = "uploads/$filename";
chmod("uploads",0777);
function uploadImage($image){
if ((($_FILES["image"]["type"] == "image/gif")
|| ($_FILES["image"]["type"] == "image/jpeg")
|| ($_FILES["image"]["type"] == "image/pjpeg")
|| ($_FILES["image"]["type"] == "image/jpg")
|| ($_FILES["image"]["type"] == "image/png"))
&& ($_FILES["image"]["size"] < 2097152)
&& (strlen($_FILES["image"]["name"]) < 51)){
if ($_FILES["image"]["error"] > 0){
echo "Return Code: " . $_FILES["image"]["error"];
}
else{
echo "Upload: " . $_FILES["image"]["name"] . "<br />";
echo "Type: " . $_FILES["image"]["type"] . "<br />";
echo "Size: " . ($_FILES["image"]["size"] / 1024) . " Kb<br />";
echo "Temp file: " . $_FILES["image"]["tmp_name"] . "<br />";
if (file_exists("images/" . $_FILES["image"]["name"])){
echo $_FILES["image"]["name"] . " already exists. ";
}
else{
move_uploaded_file($_FILES["image"]["tmp_name"],
"images/" . $_FILES["image"]["name"]);
}
}
}else{
echo "Invalid file";
}
$filename = $_FILES["image"]["type"];
$dir = "uploads/$filename";
chmod("uploads",0777);
$success = copy($_FILES[images][tmp_name], $dir);
if ($success) {
echo " Files Uploaded Successfully<BR>";
SendIt();
}
}
function SendIt() {
//
global $attachments,$Email_to,$Email_msg,$email_subject,$email_from;
//
$mail = new PHPMailer();
//$mail->IsSMTP();// send via SMTP
//$mail->Host = "localhost"; // SMTP servers
//$mail->SMTPAuth = false; // turn on/off SMTP authentication
$mail->From = $email_from;
$mail->AddAddress($Email_to);
$mail->AddReplyTo($email_from);
$mail->WordWrap = 50;// set word wrap
//now Attach all files submitted
$mail->AddAttachment("uploads"."/".$_FILES["image"]["type"]);
//
$mail->IsHTML(true);// send as HTML
if(!$mail->Send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
exit;
}
}
?>
You should only be firing the uploadImage function when there IS an $action:
...previous code...
if (empty($action))
{
?>
<form action=''>
<h1>header: </h1>
<label for='image'>upload: </label>
<input type='file' id='image' name='image' maxlength=50 >
</form>
<?php
exit; // stop the upload script running
}
$image = $_POST["image"];
uploadImage($image);
require("class.phpmailer.php");
... rest of the code ...
Related
By way of partial explanation, my mind-set is strongly procedural, since I've been programming that way since the 60s
I'm working in PHP and trying to get my head around form handling starting with an interactive 404 error form. What I want in minimal pseudo-code is:
do {
OK = true;
display_form;
ask for optional name
ask for optional email address
ask for optional comments
on – submit{
sanitise input
validate input (which could be no input since all is optional)
if one or more inputs invalid set OK = false
}
} while (OK == false)
assemble email to webmaster using $_SERVER superglobals as well as input
send using mail function
Someone "helpfully" added curlies after the while AND at the end -- they really don't belong there -- the idea was that I wanted execution to "drop through" to those two statements only after the DO -- WHILE completed
The mail assembly could be in a separate file, or not
While this is a semi-specific problem, I'm working on the assumption that, if I can get this to work, then getting a database update working will be easier.
It seems to me that my whole conceptual algorithm is incorrect, and until I sort that I'm nowhere. I've been banging at this for a a couple of days – Google pointed at a number of semi-relevant answers here, so I'm giving it a go. The W3C examples clearly show the response code running even when there are problems with the input, which is not what I want.
The main switch you need to make here is probably the one to a request-response model of execution. You can't do a literal do..while, since you will need to send a response back to the client. The next iteration of that will be triggered by a new request to PHP, which begins again from the beginning and doesn't remember any previous state.
So, in pseudo code, it works like this:
if is POST request:
validate input, populate error variables
if input is valid:
send email with data
redirect to different page or display "thanks"
form start
for $field in fields:
output HTML for $field
maybe highlight if error
maybe set value to POSTed value to retain data
form end
So, upon the first page visit, it won't be a POST request and falls straight through to the form part. There won't be any errors or existing data, so the plain form will be output. When the form is submitted, the same code runs again and now enters the if is POST branch. If any values are invalid, it will fall through to the form again, which now can also output any error messages and existing submitted values. Only when all values are valid, will the server send an email and exit this "loop" by redirecting to another page, or maybe just outputting a "Thank you" note.
If you properly separate that into an MVC architecture, you'd have these components:
Model
data validation
email sending
View
outputs the form HTML
Controller
one for handling GET requests, just invoking the view
one for handling POST requests, essentially doing:
errors = model.validate(data)
if no errors:
model.send_email(data)
redirect()
else:
view.display_form(data, errors)
some form of router invoking the right controller based on the request URL and method
These could all be separate functions, or classes, or methods, or just files.
Below is the final code for the page. It's a basic 404 error page that may be of use to someone. And it should answer the requests that I supply the code that I was working with
It includes three files that I've not supplied:
top.php and footer.php and functions.php
top produces the HTML head statements including meta codes and also including top level banners and menu, as well as establishing the basic page format.
footer-- using the server superglobal just before the footer include, the page can provide a code update date for the page. And a consistent name and registration number for our organisation
functions.php supplies a bunch of reused functions. There are a couple of little (fairly obvious) functions in used in this code:
spacer outputs code to create an empty cell in a table.
spanCol creates a column spanning cell in a table, with the specified text and
specified tag open and close
The full page is at http://www.vfmc.org.au/notfound.php -- please don't send me too much junk email.
Code for the guts is here - I don't claim that it's brilliant, but it works thanks to help from here:
<?php
$pageTitle = "File Not Found";
$authorName = "Don Gingrich";
$styleSheet = "./css/mainstyle.css";
include_once 'top.php';
require_once "functions.php";
$indicesServer = array(
'PHP_SELF',
'HTTP_REFERER',
'SCRIPT_FILENAME',
'SCRIPT_NAME',
'REQUEST_URI',
'ORIG_PATH_INFO'
);
if (isset($_SERVER['HTTP_REFERER'])) {
$refering = $_SERVER['HTTP_REFERER'];
} else {
$refering = NULL;
}
$requested = $_SERVER['REQUEST_URI'];
// $refering = $_SERVER['HTTP_REFERER'];
if ($refering == NULL || $refering == " ") {
$refering = "referrer field was blank\n - may be due to mis-typing address\n";
}
/* basic "sanitise input" function */
function test_input($data)
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
function send_webmaster_email($name, $email, $comment, $requested, $refering)
{
global $sent;
$subject = "File not Found: $requested";
$txt = "Trying to access $requested from $refering\n" . "Visitor comments follow:\n" . $comment;
if ($name != "") {
$txt .= "\n\tReporting person's name is: $name\n";
}
if ($email != "") {
$txt .= "\n\tReporting person's email is: $email\n";
}
$to = "webmaster#vfmc.org.au";
$additional_headers = "From: webmaster#vfmc.org.au\r\n";
mail($to, $subject, $txt, $additional_headers);
$sent = true;
}
// define variables and set to empty values
$nameErr = $emailErr = "";
$name = $email = $comment = "";
$myError = false;
global $sent;
$sent = false;
/********************************************************
* Processing code follows -- Only executed after POST
*
*******************************************************/
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$requested = $_POST['requested'];
$refering = $_POST['refering'];
$requested = test_input($requested);
$refering = test_input($refering);
$myError = false;
if ($_POST["button"] == "Submit") {
if (empty($_POST["name"])) {
$name = "";
} else {
$name = test_input($_POST["name"]);
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z -]*$/", $name)) {
$myError = true;
$nameErr = "Only letters, hyphen, and white space allowed";
}
}
if (empty($_POST["email"])) {
$email = "";
} else {
$email = test_input($_POST["email"]);
// check if e-mail address is well-formed
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$myError = true;
$emailErr = "Invalid email format";
}
}
if (empty($_POST["comments"])) {
$comment = "";
} else {
$comment = test_input($_POST["comments"]);
}
if ($myError == false) {
send_webmaster_email($name, $email, $comment, $requested, $refering);
}
}
}
echo "\n";
echo "<h2>File Not Found</h2>\n";
echo "<br>\n";
echo "<br>\n";
if ($sent == true ){
echo "<h5>Email sent to Webmaster, Thank you</h5>\n";
echo "<br>Use the menu to the left or the back button<br>\n";
echo "to return to the VFMC site<br>\n";
} else {
echo " Unfortunately the file that you have asked for is unavailable.\n";
echo "<br>\n";
echo "<br>\n";
echo "This may mean that the Webmaster has forgotten to load it or the link to it is broken in some way.<br>\n";
echo "Or, if you typed a page in the browser address bar, you may have mis-typed, remember that everything<br>\n";
echo "after the <b>www.vfmc.org.au/</b> is CaSeSensitive -- FiresideFiddlers, is spelled as written.<br>\n";
echo " <br>\n";
echo " <br>\n";
echo "<h6>Please tell the webmaster by sending a message:</h6>\n";
echo " <br>\n";
echo " <br>\n";
$myFile = htmlspecialchars($_SERVER['PHP_SELF']);
echo " <form action= \"$myFile\" method=\"post\">\n";
echo "<input type=\"hidden\" name=\"refering\" value=\"$refering\" />\n";
echo "<input type=\"hidden\" name=\"requested\" value=\"$requested\" />\n";
echo " <table border=\"0\" cellpadding=\"8\" cellspacing=\"8\">\n";
echo " <colgroup>\n";
echo " <col width = auto>\n";
echo " <col width = auto>\n";
echo " <col width = auto>\n";
echo " </colgroup>\n";
echo " <tr>\n";
spanCol("3", "Your name and email address are optional,<br> but the webmaster will be unable to respond <br>directly without them", "h5");
echo " <tr>\n";
echo " <td><label for=\"tswname\">Name</label>:</td>\n";
echo " <td><input type=\"text\" name=\"name\" id=\"tswname\" size=\"25\" /></td>\n";
echo " <td>\t";
if ($nameErr == "") {
echo "(Optional)\n";
} else {
echo "<span class=\"error\">*" . $nameErr . "</span>\n";
}
echo "</td></tr>\n";
echo " <tr>\n";
echo " <td>\n";
echo " <label for=\"tswemail\">Email address</label>:</td>\n";
echo " <td>\n";
echo " <input type=\"text\" id=\"tswemail\" name=\"email\" size=\"25\" />\n";
echo " </td>\n";
echo " <td>\n";
if ($emailErr == "") {
echo "(Optional)\n";
} else {
echo "<span class=\"error\">*" . $emailErr . "</span>\n";
}
echo "</td></tr>\n";
echo " <tr>\n";
echo " <td>\n";
echo " <label for=\"tswcomments\">Comments</label></td>\n";
echo " <td colspan=\"2\">\n";
echo " <textarea rows=\"15\" cols=\"45\" name=\"comments\" id=\"tswcomments\"></textarea>\n";
echo " </td>\n";
echo " </tr>\n";
echo " <tr>\n";
echo " <td align=\"center\" colspan=\"2\">\n";
echo " <input type=\"submit\" name=\"button\" value=\"Submit\" /><br>\n";
echo " </td>\n";
echo " </tr>\n";
echo " </table>\n";
echo " </form>\n";
}
echo " <br>\n";
echo " <br>\n";
echo " <br>\n";
echo " <br>\n";
echo "</td>\n";
echo "</tr>\n";
$filename = $_SERVER['SCRIPT_NAME'];
require_once "footer-code.php";
?>
</tbody>
</table> <!--PWK-EDIT END FOOTER-->
</body>
</html>
I've never touched PHP, but was tasked with fixing an Intern's code..
I am trying to attach a file being uploaded to an email that I am sending. The email sends, but without the file. I am using PHPMailerAutoUpload.php (found on GitHub).
Here's the code I am using.
The attachment is being saved via move_uploaded_file
move_uploaded_file( $resume['tmp_name'] , $up_dir .basename( $random_var . '_wse_' . $resume['name'] ) )
Note: I have commented out the move_uploaded_file function to make sure I wasn't getting rid of the attachment.
require_once('phpmailer/PHPMailerAutoload.php');
$mail = new PHPMailer(true);
$mail->IsSMTP();
$mail->SMTPDebug = 2;
$mail->SMTPAuth = false;
$mail->Host = 'oursmtp';
$mail->Port = 25;
$mail->setFrom( $_POST['E-mail'] , $_POST['first_name'] . " " . $_POST['last_name'] );
$mail->addAddress( 'test#test.com' );
$mail->Subject = "Test" . #date('M/D/Y');
$mail->msgHTML($msgDoc);
if (isset($_FILES['uploaded_file']) &&
$_FILES['uploaded_file']['error'] == UPLOAD_ERR_OK) {
$mail->AddAttachment($_FILES['uploaded_file']['tmp_name'],
$_FILES['uploaded_file']['name']);
}
if (!$mail->send()) {
$mailError = $mail->ErrorInfo;
$outcomeArr = array(
'outcome'=>'failure',
'message'=>'Error' . $mailError
);
echo json_encode( $outcomeArr );
exit();
} else {
// success
$outcomeArr = array(
'outcome'=>'success',
'message'=>'Thank you'
);
echo json_encode( $outcomeArr );
}
From what I have read, $_FILES is a temporary storage for uploaded files in PHP. With this code, the email sends, but with no attachment (only a link to the uploaded file location).
I tried following this, but it isn't working for me.
Your intern was apparently a rockstar that had no need to check for or indicate error conditions, and then mail will send even if there's no attachment or if there was an error during the upload. Change these bits to the code to tell you why the file wasn't attached:
if (isset($_FILES['uploaded_file']) && $_FILES['uploaded_file']['error'] == UPLOAD_ERR_OK) {
if( ! $mail->AddAttachment($_FILES['uploaded_file']['tmp_name'], $_FILES['uploaded_file']['name']) ) {
echo 'Error adding attachment: ' . $mail->ErrorInfo;
}
} else if( !isset($_FILES['uploaded_file']) ) {
echo 'No uploaded file found';
} else {
echo 'Uploaded file error: ' . $_FILES['uploaded_file']['error'];
}
Hi i am new to PHP and MySql and I'm facing one problem:
I am having a page that allows users to upload an image and some details like their name and their email address to my database but the code that i have used is not working.
In fact, it is not adding data to my database but the image is being uploaded.
I also want to ask that is there any way to make all the form fields compulsory for users to fill in the form.
The html form is as below:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div id="content"><br><div align="center">
<form enctype="multipart/form-data" action="upload1.php" method="POST">
Your Full Name: <input type="text" name="name" maxlength="40"><br>
Your Image Please: <input type="file" name="photo"><br>
<input type="submit" value="Upload!">
</form>
</div>
</body>
</html>
And this is the code of upload1.php:
<?php
// random 4 digit to add to our file name
// some people use date and time in stead of random digit
$random_digit=rand(00000000000000,99999999999999);
//combine random digit to you file name to create new file name
//use dot (.) to combile these two variables
$new_file_name=$random_digit.$file_name;
//This is the directory where images will be saved
$target = "g/".$new_file_name;
$target = $target . basename( $_FILES['photo']['name']);
//This is our size condition
if ($photo_size > 350000)
{
echo "Your file is too large.<br>";
$ok=0;
}
if (!($uploaded_type=="image/gif")) {
$ok=0;
}
if (!($uploaded_type=="image/jpg")) {
$ok=0;
}
if (!($uploaded_type=="image/png")) {
$ok=0;
}
if (!($uploaded_type=="image/bmp")) {
$ok=0;
}
if (!($uploaded_type=="image/jpeg")) {
$ok=0;
}
if ($ok=0)
{
Echo "Sorry your file was not uploaded";
}
else
{
//This gets all the other information from the form
$name=$_POST['name'];
$email=$_POST['email'];
$pic=($_FILES['photo']['name']);
$banner="/$target";
$url="xxxxxxxxxx";
$clicks='0';
// Connects to your Database
mysql_connect("xxxxxxxxxxx", "xxxxxxxxxxx", "xxxxxxxxx") or die(mysql_error()) ;
mysql_select_db("xxxxxxx") or die(mysql_error()) ;
//Writes the information to the database
mysql_query("INSERT INTO girls (name, banner, clicks, url, email) VALUES ('{$name}','{$banner}','{$clicks}','{$url}','{$email}') ");
//Writes the photo to the server
if(move_uploaded_file($_FILES['photo']['tmp_name'], $target))
{
//Tells you if its all ok
echo " The file has been uploaded and renamed to '$target' your information has also been added to the database.<br>To view your image online visit www.facesnap.tk/$target ";
}
else {
//Gives and error if its not
echo "Sorry, there was a problem in your upload. Be sure that you follow instructions.";
}
}
?>
You have to put '' only in varchars not in int values, if '{$clicks}' is an int in your database try remove the ''.
To make fields required now, do this in your upload1.php script:
session_start();
//connect to db
$errors = array();
//validate name
if (!isset($_POST['name']) || empty($_POST['name'])) {
$errors[] = 'Your name is required.';
}
else {
$name = mysql_real_escape_string(trim($_POST['name']));
}
//validate email
if (!isset($_POST['email']) || empty($_POST['email'])) {
$errors[] = 'Your email is required.';
}
else {
$email = mysql_real_escape_string(trim($_POST['email']));
$regex = '/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,4})$/';
//change the 128 to your email field length in your db
if (preg_match($regex, $email) && strlen($email) <= 128) {
$email = strtolower($email);
}
else {
$errors[] = 'Your email is not valid.';
}
}
//validate the file upload
if (!isset($_FILES['photo']) || empty($_FILES['photo'])) {
$errors[] = 'Your photo is required.';
}
else if ($_FILES['logo']['name'] == '') {
$errors[] = 'Your photo is required.';
}
else if (!file_exists($_FILES['photo']['tmp_name']) || !is_uploaded_file($_FILES['photo']['tmp_name'])) {
$errors[] = 'The file could not be uploaded, please try again later.';
}
else {
//validate the extention with your function is_img_ext()
if (is_img_ext($_FILES['photo']['name'])) {
$errors[] = 'The file you uploaded is not an image.';
}
//validate image size
if ($_FILES['photo']['size'] > 350000) {
$errors[] = 'The image you uploaded is too large.';
}
//if no errors and the file not exist move it to the target dir
if (empty($errors)) {
//generate a new filename for the image
$random_digit=rand(00000000000000,99999999999999);
$new_file_name = $random_digit.$file_name;
$target = "g/".$new_file_name;
$target = $target . basename( $_FILES['photo']['name']);
if (move_uploaded_file($_FILES['photo']['tmp_name'], $target)) {
echo " The file has been uploaded and renamed to '$target' your information has also been added to the database.<br>To view your image online visit www.facesnap.tk/$target ";
}
else {
echo "Sorry, there was a problem in your upload. Be sure that you follow instructions.";
}
}
}
if(!empty($errors)) {
$_SESSION['form_error'] = $errors;
header('Location: your_form.php');
die();
}
//your rest script
.....
function is_img_ext($filename) {
$ext = explode('.', $filename);
$ext = strtolower(end($ext));
if ($ext == jpeg || $ext == jpg || $ext == png || $ext == gif || $ext == bmp) {
return true;
}
else {
return false;
}
}
In your_form.php now:
session_start();
if (isset($_SESSION['form_error'])) {
$errors = $_SESSION['form_error'];
unset($_SESSION['form_error']);
}
echo '<ul>';
foreach($errors as $error) {
echo '<li>' . $error . '</li>';
}
echo '</ul>';
//your form here
My form has a input file type field.
<input type="file" name="file" size="80" value="">
when submitted and this field is empty the file upload part of my php script should be skipped. This does not seem to be happening. What I am getting is the wrong file type message popping. Nothing was populated in the field on the form so why is my if/else statement not being followed? What am I doing wrong?
<?php
// connect to datebase
require "master.db.php";
// this if(empty statement is not working?
// should be checking to see if the form field 'file' is populated if so check file
// type if not skip and update sql database with information in form field 'test'
if(!empty($_FILES))
{
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 2097152))
{
// code here works - function is to upload the file - not part of my current problem
}
// currently this else statement is displayed regardless of 'file' input
// wrong function for its intended purpose
else
{
// wrong file type
echo "Invalid file <br />";
echo "Tryed to upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb Max 2Mb <br />";
echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
die;
}
}
else
{
// update other data in mysql database
$sql="UPDATE `characters` SET test='$test' WHERE ID='$id'";
$result=mysql_query($sql);
// if successfully updated mysql.
if($result){
echo "<b>Update successful</b> <br />";
echo "<a href='test.html'>View result</a>";
touch('master.html');
clearstatcache();
}
else
{
echo "Whoops: " . mysql_error(); ;
}
mysql_close();
}
?>
The browser will still send the input value, even though the value is empty. As a consequence, PHP will populate the $_FILES array with something like:
Array
(
[file] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)
)
So instead of checking with isset/empty, I guess you should use PHP's native is_uploaded_file method. See this SO post for more info on checking if an optional file input was provided.
I'll try to clarify my answer. The reference I just gave suggests using file_exists and is_uploaded_file. According to the PHP manual only using is_uploaded_file is sufficient. In fact, I can imagine is_uploaded_file looks up the file anyway (so internally already does something like file_exists).
Please note that you really should use the tmp_name-key instead of the name-key. The 'name' key specifies the name of the file on the client's PC, but the tmp_name specifies the name on the server. There are situations when the server renames the file and therefore differs from the name on the users PC.
please be sure to add
enctype="multipart/form-data"
attribute in you form tag . and follow #Martijn guidelines
check the below code, it must work. be sure to customize .
<?php
// connect to datebase
require "master.db.php";
// this if(empty statement is not working?
// should be checking to see if the form field 'file' is populated if so check file
// type if not skip and update sql database with information in form field 'test'
if(!empty($_FILES)) // MEANS form is valid ( have valid file and other data)
{
$sql="UPDATE `characters` SET test='$test' WHERE ID='$id'";
$result=mysql_query($sql);
if (((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 2097152)) && $result ))
{
// code you need to execute
echo "<b>Update successful</b> <br />";
echo "<a href='test.html'>View result</a>";
touch('master.html');
clearstatcache();
}
else
{
// wrong file type
echo "Invalid file <br />";
echo "Tryed to upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb Max 2Mb <br />";
echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
die;
}
}
else
{
echo "data is not valid";
}
?>
Hopefully someone here might have an answer to my question.
I have a basic form that contains simple fields, like name, number, email address etc and 1 file upload field.
I am trying to add some validation into my script that detects if the file is too large and then rejects the user back to the form to select/upload a smaller file.
My problem is, if a user selects a file that is bigger than my validation file size rule and larger than php.ini POST_MAX_SIZE/UPLOAD_MAX_FILESIZE and pushes submit, then PHP seems to try process the form only to fail on the POST_MAX_SIZE settings and then clears the entire $_POST array and returns nothing back to the form.
Is there a way around this? Surely if someone uploads something > than the max size configured in the php.ini then you can still get the rest of the $_POST data???
Here is my code.
<?php
function validEmail($email)
{
$isValid = true;
$atIndex = strrpos($email, "#");
if (is_bool($atIndex) && !$atIndex)
{
$isValid = false;
} else {
$domain = substr($email, $atIndex+1);
$local = substr($email, 0, $atIndex);
$localLen = strlen($local);
$domainLen = strlen($domain);
if ($localLen < 1 || $localLen > 64)
{
// local part length exceeded
$isValid = false;
}
else if ($domainLen < 1 || $domainLen > 255)
{
// domain part length exceeded
$isValid = false;
}
else if ($local[0] == '.' || $local[$localLen-1] == '.')
{
// local part starts or ends with '.'
$isValid = false;
}
else if (preg_match('/\\.\\./', $local))
{
// local part has two consecutive dots
$isValid = false;
}
else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
{
// character not valid in domain part
$isValid = false;
}
else if (preg_match('/\\.\\./', $domain))
{
// domain part has two consecutive dots
$isValid = false;
}
else if
(!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\","",$local)))
{
// character not valid in local part unless
// local part is quoted
if (!preg_match('/^"(\\\\"|[^"])+"$/', str_replace("\\\\","",$local)))
{
$isValid = false;
}
}
}
return $isValid;
}
//setup post variables
#$name = htmlspecialchars(trim($_REQUEST['name']));
#$emailCheck = htmlspecialchars(trim($_REQUEST['email']));
#$organisation = htmlspecialchars(trim($_REQUEST['organisation']));
#$title = htmlspecialchars(trim($_REQUEST['title']));
#$phone = htmlspecialchars(trim($_REQUEST['phone']));
#$location = htmlspecialchars(trim($_REQUEST['location']));
#$description = htmlspecialchars(trim($_REQUEST['description']));
#$fileError = 0;
#$phoneError = "";
//setup file upload handler
$target_path = 'uploads/';
$filename = basename( #$_FILES['uploadedfile']['name']);
$max_size = 8000000; // maximum file size (8mb in bytes) NB: php.ini max filesize upload is 10MB on test environment.
$allowed_filetypes = Array(".pdf", ".doc", ".zip", ".txt", ".xls", ".docx", ".csv", ".rtf"); //put extensions in here that should be uploaded only.
$ext = substr($filename, strpos($filename,'.'), strlen($filename)-1); // Get the extension from the filename.
if(!is_writable($target_path)) die('You cannot upload to the specified directory, please CHMOD it to 777.'); //Check if we can upload to the specified upload folder.
//display form function
function displayForm($name, $emailCheck, $organisation, $phone, $title, $location, $description, $phoneError, $allowed_filetypes, $ext, $filename, $fileError)
{
//make $emailCheck global so function can get value from global scope.
global $emailCheck;
global $max_size;
echo '<form action="geodetic_form.php" method="post" name="contact" id="contact" enctype="multipart/form-data">'."\n".
'<fieldset>'."\n".'<div>'."\n";
//name
echo '<label for="name"><span class="mandatory">*</span>Your name:</label>'."\n".
'<input type="text" name="name" id="name" class="inputText required" value="'. $name .'" />'."\n";
//check if name field is filled out
if (isset($_REQUEST['submit']) && empty($name))
{
echo '<label for="name" class="error">Please enter your name.</label>'."\n";
}
echo '</div>'."\n". '<div>'."\n";
//Email
echo '<label for="email"><span class="mandatory">*</span>Your email:</label>'."\n".
'<input type="text" name="email" id="email" class="inputText required email" value="'. $emailCheck .'" />'."\n";
// check if email field is filled out and proper format
if (isset($_REQUEST['submit']) && validEmail($emailCheck) == false)
{
echo '<label for="email" class="error">Invalid email address entered.</label>'."\n";
}
echo '</div>'."\n". '<div>'."\n";
//organisation
echo '<label for="phone">Organisation:</label>'."\n".
'<input type="text" name="organisation" id="organisation" class="inputText" value="'. $organisation .'" />'."\n";
echo '</div>'."\n". '</fieldset>'."\n".'<fieldset>'. "\n" . '<div>'."\n";
//title
echo '<label for="phone">Title:</label>'."\n".
'<input type="text" name="title" id="title" class="inputText" value="'. $title .'" />'."\n";
echo '</div>'."\n". '</fieldset>'."\n".'<fieldset>'. "\n" . '<div>'."\n";
//phone
echo '<label for="phone"><span class="mandatory">*</span>Phone <br /><span class="small">(include area code)</span>:</label>'."\n".
'<input type="text" name="phone" id="phone" class="inputText required" value="'. $phone .'" />'."\n";
// check if phone field is filled out that it has numbers and not characters
if (isset($_REQUEST['submit']) && $phoneError == "true" && empty($phone)) echo '<label for="email" class="error">Please enter a valid phone number.</label>'."\n";
echo '</div>'."\n". '</fieldset>'."\n".'<fieldset>'. "\n" . '<div>'."\n";
//Location
echo '<label class="location" for="location"><span class="mandatory">*</span>Location:</label>'."\n".
'<textarea name="location" id="location" class="required">'. $location .'</textarea>'."\n";
//check if message field is filled out
if (isset($_REQUEST['submit']) && empty($_REQUEST['location'])) echo '<label for="location" class="error">This field is required.</label>'."\n";
echo '</div>'."\n". '</fieldset>'."\n".'<fieldset>'. "\n" . '<div>'."\n";
//description
echo '<label class="description" for="description">Description:</label>'."\n".
'<textarea name="description" id="queryComments">'. $description .'</textarea>'."\n";
echo '</div>'."\n". '</fieldset>'."\n".'<fieldset>'. "\n" . '<div>'."\n";
//file upload
echo '<label class="uploadedfile" for="uploadedfile">File:</label>'."\n".
'<input type="file" name="uploadedfile" id="uploadedfile" value="'. $filename .'" />'."\n";
// Check if the filetype is allowed, if not DIE and inform the user.
switch ($fileError)
{
case "1":
echo '<label for="uploadedfile" class="error">The file you attempted to upload is not allowed.</label>';
break;
case "2":
echo '<label for="uploadedfile" class="error">The file you attempted to upload is too large.</label>';
break;
}
echo '</div>'."\n". '</fieldset>';
//end of form
echo '<div class="submit"><input type="submit" name="submit" value="Submit" id="submit" /></div>'.
'<div class="clear"><p><br /></p></div>';
} //end function
//setup error validations
if (isset($_REQUEST['submit']) && !empty($_REQUEST['phone']) && !is_numeric($_REQUEST['phone'])) $phoneError = "true";
if (isset($_REQUEST['submit']) && $_FILES['uploadedfile']['error'] != 4 && !in_array($ext, $allowed_filetypes)) $fileError = 1;
if (isset($_REQUEST['submit']) && $_FILES["uploadedfile"]["size"] > $max_size) $fileError = 2; echo "this condition " . $fileError;
$POST_MAX_SIZE = ini_get('post_max_size');
$mul = substr($POST_MAX_SIZE, -1);
$mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1)));
if ($_SERVER['CONTENT_LENGTH'] > $mul*(int)$POST_MAX_SIZE && $POST_MAX_SIZE) echo "too big!!";
echo $POST_MAX_SIZE;
if(empty($name) || empty($phone) || empty($location) || validEmail($emailCheck) == false || $phoneError == "true" || $fileError != 0)
{
displayForm($name, $emailCheck, $organisation, $phone, $title, $location, $description, $phoneError, $allowed_filetypes, $ext, $filename, $fileError);
echo $fileError;
echo "max size is: " .$max_size;
echo "and file size is: " . $_FILES["uploadedfile"]["size"];
exit;
} else {
//copy file from temp to upload directory
$path_of_uploaded_file = $target_path . $filename;
$tmp_path = $_FILES["uploadedfile"]["tmp_name"];
echo $tmp_path;
echo "and file size is: " . filesize($_FILES["uploadedfile"]["tmp_name"]);
exit;
if(is_uploaded_file($tmp_path))
{
if(!copy($tmp_path,$path_of_uploaded_file))
{
echo 'error while copying the uploaded file';
}
}
//test debug stuff
echo "sending email...";
exit;
}
?>
PHP is returning this error in the log:
[29-Apr-2010 10:32:47] PHP Warning: POST Content-Length of 57885895 bytes exceeds the limit of 10485760 bytes in Unknown on line 0
Excuse all the debug stuff :)
FTR, I am running PHP 5.1.2 on IIS.
PHP throws all the POST data away because there was no room to put it. There is nothing reliable to be had from only part of the data.
I would work around this problem by uploading the necessary files in a separate step, a different form. You can store the values already obtained in session, ensuring they are not lost because of excessive POST data.
Erisco is right, this will need to be broken down into multiple steps. I do not believe, however, that there is any need to expose this back-end delineation to the user, so I would recommend one of the following courses of action:
Break the file upload into a separate <form> element. When the submit action is taken on either form, cancel the default action, and instead do one of the two things:
Submit the regular form data via AJAX, and when that is complete submit the uploaded file via the standard process (involving the page reloading and what-not)
Check out this example of iFrame trickery to upload the file first, ensure it is not too large, and prevent the page from even reloading if it would not otherwise pass. If the file does pass, store its identifier in a hidden input element and submit the form normally. Take whatever action is appropriate if the file does not upload correctly. Note that this solution does not require you to use the PHP session, just a little bit of response trickery.
You might try seeing if you can read anything from php://input or php://stdin after you find the _POST array has been nuked. You may be able to retrieve the POST data from there and process it manually, but the manual also says that this will not work for //input if your form is using enctype=multipart/form-data
"Try moving the file field to the
bottom of the form and see what
happens. – Marc B"
Unfortunately the same happens: the $_POST array is cleared.
So the iFrame trickery seems to be one of the best solutions. Thanks for that, Dereleased!
one of the tricks is to use something like this:
$lE = error_get_last();
if ( !empty($lE) && strpos($lE['message'] , 'POST Content-Length' ) !== false)
{
die ('Naughty naughty. you can only upload xxxxx bytes');
}