从C程序执行PHP脚本和存储的结果给一个变量 [英] executing php script from C program and store the results in to a variable

查看:119
本文介绍了从C程序执行PHP脚本和存储的结果给一个变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从C程序执行PHP脚本,并返回的内容存储到一个C变量。

I would like to execute a PHP script from a C program and store the returning content in to a C variable.

我试着喜欢下面,但它不工作:

I tried like following but it doesn't work:

C:

printf("calling php function\n");
execl("/usr/bin/php -q", "/var/www/html/phpinfo.php", NULL);
printf("End php function\n");

PHP:

<?php
echo "hello";
?>

环境:


  • PHP 5.2.6

  • Apache 2.0的

  • 的Fedora Core 10

同时建议任何其他更好的方式来做到这一点。

Also suggest any other better way to do this.

推荐答案

短这里的答案是使用系统()的popen(),而不是 EXECL()。眼看贾森已经张贴了关于使用一个很好的答案的popen(),我会跳过,并解释如何使用 EXECL()万一你真的不在乎。最有可能的,这是所有不必要的技术魔神 - 但该死的,我这个最敲出已经作为一项长期的prelude讨论之前的popen()和我又不是把它扔了吧!

Short answer here is to use system() or popen() rather than execl(). Seeing as Jason has already posted a good answer about using popen(), I'll skip that and explain how to use execl() just in case you actually care. Most likely, this is all unnecessary technical mumbo jumbo--but dammit, I had most of this typed out already as a long prelude before discussing popen() and I'm not throwing it away now!

致电时 EXECL()所有的命令行参数需要单独通过。此外,第一个参数必须重复的argv [0] 在任何程序中的的main()是传统的名该程序。因此,固定电话应该是这样的:

When calling execl() all of the command-line arguments need to be passed separately. Also, the first argument must be repeated as argv[0] in any program's main() is traditionally the name of the program. So the fixed call should look like:

execl("/usr/bin/php", "/usr/bin/php", "-q",
    "/var/www/html/phpinfo.php", (char *) NULL);

(我增加了投地(字符*)来确保一个空指针作为最后一个参数,而不是整数0过去了,如果 NULL 碰巧被定义为 0 ,而不是(无效*)0 ,其中是合法的。)

(I added the cast to (char *) to ensure that a null pointer is passed as the final argument rather than the integer 0, if NULL happens to be defined as 0 and not (void *) 0, which is legal.)

这得到 EXECL()调用正确的,但有一个更大的问题。在 EXEC 系列函数几乎总是结合使用叉()和一些复杂的管()杂耍。这是因为 EXEC 功能不运行在单独的进程方案;他们实际上取代目前的过程!所以一旦你叫 EXECL(),您的code完成。成品。 EXECL()永不再来。如果你只是把它像你这样做,你永远也没有机会看看会发生什么作为你的程序会奇迹般地转变为的/ usr / bin中/ PHP 的过程。

This gets the execl() call right, but there's a bigger problem. The exec family of functions are almost always used in combination with fork() and some complicated pipe() juggling. This is because the exec functions do not run the program in a separate process; they actually replace the current process! So once you call execl(), your code is done. Finished. execl() never returns. If you just call it like you've done you'll never get to see what happens as your program will magically transform into a /usr/bin/php process.

好了,这是什么关于叉()管道()?在一个较高的水平,你必须做什么是你的分裂过程分为两个过程。父进程将继续以你的过程,而子进程会立即调用 EXECL()和自身转变为的/ usr / bin中/ PHP 。然后,如果你已经在一起接线正确的父子进程他们将能够与对方进行沟通。

OK, so what's this about fork() and pipe()? At a high level, what you've got to do is split your process into two processes. The parent process will continue to be "your" process, while the child process will immediately call execl() and transform itself into /usr/bin/php. Then if you've wired the parent and child processes together correctly they'll be able to communicate with each other.

为了使长话短说,如果你还在这里,并没有点头答应下来,你应征询聪明的甲骨文谷歌的方式更多细节了这一切。有很多网站在那里提供更多的(!)深入了解如何做叉细节 / EXEC 舞蹈。

To make a long story short, if you're still here and haven't nodded off you should consult the wise oracle Google for way more details about all of this. There are plenty of web sites out there giving even more (!) in-depth details about how to do the fork/exec dance.

我不会离开你的,虽然绞刑。下面是我用我自己的程序,不正是我所概述的功能。这非常类似于的popen()事实上,唯一的区别在于调用方可以访问孩子的标准错误流除了标准输入标准输出

I won't leave you hanging though. Here's a function I use for my own programs that does exactly what I've outlined. It is very similar to popen() in fact, the only difference being that the caller can access the child's stderr stream in addition to stdin and 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;
    }
}

这篇关于从C程序执行PHP脚本和存储的结果给一个变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆