PHP, Email and Cron - php

Let me rephrase my question, I have a mysql database that is holding emails to be sent, on a shared host. I would like to run a cron job that will read the database and sent out any messages in the database every 10 minutes or so.
Now my question is, what is the best way with php to read my database and send out the emails in small batched so that I don't overwhelm the shared host.

Assuming the use of PDO, and making some accommodation for not knowing your schema, it might look something like this:
$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', 'dbuser', 'dbpass');
$msgh = $dbh->prepare('SELECT subject, body from message where listname = :listname');
$msgh->bindParam(':listname', $listname, PDO::PARAM_STR);
$msgh->execute();
$msg = $msgh->fetch(PDO::FETCH_ASSOC);
$usrh = $dbh->prepare('SELECT recipient from userlist where is_subscribed_to = :listname');
$usrh->bindParam(':listname', $listname, PDO::PARAM_STR);
$usrh->execute();
while ($recipient = $usrh->fetch(PDO::FETCH_ASSOC)) {
mail($recipient, $msg['subject'], $msg['body']);
if ($over_throttle) {
sleep(THROTTLE_SLEEP_SECONDS);
$over_throttle = 0;
}
++$over_throttle;
}
As for 'prewritten', you might take a look at phplist.

I would leave the throttling to the email server. Ie, run an email server locally, and have your PHP code relay all these messages to that. Then configure the email server itself to only send out at a certain rate.

Well I came up with this solution similar to the PDO one. Are there any unforeseen problems with running this as a cron job?
<?php
$con = mysql_connect("localhost","root","123456");
$throttle = 0;
$batch = 50;
$pause = 10; // seconds
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("maildb", $con);
// Message Table
$MSGresult = mysql_query("SELECT * FROM msgs");
// User Table
$USERresult = mysql_query("SELECT * FROM members");
while($MSGrow = mysql_fetch_array($MSGresult))
{
while($USERrow = mysql_fetch_array($USERresult))
{
mail($USERrow['email'],$MSGrow['subject'],$MSGrow['body']);
$throttle += 1;
if ($throttle > $batch ) { sleep($pause); $throttle = 0;}
}
mysql_data_seek($USERresult,0);
}
mysql_close($con);
?>

Related

Sytems running out of memory when Postgresql connection is established

I have built an api that is called 20 times in a second to perform a function that establishes connection to a postgresql but anytime the call is made the system memory gets full. I am a novie in postgresql and any assistance will be appreciated. Below is my php code
try
{
$input=file_get_contents("php://input");
$pgconn = new PgSql();
$selectRecords="SELECT messageid, msisdn, smsmessage, serviceid, isbilled, linkid FROM sdpmtn_mt.smssendingtable WHERE priority = 0 LIMIT 1";
foreach($pgconn->getRows($selectRecords) as $rows){
$msisdn = $rows->msisdn;
$message = $rows->smsmessage;
$serviceid = $rows->serviceid;
$isbilled = $rows->isbilled;
$linkid = $rows->linkid;
$msgid = $rows->messageid;
}
}
catch(Exception $e)
{
print $e->getMessage();
}
I am calling this API twenty times in a second. Please assist with any configurations I have to make.

Cron job script not working

So basically I have this cronjob script which worked on godaddy php 5.4, but in different host it does not work, tried different php versions too. I have correct path to cron, the host support said I did, even presented me with logs. Maybe there is some problem with this script? It basically adds energy points to user account.
<?php
include "../core.php";
//Fuel Refill (by default every 10 minutes)
$sqlusers = mysql_query("SELECT * FROM users WHERE banned='No'");
while ($rowuser = mysql_fetch_assoc($sqlusers)) {
if ($rowuser['fuel'] < $rowuser['fuelcapacity']) {
$userfuelrefill = mysql_query("UPDATE users SET fuel=fuel+1 WHERE username='$rowuser[username]'");
}
}
echo '<meta http-equiv="refresh" content="0;url=../garage">';
?>
mysql extensions are deprecated so try this PDO approach:
<?php
require [full/script/path/]core.php;
$PDO = new PDO([INSERT CONNECTION STRING]);
$result = $PDO->query("SELECT * FROM users WHERE banned='No'")->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $row)
{
if ($row['fuel'] < $row['fuelcapacity']) {
$query = "UPDATE users SET fuel=fuel+1 WHERE username= :username";
$query = $PDO->prepare($query);
if ($query->execute(array(':username' => $row[username]))) {
} else { throw new Exception('SQL Query Failed [' . $query->errorCode . ']'); }
}
}
echo '<meta http-equiv="refresh" content="0;url=../garage">';
Now of course there are some things you will have to replace like the connection string and full path but this should work with PHP PDO enabled.

Cron job: Code you cannot have PHP

My cron job does not work and I was wandering if there is any PHP code which will stop it from forming.
I know how it works, but I want to know what kind go code will not read in PHP code.
One code I found out does not work is sessionstart() and $_SESSION because it saves it on the server like a cookie and cron job does not go through the server or something.
Therefore, is there any other code which will not work from your own knowledge like maybe file_get_contents or fopen() (I don't know if these don't work. Just giving ideas)
EDIT
<?php
$dbhost = "localhost";
$dbuser = "it32_2015";
$dbpass = "it32_2015";
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
$sql = 'SELECT Title, Pubdate, Link FROM ytable';
mysql_select_db('it32_2015');
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
die('Could not get data: ' . mysql_error());
}
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
$status .= "速報ニュース:".
"{$row['Title']} : ".
"ここでチェック!".
"{$row['Link']}".
"時間:".
"{$row['Pubdate']}".
" #yahoonews END";
}
$statusarray = explode(" END",$status);
$result = mysql_query('SELECT MIN(ID) AS min, MAX(ID) AS max FROM ytable') or exit(mysql_error());
$row = mysql_fetch_assoc($result);
$check = file_get_contents('/home/www2/it32.lady2.itall.co.jp/www/counter.php');
if($check < $row['max']){
if (is_numeric($check)){
$counter = ++$check;
}
}
$fp = fopen('/home/www2/it32.lady2.itall.co.jp/www/counter.php',"w+");
fwrite($fp, $counter);
fclose($fp);
require("/home/www2/it32.lady2.itall.co.jp/www/tweet.php");
?>
Is there any code I cannot use for cron in my code.
Cron jobs i.e. scheduled tasks are scripts that run periodically. As such, the script isn't meant to be interfaced with by a user. It is just meant to carry out an action. So the reason sessions don't work with cron jobs is because there is no user to start a session for. Any PHP function that requires a user to work (e.g. setcookie(), session_start()) will not work. All other functions will.
Edit:
All the functions in your script will work as intended.

Sending emails to multiple recipients (PHP, My SQL)

Hi I am new to this and only have a basic understanding on PHP so any help would be most welcome. Basically I am trying to send an email via PHP that can have multiple recipients. The content also needs to display a list of users following certain criteria. I have got the script to look at the database and send an email however it only sends it to one person and only lists one person in the content. Please could someone advise on how to change that to email / display to multiple recipients. I know that there should be at least three people it is sent to.
Any help / pointers would be most welcome. Thank you.
<?php
session_start();
require_once('../config.php');
$errmsg_arr = array();
$errflag = false;
$link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
if(!$link) {
die('Failed to connect to server: ' . mysql_error());
}
$db = mysql_select_db(database_name);
if(!$db) {
die("Unable to select database");
}
$result = mysql_query("SELECT username FROM users WHERE user_type='admin'");
while($result_email = mysql_fetch_array($result))
$to = $result_email['username'];
$result2 = mysql_query("SELECT * FROM users
WHERE ticked='1' AND NOT user_type='super'");
while($result2 = mysql_fetch_array($result2))
$body = $result2['fname'] . " " . $result2['lname'] . " , " . $result2['username'];
mail ($to, 'Subject', $body);
?>
You can do that. They just need to be comma separated.
$to = "email#email.com, email2#email2.com";
Reference: http://php.net/manual/en/function.mail.php
Also, your code is a little confusing the way you have pasted it. But if you are loading all the emails in a while loop. Then you want to send it after the while. For example:
You want it to be:
//create an empty $to string
$to = '';
//add all the emails
while($emails as $email)
{
$to .= $email . ',';
}
//remove the last comma
rtrim($to, ",");
//send away
mail($to, $subject, $message);
your code is wrong. you would have error if you used it. you need to use implode to add comma between the emails. check your php. i corrected but you have to use while statement right. you have multiple mysql query for one job. also you should not use mysql_query. use PDO instead...
you should use it like this
<?php
while($row = mysql_fetch_array($result2))
{
$addresses[] = $row['username'];
}
$to = implode(", ", $addresses);
?>
with your code
<?php
session_start();
require_once('../config.php');
$errmsg_arr = array();
$errflag = false;
$link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
if(!$link) {
die('Failed to connect to server: ' . mysql_error());
}
$db = mysql_select_db(database_name);
if(!$db) {
die("Unable to select database");
}
$result = mysql_query("SELECT username FROM users WHERE user_type='admin'");
while($row = mysql_fetch_array($result2))
{
$addresses[] = $row['username'];
}
$to = implode(", ", $addresses);
$result2 = mysql_query("SELECT * FROM users
WHERE ticked='1' AND NOT user_type='super'");
$body = mysql_fetch_array($result2);
$body = $result2['fname'] . " " . $result2['lname'] . " , " . $result2['username'];
mail ($to, 'Subject', $body);
?>
You are overwriting the value of $to repeatedly with the statement $to = $result_email['username'];. You should make a comma-separated list instead. But for goodness' sake,
Consider setting the addresses as BCC, and set TO to something that does not matter, e.g. noreply#[yourdomain] to hide the recipients' addresses from each other.
Use DB-access that is not deprecated: PDO
Your call to mail() is not in a loop, so it will only send one e-mail.
And your while loop where you're setting $to is simply overwriting the previous value each time the loop iterates.
So in the end $to will be set to the last username the first query returns. And your $body will be the body you want for the last row your second query returns.

Connecting desktop app to online database via php

I've read a lot of posts on this general subject but I still can't seem to figure it out.
I'm building a Mac/PC desktop application. When a user first authorizes the app, I want to store their info in an online Mysql database. I'm using the JUCE library to call and handle a php file online which in turn handles the updating of the online database. On my desktop app:
String url = "http://www.syntorial.com/onlinePHPFileToCall.php?email=" + email + "&computer=" + SystemStats::getComputerName();
URL authURL(url);
InputStream *input = authURL.createInputStream(true);
String result = input->readString();
And the php file:
<?php
$result = "";
$mysqli = new mysqli('localhost','username','password','dbname');
if (mysqli_connect_errno())
{
$result = "connection failed";
}
else
{
$mysqli->select_db("UserInfo");
$email = $_GET['email'];
$computer = $_GET['computer'];
$query = "UPDATE UserInfo SET computer = '$computer' WHERE email = '$email'";
if ($queryResult = $mysqli->query($query))
{
$result = "true";
}
else
{
$result = "false";
}
}
echo $result;
?>
The result comes back "true" on my desktop app, but the information doesn't actually get saved into the database. If instead of
InputStream *input = authURL.createInputStream(true);
I use:
authURL.launchInDefaultBrowser();
it opens up the php file in a browser and everything works fine. Any ideas what I'm doing wrong?
Joe,
Seems like one of your first question on this forum. So Welcome. You mentioned you want to store information in an online database. But while connecting you added db information about your local via
mysqli('localhost',
. Update localhost to point to an online database by finding its ip address/servername, username and password. Also you will have to ensure the computer where you run this application can connect to that online db.
Here is what I am ran on my local and worked for me.
<?php
$result = "";
$mysqli = new mysqli('localhost','root','','test');
if (mysqli_connect_errno())
{
$result = "connection failed";
}
else
{
$email = "xyz#yahoo.com";
$computer = "1mycomp";
$query = "UPDATE so1 SET computer = '$computer' WHERE email = '$email'";
/*
Printing the query to check what is being executed.
Remove the below line after program works.
*/
echo $query;
if ($queryResult = $mysqli->query($query))
{
$result = "true";
}
else
{
$result = "false";
}
}
echo $result;
Turns out the "true" argument in CreateInputStream was telling it to use POST data instead of GET so the call was ignoring the GET data. Thanks the help.

Categories