我想从C程序执行PHP脚本并将返回的内容存储到C变量中.
我试过跟随,但它不起作用:
C:
printf("calling php function\n");
execl("/usr/bin/php -q", "/var/www/html/phpinfo.php", NULL);
printf("End php function\n");
Run Code Online (Sandbox Code Playgroud)
PHP:
<?php
echo "hello";
?>
Run Code Online (Sandbox Code Playgroud)
环境:
还建议任何其他更好的方法来做到这一点.
Joh*_*ica 13
这里简短的回答是使用system()或popen()不是execl().看到Jason已经发布了一个关于使用的好答案popen(),我将跳过这个并解释如何使用execl()以防你真正关心.最有可能的是,这是所有不必要的技术笨蛋 - 但是该死的,在讨论之前我已经将其中的大部分内容作为一个长长的前奏popen()而且我现在不会丢掉它!
调用execl()所有命令行参数时需要单独传递.此外,必须重复第一个参数,因为argv[0]在任何程序main()中传统上都是程序的名称.所以固定电话应该是这样的:
execl("/usr/bin/php", "/usr/bin/php", "-q",
"/var/www/html/phpinfo.php", (char *) NULL);
Run Code Online (Sandbox Code Playgroud)
(我添加了强制转换,(char *)以确保将空指针作为最终参数传递而不是整数0,如果NULL碰巧定义为0和不(void *) 0,这是合法的.)
这使得execl()呼叫正确,但是存在更大的问题.该exec系列函数几乎总是与结合使用fork()和一些复杂的pipe()戏法.这是因为exec函数不在单独的进程中运行程序; 他们实际上取代了当前的流程!所以一旦你打电话execl(),你的代码就完成了.成品.execl()永远不会回来 如果你只是像你所做的那样打电话,你将永远不会看到会发生什么,因为你的程序将神奇地转变为一个/usr/bin/php过程.
好了,这是怎么fork()和pipe()?在高层次上,您需要做的是将流程分为两个流程.父进程将继续是"您的"进程,而子进程将立即调用execl()并转换为自己的进程/usr/bin/php.然后,如果您已将父进程和子进程正确连接在一起,则它们将能够相互通信.
长话短说,如果你还在这里并且没有点头,你应该向智慧的oracle谷歌咨询有关所有这些的更多细节.有很多网站提供更多(!)深入细节如何做fork/ exec舞蹈.
我不会离开你的.这是我用于我自己的程序的函数,它完全按照我的概述.它实际上非常相似popen(),唯一的区别是调用者stderr除了stdin和之外还可以访问子流stdout.
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
pid_t execute(const char *command, FILE **in, FILE **out, FILE **err)
{
pid_t pid;
int fd[6];
pipe(&fd[0]);
pipe(&fd[2]);
pipe(&fd[4]);
switch (pid = fork()) {
case -1:
perror("unable to fork()");
exit(1);
case 0:
close(fd[1]); // Close write end of stdin.
close(fd[2]); // Close read end of stdout.
close(fd[4]); // Close read end of stderr.
dup2(fd[0], STDIN_FILENO); // Have stdin read from the first pipe.
dup2(fd[3], STDOUT_FILENO); // Have stdout write to the second pipe.
dup2(fd[5], STDERR_FILENO); // Have stderr write to the third pipe.
execlp("/bin/sh", "/bin/sh", "-c", command, (char *) NULL);
perror("execlp() failed");
_exit(1);
default:
close(fd[0]); // Close read end of stdin.
close(fd[3]); // Close write end of stdout.
close(fd[5]); // Close write end of stderr.
if (in) *in = fdopen(fd[1], "wb"); else close(fd[1]);
if (out) *out = fdopen(fd[2], "rb"); else close(fd[2]);
if (err) *err = fdopen(fd[4], "rb"); else close(fd[4]);
return pid;
}
}
Run Code Online (Sandbox Code Playgroud)
可能最简单的方法是使用popen函数 :(摘自链接页面):
以下示例演示如何使用popen()和pclose()执行命令ls*以获取当前目录中的文件列表:
#include <stdio.h>
...
FILE *fp;
int status;
char path[PATH_MAX];
fp = popen("ls *", "r");
if (fp == NULL)
/* Handle error */;
while (fgets(path, PATH_MAX, fp) != NULL)
printf("%s", path);
status = pclose(fp);
if (status == -1) {
/* Error reported by pclose() */
...
} else {
/* Use macros described under wait() to inspect `status' in order
to determine success/failure of command executed by popen() */
...
}
Run Code Online (Sandbox Code Playgroud)
但是,想要从C程序中读取PHP脚本的输出是一种危险信号,我怀疑可能有一些更清晰的整体解决方案,但如果没有更高级别的描述,你很难说更多重新尝试.