使用PHP shell_exec()无法执行telnet命令。

5
我正在尝试使用telnet和php进行邮件验证。整个过程在终端中运行良好,但当我使用php shell_exec()时,它仅运行到Telnet连接命令。一旦建立了telnet连接,剩余的telnet特定命令就不再起作用。
是否有其他方法需要使用php执行telnet?
更新:我正在尝试复制this教程。
这是我的代码。
public function mailtest(Request $request){
        //Taking input email
        $email = $request->input("email");
        $divide = explode("@", $email);
        //Find out the Domain
        $server = $divide[1];
        $response = shell_exec("nslookup -q=mx $server");
        //Response of the nslookup
        print_r($response);
        $mailServerList = explode(PHP_EOL, $response);
        $line = $mailServerList[4];

        $serverArr = preg_split('/\s+/', $line);
        $n = sizeof($serverArr);
        $mailServer = $serverArr[$n-1];
        //Printing out the mail server out of the nslookup response
        print_r($mailServer);
        //Executing Telnet command
        $telnet = shell_exec("telnet $mailServer 25");
        print_r("telnet response ".$telnet);

        //Telnet Helo
        $helo = shell_exec("Helo testing.com");
        print_r("Helo response ".$helo);
        //Telnet mail from 
        $from = shell_exec('mail from: testing@gmail.com');
        print_r("MAil from response ".$from);
        //Telnet RCPT to
        $finalResponse = shell_exec("rcpt to: $email");
        print_r("Mail to response ".$finalResponse);
    }

这里是回应

Server:     10.0.80.11
Address:    10.0.80.11#53

Non-authoritative answer:
gmail.com   mail exchanger = 5 gmail-smtp-in.l.google.com.
gmail.com   mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
gmail.com   mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.
gmail.com   mail exchanger = 30 alt3.gmail-smtp-in.l.google.com.
gmail.com   mail exchanger = 20 alt2.gmail-smtp-in.l.google.com.

Authoritative answers can be found from:
gmail-smtp-in.l.google.com  internet address = 173.194.64.27
gmail-smtp-in.l.google.com  has AAAA address 2607:f8b0:4003:c02::1a
alt1.gmail-smtp-in.l.google.com internet address = 173.194.219.27
alt1.gmail-smtp-in.l.google.com has AAAA address 2607:f8b0:4002:c03::1b
alt4.gmail-smtp-in.l.google.com internet address = 64.233.190.26
alt4.gmail-smtp-in.l.google.com has AAAA address 2800:3f0:4003:c01::1b
alt3.gmail-smtp-in.l.google.com internet address = 74.125.141.26
alt3.gmail-smtp-in.l.google.com has AAAA address 2607:f8b0:400c:c06::1a
alt2.gmail-smtp-in.l.google.com internet address = 173.194.205.27
alt2.gmail-smtp-in.l.google.com has AAAA address 2607:f8b0:400d:c02::1b

gmail-smtp-in.l.google.com.telnet response Trying 2607:f8b0:4003:c02::1a...
Connected to gmail-smtp-in.l.google.com.
Escape character is '^]'.
Helo response 
MAil from response No message, no subject; hope that's ok
Mail to response 

作为替代方案,可以尝试使用PHP的imap扩展和imap_*函数。 - Alex Andrei
@AlexAndrei 抱歉,但它确切地做什么? - Parthapratim Neog
该扩展提供了允许您通过IMAP协议进行操作的函数,请参见此处http://php.net/manual/en/book.imap.php。 - Alex Andrei
@AlexAndrei 对此我不是很了解,但是你能告诉我它是否有助于电子邮件验证或执行Telnet命令吗? - Parthapratim Neog
3个回答

4

shell_exec 不适合这种情况(请参考 Ulrich 的解释)。

fsockopen 应该可以解决问题。

$fp = @fsockopen('yourMailServer.com', 9001);      

if ($fp) { 
    fwrite($fp, "username\n");
    fwrite($fp, "password\n");

    while ($line = fread($fp, 2048)) {    
       // do things with $line    
    }    
} else {    
    //return error    
}

基本上我想要执行 telnet myMailServer.com 25 来开始连接,然后按照这个Tutorial所示的方式以 Helo hi 开始等等。我尝试使用 fsockopen,但似乎没有起作用。你能否检查一下教程,并看看我应该如何使用 fsockopen 或任何你认为可以达到目的的方式? - Parthapratim Neog
对于教程中的每一条绿色线,您应该调用fwrite命令。对于每一条蓝色线,您应该在while循环内读取(并执行)$line参数。 - Lavi Avigdor
那么,一旦@fsockopen('yourMailServer.com', 25);成功了,我是要用telnet yourMailServer.com 25开始吗?还是说fsockopen命令已经达到了同样的目的? - Parthapratim Neog
fsockopen替代了telnet,它打开一个套接字。 - Lavi Avigdor

2

在参考了@Lavi的答案后,我成功解决了这个问题。使用fputs而不是fwrite就搞定了。

$connect = @fsockopen($mailServer, 25);
if($connect){
    fputs ($connect , "HELO $mailServer\r\n");
    $out = fgets ($connect, 1024);
    $details .= $out."\n";

    fputs ($connect , "MAIL FROM: <$fromemail>\r\n");
    //$from = fgets ($connect, 1024);
    fputs ($connect , "RCPT TO: <$toemail>\r\n");
    //$to = fgets ($connect, 1024);
    fputs ($connect , "QUIT");
    fclose($connect);
}

这个工作得非常完美,但是我不得不改变fgets的位置,因为需要4个来获取所有输出的信息。 - Dan Hastings
它说即使是无效的电子邮件也是有效的 ::( - Anubhav Tiwari

1

shell_exec() 启动一个新进程。它首先启动一个 shell,然后将给定的字符串作为命令执行。您不能使用多个 shell_exec() 命令与同一 shell 交互,就像远程控制终端一样。

如果我是你,我会尝试构建现有代码。例如,有许多现有的 PHP SMTP 库。我相信其中至少有一个库能够做到你想要的或者至少能够展示出你可以实现缺失功能的方法。

如果你真的坚持要自己开发,可以参考现有的答案,例如与命令行程序交互或 PHP 的 expect 模块。除非绝对必要,否则最好避免这样做,因为它效率低下。另外,为了安全起见,Web 服务器通常配置为禁止启动新进程,因此如果您的代码在命令行中运行时正常但在 Web 服务器内部不正常,请记住这种差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接