user123
user123

Reputation: 5407

Returning argument to shell_exec() function in php script

I am calling executable file with main() function from php script using exec(). Which works fine but return all printf() values rather only returning array:

main.cpp:

#include<stdio.h>
#include<string.h>
#include "foo.h"
int main(int argc, char *argv[] )
{
    char buffer[1024];
    char *ch;
    static int ar[2];
    strcpy(buffer,argv[1]);
    printf("Client : \n");
    if ( argc != 2 ) /* argc should be 2 for correct execution */
    {
              printf( "\n%s filename\n", argv[0] );
    }
    else 
    {
        printf("\nstring is :%s \n",buffer);
    ch=foo(buffer);
    ar[0]=((int*)ch)[0];
    ar[1]=((int*)ch)[1];
    printf("Counts is :%d  %d \n",ar[0],ar[1]);
    }
    return (int)ar;

}

my test.php

<?php
$s="critic worst";
escapeshellarg($s);
$a=array(shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad"'));
print_r($a[0]);
//echo exec('whoami');
?>

Which shows output:

Client : string is :nice bad Positive count: 2 Negative count: 2 array item2 2 Count is :2 2

I also tried with exec() which also gives same prob. Can any one suggest how to get ar[0] and ar[1] from main.cpp?

Client : string is :nice bad Positive count: 2 Negative count: 2 array item2 2 

This is from all printf() present in foo.cpp file.

When I use exec() then it gives Count is :2 2

How to get exact ar[0] and ar[1]

Upvotes: 2

Views: 1135

Answers (3)

user1788542
user1788542

Reputation:

This will also work:

if (preg_match_all('/[^=]*=([^;@]*)/', shell_exec("/home/technoworld/Videos/LinSocket/client '$s'"), $matches)) //Values stored in ma.
{
    $x = (int) $matches[1][0];  //optionally cast to int
    $y = (int) $matches[1][1];
}

echo "<br/>"; echo "Positive count :$x";
echo "<br/>"; echo "Negative count :$y"; echo "<br/>";

Upvotes: 1

user123
user123

Reputation: 5407

Thanks to Elias for help. This is the solution:

<?php

if (preg_match_all('/[^=]*\=([^;@]*)/', shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad worst good"'), $matches))
{
   $x = (int) $matches[1][0];//optionally cast to int
   $y = (int) $matches[1][1];
   echo $x. '<br/>'. $y. '<br/>'
}

?>

$x,$y contain ar[0] and ar[1] respectively

Upvotes: 2

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76433

Perhaps simply

preg_match('/[0-9]*/', $output, $matches);

If I'm not mistaken...

To be sure:

preg_match('Counts is :([0-9]*)[^0-9]*([0-9]*)/',$output,$matches);

Also have a look at this question to find ouy how to use PHP and C(++) interactively

A quick, and hacky ugly messy workaround could be:

printf("%d",ar[0]);
return ar[1];//end main function

Then, in your PHP script:

$a = array(shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad"'),
           shel_exec('echo $?');
);

Then get the last numeric value from the output string, (preg_match('/([0-9]*)\w*$/',$a[0],$matches); should do it, and $a[1] will contain the value of ar[1] of the main.cpp file, because that was the exit code. Note that exit codes aren't for show. The signify something! Changeing them is generally a bad idea. I'd just change my main.cpp, and add the line:

printf("@ar[0]=%d;ar[1]=%d@",ar[0],ar[1]);

This prints a clearly formatted string, which is easy to parse using a regular expression. Assuming *ar held values 123 and 456 respectively:

preg_match_all('/\]\=([^;@]*)/',$a[0],$matches);
var_dump($matches[1]);//[123,456]

Or better stil:

$parts = explode('@', $a[0]);
echo $parts[1];//ar[0]=123;ar[1]=456

Bottom line:

Add this to your main function in main.cpp:

printf("@ar[0]=%d;ar[1]=%d@",ar[0],ar[1]);

and, to get the int values in php:

$a = array(shell_exec('..'));
preg_match_all('/[^=]*\=([^;@]*)/',$a[0],$matches);
var_dump($matches[1]);

That should do it.

$a = array();
$b = array();
if (preg_match_all('/[^=]*\=([^;@]*)/', shell_exec('your command'), $matches))
{
   $a[] = (int) $matches[1][0];//optionally cast to int
   $b[] = (int) $matches[1][1];
}

That's all... not sure why $a and $b need to be arrays, but that's probably because you're going to call the client bin a couple of times.

Upvotes: 2

Related Questions