InMotion Hosting Support Center

php mail() function returns false


InMotionFans
n/a Points
Asked:
2015-08-07 12:02 pm EST

Hits: 3,286
Our domain was previously hosted on a VPS account and a php mail() function created to query the server and return database changes in a human-readable format worked without any problems.

Recently, we switched to a shared hosting plan, and now that same php mail() function returns false. I have searched around for answers, and it may be related to the fact that we are now on a shared hosting account? Most of the related questions had to do with PrestaShop, which does not appear to apply to us in this situation. We do not use any pre-installed applications.

The email account configuration information is as follows:

Secure SSL/TLS Settings
(Recommended)

Username: admin@[my-domain].org
Password: Use the email account’s password.
Incoming Server: secure170.inmotionhosting.com
IMAP Port: 993
POP3 Port: 995
Outgoing Server: secure170.inmotionhosting.com
SMTP Port: 465
Authentication is required for IMAP, POP3, and SMTP.

For reference, the script simply sets the $email, $subject, $message and $headers variables. The only thing explicitly set in the $headers variable is "From: admin@[my-domain].org". No additional_parameters are normally set, though I did try "-fadmin@[my-domain].org" and "-f admin@[my-domain].org" in further troubleshooting.

Thank you.

You must login before you can ask a follow up question.

You must login before you can submit an answer.

OTHER ANSWERS

0

John-Paul
Staff
31,633 Points
2015-08-07 12:23 pm EST
Hello,

Thank you for contacting us about issues with the php mail() function. Several of us looked into this, and we cannot determine what code would work on a vps, but not on shared. Especially, if nothing is explicitly set (such as paths, etc).

We are happy to help you troubleshoot your script further, but will need to see the actual coding to proceed.

Let us know if you have any further questions.

Thank you,
John-Paul

You must login before you can post a comment about this answer.

I will get the code posted, I just need to clean it up and check for any sensitive information first.

Thanks.
nealb
32 Points
2015-08-07 12:46 pm EST
0

nealb
2015-08-07 1:24 pm EST
Most of this code is the manipulation of data retrieved from the db, but I included all of it just in case. And again, this all worked as recently as May of this year. The only thing that changed, that I am aware of, was the account switch at the end of that same month.

In the future, is there a way to format code, such as when posting to StackOverflow? If necessary and possible, I can also upload the code as a file.

CODE:
-------------------------------------------------------
<?php
include("../globalsession.php");

$edits_array = array();
$type = $_GET['type'];

$current_time = date('Y-m-d H:i:s');
$past_time = date('Y-m-d H:i:s', strtotime('-1 weeks Sunday')); // get previous Sunday at midnight
$past_time = date('y-m-d H:i:s', strtotime('+17 hours', strtotime($past_time))); // convert to previous Sunday at 5:00 pm

$query = $db->prepare("
SELECT firstname, lastname, id
FROM users_stats
WHERE
active = :active
ORDER BY team ASC, title DESC, on_campus DESC, gender DESC, lastname ASC
");
$params = array(':active' => 1);
$didwork = $query->execute($params);
if ($didwork) {
$all_users = $query->fetchAll();
$num_users = count($all_users);

for ($i = 0; $i < $num_users; $i++) {
$get_edits = $db->prepare("
SELECT
edit_log.stat_type,
edit_log.table_name,
edit_log.old_stat,
edit_log.new_stat,
edit_log.member_id,
edit_log.week,
edit_log.semester,
edit_log.year,
all_members.firstname AS att_fname,
all_members.lastname AS att_lname,
users_stats.firstname AS user_fname,
users_stats.lastname AS user_lname,
edit_log.timestamp,
edit_log.type
FROM edit_log
LEFT JOIN all_members ON edit_log.member_id = all_members.id
LEFT JOIN users_stats ON edit_log.user_id = users_stats.id
WHERE
edit_log.user_id = :user_id
AND
edit_log.timestamp BETWEEN :first AND :last
AND
edit_log.type = :type
");
$get_edits_params = array(':user_id' => $all_users[$i]['id'], ':first' => $past_time, ':last' => $current_time, ':type' => 'u');
$didget = $get_edits->execute($get_edits_params);
if ($didget) {

$edits = $get_edits->fetchAll();
$num_edits = count($edits);
if (!empty($edits)) {
array_push($edits_array, $edits);
}
}
else {
echo 'Failed getting edits for ' . $all_users[$i]['firstname'] . ' ' . $all_users[$i]['lastname'] . '<br>';
}
}

$num_user_edits = count($edits_array); // count the number of users that submitted edits

$subject = 'Edits made during week ' . $semester_week . '';
if ($_GET['num'] == 'all') {
$emails = '[other-addresses]@domain.com';
}
else {
$emails = '[my-address]@domain.com';
}

$headers = "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: admin@[my-domain].org";

if ($num_user_edits > 0) { // check if anybody submitted edits

for ($k = 0; $k < $num_user_edits; $k++) { // loop through all users that submitted edits

$loop_info = null;

if ($k !== 0) {
$loop_info .= "<br><br><br>";
}
else {
$loop_info .= 'The following edits were made between ' . date('m/j/y', strtotime($past_time)).
' @ ' . date('g:i a' , strtotime($past_time)).
' and ' . date('m/j/y', strtotime($current_time)) . ' @ ' . date('g:i a', strtotime($current_time)) . ' <br><hr><br>';
}

$loop_info .= $edits_array[$k][0]['user_fname'] . " " . $edits_array[$k][0]['user_lname'] . " updated the following stat(s):<br>";

$num_edits_by_user = count($edits_array[$k]);

for ($j = 0; $j < $num_edits_by_user; $j++) { // loop through all edits made by current minister

// get timestamp and convert into report format
$timestamp = strtotime($edits_array[$k][$j]['timestamp']);
$day1 = date('l', $timestamp);
$mon = date('M', $timestamp);
$day2 = date('j', $timestamp);
$time = date('g:i a', $timestamp);
$time_string = $day1 . ', ' . $mon . '. ' . $day2 . ' at ' . $time;

if (!empty($edits_array[$k][$j]['member_id'])) { // checks if edit was for a member's attendance and adjusts wording
$stats = " - Week " . $edits_array[$k][$j]['week'] . ' ' . $edits_array[$k][$j]['stat_type'] . " for " . $edits_array[$k][$j]['att_fname'] . " " . $edits_array[$k][$j]['att_lname'] . " from " . $edits_array[$k][$j]['old_stat'] . " to " . $edits_array[$k][$j]['new_stat'] . " <i>(" . $time_string . ")</i>";
if ($j == ($num_edits_by_user - 1)) {
$loop_info .= $stats;
}
else {
$loop_info .= $stats . "<br>";
}
}
else if ($edits_array[$k][$j]['table_name'] == 'guest info') { // check if edit was to guest information
if ($edits_array[$k][$j]['stat_type'] == 'not submitted') {
$stats = " - Submitted a " . $edits_array[$k][$j]['new_stat'] . " guest for Week " . $edits_array[$k][$j]['week'] . " <i>(" . $time_string . ")</i>";
}
else if ($edits_array[$k][$j]['stat_type'] == 'deleted') {
$stats = " - Deleted guest " . $edits_array[$k][$j]['old_stat'] . " for Week " . $edits_array[$k][$j]['week'] . " <i>(" . $time_string . ")</i>";
}
else {
$stats = " - Week " . $edits_array[$k][$j]['week'] . ' ' . $edits_array[$k][$j]['table_name'] . ' "' . $edits_array[$k][$j]['stat_type'] . '" from ' . $edits_array[$k][$j]['old_stat'] . " to " . $edits_array[$k][$j]['new_stat'] . " <i>(" . $time_string . ")</i>";
}

if ($j == ($num_edits_by_user - 1)) {
$loop_info .= $stats;
}
else {
$loop_info .= $stats . "<br>";
}
}
else { // edit was for user's stats
if ($edits_array[$k][$j]['table_name'] == 'dorm_stats') {
$stats = " - Week " . $edits_array[$k][$j]['week'] . ' ' . $edits_array[$k][$j]['stat_type'] . " in dorms from " . floatval($edits_array[$k][$j]['old_stat']) . " to " . floatval($edits_array[$k][$j]['new_stat']) . " <i>(" . $time_string . ")</i>";
}
else {
$stats = " - Week " . $edits_array[$k][$j]['week'] . ' ' . $edits_array[$k][$j]['stat_type'] . " from " . floatval($edits_array[$k][$j]['old_stat']) . " to " . floatval($edits_array[$k][$j]['new_stat']) . " <i>(" . $time_string . ")</i>";
}
if ($j == ($num_edits_by_user - 1)) {
$loop_info .= $stats;
}
else {
$loop_info .= $stats . "<br>";
}
}
}

$message .= $loop_info;
}
/* testing
echo $emails.'<br>';
echo $subject.'<br>';
echo $message.'<br>';
echo $headers.'<br>';
*/
$mailed = mail($emails, $subject, $message, $headers);

if ($mailed) {
echo 'Email(s) sent';
} else {
echo 'Email(s) not sent...';
}
}
else { // no edits so adjust email message
$message .= 'There were no edits made between ' . date('m/j/y', strtotime($past_time)).
' @ ' . date('g:i a' , strtotime($past_time)).
' and ' . date('m/j/y', strtotime($current_time)) . ' @ ' . date('g:i a', strtotime($current_time)) . ' <br><hr><br>';

mail($emails, $subject, $message, $headers);
echo 'Email(s) sent';
}
}
else {
die("Couldn't get list of users.");
}
?>

You must login before you can post a comment about this answer.

Hello nealb,

Thank you for providing additional information. Since PHP error logging is disabled by default on shared server, I first recommend Displaying and logging errors for PHP. This may provide more detailed error messages.

To rule out a long-running query; as a test, trying running your code without the following section:
$query = $db->prepare("
SELECT firstname, lastname, id
FROM users_stats
WHERE
active = :active
ORDER BY team ASC, title DESC, on_campus DESC, gender DESC, lastname ASC
");
$params = array(':active' => 1);
$didwork = $query->execute($params);
if ($didwork) {
$all_users = $query->fetchAll();
$num_users = count($all_users);

for ($i = 0; $i prepare("
SELECT
edit_log.stat_type,
edit_log.table_name,
edit_log.old_stat,
edit_log.new_stat,
edit_log.member_id,
edit_log.week,
edit_log.semester,
edit_log.year,
all_members.firstname AS att_fname,
all_members.lastname AS att_lname,
users_stats.firstname AS user_fname,
users_stats.lastname AS user_lname,
edit_log.timestamp,
edit_log.type
FROM edit_log
LEFT JOIN all_members ON edit_log.member_id = all_members.id
LEFT JOIN users_stats ON edit_log.user_id = users_stats.id
WHERE
edit_log.user_id = :user_id
AND
edit_log.timestamp BETWEEN :first AND :last
AND
edit_log.type = :type
");


Also, check your variables to make sure they are correct, such as free of misspellings, etc.

Thank you,
John-Paul
John-Paul
31,633 Points
Staff
2015-08-10 1:09 pm EST
I simplified the code as you suggested, and simply included the following:

BEGIN CODE
------------------------------------------------------------------------------------------
$subject = 'Test';
$emails = '[my-email]@[mail-host].com';

$headers = "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: admin@[my-domain].org";

$message = 'Some test text here!';

$mailed = mail($emails, $subject, $message, $headers);
if ($mailed) {
echo 'Email sent';
} else {
var_dump($mailed);
}
------------------------------------------------------------------------------------------
END CODE

I still receive a bool(false) from the $mailed variable. After enabling the error_logging, I tested it by simulating a fatal error which was reported both via the website (non-production) and in the error_log file. However, nothing beyond that has been reported after running the simplified script multiple times.
nealb
32 Points
2015-08-11 1:26 pm EST
0

TJEdens
Staff
10,077 Points
2015-08-12 9:13 am EST
Hello nealb,

I ran some test on your code and while I was getting bool(false) if I visit the url myself, I can run php filename.php from command line (similar to how a cron would work) and it was working just fin and the email sent. I am not fully sure why it fails when visiting the page as that is very weird and not normal. It may be a setting on the shared servers that was not blocked on the VPS server.

Best Regards,
TJ Edens

You must login before you can post a comment about this answer.

Is there anything one can check in regards to this functionality issue?
nealb
32 Points
2015-08-13 11:47 am EST
Hello nealb,

Thank you for contacting us. We spent some time looking into this. As a test, try switching your PHP version to the same one that was used on your VPS server.

A VPS comes with a standard version of PHP, for example 5.5. But shared servers often come with a different version (such as 5.3), but you have a switcher tool that allows you to change versions.

Also, I see in your initial question, you listed your SMTP settings. Ensure you are authenticating with the server with these settings.

If your problems persist, it may be easier to contact Live Support so they can review the mail logs in real-time, while you are testing the mail functionality of your script.

Thank you,
John-Paul
John-Paul
31,633 Points
Staff
2015-08-13 1:14 pm EST
0

nealb
2015-08-23 8:01 pm EST
I ended up calling technical support. They explained that the php.ini file for a VPS account points to a different directory for the php libraries than a shared hosting account does.

Once a fresh php.ini file was generated, the function worked fine.

You must login before you can post a comment about this answer.

Like this Question?

Forum Login

You are NOT logged in. You can still browse our Support Center.

To participate within our Community Support Forum:

Need more Help?

Ask the Community!

Get help with your questions from our community of like-minded hosting users and InMotion Hosting Staff.

Current Customers

Chat: Click to Chat Now E-mail: support@InMotionHosting.com
Call: 888-321-HOST (4678) Ticket: Submit a Support Ticket

Not a Customer?

Get web hosting from a company that is here to help. Sign up today!