1

这是围绕我要询问的部分的所有代码(请参阅本节下方的重点部分)。

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 =
4

2 回答 2

1

我在 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"

基本上发生的事情是,它将在“php”之后的终端命令中以空格分隔的每个字符串作为从 0 开始的数组值传递。

为了进一步澄清,如果我在“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"

如果您在命令中输入@ 符号,它将中断!!!!

yourremail@google.com 必须放入两个数组键中,如“youremail”和“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();
?>
于 2013-05-16T20:16:23.247 回答
0

如果您真的需要将其分开,您可以:

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

键入“crontab -e”,然后添加此行以每 10 分钟运行一次命令。

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

确保 PHP 的路径正确。

但是,我会尝试弄清楚为什么 mail() 函数需要这么长时间,但现在这将是一个快速修复。

于 2013-05-16T00:41:18.497 回答