Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

mail() function doesn't send email; mistakes in the code

23 views
Skip to first unread message

Alla

unread,
Aug 4, 2016, 2:56:57 AM8/4/16
to
Hello!

Please, take a look at the code below. I will be grateful for your help on why the code doesn't
work - I have tested it, but the email doesn't arrive. All other parts of the code are correct,
because these have been tested many times in other related files, i.e. those are templates.

<?php

// configuration
require("../includes/config.php");

// check if the user is logged in
if (isset($_SESSION["id"]))
{
//get email from the mysql table and store it in the variable $email
//three lines below work perfectly, they do retrieve the necessary data from the table,
I have checked that many times in this file and other ones as well

$row = CS50::query("SELECT username, email FROM users WHERE id = ?", $_SESSION["id"]);
$email = $row[0]["email"];
$name = $row[0]["username"];


$salt = "3453#2K:90k≈“π631%380‘“HJK0D*7WPJ987NU";
// Create the unique user password reset key
$password = hash('sha512', $salt.$email);

// url to reset password
$reset_url = "https://ide50-name.cs50.io/new_password.php?q=".$password;
$email_subject = "Requested link";

//email the url
$email_body = "Dear $name,\n\nYou have requested to reset your password.
\n\nTo reset your password, please click the link below.\n\n".$reset_url."\n\nThank you!";

if(mail($email, $email_subject, $email_body))
{
// render form
render("email_link_form.php", ["email" => $email]);
}
}
else
{
redirect("login.php");
}

?>

Thank you very much for your help!

R.Wieser

unread,
Aug 4, 2016, 6:36:54 AM8/4/16
to
Alla,

How have you made sure that your subject line ("mail() function doesn't send
email; mistakes in the code") is correct ? The latter part is easy to
check: if something is wrong in the code the "mail" command should return a
False, which is something you already check for. In other words, does that
"email_link_form.php" page get displayed ? If so, the email is *scheduled*
to be send.

But even when you see that "email_link_form.php" page, that does not mean
that the email is actually send, as that depends on a number of settings in
your PHP.INI file (suggestion: look up how to configure PHP for email
sending), like which (SMTP) server and port to use.

None of the above guarantees that the email actually leaves your 'puter
though. For that you could try to set up a local dummy SMTP server (or
even just a program that will listen for data packets on a certain port),
change the PHP.INI settings to point at that dummy server and try again to
send an email. If all goes well you should see the email being delivered
to that dummy SMTP server (indicating it actually leaves your 'puter).

But even if all of that works and the email is actually send out to the SMTP
server there is a possibility that it refuses to relay the message, and you
either get a direct refusal response (which should be in the logs!), bit it
*could* also silently drop the message (so it can't be used to "bounce"
spam)

Just make sure that the emails return (non-delivery) address is set up
corectly, so you give yourself a chance to recieve and non-delivery
responses.

In short: It might be that your code is A.OK, but something else down the
line doesn't want to cooperate.

Hope that helps.

Regards,
Rudy Wieser


-- origional message:
Alla <modelli...@gmail.com> schreef in berichtnieuws
0d3735d9-7ed7-46f6...@googlegroups.com...
Hello!

Please, take a look at the code below. I will be grateful for your help on
why the code doesn't
work - I have tested it, but the email doesn't arrive. All other parts of
the code are correct,
because these have been tested many times in other related files, i.e. those
are templates.

<?php

// configuration
require("../includes/config.php");

// check if the user is logged in
if (isset($_SESSION["id"]))
{
file://get email from the mysql table and store it in the variable
$email
file://three lines below work perfectly, they do retrieve the
necessary data from the table,
I have checked that many times in this file and other ones as well

$row = CS50::query("SELECT username, email FROM users WHERE id = ?",
$_SESSION["id"]);
$email = $row[0]["email"];
$name = $row[0]["username"];


$salt = "3453#2K:90k?"?631%380'"HJK0D*7WPJ987NU";
// Create the unique user password reset key
$password = hash('sha512', $salt.$email);

// url to reset password
$reset_url =
"https://ide50-name.cs50.io/new_password.php?q=".$password;
$email_subject = "Requested link";

file://email the url

Jerry Stuckle

unread,
Aug 4, 2016, 1:30:09 PM8/4/16
to
First of all, PHP is not an MTA (Mail Transport Agent, which is an email
server). All the mail() function does is connect to an MTA. To do
that, you either need one running on your system, or on a system you can
access.

There are several options in your php.ini file which controls this. For
instance, if sendmail_path is set (it must contain the full path to your
sendmail executable), it will look for the executable on your current
system, which is almost always supplied with the MTA (it would be
possible to have a program which connects to a remote MTA instead, but
this is much more complicated). Another way is to set SMTP and
smtp_port to the host name (or ip address) and port of your MTA.

But even a correct configuration will not necessarily work. For
instance, the PHP mail() function can only handle MTAs which require no
authentication (common for a local MTA, but should be non-existent for a
remote MTA).

Additionally, nowadays many ISPs are blocking outbound port 25,
especially for residential customers, because this how email traffic is
sent between servers, and therefore is an easy way to generate virtually
untraceable SPAM. Port 587 is designated for users to connect to their
MTA, but this port should ALWAYS require a signon.

Finally, even though get everything set up right and the email does in
fact get sent, it could be rejected by the receiving MTA for many
reasons - the most common (other than an incorrect address) being
something triggers the spam filters. But every system is different, so
it's hard to tell why that happens.

So, you can see some of the problems here. Several things you need to
do to find why your email isn't being received.

The first thing, as Rudy indicated, is to check the response from your
mail() command. If that is returning false, the email is never getting
to the MTA. You need to ensure you can access your MTA without
requiring authentication; the parameters I indicated earlier are a start.

If mail() returns true and you still don't see the mail being received,
you need to look at your MTA's log to see what it says. It should have
some clues on what's causing your problem.

Finally, if you can't access your MTA without authentication (as in most
ISPs), I recommend PHPMailer (https://github.com/PHPMailer/PHPMailer).
It's more flexible and can handle MTAs which require authentication. In
fact, I recommend using it over the mail() command anyway, because it is
so much easier to use.

So, check these things out and feel free to come back if you're still
having problems. And good luck.

--
==================
Remove the "x" from my email address
Jerry Stuckle
jstu...@attglobal.net
==================

Eli the Bearded

unread,
Aug 4, 2016, 4:28:07 PM8/4/16
to
In comp.lang.php, Alla <modelli...@gmail.com> wrote:
> $salt = "3453#2K:90k≈“π631%380‘“HJK0D*7WPJ987NU";
> // Create the unique user password reset key
> $password = hash('sha512', $salt.$email);
>
> // url to reset password
> $reset_url = "https://ide50-name.cs50.io/new_password.php?q=".$password;

NICE!

Now all I have to do is guess (or find) the email address of a user and
I can reset their password without needing to actually read the new
password email!

Elijah
------
or did you not mean to give away those keys?

J.O. Aho

unread,
Aug 5, 2016, 1:03:44 AM8/5/16
to
On 08/04/16 08:56, Alla wrote:
> Hello!
>
> Please, take a look at the code below. I will be grateful for your help on why the code doesn't
> work - I have tested it, but the email doesn't arrive. All other parts of the code are correct,
> because these have been tested many times in other related files, i.e. those are templates.
>
> if(mail($email, $email_subject, $email_body))
> {
> // render form
> render("email_link_form.php", ["email" => $email]);
> }

The only time mail() will give you a false is when it fails to connect
to the SMTP service configured in the php.ini.

Most of the cases when mail do not arrive to the recipient, the mail has
been deemed as spam of either the SMTP service configured in the php.ini
or by the receiving SMTP server.

I do recommend you to set a proper from in the header, which you do not
have in this case.


> // check if the user is logged in
> if (isset($_SESSION["id"]))
> {

You know you can use a form to allow the user to change their password,
just a have a field for their current password and a field for the new
password (you may want to have a confirm the new password too).


> $salt = "3453#2K:90k≈“π631%380‘“HJK0D*7WPJ987NU";
> // Create the unique user password reset key
> $password = hash('sha512', $salt.$email);

If redirecting a user to a page, don't use something which is permanent
for the user, generate a random value instead, which will only be used
once, store it temporarily in a table together with the user id, so you
know who it is (only applies to users who ain't logged in, as you have
already the session for those who are logged in and do not need to use
temporarily tokens to know who they are).

--

//Aho

Alla

unread,
Aug 5, 2016, 10:05:34 AM8/5/16
to
> <snip>
Thank you very much!
Yes, I did see the "email_link_form.php" page, but email never arrived. I have
checked numerous resources on this matter, including php.net page; and, yes,
it's said everywhere that mail() doesn't guarantee the delivery.
But! I should have mentioned that - I was running the code in the io cloud.
I have also tried phpmailer code. Now I am working on setting up local machine
to run same codes on it and see what happens.

Alla

unread,
Aug 5, 2016, 10:06:58 AM8/5/16
to
))))) That's funny ) Have you noticed that the salt code is commented out? It doesn't work )
And if I use the salt ever, I'll surely change it )

Alla

unread,
Aug 5, 2016, 10:07:49 AM8/5/16
to
Thank you very much for this explanation. I have to study all this further.
Unbelievably difficult matter.

Jerry Stuckle

unread,
Aug 5, 2016, 10:24:24 AM8/5/16
to
On 8/5/2016 1:03 AM, J.O. Aho wrote:
> On 08/04/16 08:56, Alla wrote:
>> Hello!
>>
>> Please, take a look at the code below. I will be grateful for your help on why the code doesn't
>> work - I have tested it, but the email doesn't arrive. All other parts of the code are correct,
>> because these have been tested many times in other related files, i.e. those are templates.
>>
>> if(mail($email, $email_subject, $email_body))
>> {
>> // render form
>> render("email_link_form.php", ["email" => $email]);
>> }
>
> The only time mail() will give you a false is when it fails to connect
> to the SMTP service configured in the php.ini.
>
> Most of the cases when mail do not arrive to the recipient, the mail has
> been deemed as spam of either the SMTP service configured in the php.ini
> or by the receiving SMTP server.
>
> I do recommend you to set a proper from in the header, which you do not
> have in this case.
>
>
>> // check if the user is logged in
>> if (isset($_SESSION["id"]))
>> {
>
> You know you can use a form to allow the user to change their password,
> just a have a field for their current password and a field for the new
> password (you may want to have a confirm the new password too).
>
>

Which doesn't work if the user has forgotten his password - a problem
with which code like this would help resolve. But in that case the user
wouldn't be signed in, so the code would never be executed.

Perhaps a problem with the logic?

Jerry Stuckle

unread,
Aug 5, 2016, 10:26:32 AM8/5/16
to
On 8/5/2016 1:03 AM, J.O. Aho wrote:
> On 08/04/16 08:56, Alla wrote:
>> Hello!
>>
>> Please, take a look at the code below. I will be grateful for your help on why the code doesn't
>> work - I have tested it, but the email doesn't arrive. All other parts of the code are correct,
>> because these have been tested many times in other related files, i.e. those are templates.
>>
>> if(mail($email, $email_subject, $email_body))
>> {
>> // render form
>> render("email_link_form.php", ["email" => $email]);
>> }
>
> The only time mail() will give you a false is when it fails to connect
> to the SMTP service configured in the php.ini.
>

I forgot to add - that is true - but if PHP does connect to the MTA,
then there will be information in the MTA's log showing what happened.

J.O. Aho

unread,
Aug 5, 2016, 5:02:11 PM8/5/16
to
On 08/05/16 16:26, Jerry Stuckle wrote:
> On 8/5/2016 1:03 AM, J.O. Aho wrote:
>> On 08/04/16 08:56, Alla wrote:
>>> Hello!
>>>
>>> Please, take a look at the code below. I will be grateful for your help on why the code doesn't
>>> work - I have tested it, but the email doesn't arrive. All other parts of the code are correct,
>>> because these have been tested many times in other related files, i.e. those are templates.
>>>
>>> if(mail($email, $email_subject, $email_body))
>>> {
>>> // render form
>>> render("email_link_form.php", ["email" => $email]);
>>> }
>>
>> The only time mail() will give you a false is when it fails to connect
>> to the SMTP service configured in the php.ini.
>>
>
> I forgot to add - that is true - but if PHP does connect to the MTA,
> then there will be information in the MTA's log showing what happened.

Yes, but only if you have access to the logs will you be able to figure
out if it's the sending or receiving MTA which has blocked the mail and
for most shared hostings you don't have access to mail logs.

--

//Aho

Jerry Stuckle

unread,
Aug 5, 2016, 7:39:17 PM8/5/16
to
Yes, but it's the only way you can find out what the MTA is doing with
the message.

I have had hosting companies forward relevant logs before with a fair
amount of success (you may have to show you actually know what you're
doing :) ).

I've been running my own servers for well over a decade, and don't have
that problem any more. But it's also a fair amount of work.
0 new messages