Is there any way i can send out about 3000+ emails from one php script request without overloading a dedicated IP... the max would be 500 per hour?
If you dont get me.. here is detailed :)
I can only send out 500 emails via the mail() function in PHP per hour via my dedicated IP, is there any way i could send out for example 3000 rows of emails pulled from an email address but stagger the mail() functions out for 500 per hour...
Thanks already!
Create 2 tables, one for the email message and one for the list of recipients.
Then create a script to be run by cron that checks if there is a new message in the message table and if so sends a batch of email to the next set of recipients. Marking each recipient after the mail is sent.
Then you create a web interface for your client to create a message and attach recipients to the message once the user marks the message as ready to go your cron job picks it up and processes it.
If there aren't any messages to be sent your cron job doesn't do anything.
You could sleep between the calls, or, if they're already in a database, put a field in there that says when they were sent. Then you select the ones that haven't been sent, and start from there.
I would put a field in the DB to show when the last email was sent to each user and what email it was. I would also have another DB table to show each email you sent and if it has been sent to all users yet.
User Table:
Id, UserName, Email, etc, DateTimeOfLastEmail, LastEmailId
Email Table:
Id, EmailSubject, EmailContent, DateTimeSent, SentToAll(True/False), DateTimeOfFinish
Thanks for all the answers!
The best way i found was actually to simply sleep() between calls using the sleep() as i tested 400 mails, this took 17 seconds :)
It is unlikely the user will send more than the 450 limit ... but if they do i have an if statement before the while() ends checking if there are more than 450 rows, if so it will sleep between each... this works without fiddly databases :)
Thanks!
well after doing some math you could send an email every 8.3 seconds (498/hr) but it doesn't solve the problem. I think another approach would be to use a DB, query for the 500 and have a CRON job run the script every hour.
So in the DB table you could have the script update a field after the email has been sent so the next cron job will query and get the next 500 emails that need to be sent.
Related
I'm a beginner in php and I want to know if there is a way to send out an email with delay. I want to build a website where users can send an email to themselves with their goals and predictions, and after one year, they should receive their own email automatically.
Does anyone has an idea how I could do this?
You will have to take a look at CRON Jobs. CRON Jobs can be set to run at certain intervals. Hourly, Daily ect.
Here is a link to a tutorial.
You would need to store the email inside of a database or something.
Then you would need code that either auto starts 15 minutes after a new row has been added, or you would need code to check through the database for any unsent mail every few minutes. Usually "cron" is used for this.
I have developed a custom newsletter sending module using php in which admin can send newsletter to subscribers. Newsletter can be designed within the module and can be send by selecting the category of subscribers that contain thousands of emails with one click. Now issue is i have a restriction of sending 500 emails per hour. Using sleep() cause expiry of max execution script time.
After some research it came to me that this can be done via cron job. I created a cron job in cpanel that is set to every 5 minutes but i am not able to figure out that how this cron job will be triggered when admin click on send newsletter button in administrative panel. I am using swiftmailer library and querying subscriber table on some category id.
Any Help will be greatly appreciated.
This is what I would do:
Have two tables. One for the email being sent and one for the emails that the newsletter is going to with what newsletter the email is receiving.
Structure examples
table newsletter :
id - Auto INC
email_subject - Subject of newsletter
email_html - HTML version of the email
email_plain_text - Plain text version of email
created_datetime - datetime newsletter was created
table newsletter_recipients:
id - Auto INC
newsletter_id - ID of what newsletter is being sent out (create a foreign key referring to the id field on the newsletter table
email - HTML version of the email
name - Name of client
sent - Whether the email was sent off or not (this isn't required, see below)
When the administrator sends the email create the newsletter row with the html/plain text version (you can use only one column, just better to have a html and plain text version of email) and also add the recipients to the newsletter_recipients table referring the newsletter_id to the id of the newsletter you added.
Now you have your PHP cron job file run every hour. This file will check if any clients need a newsletter sent out and if so send it out. Once sent out you can either delete the recipient row or mark it as sent. Personally I would delete them to keep data from backing up. Only run the php job up till 500 or whatever amount of emails you want to send out then have the script end. Next hour it will run and pick up the next 500.
With this system the newsletter wont be sent out immediately, it will be done when the cron job runs. But this is the best solution I can quickly think up for you. That or get a mail server that lets you send out all the emails you want and use something like gearman to handle load balancing.
NOTE: Storing the newsletter in a database can be handy so the admin can look back and see when they sent out their newsletter. Also you can step it up another level and create a sent_date column on the newsletter_recipient table that stores when the email was sent (if you are simply marking the recipient as sent or not instead of deleting) that way you know when the emails finished sending, who received the emails at what time, etc. This is totally up to you).
I have a php script which sends user a mail if his purchase is successful. The problem is it the page loads slow due to mail(). I know there are ways like putting the mails in a database table and then using a cron job to send them but the frequency of purchase can be high and I want the mail to be sent right away, so that doesn't look like a good option.
The purchase request gets processed by the same page from where he purchased and he can only do so once. The user doesn't control any part of mail other than the purchase details. I thought of using Ajax, the script would send the data to client side and call a ajax function which then calls another mail script but this would let user know what is being sent and can be tampered. Is there any other way I can use Ajax safely without letting user know whats being sent and where? And are there any better workarounds?
mail() should return immediately upon queuing the message to your mail server, which (generally) should take no time at all, so I think your problem here is definitely the mail server and not your PHP. I'm guessing that the mail server you're submitting to is running some anti-spam checks, like reverse DNS lookups. It might also be throttling you based on usage. Can you try sending through another mail server to verify?
Also, if you have shell access, try sending a message from the shell (e.g., echo test | mail -v -s test me#whatever.com) to see what it's doing and how long it takes.
Edit: Just noticed your comment re: Windows. In this case, at least you can try a telnet from the PHP server to port 25 on the mail host to see how long it takes to connect and get the 220 greeting header. (I bet you'll connect immediately but won't get the 220 header for a while.)
You're on to the right idea. Here's what I would do in this scenario:
The user makes a purchase (no ajax unless you want to at this point)
In processing that purchase an email is inserted into the email table with an "id" & "sent" column plus all the other stuff.
User is brought to a success page
The success page kicks off ajax in the background to send the email with that id from the db - and doesn't care about the result
The php page in charge of emailing sends the email and marks the sent column
If someone ever makes a call to your database with an id that's not sent, that email needed to get sent out anyway, so it's ok. If the id doesn't match or the sent column is marked true, you can ignore it. No worries about people trying to send spam using your system.
I want to send email to my app users ensuring that every email is sent only once.
I will be recording the email transmission in a database.
If I use this order of operations:
Insert into database
Send email
Commit
There is a chance that script times out just after sending the email (step #2) and before doing the commit (step #3). In that case the change in step #1 will not be committed and email sending job won't be able to know that the email was successfully sent last time so the same email will be sent again.
Is there a way out or do I have to live with occasional duplicate emails?
To make a long story short: you can't make email transactional.
At best you know that your smtp server recieved your request to sent the message. You have however no way of knowing whether it got sent, was received or bounced.
So your best bet, as you already suggested, is to live occasional duplicate emails. It will be a very rare event anyway.
You can use MySQL transactions for this, basically it prepares all your queries and executes them when you tell it to do so.
So you prepare the queries before sending the mail, then commit it after sending it.
More info
http://dev.mysql.com/doc/refman/5.0/en/commit.html
Alternatively you could set the mail as pending, and afterwards update it as completed. Then run a cron job that kills pending jobs that have been running for a certain amount of time, or try to reprocess them.
well you can make a column status which can be enum or int with values representing sending, failed, sent_successfully
Now, you do this:
Insert the data before sending the mail. And set status to sending
Send the mail
based on the result in step (2), update the row either failed or sent_successfully.
You might also like to have a column tries and a batch process that sends failed mails at every 30 minutes, if tries < TRY_THRESHOLD. And then, set status to failed_permanently or sent_successfully and log the error.
Just got some time to think over my own question. Here is what I think now:
The email sending steps in question were:
Insert into database
Send email
Commit
Email cannot be made transactional because the step #2 (above) is not part of the transaction even though it is done while the transaction is active.
These steps can help ensure that any failed email-sending attempts is retried but cannot guarantee that an email is not sent more than once. This situation could only be improved if the email sending engine is transaction-aware. Such an engine would (atleast) do the following:
Accept email job submission but don't send the email until the commit is performed
Make the commit fail if the email is not sent.
Cancel the submitted job if the transaction is rolled-back
I am not aware of any such email server.
Nishant, in his answer suggested following steps:
Insert the data before sending the mail. And set status to sending
Send the mail
based on the result in step (2), update the row either failed or sent_successfully.
These steps also cannot ensure duplicate sending of email due to script timeout for the same reason as noted above.
So far, I think, I will just have to live with occasional duplicate emails.
i have a program which use to send group emails, i set a cornjob per mins for this program, and set execute per 2nd/min, and check if the now time is match to my defined schedule time in db. if true the program will run and send email, else nth...
the problem is i want to dynamic set the amount of email sending per mins by user, let say i have 10000 emails to send, and i want to send 3 emails per min, something like that, but i cant find the way when using cronJob, (set cookie? record the current email to db?),
since i found that if i use sleep(), it will cause php execute limit error...
Can anyone tell me how to do that?
or using other method to do schedule task? pear?
if using other methods, can show how to use it briefly ?
Please And Thx
First of all. 10000 emails with 3 per minute will take over 2 days.
Secondly, the best way to do this is to save the emails to database (to, title, body etc) and then create a script that sends out 3 emails and set the cronjob to run every minute.
Also check out these questions.
Sending bulk email in PHP
Sending mass email using php
Best way to send 10,000+ emails with PEAR/Mail_Queue
I think you should set this configuration at the application level rather than the cron job level.
Let's say, cron job should run every minute but the application itself should know howmany e-mails to send when a cron job runs by checking the datetime for the last e-mail is sent, and let's say, send 3 more e-mails and so.
its only example to said 3 emails per mins
actually i want to give user to set the amount of sending email per min/ per hour/ per second
and i know about the send email program, but what if mutil task doing..
such as 3 newsletter will blast at 20/3/2009 15:15:00; each of those target to 10000pls
i dun want to save the whole blast list in db, since client may import a email list for 40000 ppls, always timeout when import, even i set the time limit to 2 mins, dun want to take more then that time
so do u have any sugeestion on the email sending?