vinpkl
August 17, 2013, 2:51pm
1
hi
I have a form in which the “ADD attachment” field is optional.
I m sending this form information to email with file attachment as optional
if i dont upload/ attach any file then i get these below errors
vineet
Warning: fopen() [function.fopen]: Filename cannot be empty
Warning: fread() expects parameter 1 to be resource, boolean given
Warning: fclose() expects parameter 1 to be resource, boolean given
this is the script
<?php
if(isset ($_POST["send"]))
{
$upload_name=$_FILES["upload"]["name"];
$upload_type=$_FILES["upload"]["type"];
$upload_size=$_FILES["upload"]["size"];
$upload_temp=$_FILES["upload"]["tmp_name"];
$name=$_POST["name"];
$message=$_POST["msg"];
$subject = $_POST["subject"];
$to="me@gmail.com";
if($message==""||$subject==""||$name=="")
{
echo '<font style="font-family:Verdana, Arial; font-size:11px; color:#F3363F; font-weight:bold">Please fill name,subject,message</font>';
}
else
{
$fp = fopen($upload_temp, "rb");
$file = fread($fp, $upload_size);
$file = chunk_split(base64_encode($file));
$num = md5(time());
// Attachment headers
$headers .= "Content-Type:".$upload_type." ";
$headers .= "name=\\"".$upload_name."\\"r\
";
$headers .= "Content-Transfer-Encoding: base64\\r\
";
$headers .= "Content-Disposition: attachment; ";
$headers .= "filename=\\"".$upload_name."\\"\\r\
\
";
$headers .= "".$file."\\r\
";
$headers .= "--".$num."--";
// SEND MAIL
@mail($to, $subject, $message, $headers);
fclose($fp);
echo '<font style="font-family:Verdana, Arial; font-size:11px; color:#333333; font-weight:bold">Mail sent please check inbox and spam both <br /></font>';
}
}
?>
<form id="attach" name="attach" method="post" action="<?php echo $_SERVER["PHP_SELF"]; ?>" enctype="multipart/form-data">
Name : <input type="text" name="name" id="name"><br>
Subject : <input type="text" name="subject" id="subject"><br>
Message : <input type="text" name="msg" id="msg"><br>
File Attach : <input type="file" name="upload" id="upload"> (Optional)<br>
<input type="submit" value="Submit" id="send" name="send">
</form>
All you need to do is some simple variable tracking to see if the file input has been used, see the below. Also I strongly recommend you steer clear of using the suppressor @ character as you should be catching errors instead of suppressing them.
if (isset($_POST['send'])) {
$headers = '';
$name = $_POST['name'];
$message = $_POST['msg'];
$subject = $_POST['subject'];
$to = 'me@gmail.com';
if ($message === '' || $subject === '' || $name === '') {
echo '<font style="font-family:Verdana, Arial; font-size:11px; color:#F3363F; font-weight:bold">Please fill name,subject,message</font>';
} else {
if (isset($_FILES['upload'])) {
$upload_name = $_FILES['upload']['name'];
$upload_type = $_FILES['upload']['type'];
$upload_size = $_FILES['upload']['size'];
$upload_temp = $_FILES['upload']['tmp_name'];
$fp = fopen($upload_temp, "rb");
$file = fread($fp, $upload_size);
$file = chunk_split(base64_encode($file));
$num = md5(time());
// Attachment headers
$headers .= "Content-Type: " . $upload_type . " name=\\"" . $upload_name . "\\"r\
";
$headers .= "Content-Transfer-Encoding: base64\\r\
";
$headers .= "Content-Disposition: attachment;";
$headers .= "filename=\\"" . $upload_name . "\\"\\r\
\
";
$headers .= "" . $file . "\\r\
";
$headers .= "--" . $num . "--";
fclose($fp);
}
echo '<font style="font-family:Verdana, Arial;font-size:11px; color:#333333; font-weight:bold">';
// Send mail
try {
mail($to, $subject, $message, $headers);
echo 'Mail sent please check inbox and spam both';
} catch(Exception $e) {
echo 'An error occurred while trying to send the email: ' . $e->getMessage();
}
echo '<br /></font>';
}
}
chris_upjohn:
Also I strongly recommend you steer clear of using the suppressor @ character as you should be catching errors instead of suppressing them.
// [...]
// Send mail
try {
mail($to, $subject, $message, $headers);
echo 'Mail sent please check inbox and spam both';
} catch(Exception $e) {
echo 'An error occurred while trying to send the email: ' . $e->getMessage();
}
echo '<br /></font>';
}
}
You can’t do this in PHP, the mail function doesn’t raise an exception, this is like most of the procedural functions in PHP. Instead, @ error suppression should be used combined with the result of the function:
$success = @mail($to, $subject, $message, $headers);
if ($success) {
echo 'Mail sent please check inbox and spam both';
} else {
echo 'An error occurred while trying to send the email';
}
How very true, I’ve been working in C# for too long. In any case though you should never suppress errors as on production servers they should be invisible to users anyway hence on development machines you should see them.
vinpkl
August 18, 2013, 4:08am
5
hi Chris
thanks for the reply.
I tried your code but i am getting the same 3 errors again
vineet
chris_upjohn:
All you need to do is some simple variable tracking to see if the file input has been used, see the below. Also I strongly recommend you steer clear of using the suppressor @ character as you should be catching errors instead of suppressing them.
if (isset($_POST['send'])) {
$headers = '';
$name = $_POST['name'];
$message = $_POST['msg'];
$subject = $_POST['subject'];
$to = 'me@gmail.com';
if ($message === '' || $subject === '' || $name === '') {
echo '<font style="font-family:Verdana, Arial; font-size:11px; color:#F3363F; font-weight:bold">Please fill name,subject,message</font>';
} else {
if (isset($_FILES['upload'])) {
$upload_name = $_FILES['upload']['name'];
$upload_type = $_FILES['upload']['type'];
$upload_size = $_FILES['upload']['size'];
$upload_temp = $_FILES['upload']['tmp_name'];
$fp = fopen($upload_temp, "rb");
$file = fread($fp, $upload_size);
$file = chunk_split(base64_encode($file));
$num = md5(time());
// Attachment headers
$headers .= "Content-Type: " . $upload_type . " name=\\"" . $upload_name . "\\"r\
";
$headers .= "Content-Transfer-Encoding: base64\\r\
";
$headers .= "Content-Disposition: attachment;";
$headers .= "filename=\\"" . $upload_name . "\\"\\r\
\
";
$headers .= "" . $file . "\\r\
";
$headers .= "--" . $num . "--";
fclose($fp);
}
echo '<font style="font-family:Verdana, Arial;font-size:11px; color:#333333; font-weight:bold">';
// Send mail
try {
mail($to, $subject, $message, $headers);
echo 'Mail sent please check inbox and spam both';
} catch(Exception $e) {
echo 'An error occurred while trying to send the email: ' . $e->getMessage();
}
echo '<br /></font>';
}
}
Try the following, instead of fopen it uses file_get_contents which should always work.
if (isset($_POST['send'])) {
$headers = '';
$name = $_POST['name'];
$message = $_POST['msg'];
$subject = $_POST['subject'];
$to = 'me@gmail.com';
if ($message === '' || $subject === '' || $name === '') {
echo '<font style="font-family:Verdana, Arial; font-size:11px; color:#F3363F; font-weight:bold">Please fill name,subject,message</font>';
} else {
if (isset($_FILES['upload'])) {
$upload_name = $_FILES['upload']['name'];
$upload_type = $_FILES['upload']['type'];
$upload_size = $_FILES['upload']['size'];
$upload_temp = $_FILES['upload']['tmp_name'];
// Get the file contents
$file = chunk_split(base64_encode(file_get_contents($upload_temp)));
$num = md5(uniqid(time()));
// Attachment headers
$headers .= "Content-Type: application/octet-stream; name=\\"" . $upload_name . "\\"\\r\
";
$headers .= "Content-Transfer-Encoding: base64\\r\
";
$headers .= "Content-Disposition: attachment; filename=\\"" . $upload_name . "\\"\\r\
\\r\
";
$headers .= $file . "\\r\
";
$headers .= "--" . $num . "--";
}
$email_success = mail($to, $subject, $message, $headers);
echo '<font style="font-family:Verdana, Arial;font-size:11px; color:#333333; font-weight:bold">';
if ($email_success) {
echo 'Mail sent please check inbox and spam both';
} else {
echo 'An error occurred while trying to send the email';
}
echo '<br /></font>';
}
}
vinpkl
August 18, 2013, 4:52am
7
hi
thanks for the reply.
With your new code, This time i m getting this below error
Warning: file_get_contents() [function.file-get-contents]: Filename cannot be empty
vineet
chris_upjohn:
Try the following, instead of fopen it uses file_get_contents which should always work.
if (isset($_POST['send'])) {
$headers = '';
$name = $_POST['name'];
$message = $_POST['msg'];
$subject = $_POST['subject'];
$to = 'me@gmail.com';
if ($message === '' || $subject === '' || $name === '') {
echo '<font style="font-family:Verdana, Arial; font-size:11px; color:#F3363F; font-weight:bold">Please fill name,subject,message</font>';
} else {
if (isset($_FILES['upload'])) {
$upload_name = $_FILES['upload']['name'];
$upload_type = $_FILES['upload']['type'];
$upload_size = $_FILES['upload']['size'];
$upload_temp = $_FILES['upload']['tmp_name'];
// Get the file contents
$file = chunk_split(base64_encode(file_get_contents($upload_temp)));
$num = md5(uniqid(time()));
// Attachment headers
$headers .= "Content-Type: application/octet-stream; name=\\"" . $upload_name . "\\"\\r\
";
$headers .= "Content-Transfer-Encoding: base64\\r\
";
$headers .= "Content-Disposition: attachment; filename=\\"" . $upload_name . "\\"\\r\
\\r\
";
$headers .= $file . "\\r\
";
$headers .= "--" . $num . "--";
}
$email_success = mail($to, $subject, $message, $headers);
echo '<font style="font-family:Verdana, Arial;font-size:11px; color:#333333; font-weight:bold">';
if ($email_success) {
echo 'Mail sent please check inbox and spam both';
} else {
echo 'An error occurred while trying to send the email';
}
echo '<br /></font>';
}
}
Ok, try changing the following
if (isset($_FILES['upload'])) {
to
if (isset($_FILES['upload']) && !empty($_FILES['upload']['name'])) {
vinpkl
August 18, 2013, 6:30am
9
hi Chris
Thanks for the reply
This solution worked PERFECTLY FINE with both options “fopen” and “file_get_contents”.
But can you suggest me which one is better and which one should i use.
“fopen” OR “file_get_contents”
thanks
vineet
chris_upjohn:
Ok, try changing the following
if (isset($_FILES['upload'])) {
to
if (isset($_FILES['upload']) && !empty($_FILES['upload']['name'])) {
As far as execution is concerned there really isn’t a different in how they operate as they are both stream readers, however in saying that fopen() allows for more control over the stream as you can control how many bytes of data are transferred at any given time whereas file_get_contents() only gives you the ability to receive content for the file you specified.
In my personal opinion file_get_contents() is good for those times when you need to collect content from small files such as 100MB and less compared to fopen() which allows for greater control as I said over the amount of data your pulling in which makes it great for processing large files.