Passing data between PHP and C executable in linux

2020-03-20 17:44发布

问题:

Under Linux ,if I want to pass pure string from PHP to C, how do i do that? what I've tried do far is:

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

in PHP and

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

in C

everything works, but when i pass strings longers than MAX_ARG_STRLEN (131072), it will no longer return 0 instead it returns 127 which is command not found....

is there any other ways to pass string data to a linux executable? or is there any way to overcome the MAX_ARG_STRLEN problem?

回答1:

You could use popen() to open a pipe to the executable:

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

Then, as previously suggested, read from stdin in your C program:

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

It is "safer" to use popen() rather than exec('/bin/echo') because you can write characters that would otherwise be interpreted by the shell (&, |, ...). Note that the handle returned from PHP's popen() must be closed with pclose().



回答2:

A few options spring immediately to mind:

  • Store the data in a file and pass the filename on the command line. It's easy and simple but does require permissions to create and store files somewhere on the filesystem.

  • Open a pipe between your program and the C program; leave both processes running, at least until the C program has consumed the entire contents of your string. popen() is a convenient wrapper around this approach, but it does assume that standard input is the right destination, and it is unidirectional. Managing the pipes yourself lets you use a different file descriptor -- and you can tell the child which file descriptor to read via a command line argument. (See gpg(1)'s command line option --passphrase-fd to see what I mean.)

  • Use a SysV or POSIX shared memory segment to store you data in PHP, and then attach to the shared memory segment from your C program to read the contents. Note that shared memory segments persist, so you must clean up after them when you are done -- otherwise you will leak memory. This doesn't require permissions to create files in the filesystem and might be a nicer mechanism than dealing with pipes and keeping both processes alive long enough for one to completely write the data and the other to completely read the data.



回答3:

If it is more like a data structure than a string, what about using an embedded webserver? At first sight it may sound like overkill for your purpose, but mongoose for example is a very lightweight embeddable webserver:

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

There's also a nice tutorial about the exact same problem you have, transfering data between a PHP application and a C/C++ application. It's in german, though ... but maybe google translator can help:

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



回答4:

try using echo and pipe the output to your C executable instead of using args:

exec("/bin/echo | ./myexec.bin");

as @sarnold mentioned in comments it's wrong. Look at @Linus Kleen answer.

in your C program:

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