I'm developing a little web server in C++, now I'm trying to implement PHP support for my WS, or better I'm trying to figure out how to implement that.
But I've got some doubts: for now I have the client's request in a std::string, if it's a static request there's no problem: let's find file and put in on socket buffer; if it's a dynamic request(PHP only for now), of course I will need to call the interpreter(std::system() ??).
Now my mainly doubt is about forms, I get my POST request and I save form fields in a string, but now: How can I fill $_POST used in my php script and call the interpreter? I could put my fields string as argv by "php -f file.php "fields string" but ,of course, it's awful.
To pass the POST body, you basically pipe it in
echo "$POST_BODY" | php-cgi
For C and C++ you don't want to use just popen(), but also capture the output and stderr. So you need something like: how to control popen stdin, stdout, stderr redirection?
Related
I'm trying to execute a piece of php code with the php command in the ubuntu terminal. I'm testing it with a sample code that you can find here.
I created a file with the code, calling it welcome.php, and tried executing it with:
php welcome.php
And obviously says there are undefined indexes, because it expects arguments via POST
Obviously I would like to do is to run it with the POST arguments as well. I tried the following:
declare -A _POST
_POST[name]="Sample name"
_POST[email]="sample#mail.com"
Before executing again, but the result still doesn't show. So is there any way I can declare the POST arguments manually in order to achieve loading the html file properly?
----------------- Context, in case it seems relevant -----------------
I'm programming a modest C server for my studies, and among the functionality required, there is executing php scripts. So my idea is to execute whatever command is required and generate the html output in a file that is later read and transmitted. Parsing the arguments as keys and values is not a problem (although yet to be done).
So far I know, you need to create a post request to a server to get the $_POST variable's values. In case you want to generate an HTML file, you can pass values through the argument, process it and return (print) an HTML document.
I want to execute python script with post data and get result from there using curl in php. If anyone have done this kind of functionality then please help. I have searched a lot but didn't get anything.
This is my python script path
cgi-bin/interactive.py
And i want to pass title=abc as post data.
I have done it with shell_exec in php file,
$command = escapeshellcmd('cgi-bin/interactive.py test');
$output = shell_exec($command);
echo $output;
But in this i am facing issue with sys.argv to fetch argument in python file.
Is it possible to pass argument with key=value with shell_exec? If yes then it can solve my problem otherwise i need to call with curl post data.
Thanks in advance!
To do advanced parsing of shell arguments you can use getopt or argparse modules. They are highly configurable and flexible.
Passing post data via shell arguments is, however, not proper as per the CGI spec (if this is supposed to be a true CGI application). Post data comes from stdin in CGI, so in your Python program you can read in the HTTP response like regular user input, and then parse out the POST data. See this thread for more info.
Is there a way for PHP to pass HTML form variables (POST) directly to a python script called with "passthru" in PHP without PHP having to know the variable names?
Can PHP pass the HTTP POST request to python so that i.e. the cgi module in python will read it like it was passed "from the web"?
Basic setup: Joomla CMS, with the jumi module.
NB! Python 2.4, PHP 5.3.3 on RedHat 5.9 - only standard packages.
One of the jumi applications is a python script which creates a form, and also handles the POST variables.
Reason: A lot more python knowledge in our shop, and the python script does a lot in the background.
In the jumi PHP script I have:
<?php
$var1 = $_REQUEST['myVar1'];
$var2 = $_REQUEST['myVar2'];
echo passthru('/usr/bin/python /var/www/html/joomla/jumi/portal-ldap.py '.$myVar1.' '.$myVar2);
?>
The python scripts then uses sys.arvg to process these variables.
It works - by all means, but it also means that any additinal variables must be known to both scripts.
Is there a way for PHP to pass the form variables directly to the python script in a way so that the "cgi" module in Python can process the variables as it would if I ran the python script with a framework/cgi/mod_python/...?
Python handling form variables:
import cgi
form = cgi.FieldStorage()
var1 = form.getvalue("myVar1", "nothing")
var2 = form.getvalue("myVar2", "nothing")
If you absolutely want to read the values through cgi.FieldStorage, you could run the python script on an HTTP server, preferably limiting its access to localhost. Executing the call over HTTP would also be a lot more secure than passing the parameters to passthrough() unparsed.
Alternatively, you could change your python script to use the getopt module, which makes it easier to define the argument in key-value pairs like this (paths omitted for brevity):
python portal-ldap.py --myvar1 nothing --myvar2 nothing
If you decide to keep using passthgough(), do remember to escape all the arguments with escapeshellarg().
Edit: You could also json_encode($_REQUEST) and pass it as a parameter, then json.loads() it in Python to get the array as a dictionary.
I'll answer my own question to explain how I used the info I've gotten.
I must also add that I'm limited by using python 2.4 and (maybe not limited by) simplejson - since I'm on RedHat 5.9 in this project - and want/need to keep to the supplied packages. So I have web --> Joomla --> jumi --> php --> python --> backend...
Building on the answer and comments from Kaivosukeltaja and supporting articles executing Python script in PHP and exchanging data between the two and http://pymotw.com/2/json/
In the jumi application / php-script I have put (amongst other things) the following to allow HTTP POST to be sent as a JSON object to my supporting python script.
echo passthru('/usr/bin/python /var/www/html/joomla/jumi/ldap-script.py '. escapeshellarg(json_encode($_POST)))
Then, in the python script I use sys.argv to read the variable, and simplejson to map the json object from PHP to a python dictionary (heavily simplified):
import sys
import simplejson as json
myjson = sys.argv[1]
mydict = json.loads(myjson)
I can now test if my desired keys can be found:
if ( 'var1' in mydict):
print mydict['var1']
The user posts to these variables in a simple form:
<form name="INPUT" action="" method="POST">
MyVar1 <input type="number" name="var1">
<input type=SUBMIT" value="Submit">
</form>
The avid reader will see that "var1" is referenced in most of these steps, while PHP isn't, don't have to be, aware of it.
My problem is I need to fetch FOOBAR2000's title because that including information of playing file, so I create a execute file via Win32 API(GetWindowText(), EnumWindows()) and it's working good.
TCHAR SearchText[MAX_LOADSTRING] = _T("foobar2000");
BOOL CALLBACK WorkerProc(HWND hwnd, LPARAM lParam)
{
TCHAR buffer[MAX_TITLESTRING];
GetWindowText(hwnd, buffer, MAX_TITLESTRING);
if(_tcsstr(buffer, SearchText))
{
// find it output something
}
return TRUE;
}
EnumWindows(WorkerProc, NULL);
Output would look like "album artis title .... [foobar2000 v1.1.5]"
I created a php file like test.php, and use exec() to execute it.
exec("foobar.exe");
then in console(cmd) I use command to execute it
php test.php
It's working good too, same output like before.
Now I use browser(firefox) to call this php file(test.php), strange things happened.
The output only foobar2000 v1.1.5, others information gone ...
I think maybe is exec() problem? priority or some limitation, so I use C# to create a COM Object and register it, and rewrite php code
$mydll = new COM("FOOBAR_COMObject.FOOBAR_Class");
echo $mydll->GetFooBarTitle();
still same result, command line OK, but browser Fail.
My question is
Why have 2 different output between command line and browser. I can't figure it out.
How can I get correct output via browser.
or there is a easy way to fetch FOOBAR2000's title?
Does anyone have experience on this problem?
== 2012/11/28 edited ==
follow Enno's opinion, I modify http_control plug-in to add filename info, original json info is "track title".
modify as following
state.cpp line 380 add 1 line
+pb_helper1 = pfc::string_filename(pb_item_ptr->get_path());
pb_helper1x = xml_friendly_string(pb_helper1);
# 1: when firefox opens the php and it gets executed, it the context depends on the user which runs the php-container (apache), this is quite different from the commandline call which gets executed in your context
# 2 and 3: there seems to be more than one way for getting the title: use the foobar-sdk and create a module which simply reads the current title per api, then write your result in an static-html-document inside your http-root-folder OR use the http-client inside the sdk, with it, you do not need a wabserver, even better use a already implemented module: for instance foo_upnp or foo-httpcontrol
Good luck!
If your webserver runs as a service, in windows you need to enable "allow desktop interaction" for the service. Your php script runs as a child of the webserver process when requested via browser.
I have a similar question here, but it was oriented to PHP side. It looks like PHP is able to receive a package of data and immediately (in the same session) send and answer back.
My question is can Delphi do that? From what I know the answer is a big NO. I need to do this in two steps (two procedures). The thing is that the session will be probably closed when the first procedure ends. Can I keep the session open between the two procedure calls.
I'm going to give you sample code for both PHP and Delphi. We're going to use the GET request method because it's much easier and it's enough if you don't need to send too much data. I'm going to start with the PHP script, because it can be tested alone, without the Delphi app (we'll test it using an Browser).
Here's the PHP script:
<?php
$a=$_GET['a'];
$b=$_GET['b'];
echo intval($a)*intval($b);
?>
This scripts expects two values sent encoded in the URL (a and b), multiplies the values and returns the answer. Assuming you're playing on the computer that's running LAMP, and you called this script script.php, if you navigate to this on your browser:
http://localhost/script.php?a=2&b=3
You'll see this in your browser:
6
To break down the URL we're writing in the browser: we're requesting the page /script.php from the server localhost and we're passing this query string to the script: a=2&b=3. The stuff that goes after the ? in the URL is the query string; The & symbol separates the two separate parameter=value pairs: a=2 and b=3. On the PHP side you use $a=$_GET['a'] to get the value of the parameter a. It's that simple!
Delphi code
Now that we know the PHP script is up and running, we can move on to the Delphi part. Here's a routine that multiplies two values using the most inefficient method imaginable:
function MultiplyTwoNumbers(a,b:Integer):Integer;
var url: string;
H: TIdHttp;
SS: TStringStream;
begin
// Prepare the URL
url := 'http://fisiere.sediu.ro/script.php?a=' + IntToStr(a) + '&b=' + IntToStr(b);
H := TIdHttp.Create(nil);
try
SS := TStringStream.Create;
try
H.Get(url, SS);
Result := StrToInt(SS.DataString);
finally SS.Free;
end;
finally H.Free;
end;
end;
I intentionally left my proper working URL in there, so you can actually test against my known-to-work script.
Here's how you'd call this routine:
procedure TForm8.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(MultiplyTwoNumbers(3,4)));
end;
Summary
HTTP is stateless, people go to lots of trouble to maintain some kind of state. Your Delphi app makes two calls, first to SendID then a second to GetDataBack idea doesn't work, because the thing running on the server when you call (actually GET) GetDataBack has no idea someone sometime called (GET again) SendID.
Happily when GET-ing data from an HTTP server we can use the query string to easily send some information. If we need to send a lot of information we'd use the POST requests.