1

I want to be able to send out newsletters from my server to all my subscribers via email. There are over a thousand email addresses in the database that I'll need to cater to. I've just created a backend system for me to do this, which allows me to write newsletters and start sending them, along with a progress bar to monitor the progress. For testing purposes instead of sending emails, I call sleep(1) I then realised if I try to reload the page or run another PHP script while the script is running, nothing happened - the batch email process had to finish first. And then I remembered that PHP is single threaded and my system was ill-conceived.

I know there is a way to simulate multi-threading with the Thread class, but my host server does not support this.

The other obvious way round this is to break the task up and use cron jobs to fire off a few emails bit by bit, but that means I'd have to authenticate my email server repeatedly, perhaps upto 100 times in a fairly short time period if I want my site to remain active. With my server restrictions this would likely throw up an issue.

The obvious answer is to find a new server with less restrictions, or to stagger the newsletter to such a degree that it would overcome any problems, but that's a last resort, and in which case I'll probably just find a way to do the batch emailing locally.

Is there any way I can execute a long running PHP script like this without delaying every other script until it completes?

Have I misunderstood some rather basic PHP knowledge somewhere? Because paradoxically I find I can run some long running scripts (for instance I have a php script that takes about 5 seconds to complete as it converts my old database to a new format) that for some reason can run parallel to other scripts it seems.

Yes, I'm confused. Please help.

EDIT: As wischi correctly pointed out, the script that sends the emails also calls session_start(), as it needs to check if an admin is logged in and calling the script for security purposes. This is why literally everything halts during this batch email script is working.

hedgehog90
  • 1,402
  • 19
  • 37
  • run it via the command line in the background `exec("nohup /usr/bin/php mailer.php > /dev/null");` –  Sep 03 '15 at 20:26

2 Answers2

1

Sounds like you are using sessions.

It is not possible to run multiple php scripts in parallel for a single session, because this would lead to unexpected behaviour when using session variables.

More infos about this topic:

Long running php scripts

After you fixed the session locking you may be looking for something to prevent the script being killed after the client disconnects (closes the tab or cancels loading):

How do I stop PHP from sending data to client while still running PHP code in server?

wischi
  • 666
  • 10
  • 34
  • where does he mention sessions? –  Sep 03 '15 at 21:04
  • Of cause he does not mention sessions. If he knew that this is information is crucial he would have solved this problem without posting a question. He also does not mention the apache and os version and his screen resolution and many other things - because usually the do not matter. – wischi Sep 03 '15 at 21:08
  • what are you on about? this has noting to do with sessions at all –  Sep 03 '15 at 21:50
  • "I try to reload the page or run another PHP script while the script is running, nothing happened - the batch email process had to finish first" this is exactly what happens when the first script locks the session file and the second script has to wait until it is unlocked. – wischi Sep 03 '15 at 21:55
  • 1
    He's right, I'm using sessions for admin authentication in the one that prevents other scripts from loading – hedgehog90 Sep 04 '15 at 10:16
  • @hedgehog90 Would be great if you can mark the answer as accepted. If you miss any information let pls let me know ;-) – wischi Sep 04 '15 at 10:25
  • Thanks for the help wischi, still need some help on a few things though: I thought PHP was single threaded but I can run multiple php scripts in parallel, correct? Of course, when I check my php status on my server I can see there are multiple processes running at once. Why did nobody correct me on this? Also, if I need to check if the admin is authenicated only at the beginning of the script, should I just end the session immediately after the check to prevent the subsequent bottleneck? I don't know why but this seems... wrong. – hedgehog90 Sep 04 '15 at 10:51
  • php (served by apache) is not(!) single threaded. Apache creates a new thread (or process) for every request. The concept you've described ("single threaded but I can run multiple scripts in parallel") is used in node.js for example but not in php. A session is there to share information between requests. If you no longer need the session (or cached the infos for later use) you can close it - nothing wrong about that. – wischi Sep 04 '15 at 10:58
1

You could try :

system('php my_mailing_script.php > /tmp/mail_logs.txt &');

Don't forget the & symbol, it'll basically say : "Use a new thread to do that".

Loïc
  • 11,804
  • 1
  • 31
  • 49
  • I think (because he said "but my host server does not support this") that he is using a generic webspace hoster (without root access) and they do not allow system calls for obvious reasons. – wischi Sep 03 '15 at 21:12