【问题标题】:Passing data between PHP and C executable in linux在Linux中的PHP和C可执行文件之间传递数据
【发布时间】:2011-11-19 09:18:26
【问题描述】:

在 Linux 下,如果我想将纯字符串从 PHP 传递到 C,我该怎么做? 我到目前为止所做的是:

exec("./myexec.bin -a mystring");

在 PHP 中和

getopt(argc,argv, "a:");

在 C 中

一切正常,但是当我传递的字符串长度超过MAX_ARG_STRLEN (131072) 时,它将不再返回 0,而是返回 127,即找不到命令....

还有其他方法可以将字符串数据传递给 linux 可执行文件吗?或者有什么办法可以克服MAX_ARG_STRLEN 的问题?

【问题讨论】:

  • 只是补充一下,我传递的字符串可能超过 393216 个字符,因为 ((256^2)*6)*2;我想将它们存储在一个文件中,但它的大小几乎为 1MB,@Linus Kleen 解决方案目前是我迄今为止最好的解决方案
  • 它真的只是一个字符串还是你想要传递的数据结构?
  • 经过一些实验,我得出结论 proc_open() 更好,因为它同时提供标准输入和标准输出,而 popen() 只提供输入或输出

标签: php c linux string parameter-passing


【解决方案1】:

您可以使用popen() 打开通往可执行文件的管道:

$fp = popen('./myexec.bin', 'w');
fwrite($fp, $data);
pclose($fp);

然后,如前所述,在您的 C 程序中从 stdin 读取:

fopen(stdin, "r");
// ...

使用popen() 而不是exec('/bin/echo') 更“安全”,因为您可以编写否则会被shell 解释的字符(&、|、...)。请注意,从 PHP 的 popen() 返回的句柄 必须pclose() 关闭。

【讨论】:

    【解决方案2】:

    一些选项立即浮现在脑海中:

    • 将数据存储在文件中并在命令行中传递文件名。它简单易行,但需要权限才能在文件系统的某个位置创建和存储文件。

    • 在你的程序和 C 程序之间打开一个管道;让两个进程都运行,至少在 C 程序使用完字符串的全部内容之前。 popen() 是围绕这种方法的一个方便的包装器,但它确实假设标准输入是正确的目标,并且它是单向。自己管理管道可以让您使用不同的文件描述符——您可以通过命令行参数告诉孩子要读取哪个文件描述符。 (请参阅gpg(1) 的命令行选项--passphrase-fd 了解我的意思。)

    • 使用 SysV 或 POSIX shared memory segment 将数据存储在 PHP 中,然后从 C 程序附加到共享内存段以读取内容。注意共享内存段persist,所以你必须在完成后清理它们——否则你会泄漏内存。这不需要在文件系统中创建文件的权限,并且 可能 是一种比处理管道和保持 两个 进程存活足够长的时间以完全写入数据的机制更好另一个是完全读取数据。

    【讨论】:

      【解决方案3】:

      如果它更像是一个数据结构而不是一个字符串,那么使用嵌入式网络服务器呢?乍一看,这听起来有点过分,但例如 mongoose 是一个非常轻量级的可嵌入网络服务器:

      http://code.google.com/p/mongoose/

      还有一个很好的教程,关于您遇到的完全相同的问题,在 PHP 应用程序和 C/C++ 应用程序之间传输数据。虽然它是德语的......但也许谷歌翻译可以提供帮助:

      http://blog.aditu.de/2010/05/15/serverbridge-zwischen-php-und-cc/

      【讨论】:

        【解决方案4】:

        尝试使用 echo 并将输出通过管道传输到您的 C 可执行文件,而不是使用 args:

        <strike>exec("/bin/echo | ./myexec.bin");</strike>

        正如@sarnold 在 cmets 中提到的那样,这是错误的。看@Linus Kleenanswer

        在您的 C 程序中:

        fopen(stdin, "r");
        // ...
        

        【讨论】:

        • 您的echo 命令对参数长度有完全相同的限制。
        • @sarnold 我认为限制是因为C 程序。谢谢指正。
        • 这是内核强制的限制——今天的 128KB 实际上比以前大得多。 :)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多