Edit: I solved the problem! It was an issue unrelated to the code that I posted - I had an exit command in the script - but all of your advice still helped in other ways.
I'm trying to automatically send an e-mail to a user when they fill out their picks on a sports website. The early part of the script works: Their picks are correctly inserted or updated in the database. The script breaks when I try to pull the user's e-mail address from a table in the MySQL database and use it to send them a message. But what is very strange about this bug is that it doesn't result in any error messages, and for some reason prevents certain echo statements from running while allowing others.
Here's the relevant code:
...
//set variable for the userID, grabbed from the session array
$userID = $_SESSION['identifier'];
...
//write query to get user's e-mail from the database
$getEmail = "SELECT `email` FROM `useraccounts` WHERE `userID` = '".$userID."'";
//execute query
$result = $db->query($getEmail);
//check if query failed
try
{
if (!$result)
{
throw new customexception("Some kind of database problem occurred when trying to find your e-mail address.");
}
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
//get the info from the row
$row = $result->fetch_assoc();
//check if function ran, catch exception if it failed
try
{
if ($row === false)
{
throw new customexception("Some kind of database problem occurred when trying to get your e-mail address from your user record in the database.");
}
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
//set e-mail variable
$email = $row['email'];
//set up e-mail information to send a record of their picks to the user
$toAddress = "$email";
$subject = "Your Picks";
$fromAddress = "From: picks#mysite.com";
//take the info the user submitted, format it for the e-mail, and assign to variable $mailContent
//the $winner1, $spread1, etc. variables are defined earlier in the function, and were successfully submitted into the database
$mailContent = "You picked $winner1 to win by $spread1 points, $winner2 to win by $spread2 points, $winner3 to win by $spread3 points, $winner4 to win by $spread4 points, and $winner5 to win by $spread5 points. \n".
"You can change your picks at any time before 1:00pm EST, February 27, 2011. Just go back to the form on the game page and enter your new picks. Good luck!";
//use wordwrap to limit lines of $mailContent to 70 characters
$mailContent = wordwrap($mailContent, 70);
//send the e-mail
$isMailed = mail($toAddress, $subject, $mailContent, $fromAddress);
//debug: check if mail failed
if (!$isMailed)
{
echo "Mail failed.";
}
//debug: echo $email to see if there's anything in there
echo "<p>E-mail: $email</p>";
//debug: echo $toAddress to see if there's anything in there
echo "<p>To address: $toAddress</p>";
//if everything succeeded, write reply and close database
echo $reply;
$db->close();
?>
Just to be clear, $userID is set correctly, because their picks enter the database like they're supposed to. None of the exceptions listed in the code come up, meaning the query seems to have run successfully. I checked the query again by copying it from the PHP code and running it directly on the MySQL database. When it ran directly, it found the correct e-mail address for every userID value I entered.
But the mail never gets delivered, and when I try to echo the $email and $toAddress variables to see if they're empty:
//debug: echo $email to see if there's anything in there
echo "<p>E-mail: $email</p>";
//debug: echo $toAddress to see if there's anything in there
echo "<p>To address: $toAddress</p>";
...nothing shows up. Not even an error message. And that doesn't necessarily mean that the variables are empty: Not even the labels are echoed.
I also tried the code with my personal e-mail hardcoded instead of $toAddress, and no mail was sent. So the mail function isn't working.
I should also note that the script still successfully echoes $reply (which is a string defined much earlier) at the end.
What's really strange is that the login script for my website uses an almost identical piece of code and works perfectly:
$getuserID = "SELECT `userID` FROM `useraccounts` WHERE `u_name` = '".$login."' AND `p_word` = SHA1('".$password."')";
$result = $db->query($getuserID);
//check if query ran, catch exception if it failed
try
{
if ($result === false)
{
throw new customexception("Some kind of database problem occurred when trying to find your user ID.");
}
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
//get the info from the row
$row = $result->fetch_assoc();
//check if function ran, catch exception if it failed
try
{
if ($row === false)
{
throw new customexception("Some kind of database problem occurred when trying to get info from your user record in the database.");
}
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
//set userID variable
$userID = $row['userID'];
//assign the session identifier and include successfullogin.html if all is well
$_SESSION['identifier'] = $userID;
And I used to have the signup script send me an e-mail every time I got a new user, so I know that mail() works in general with my hosting provider:
//set up static e-mail information
$toAddress = "myemail#mysite.com";
$subject = "Advance Sign-Up";
$mailContent = "Name: $firstName $lastName \n".
"Username: $username \n".
"Password: $password \n".
"E-mail: $email \n".
"Country: $country \n".
"State: $state \n".
"City: $city \n".
"ZIP: $zip \n";
$fromAddress = "From: $email";
...
mail($toAddress, $subject, $mailContent, $fromAddress);
This bug is completely mystifying to me. I wish I had some sort of error message to work with, at least. Can anyone see what's wrong?
It should be a comment but for the sake of formatting.
Your way of error handling is quite unusual.
If you really want to use exceptions, it should be done different way: one try block and multiple throws:
try
{
$getEmail = "SELECT `email` FROM `useraccounts` WHERE `userID` = '".$userID."'";
$result = $db->query($getEmail);
if (!$result)
{
throw new customexception("Some kind of database problem occurred when trying to find your e-mail address.");
}
$row = $result->fetch_assoc();
if ($row === false)
{
throw new customexception("Some kind of database problem occurred when trying to get your e-mail address from your user record in the database.");
}
$email = $row['email'];
$toAddress = "$email";
$subject = "Your Picks";
$fromAddress = "From: picks#mysite.com";
$mailContent = "yadda yadda yadda";
$mailContent = wordwrap($mailContent, 70);
mail($toAddress, $subject, $mailContent, $fromAddress);
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
?>
Are you positive the database variables have contents? I use echo (or print) to quickly make sure the variables aren't empty. Are you positive your email code works? Try it with set values (such as your own personal e-mail) to make sure it works.
The best way out to ignore such notices is to ensure that the variables exist or in plain PHP, use isset(),if !isset() throw an exception/error and handle it properly.
Related
I have a html document with a form page that is debugged and is correct. The problem is the DB, Im hosted on strato, but I think its more of a code problem rather than a serverside problem. The html document is a form that feeds in the Super globals POST, so First, Lastname, Email, Subject, Address, PLZ and message. However the message is not going into the db, its gonna get mailed to my support email. I havent setupp the mail function because I wanted to debug the sql db part first. All the if statements filter the input, for valid email and patterns, so you are not allowed to put in numbers in the form of the html form. I know you can make the pattern in html but I want 100% safety. After the inputs have passed all the filters the connection to my db is going to connect, I want to insert first, lastname and email address and subject as well as plz.
$fname = $_POST['fname'];
$lname = $_POST['lname'];
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
$subject = $_POST['thema'];
$address = $_POST['address'];
$plz = $_POST['plz'];
$text = $_POST['text'];
$pattern = "/^([a-zA-Z' äöü ÄÖÜ]+)$/";
$pattern_plz = "/[0-9]$/";
//VALID INPUT//
if(preg_match($pattern, $fname)){
if(preg_match($pattern, $lname)){
if($email == TRUE){
if(preg_match($pattern_plz, $plz)){
if(is_numeric($plz)){
$con = new mysqli($host, $db, $user, $passwd) or die ("Keine Verbindung konnte aufgebaut werden");
if($con){
$sql="INSERT INTO contact (fname, lname, email, thema, address, plz)
VALUES ($fname, $lname, $email, $subject, $address, $plz)";
if($con->mysqli_query($sql) == TRUE){
echo "success";
}else{mysqli_close($con); exit("Keine Verbindung konnte aufgebaut werden");}
}else{mysqli_close($con); exit("Keine Verbindung konnte aufgebaut werden");}
}else{exit("Inavlid PLZ");}
}else{exit("Inavlid PLZ");}
}else{exit("Inavlid email");}
}else{exit("Inavlid email");}
}else{exit("Inavlid lastname");}
as you are using it on live hosting, displaying error might be turned off from your directadmin or cpanel, you can find php options in hosting and turn on, or else you can use try catch for example
//trigger exception in a "try" block
try {
//Your code
}
//catch exception
catch(Exception $e) {
echo 'Message: ' .$e->getMessage(); // display error
}
I have the below script running as part of a password forgot system. Everything seems to be working fine except that the database is not being updated with the 'token'. As everything else is working fine (i.e. $str is being set and used in the URL sent via email)... i think this must be a problem with the update script but I cant see why. My code is below, all help greatly appreciated.
if(isset($_POST["sign"])){
include('connections/conn.php');
$email = mysqli_real_escape_string($conn, $_POST["email"]);
$data = $conn->query("SELECT id FROM travisor_tradesperson WHERE email='$email'");
if ($data-> num_rows > 0) {
$str = "0123456789qwertyuiopasdfghjklzxcvbnm";
$str = str_shuffle($str);
$str = substr($str, 0, 10);
$url = "http://rhamilton461.web.eeecs.qub.ac.uk/travisor/passReset.php?token=$str&email=$email";
mail($email, "Reset Password", "To reset your password please visit: $url" , "From: rhamilton461#qub.ac.uk\r\n");
$conn->query("UPDATE travisor_tradesperson SET token = '$str' WHERE email='$email'");
echo "Please check your email.";
} else {
echo "Please check your inputs.";
}
}
try out to run script by commenting the calling statement of mail function.
it is possible that your table is not updating because there is error in mail function.
are you getting output as "Please check your email" ???
I'm so close to completing the login/registration section of my site but I've got some bugs that don't show up in error_log or anything.
About an hour ago, the script worked for the most part. It would validate, insert into/check database, and redirect to index.php (located in user directory along with login and register forms).
Contents of index.php:
/*
If validation script is successful, continue to $destinationUrl, otherwise, go back to try
again. Ultimately, the TRUE statement's output will be the referring page's URL stored as
$_SESSION['Return_Url'] to send users back to where they were, simply as a convenience.
*/
session_start();
if(isset($_SESSION['UserData'])) {
exit(header("location:" . $destinationUrl));
} else {
exit(header("location:" . $loginUrl));
}
That's exactly what I want except one detail: it won't show any user input errors. While trying to fix that, I've managed to screw everything up again and now it still submits data and inserts into the database but doesn't insert $email, and doesn't redirect or anything. On top of that, I don't get any PHP errors so I'm at a loss.
I know the login and registration will work because it did before, but I don't know what I did to cause this issue due to know errors being thrown. I just want the input errors to show up. I'm going to post the original code I copied and edited because what I'm messing with right now is a mess but the validation section is the same.
I did not write these, they were found online after hours of trying script after script. Only this one worked. Therefore, I don't understand exactly what's going on with every part of the script, but I do understand the basic mechanics of what happens, or is supposed to happen as far as validation of input data and adding to/checking data against the database when the form is submitted. The only thing that I have absolutely no idea what and how it works is the output($var) function
Included Scripts
$db= mysqli_connect($dbhost,$dbuser,$dbpwd,$dbase); }
function safe_input($db, $data) {
return htmlspecialchars(mysqli_real_escape_string($db, trim($data)));
}
/*
Currently, I have no idea about JSON or any other languages. Only a decent
portion of PHP, and HTML, of course. Can I just forget this function and use
{return $var;} instead? Because that would make everything so much easier
and I probably wouldn't even be posting these questions... but it's a new
language to me that I couldn't tell you the first thing about.
*/
function output($Return=array()){
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
exit(json_encode($Return));
}
Validation Scripts
(Both scripts are in one file)
<?
require 'config.php';
require 'functions.php';
if(!empty($_POST) && $_POST['Action']=='login_form'){
$Return = array('result'=>array(), 'error'=>'');
$email = safe_input($db, $_POST['Email']);
$password = safe_input($db, $_POST['Password']);
if(filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$Return['error'] = "Please enter a valid email address.";
}elseif($password===''){
$Return['error'] = "Please enter password.";
}
if($Return['error']!=''){
output($Return);
}
$result = mysqli_query($db, "SELECT * FROM tbl WHERE email='$email' AND password='".md5($password)."' LIMIT 1");
if(mysqli_num_rows($result)==1){
$row = mysqli_fetch_assoc($result);
$Return['result'] = $_SESSION['UserData'] = array('id'=>$row['id']);
} else {
$Return['error'] = 'Invalid Login Credential.';
}
output($Return);
}
if(!empty($_POST) && $_POST['Action']=='registration_form'){
$Return = array('result'=>array(), 'error'=>'');
$name = safe_input($db, $_POST['Name']);
$email = safe_input($db, $_POST['Email']);
$password = safe_input($db, $_POST['Password']);
if($name===''){
$Return['error'] = "Please enter Full name.";
}elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$Return['error'] = "Please enter a valid Email address.";
}elseif($password===''){
$Return['error'] = "Please enter Password.";
}
if($Return['error']!=''){
output($Return);
}
$result = mysqli_query($db, "SELECT * FROM tbl WHERE email='$email' LIMIT 1");
if(mysqli_num_rows($result)==1){
$Return['error'] = 'The email you entered already belongs to an account, please login.';
}else{
mysqli_query($db, "INSERT INTO tbl (GUID, email, password, entry_date) values(MD5(UUID()), '$email', '".md5($password)."' ,NOW() )");
$id = mysqli_insert_id($db);
mysqli_query($db, "INSERT INTO `tbl' (id,name) VALUES('$id','$name')");
$Return['result'] = $_SESSION['UserData'] = array('id'=>$id);
}
output($Return);
}
?>
I'm not sure how I would echo the $Return array values. I tried making a function out of it like so:
function inputErr($Return) {
if($Return['error']!=''){
output($Return);
}
}
but that didn't work either. Is there a special way to echo an array value? Without the index name attached
Also, if you have any ideas why the email $var is not being added to db while everything else is, please, do share! With the script not throwing any PHP errors, I have no idea where to start.
I am a bit confused about how to use foreach. I read some internet things on it and I kind of understand how it works, but I don't fully understand it. I think I could use foreach to create a PHP mass emailer that sends blank carbon copy to email addresses and adresses the customer by name in the subject (Dear, Michael Here is your email). I've figured out how to retrieve the names and emails from my database into variables and I know how to email, but I don't know how to send multiple emails at once and to associate the name and email address.
<?php
//Variables for connecting to your database.
//These variable values come from your hosting account.
$hostname = "MichaelBerna.db.10339998.hostedresource.com";
$username = "MichaelBerna";
$dbname = "MichaelBerna";
//These variable values need to be changed by you before deploying
$password = "********";
$usertable = "subscribers";
$yourfield = "name";
$yourfield1 = "email";
//Connecting to your database
$link = mysql_connect($hostname, $username, $password) OR DIE ("Unable to connect to database! Please try again later.");
mysql_select_db($dbname);
//Fetching from your database table.
$query = "SELECT * FROM $usertable";
$result = mysql_query($query);
if ($result)
{
while($row = mysql_fetch_array($result))
{
$name = $row["$yourfield"];
$email = $row["$yourfield1"];
echo "Name: $name<br>";
echo "Email: $email<br>";
//mysqli_free_result($result);
//mysqli_close($link);
}
}
?>
Here is my email code:
<?php
require_once '../PHPMailer_5.2.2/class.phpmailer.php';
$name = $_POST['name'] ;
$email = $_POST['email'] ;
//$file = $_POST['file'] ; // I'm going to later add a file later to be attached in email from database
$body = "Hey $name thank you for continuing to be a valued customer! This month's story is included in this email asa an attachment.";
$mail = new PHPMailer(true); //defaults to using php "mail()"; the true param means it will throw exceptions on errors, which we need to catch
try
{
$mail->AddAddress($email, $name);
$mail->SetFrom('admins_email#yahoo.com', 'Site Admin');
$mail->AddReplyTo('admins_email#yahoo.com', 'Site Admin');
$mail->Subject = "Dear $name Your monthly subscription has arrived!";
$mail->Body = $body;
if ($_FILES['file']['size'])
{
$mail->AddAttachment($_FILES['file']['tmp_name'], $_FILES['file']['name']);// attachment
}
$mail->Send();
echo "Email Sent Successfully</p>\n";
}
catch (phpmailerException $e)
{
echo $e->errorMessage(); //Pretty error messages from PHPMailer
}
catch (Exception $e)
{
echo $e->getMessage(); //Boring error messages from anything else!
}
?>
Basically, I need a way to combine these two scripts and link them together and that's what I'm unsure of how to do.
Put the mailing code in a function, e.g. send_mail(), so that it can be called from different places. Then change your database query loop to:
while ($row = mysql_fetch_assoc($result)) {
send_mail($row['name'], $row['email'), "Text of the email");
}
I have a piece of code which upon approval sends a mail to an email address. The email is not being sent. Do I need to configure something on my web server?
function mailpassword($email, $password){
//notify that the password has been changed
mysqli_select_db($connect,"members");
$query = "select email from users where email = '".$email."'";
$mailquery = mysqli_query($connect,$query);
if(!$mailquery)
{
throw new Exception ('The entered email address could not be found');
}
else if($mailquery->num_rows==0)
{
throw new Exception ('The entered email address could not be found');
//username not in database
}
//if no errors, send mail
else
{
$row = $mailquery->fetch_object();
$email = $row->email;
$from = "From : support#example.com \r\n";
$mesg = "Hey,\n\n You requested for a new password. We have generated a completely random password for you, use it to login.\n\n
New Password - ".$password."\r\n
Please change this random password to a password of your choice once you log in. To change your password, click on the Accounts tab present in your dashboard.\r\n
Cheers\r\n
Hap";
if(mail($email, 'Password Change Account Details', $mesg, $from))
{
return true;
echo "great";
}
else
{
echo "Something went wrong";
}
}
$mails = mailpassword();
}
There's an easy solution to email problems: use a hosted solution that makes sure all email sent from your application gets through. There are some alternatives like Amazon and Postmark. We use Postmark with great success (not affiliated though ehe;)
There's this PHP class for Postmark that I'm kinda proud of... :-)
This wasn't directly an answer to your question, but I hope it was helpful anyway!
Try to remove the space before the colon in the From header:
$from = "From: support#example.com \r\n"