[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Passing PHP variables to C++

Posted on 2004-11-10
26
Medium Priority
?
336 Views
Last Modified: 2012-06-21
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?
0
Comment
Question by:sopuhia
  • 14
  • 11
26 Comments
 
LVL 19

Expert Comment

by:mrwad99
ID: 12543665
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12544040
Try using PHP's popen with 'w' and write your variables to the C++ program's standard input.
0
 

Author Comment

by:sopuhia
ID: 12546938
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:sopuhia
ID: 12546976
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12547933
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
 

Author Comment

by:sopuhia
ID: 12553199
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12553339
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12553405
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
 

Author Comment

by:sopuhia
ID: 12555984
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
 

Author Comment

by:sopuhia
ID: 12556013
and also for php, '/home/rstaveley/public_html/bin/test' was stated, but for C++, the file was changed....how come?
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12556912
> 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
 

Author Comment

by:sopuhia
ID: 12557358
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
 

Author Comment

by:sopuhia
ID: 12557470
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12557688
> 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
 

Author Comment

by:sopuhia
ID: 12558110
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12558421
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
 

Author Comment

by:sopuhia
ID: 12562508
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
 
LVL 17

Accepted Solution

by:
rstaveley earned 500 total points
ID: 12563976
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12563990
> 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
 

Author Comment

by:sopuhia
ID: 12568038
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12569446
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
 

Author Comment

by:sopuhia
ID: 12573880
The output for $handle is "Resource id #2" .........
0
 

Author Comment

by:sopuhia
ID: 12574316
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
 

Author Comment

by:sopuhia
ID: 12574630
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12581627
> 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
 

Author Comment

by:sopuhia
ID: 12585532
Many thanks for your help!
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question