Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Mail function - working in background

Status
Not open for further replies.

d0nny

IS-IT--Management
Dec 18, 2005
278
GB
I've written a small function that essentially collects a load of emails from the (mySQL) database and creates an email to send out.
The email is created in a RTE (TinyMCE) and the Admin user then clicks on a button to send the email to his selected mailing list.

What I want to do is have that mailout function work in the background whilst a page is returned to the Admin user stating the email has been queued, or something similar.
At the moment, because of restrictions on the mail server, I need to 'sleep' my mailout loop but I don't want the Admin user to be waiting for the function to finish before they get a server response.

So how would I kick into action the function in the background whilst I return a 'finished' page to the user?
 
Hi

Something like this ?
Code:
[teal]<?php[/teal]

[b]if[/b] [teal]([/teal][COLOR=darkgoldenrod]system[/color][teal]([/teal][green][i]'/path/to/script_which_actually_does_the_mass_mailing.php > /dev/null 2> /dev/null'[/i][/green][teal])===[/teal][b]false[/b][teal])[/teal]
  [b]echo[/b] [green][i]'starting mass mailing failed'[/i][/green][teal];[/teal]
[b]else[/b]
  [b]echo[/b] [green][i]'mass mailing started in background'[/i][/green][teal];[/teal]
Well, at least supposing you are using a Unix-like operating system.


Feherke.
[link feherke.github.com/][/url]
 
OK, thanks.
I'll give that a try and let you know how I get on!
 
Hi

Oops. Missed the most important part [banghead] :
Code:
[teal]<?php[/teal]

[b]if[/b] [teal]([/teal][COLOR=darkgoldenrod]system[/color][teal]([/teal][green][i]'/path/to/script_....php > /dev/null 2> /dev/null [COLOR=red yellow]&[/color]'[/i][/green][teal])===[/teal][b]false[/b][teal])[/teal]
  [b]echo[/b] [green][i]'starting mass mailing failed'[/i][/green][teal];[/teal]
[b]else[/b]
  [b]echo[/b] [green][i]'mass mailing started in background'[/i][/green][teal];[/teal]


Feherke.
[link feherke.github.com/][/url]
 

I tried this but it doesn't seem to work.
I created a simple PHP script that sends a single email (using the PHP mail function) but the mail was not sent so I am assuming the script was not run.

When I call the script, do I not need a PHP processor proceeding the script??
 
Hi

d0nny said:
When I call the script, do I not need a PHP processor proceeding the script??
Yes. Sorry, for me was obvious that executing a PHP script implies to have execute permission set on it and a shebang line inserted at the beginning :
Code:
[highlight]#!/usr/bin/php[/highlight]
[teal]<?php[/teal]

[COLOR=darkgoldenrod]mail[/color][teal]([/teal][green][i]'test@example.com'[/i][/green][teal],[/teal][green][i]'test subject'[/i][/green][teal],[/teal][green][i]'test content'[/i][/green][teal]);[/teal]

Alternatively you can pass the script file name as parameter to the interpreter :
Code:
[teal]<?php[/teal]

[b]if[/b] [teal]([/teal][COLOR=darkgoldenrod]system[/color][teal]([/teal][green][i]'[highlight]/usr/bin/php[/highlight] /path/to/script_....php > /dev/null 2> /dev/null &'[/i][/green][teal])===[/teal][b]false[/b][teal])[/teal]
  [b]echo[/b] [green][i]'starting mass mailing failed'[/i][/green][teal];[/teal]
[b]else[/b]
  [b]echo[/b] [green][i]'mass mailing started in background'[/i][/green][teal];[/teal]
In this later case no execute permission nor shebang is needed.

Note that both the PHP interpreter's name and the path to it may be different on your system.

Feherke.
[link feherke.github.com/][/url]
 
OK, I can't seem to get this to work.

I have created a script which is just a simple mail script - it doesn't actually take any variables from my form, I just want to test the execution of the form.
I have created a cron job on the script and it does get executed. But when I put this in my if statement, it doesn't do anything.
I have tried to simplify the executing of the script by removing the if statement and just having this code:
Code:
system('/path/to/public_html/admin/mailingloop.php');
But the code doesn't execute... well, I assume it isn't as it is supposed to send a simply email and the cron job picks up the script and executes it but the above doesn't.

The cron job has the '/usr/bin/php5' interpreter prefix. Does the above command need that? Like this:
Code:
system('/usr/bin/php5 /path/to/public_html/admin/mailingloop.php');
 
Oh, just seen your response - must have crossed in the $_POST! ;-)
About to try it...
 
Still can't seem to get it to work.
I have tried:
Code:
system('/usr/bin/php5 /path/to/public_html/admin/mailingloop.php');
and also
Code:
system('/usr/bin/php5 -f /path/to/public_html/admin/mailingloop.php');
using the -f switch to execute a file ( but to no avail.

I am using a PHP switch statement and I know this is hitting the right spot as I have a resultant page being displayed after the command above. The page is displayed so I assume the 'system' command is being executed.
But still no email.
I'm bereft of ideas now. Anything else I can try?
 
I have also tried amending the action of my form directly to the mailingloop.php script and this works fine.

So the issue is either that I am not hitting the 'system' statement in my switch or the command is not executing properly.
I believe I am hitting the switch statement as the other commands in that switch, namely a resultant page, are being executing.
So my deduction is that the 'system' command is either not constructed properly or some other sort of error.
Is there a status returned by using this command? I could save that to a variable and then display it.
 
Hi

I tried the code I posted and worked for me.

d0nny said:
using the -f switch to execute a file
Unnecessary. Specify it if you find it more readable, I prefer without.

d0nny said:
Is there a status returned by using this command?
The code already checks for failure, and for now is probably pointless to check the exit code as I suppose mailingloop.php not sets any specific exit code. But you can check it anyway :
Code:
[teal]<?php[/teal]

[b]if[/b] [teal]([/teal][COLOR=darkgoldenrod]system[/color][teal]([/teal][green][i]'/usr/bin/php5 /path/to/public_html/admin/mailingloop.php > /dev/null 2> /dev/null &'[/i][/green][highlight][teal],[/teal][navy]$exitcode[/navy][/highlight][teal])===[/teal][b]false[/b][teal])[/teal]
  [b]echo[/b] [green][i]'starting mass mailing failed'[/i][/green][teal];[/teal]
[b]else[/b]
  [b]echo[/b] [green][i]'mass mailing started in background'[/i][/green][teal];[/teal]

[b]echo[/b] [green][i]"exit code was $exitcode"[/i][/green][teal];[/teal]
Just as a note, [tt]system()[/tt] is the simplest way to execute external commands. [tt]exec()[/tt], [tt]popen()[/tt] and [tt]proc_open()[/tt] allows more interaction with the child process, but that is pointless in this case. [tt]system()[/tt] should be just enough for this task.

I am sure the problem is somewhere around the permissions. But sadly I have no idea for now about how to detect what exactly is missing. A generic rule : first check the logs. In this case the web server's error log and the mail logs, whatever they are on your system.


Feherke.
[link feherke.github.com/][/url]
 
Exit code was 0.
What does that mean?
is there a list of codes?

Still not sending email (executing script)!
 
Hi

d0nny said:
Exit code was 0.
What does that mean?
is there a list of codes?
That was to be expected. By convention, 0 means Ok, anything else means some kind of error. There is no such thing like list of codes. Each program sets the exit code according to its needs. Regarding the PHP interpreter, I never met a comprehensive description of what exit codes it sets, but I suppose there are only a few if not just one ( 1 ). That way it lets the scripts to set the exit code using the [tt]exit()[/tt] language construct according to their own logic.

Feherke.
[link feherke.github.com/][/url]
 
Feherke.
Could I be so bold as to ask for a working example of this solution?
Try as I may, I simply cannot get the script to run in the background. I can get the script to run through a cron job and even get it to run if I direct my form to it, but I simply cannot get the script to run using any of the solutions above.

For the record, I have a simple form such as this:
Code:
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
Subject: <input type="text" name="subject" /><br />
Message: <textarea name="message" rows="5" cols="50"></textarea><br />
<input type="submit" name="action" value="Send Emails" />
</form>

I then hit my 'despatch.php' script which contains my switch such as this:
Code:
<?php
$action = empty($req['action']) ? '' : $req['action'];
switch ($action){
   default:
      system('/usr/bin/php5 mlm/admin/mailingloop.php > /dev/null 2> /dev/null &', $exitcode);
      $req['exit'] = $exitcode;
      require BASE . 'mlm/admin/pages/messagesuccess.html';
      break;
?>

Now, I am getting the 'messagesuccess.html' result page and I get the $exitcode listed within in (using the $req['exit'] variable posted to the new page - I'm using $req = array_merge($_GET, $_POST) ) so I can only assume the switch is going through OK, but the script simply doesn't work.

Here's my mailingloop.php script:
Code:
<?php
$to = 'donny@myemail.co.uk';
$subject = 'Test Email';
$message = 'This is a test of the mailingloop script!';
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
$headers .= 'From: Professional Travel Advisors <support@professionaltraveladvisors.com>' . "\r\n";
mail($to, $subject, $message, $headers);
?>

As you can see, this is not really doing much but I just want to prove that the script is being run and does something.
If you have a simple working example, can you share it with me?

In my form page I have even changed the action of the form to point directly to the mailingloop.php script and this does the job.
 
run this code from the command line
Code:
/usr/bin/php5 /path/to/public_html/admin/mailingloop.php

if it sends a mail (or whatever mailingloop is supposed to do), the script is good therefore the problem is permissions.

if it does not send a mail then there are other problems and hopefully an error message will be produced that will help debug.

PS. i would not trust the error codes from a system call when the stderror is being redirected to /dev/null. i can't see off the top of my head why the code would ever be anything other than zero.

 

Welcome back jpadie!

I don't have command line access but I have tried running the job as a CRON job and it runs fine, which uses the same command as you have detailed.
I'll ask my server provider if I would be allowed to run a command like this within my code.
 
OK, I contacted my server provider and they have confirmed that everything should be ok with running the system command.

What I have done on another server is really simplify things.
I have my initial script:
Code:
<?php
if (isset($_POST['submit'])) {
	// Do something when the Send button is clicked
	$_POST['subj'] = $_POST['subject'];
	if (system('/usr/bin/php mail.php > /dev/null 2> /dev/null &') === false) {
		echo 'Starting mass mailing failed!';
	} else {
		echo '<br />Mass mailing started in background';
		echo '<br /><a href="async.php">Home</a>';
	}
} else {
	//If not button clicked, display the form!
?>
	<h3>Test Form</h3>
	<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
		Subject: <input type="text" name="subject" />
		<br />
		<input type="submit" name="submit" value="Send" />
	</form>
<?php
}
?>

And here's my mail.php script the above system command calls:
Code:
<?php
$to = 'donny@myemail.com';
$subject = 'Test Email';
$message = 'This is a test message on the asynchronous method.';
mail($to,$subject,$message);
?>

This worked!!!!
I'm about to try this on my original server now. Stay tuned!
 

Tried this on my Heart server and it doesn't work!
Tried removing the STDOUT and the background fork without success.
Heart have stated the system() command is fully functional! Obviously not if I can get it work elsewhere!

Let's see what they say now ...
This is driving my to alcohol!
 

OK, Heart have now stated that "The problem here relates to the nature of PHP as a CGI module - This is not actually supported on our shared platform however a work around may be to change your command interpreter over to PHP5-CLI which does exist on our platform as a temporary work around for a Wordpress fault - That is /usr/bin/php5-cli"
(One for jpadie - Wp fault?!?)

Even so, I try this 'new' interpreter and it still doesn't work!
Damn.
 

Latest response from Heart:

The problem is the PHP process shelling out to another PHP script appears to create an indefinite loop. With your most recent comments in mind, I'd recommend looking towards AJAX to achieve your target.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top