如何在没有用户加载页面/. PHP文件的情况下运行PHP mail()函数?


How can I run a PHP mail() function without a user loading a page/.php file?

这是围绕我所询问的部分的所有代码(请参阅本文下面的要点部分的缩写)。

if($register == "true") //Registration "checks out" okay
        {
        $gooddata['password'] = md5($gooddata['password']);
//This is where the information is saved to the database.
            $query = "INSERT INTO member (username,password,votingdistrict,email,birthmonth,birthyear,city,state,zip5,registeredtovote)
                      VALUES ('$gooddata[username]','$gooddata[password]','$gooddata[votingdistrict]','$gooddata[email]','$gooddata[birthmonth]','$gooddata[birthyear]','$gooddata[city]','$gooddata[state]','$gooddata[zip5]','$gooddata[registeredtovote]')";
        $result = mysqli_query(dbcxn('member'),$query)
                or die("<h3 class='"headertag'">Username or E-mail already exists. <a href='"./register.php'">Try a different username</a> or <a href='"./resetpassword.php'">reset your password</a></h3>'n</header>");
        if($result)
            {
            $query = "SELECT vernumber FROM member WHERE username='$gooddata[username]'";
            $result = mysqli_query(dbcxn('member'),$query)
                or die("Could not find a verification number!");
                if($result)
                    {
                    $preextract = mysqli_fetch_assoc($result);
                    extract($preextract);
                    $email = $gooddata['email'];
                    $subject = "Confirmation of Unipartisan registration for " . $gooddata['username'];
                    $message = wordwrap("Please click <a href='"'">this link<a> to complete your registration.<br /> 'n" . 
                               "If you did not try to register with <a href='"http://unipartisan.com'">Unipartisan.com</a> please disregard this e-mail or click here.",70);
                    $mailsent = mail($email,$subject,$message);
                    if($mailsent == true)
                        {
                        echo "An e-mail has been sent to you to complete your registration</h3>'n";
                        }
                    else
                        {
                            echo "The registration email failed to send</h3>'n";
                        }
                    }
            }        
        echo "</header>'n";
        echo "<article class='"index'">'n";
        echo "    <h3>Return to the <a href='"./index.php'">homepage</a></h3>'n";
        echo "</article>'n";           
        }

我的问题是如何在注册成功完成后仍然向用户发送电子邮件,但没有在相同的。php文件中执行,并且不必将该。php文件发送给用户。

我问的原因是因为mail()函数需要很多时间来处理,并且页面大约30秒不会加载。然而,邮件确实被成功发送了。

下面是我所指的具体部分。

 $email = $gooddata['email'];
 $subject = "Confirmation of Unipartisan registration for " . $gooddata['username'];
 $message = wordwrap("Please click <a href='"'">this link<a> to complete your registration.<br /> 'n" . 
 "If you did not try to register with <a href='"http://unipartisan.com'">Unipartisan.com</a> please disregard this e-mail or click here.",70);
$mailsent = mail($email,$subject,$message);
if($mailsent == true)
    {
    echo "An e-mail has been sent to you to complete your registration</h3>'n";
    }

我知道我可以为此使用cronjob,但是我只发现程序员试图按时间设置重复脚本的情况,或者他们试图延迟脚本。我仍然希望它立即运行,但是我不想在注册处理的同一个文件中运行邮件函数,因为这会导致客户端出现难看的延迟。

如何在完成注册的同时执行此操作?

这是我的PHP.ini的相关部分。

[mail function]
; For Win32 only.
; http://php.net/smtp
;SMTP = localhost
; http://php.net/smtp-port
;smtp_port = 25
; For Win32 only.
; http://php.net/sendmail-from
;sendmail_from = ryan@unipartisan.com
; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
; http://php.net/sendmail-path
sendmail_path = /usr/sbin/sendmail -t -i -f ryan@unipartisan.com
; Force the addition of the specified parameters to be passed as extra parameters
; to the sendmail binary. These parameters will always replace the value of
; the 5th parameter to mail(), even in safe mode.
;mail.force_extra_parameters =

我在php中编写了两个文件,展示了如何完成此操作。如果不需要延迟或每隔一段时间运行文件,则只需使用终端。

<!--File Name: cmdlinetest.php
This is the file that execute.php would run
-->
<?php
/*  
In the Unix terminal I can write: 
php /pathtophpfile/cmdlinetest.php MyEmail MyEmail'sDomain EmailSubjectorOtherVariable

1)所以我调用程序,php,并告诉它运行cmdlinetest.php…

2)这里有一个空格,然后我写电子邮件。我希望。php文件处理我的电子邮件的第一部分:myemail

3)然后是空格和我的电子邮件的第二部分:google.com

3)然后另一个空间加上我的网站的用户名(或其他所需的变量),所以我知道我的数据库处理的哪一部分。

4)命令行全局变量$argv被传入.php文件。

$argv[0] == "/pathtophpfile/cmdlinetest.php"//this is pretty much useless, so ignore it!
$argv[1] == "MyEmail"//no @ symbol.
$argv[2] == "MyEmail'sDomain"//no @ symbol.
$argv[3] == "EmailSubjectorOtherVariable"

基本上发生的是,它在终端命令中传递以空格分隔的每个字符串

为了进一步澄清,如果我在"EmailSubjectorOtherVariable"之后添加"EmailMessage",命令将看起来像这样:

php /pathtophpfile/cmdlinetest.php MyEmail google.com EmailSubjectorOtherVariable EmailMessage

被命令调用的程序:php

$argv[0]:文件名,这样php就知道它在运行什么,如果你愿意的话,它成为$argv[0]的值只是一个"副作用"。

$argv[1]:文件名后的第一个字符串,该字符串是我的电子邮件,在@符号之前,由空格分隔。

$argv[2]:在@符号之后用空格分隔的第二个字符串,即我的电子邮件。

$argv[3]:如果我想做数据库操作或电子邮件主题,我要传递给文件的网站用户名。

$argv[4]:现在终端命令中最后一个空格分隔的字符串是"EmailMessage"…你猜对了;$argv[4] == "EmailMessage"

如果你在命令中加入@符号,它将中断!!!!

youremail@google.com必须放入两个数组键"youremail"answers"google.com"在PHP代码中添加@符号!!

这是我在电子邮件中添加@的错误:

PHP Parse error:  syntax error, unexpected '@' in /opt/lampp/htdocs/unipartisan/cmdlinetest.php on line 26

现在我将回显传递的变量以用于测试。

echo "E-mail part 1: " . $argv[1] . "'nE-mail part 2: " . $argv[2] . "'n";//Key 1 has email before the @. Key 2 has after the @.
echo "Subject of e-mail(site's username): " . $argv[3] . "'n";//The username you want to test.  (This can really be anything you want; username is an example)
echo "Message of e-mail: " . $argv[4] . "'n"; //"EmailMessage"

上面的回显只是为了测试您自己的输出。当exec()函数

在另一个文件中运行时,用户不会看到任何这些。

现在,因为电子邮件是分岔的,我们需要把它重新组合起来!

$wholeemail = $argv[1] . '@' . $argv[2]; 
echo $wholeemail . "'n";

我们人类的另一个测试,以确保它是正确的。如果您从终端运行此命令,将显示回显。

如果它在另一个。php文件的exec()中运行,用户将看不到它。所以它们只在构建此文件时用于测试!

下面我将$argv键命名为它们自己的变量,只是为了让新用户看起来不那么困惑。

$subject = $argv[3];//Username or email subject
$message = $argv[4];//"EmailMessage"
mail($wholeemail,$subject,$message,"FROM: Unipartisan Registration");//"FROM: Who ever you are"
exit();
?>

cmdlinetest.php到此结束

这就是execute.php的用武之地。

<!--File Name: execute.php
This is an example of the code you would enter in the 
php file being displayed to the user when you want to run an 
external script without showing it to the user.
-->
<!DOCTYPE html>
<html>
<body>
<?php
exec('php /YourPathTo/cmdlinetest.php EmailBeforeAt EmailAfter@ YourEmailSubject YourMessage');//Abandon all hope ye who dare put an @ symbol here
echo "Okay go check your e-mail and hope it comes.";
?>
</body>
</html>

因为我是一个好人,这里是一个简单版本的cmdline.php没有过多的注释。

<!--File Name: cmdline.php-->
<?php
echo "E-mail part 1: " . $argv[1] . "'nE-mail part 2: " . $argv[2] . "'n";//Key 1 has email before the @. Key 2 has after the @.
echo "Subject of e-mail(site's username): " . $argv[3] . "'n";//The username you want to test.  (This can really be anything you want; username is an example)
echo "Message of e-mail: " . $argv[4] . "'n"; //"EmailMessage"
$wholeemail = $argv[1] . '@' . $argv[2]; 
echo $wholeemail . "'n"; //Another test for us humans to make sure it's right.  The echos will show up if you run this from the terminal.
//If it is ran in exec() in another .php file your users will not see it. So they only serve for testing while building THIS FILE!
//Below I name the $argv keys in their own variable just to make this look less confusing for new people.
$subject = $argv[3];//Username or email subject
$message = $argv[4];//"EmailMessage"
mail($wholeemail,$subject,$message,"FROM: Something");//"FROM: Who ever you are!"
exit();
?>

如果你真的需要把它分开,你可以:

    在用户表中创建一个名为"welcomeEmailSent"的新列。将此设置为bool,默认为0。
  1. 编写一个名为sendregisteremail .php的脚本。该脚本应该连接到数据库并检索welcomeEmailSent=0的所有行。
  2. 脚本然后循环执行每个待处理用户的mail()操作,并更新用户表以标记welcomeEmailSent=1
  3. 设置一个cron任务来运行sendRegisterEmails.php脚本。

输入"crontab -e",然后添加这一行,每10分钟运行一次命令。

*/10 * * * * /usr/local/bin/php5 /path/to/sendRegisterEmails.php

确保PHP的路径是正确的。

我会试着找出为什么mail()函数花了这么长时间,但这将是一个快速修复现在。