Passing PHP variables to C++

Does anybody know how to pass PHP variables to C++?

I am now using a system() function to call the .exe and provide the parameters (PHP variables' values). However, it would become problematic to use this command-line statement if the values of the variable is very long.

Is there a better way to do this?
sopuhiaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mrwad99Commented:
Why don't you just use the Win32 Function

URLDownloadToFile(NULL,"http://site.com/querystring.php?=1&b=2","c:\\File.txt",0,NULL);    

Where File.txt holds the downloaded page, that you can then open and read in your C++ code

?
0
rstaveleyCommented:
Try using PHP's popen with 'w' and write your variables to the C++ program's standard input.
0
sopuhiaAuthor Commented:
mrwad99,

I don't write the variables to file because this would cause additional I/Os (the C++ program will be called for many times). So, I would prefer doing this in memory.

sopuhia
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

sopuhiaAuthor Commented:
rstaveley,

Could you tell me what I should put for the first parameter of popen()?
And I don't understand how to write my variables to the C++ program.

Do you mean that in PHP, I just write a command line in popen() [e.g. popen("C:\\xxx.exe $var1 $var2","w")], which is similar to the system() function???

sopuhia
0
rstaveleyCommented:
popen returns you a file handle - see http://uk.php.net/popen. When you've popened with 'w', you can simply write to it (e.g. with fwrite) to send stuff to the C++ program's standard input.

In your C++ program read from stdin.

e.g.
--------8<--------
#include <iostream>
#include <string>

int main()
{
        std::string line;
        // Parse stdin
        while (getline(std::cin,line)) {
               // Parse the line read from from standard input
        }
        // etc....
}
--------8<--------
0
sopuhiaAuthor Commented:
I've trouble with the PHP part. I wrote something like this:

$string="%testing1234567";
$handle = popen('D:\\Debug\\testing.exe','w');
$write = fwrite($handle,$string);
pclose($handle);

and it doesn't work...
Is there any problem with the code?
0
rstaveleyCommented:
I've not done any PHP on Windows, but it works fine on Linux when the executable is in a directory in which you have permissions set OK.

~/public_html/test.php
--------8<--------
<?php

$string="%testing1234567";
$handle = popen('/home/rstaveley/public_html/bin/test','w');
$write = fwrite($handle,$string);
pclose($handle);

?>
Test code
--------8<--------

~/public_html/bin/test (C++ source)
--------8<--------
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
        ofstream fout("/home/rstaveley/public_html/bin/test.dat");
        string line;
        while (getline(cin,line))
                fout << line <<'\n';
}
--------8<--------

Permissions on ~/public_html/test/bin are 0777, which is UNIX-speak for "anything goes" :-)

I thing you need to continue the question in the PHP TA, to figure out how to get it to work in Windows.
0
rstaveleyCommented:
BTW... with single quoted strings in PHP, you don't need to escape backslashes. You should be able to write 'D:\Debug\testing.exe'. However, that shouldn't be your problem, because double backslashes are treated as escapes all the same, unlike '\n'. PHP is a funky language.
0
sopuhiaAuthor Commented:
I've tried running the program but the IE displayed nothing.
I wanna ask what is the test.dat file? I cannot find it....
0
sopuhiaAuthor Commented:
and also for php, '/home/rstaveley/public_html/bin/test' was stated, but for C++, the file was changed....how come?
0
rstaveleyCommented:
> IE displayed nothing

Not even "Test code"??

> I wanna ask what is the test.dat file?

My executable proves that it does something by reading lines from standard input and writing them into "test.dat", which it creates. The crazy looking path is something that makes sense to Linux folk.

>  and also for php, '/home/rstaveley/public_html/bin/test' was stated, but for C++, the file was changed....how come?

"test" is the name I gave my executable. In Windows you'd probably have "test.exe", but in either case the code would be compiles from source code e.g. "test.cpp", and it was the source code I showed.

Not sure if I've answered your question. Let me know if this needs more clarification.
0
sopuhiaAuthor Commented:
Well, yes, only "Test code" was displayed.

I can find my .dat after php called C++ and because of the line:
ofstream fout("/home/rstaveley/public_html/bin/test.dat");
and the .dat file stores the string.

Does this mean I have succeeded?

However, when I tried to output the variable "line" to the screen using "cout<<line<<endl;", the string does not appear.......
0
sopuhiaAuthor Commented:
For your information, the followings are the PHP and C++ codes respectively:

<?php
$string="%testing1234567";
$handle = popen('D:\wamp\www\fyp\VC++6.0\Debug\testing.exe','w');
$write = fwrite($handle,$string);
pclose($handle);
?>
Test code
---------------------------
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
cout<<"C++ testing"; //does not appear on screen
ofstream fout("D:\\wamp\\www\\fyp\\VC++6.0\\Debug\\testing.dat");//other file types also work
string line;
while (getline(cin,line)){
     fout << line <<'\n';
     cout<< line << '\n';  //does not appear on screen
}
return 0;
}
0
rstaveleyCommented:
> However, when I tried to output the variable "line" to the screen using "cout<<line<<endl;", the string does not appear......

No it wouldn't. It isn't capturing standard output from the C++ program.

If you read the comments in http://uk.php.net/popen you'll see some tricks for bidirectional pipes with popen, which allow your PHP to write to the executable's standard input and allow the PHP to read from the executable's standard output.
0
sopuhiaAuthor Commented:
Do you mean I have got the expected result?

If yes, how could I make use of the variable for further manipulation in C++?

Also, what if I have multiple variables? Pass them one by one?

Many thanks for your help!
0
rstaveleyCommented:
Now you can write your variables to stdin, you can parse stdin for whatever you want.

e.g.
--------8<--------
#include <iostream>
#include <sstream>
#include <string>
#include <map>

int main()
{
      std::string line;
      std::map<std::string,std::string> parmList;
      while (getline(std::cin,line)) {
            std::istringstream is(line);
            std::string key,value;
            if (getline(is,key,'=') && getline(is,value))
                  parmList[key] = value;
      }
      const std::string sought_key = "this";
      std::cout << "If you entered a value for \"" << sought_key << "\", its value is \"" << parmList[sought_key] << "\"\n";
}
--------8<--------

If you execute this program and type...

        foo=bar            <- Type the line and then press <enter>
        this=that           <- Type the line and then press <enter>
        blah=blah         <- Type the line and then press <enter>
        Ctrl+Z               <- This closes standard input in DOS (this will get you your DOS prompt back)

... you'll see that you've got a tool for mapping values for named parameters. This is an over-engineered example to illustrate the idea.

All you need to do in your PHP is to write a load of newline delimited key=value pairs and you have a mechanism for passing as many parameters as you need.
0
sopuhiaAuthor Commented:
In fact, I am quite new to C++. Would you mind explaining to me more about your program (esp the lines in the while loop)?

When I compiled your program in Visual C++, there was an error prompting me that the getline function was not recognized. However, when I added back the line: "using namespace std;", error was fixed, but there were more than a hundred warnings which were unreadable. When the C++ program was run, there was no response at all and I could type anything I wanted until I terminated using "Ctrl+C"....

Thanks!
0
rstaveleyCommented:
OK, I guess that means you are using Visual C++ 6.0, which doesn't do something called Koenig look-up, because it isn't standard C++ compliant. You could also have got it to work by prefixing getline with std::, but using namespace std is fine.

I'm finding myself drawn into a longer answer than I wanted to give. I'll give you some pointers, but drop you in the deep end otherwise, because you'd be better off getting a C++ primer than learning C++ this way.

The map<> is something rather like an associative array in PHP, allowing you to do assignments like parmList["this"] = "that". istringstream is an input stream sourced from a string. getline is generally used to extract newline delimited strings from a stream, but you can override the default delimiter to '=' as indicated in my example code.

Here is some commented code, which EE's proportional font is going to make look very ragged.
--------8<--------
#include <iostream>      // This      gives you the standard input stream std::cin
#include <sstream>      // This      gives you string input stream std::istringstream (nests      #include <string>)
#include <map>            // This      gives you std::map<> (an associative array)

using std::getline;      // Required by VC 6.0, because of lack of Koenig look-up

int main()
{
      std::string line;                              // Read      lines from standard input into line
      std::map<std::string,std::string> parmList;            // Our associative array
      while (getline(std::cin,line)) {                  // Reads a newline delimited line from standard      input
            std::istringstream is(line);                  // Create an input string stream from the line
            std::string key,value;                        // We want to break it into key=value
            if (getline(is,key,'=') && getline(is,value))   // Read the key up to '=' and then read the value
                  parmList[key] =      value;                  // Assign value      to key in associative array
      }
      const std::string sought_key = "this";                  // In our example code, we are looking for a key called "this"
      std::cout
            << "If you entered a value for \""
            << sought_key                              // Just      to remind you, here's the key we are looking for
            << "\", its value is \""
            << parmList[sought_key]                        // This reads the value for the key sought_key
            << "\"\n";
      return 0;                                    // Required by VC 6.0
}
--------8<--------

> no response at all and I could type anything I wanted until I terminated using "Ctrl+C"....

You should have typed Ctrl+Z and then <enter> to close the input stream. Ctrl+Z is an end of file marker. If you'd entered a line saying (say) this=that. Oddly enough, I've just noticed that with the code generated by Visual C++ 6.0 you need to enter Ctrl+Z<enter> twice (alternatively press F6<enter> twice) - not sure why this is the case.... Visual C++ 7.1 only requires you to do it once as you'd expect.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rstaveleyCommented:
> If you'd entered a line saying (say) this=that

Didn't complete that sentence.

If you'd entered a lines saying (say) foo=bar, this=that and then boo=hoo, you should see:

--------8<--------
c:\Devt>x
foo=bar
this=that
boo=hoo
^Z
^Z
If you entered a value for "this", its value is "that"
--------8<--------
0
sopuhiaAuthor Commented:
Thank you very much for your code!

Two LAST questions before making you mad:
1. In php, should I write something like this as follows to pass the variable?
----------------------------------------
<?php
$string="this=%testing1234567";
$handle = popen('D:\wamp\www\fyp\VC++6.0\Debug\testing.exe','w');
$write = fwrite($handle,$string);
pclose($handle);
?>
Test code
-----------------------------------------
However, this seems not working......

2. Furthermore, would it be fine if the string to be passed is very long, say 50000 bytes?

Thanks again for your patience!
0
rstaveleyCommented:
1. Looks OK. Do you see any evidence od testing.exe executing (make it write something to a file to see evidence)? Try echoing the $handle in your PHP to check that popen has succeeded in opening the standard input for testing.exe, if will return FALSE, if not.

2. There's no limit to the amount of data you can write to the standard input stream.
0
sopuhiaAuthor Commented:
The output for $handle is "Resource id #2" .........
0
sopuhiaAuthor Commented:
it seems that the testing.exe file did not run......

However, if I use the system() function, the file could be triggered to run, but of course, no variable was passed.
0
sopuhiaAuthor Commented:
I discovered that I could output the sentence "If you entered a value for "this", its value is "testing1234567"", but "cout" seems not working. In other words, the sentence could not be output directly on screen.........
0
rstaveleyCommented:
> the sentence could not be output directly on screen.

...for the reason stated in http:#12557688. popen is designed to provide you a handle either to standard output or standard input. Follow that link for some suggestions on how to capture both. If you've got further questions about this area, I recommend that you pose them at http:/Web/Web_Languages/PHP/PHP_Windows/ Good luck!
0
sopuhiaAuthor Commented:
Many thanks for your help!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.