0

I'm trying to make a call for a c++ / python file with proc_open (bi-directional support needed).

After doing some on-line research I found created this code: (I first tried it with c++, after failure I tried python as well)

PHP:

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error-output.txt", "a")
);

$process = proc_open('new.exe', $descriptorspec, $pipes);

$input = 20;
$exp = 2;
if (is_resource($process)) {
    print fgets($pipes[1]);
    fwrite($pipes[0], $input);

    print fgets($pipes[1]);
    fwrite($pipes[0], $exp);

    print fgets($pipes[1]);

    fclose($pipes[1]);
    fclose($pipes[0]);
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
} else {
    echo "No resource availeble";
}
?>

C++:

#include <iostream>
using namespace std;

int main () {
    // Get variables from php
    cout << "input" << endl;
    cin << input
    cout << "exponent" << endl;
    cin << exp

    // Process variables
    int answer = input + exp;

    // Return variables
    cout << answer;

    // End c++ script
    return 0;
}

Python:

print 'enter input'
inp = raw_input()

print 'enter exponent'
exp = raw_input()

ant = inp + exp

print ant

But sadly enough it kept failing with the same error: file is not recognized as internal or external command, program or batch file.

Some extra information:

I used Wamp with PHP 5.3.0 The return value I get from proc_close() = 1

1
  • 1
    Did you compile the C++ program? Commented Oct 30, 2010 at 14:32

3 Answers 3

2

There are two problems in you code (at least for running your Python script). First, you're not flushing your Python output to it's STDOUT, so it never reaches PHP. This causes fgetc() to block infinitely. It's a simple fix, just add some flush() calls:

#!/usr/bin/env python
import sys

print 'enter input'
sys.stdout.flush()
inp = raw_input()

print 'enter exponent'
sys.stdout.flush()
exp = raw_input()

ant = inp + exp

print ant
sys.stdout.flush()

Then, in your PHP code you are not sending any newlines when you write to the Python script STDIN. So, Python's raw_input() waits indefinitely for a newline. Again, an easy fix. Just add "\n" to the fwrite() calls:

#!/usr/bin/php
<?php
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error-output.txt", "a")
);

$process = proc_open('/path/to/python/script.py', $descriptorspec, $pipes);

$input = 20;
$exp = 2;
if (is_resource($process)) {
    print fgets($pipes[1]);
    fwrite($pipes[0], $input . "\n");

    print fgets($pipes[1]);
    fwrite($pipes[0], $exp . "\n");

    print fgets($pipes[1]);

    fclose($pipes[1]);
    fclose($pipes[0]);
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
} else {
    echo "No resource availeble";
}

And with those changes, I can make your code work as expected:

$ ./procopen.php 
enter input
enter exponent
202
command returned 0
Sign up to request clarification or add additional context in comments.

Comments

0

You're misunderstanding what proc_open() does. It opens a process like you would from the command line, e.g. (in Unix) diff file1.txt file2.txt. proc_open() does not run an executable.

According to the page I think you got your code from, http://php.net/manual/en/function.proc-open.php, to execute an external program you would use exec(). You can use this (provided the executable is in the right directory):

<?php
echo exec('someprogram.exe');
?>

Note: I am not certain that this will work with a Windows executable.

This is assuming that someprogram.exe is a compiled executable made from the C++ source you posted. If you wanted to run a Python program from PHP, first of all good luck using Windows, but you would want to use proc_open() to call python somescript.py, just like you would do from the command line.

Comments

0

Specify the absolute path of the executable file:

$process = proc_open('/path/to/new.exe', $descriptorspec, $pipes);

I can get PHP to talk to Perl with proc_open by calling the PHP script below via command line:

#!/usr/bin/php -q
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error.log", "a")
);

$process = proc_open('/path/to/procopen.pl ' . $argv[1],
    $descriptorspec, $pipes);

if (is_resource($process)) {

  // print pipe output
  echo stream_get_contents($pipes[1]);

  // close pipe
  fclose($pipes[1]);

  // close process
  proc_close($process);
}

Here's my Perl script which is in same directory as the PHP script above:

#!/usr/bin/perl
print @ARGV;

But I can't get the PHP to run when calling your Python script. The command line just stalls forever. Why is this?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.