Hello all, I hope this is the right place to write about this. I've been
trying now for quite some time to integrate php into my non-apache server
(completely c++ written by me). Right now I have it working partially using
the CLI. My application generates a shell script when a .php page is
requested and executes it through p_open so I can pipe standard output back
to the user that requested it. The script generated looks something exactly
like:
#!/bin/bash
cd /path/to/server/ant/httpd/phpBB2/
export REQUEST_METHOD="GET"
export SCRIPT_NAME="/phpBB2/index.php"
export SERVER_NAME="localhost:5555"
export SERVER_PORT="5555"
export REMOTE_ADDR="127.0.0.1"
export DOCUMENT_ROOT="/path/to/server/ant/httpd"
export DOCUMENT_URI="/phpBB2/index.php"
export DOCUMENT_NAME="index.php"
export SERVER_PROTOCOL="HTTP/1.1"
export SERVER_SOFTWARE="ANT-1.0"
export GATEWAY_INTERFACE="CGI/1.1"
export HTTP_USER_AGENT="User-Agent: Mozilla/5.0 (X11; U; Linux x86_64;
en-US; rv:1.7.8) Gecko/20050524 Fedora/1.0.4-4 Firefox/1.0.4 "
export HTTP_ACCEPT="text/xml,application/xml,application/xhtml
xml,text/html;q 0.9,text/plain;q=0.8,image/png,/;q=0.5"
export HTTP_ACCEPT_LANGUAGE="en-us,en;q 0.5"
export HTTP_ACCEPT_CHARSET="ISO-8859-1,utf-8;q 0.7,*;q=0.7"
export HTTP_ACCEPT_ENCODING="gzip,deflate"
php -f /path/to/server/ant/httpd/phpBB2/index.php
cd /path/to/server/ant/
export > ExportsAfterScript
with path/to/server/ant being automatically generated by "pwd", and httpd
being inserted as the base httpd directory.
I tried doing it this way, because this seems to be how CGI scripts work
(from what I could gather from the tons of documents I've tried reading on
the web), so I figured maybe this would work, of course it doesn't. I also
read cgi scripts may export values to the enviorment after it finish's so I
thought php might too, which is why export > ExportsAfterScript is there.
This method works fine and dandy for simple scripts like <?php Print "Hello
World\n"?> or whatever that is, but it doesn't work with a little more
advanced things like phpBB.
Now I'm wondering, can I simply link the library in at compile time, do a
#include <php.h>, create a structure with all the exported data and pass it
to a function in php? Can anyone provide me with some pointers like, the
object I need to create, the function I need to call to get parse a file
This is what I'm looking for (general psuedo to pass the idea):
{
#include <php.h>
void runPhP(HttpdUserObject *userobject, char *file, size_t &filesize) {
struct phpHeader header = CreateHeaderFrom(userobject);
char *result = PHPProc(file, filesize, header);
struct phpResultHeader headerback = PHPResultHeader();
Send_To_User(userobject, headerback, result);
free(result);
return;
}; // and call that from my file loading routines if a .php extension is
found?
and something like: In makefile.am add -lphp and -i/usr/include/php-X/
}
Any help would be greatly appreciated, thanks!
Matthew Adams
http://www.sf.net/projects/ante
Long live free and open software!
Hello all, I hope this is the right place to write about this. I've been
trying now for quite some time to integrate php into my non-apache server
(completely c++ written by me).
Sounds like you want to use sapi/embed (or write a SAPI implementation of
your own which is notably more involved). Start with Wez's slides to get a
general idea, if you have questions later on, you can ask here or on
pecl-dev which is more non-core oriented than internals.
-Sara
http://www.php-kongress.de/2003/slides/internals_track/wez_embedding-php.pdf
Sara Golemon wrote:
Hello all, I hope this is the right place to write about this. I've been
trying now for quite some time to integrate php into my non-apache server
(completely c++ written by me).Sounds like you want to use sapi/embed (or write a SAPI implementation of
your own which is notably more involved). Start with Wez's slides to get
a general idea, if you have questions later on, you can ask here or on
pecl-dev which is more non-core oriented than internals.-Sara
http://www.php-kongress.de/2003/slides/internals_track/wez_embedding-php.pdf
Thank you for the quick response Sara! After looking in to this, I decided
embedding it in might not be the best option after all. Instead, I decided
to go with the php-cgi method, and am now facing I believe one last problem
standing between me and full php in my webserver. I first removed the .sh
script that's generated, and created my own little p_open that pipes
stdin/stdout so I can read/write from the server. I export a good chunk of
enviorment variables (listed below) after the fork in the child process
before the execl of the php-cgi command, which seem to get most of the job
done. I can GET php pages just fine (including more advanced things like
phpBB), but POST is a whole different story, I can't get ANY post data.
Now, to do posts, I'm writing the post data onto stdin of the child process,
which seems to be cgi/1.1 spec. I created my own very tiny c++ program to
test it:
#include <iostream>
#include <fstream>
int main() {
std::string x;
std::cin >> x; //read from stdin - comes from server
std::cout << "Content-Type: text/html" << "\r\n\r\n" << "You
entered: " << x << std::endl; //write to stdout - piped back to server
return 0;
}
compiled it, and tested it by sending a post through that program, it echo'd
the response to the web client containing all the POST data.
To make sure it was correct, I put this small binary in apache's cgi dir,
created a small post input form, posted to it, it echo'd exactly the same
thing it did when run through my server through apache (eg: the raw
unformatted post input).
So, am I missing something? Do I need to set another enviorment variable to
get the php-cgi module to read post data from stdin as per cgi/1.1? (as far
as I can tell....)
Enviorment variables set:
putenv(SCRIPT_NAME=/testphp.php)
putenv(REQUEST_METHOD=POST)
putenv(CONTENT_LENGTH=0)
putenv(CONTENT_TYPE=application/x-www-form-urlencoded)
putenv(POST_DATA=p_email=asdf&p_test=woork)
putenv(SCRIPT_NAME=/testphp.php)
putenv(SERVER_NAME=localhost:5555)
putenv(SERVER_PORT=5555)
putenv(REMOTE_ADDR=127.0.0.1)
putenv(DOCUMENT_ROOT=/home/user/ant/httpd/)
putenv(SCRIPT_NAME=/testphp.php)
putenv(PHP_SELF=/testphp.php)
putenv(SCRIPT_FILENAME=/home/user/ant/httpd/testphp.php)
putenv(DOCUMENT_NAME=testphp.php)
putenv(SERVER_PROTOCOL=HTTP/1.1)
putenv(SERVER_SOFTWARE=ANT-1.0)
putenv(GATEWAY_INTERFACE=CGI/1.1)
putenv(HTTP_USER_AGENT=User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US;
rv:1.7.8) Gecko/20050524 Fedora/1.0.4-4 Firefox/1.0.4 )
putenv(HTTP_ACCEPT=text/xml,application/xml,application/xhtml+xml,text/html;q
0.9,text/plain;q=0.8,image/png,/;q=0.5)
putenv(HTTP_ACCEPT_LANGUAGE=en-us,en;q 0.5)
putenv(HTTP_ACCEPT_CHARSET=ISO-8859-1,utf-8;q 0.7,*;q=0.7)
putenv(REDIRECT_STATUS=200)
putenv(HTTP_ACCEPT_ENCODING=gzip,deflate)
Method(s) tried for sending post data to php-cgi: (At the same time, and
seperately)
-
write(childstdin, poststring.c_str(), poststring.size());
-
command.append("php-cgi < echo ");
command.append(poststring);
command.append(""");
pipe_command(command); // export variables, run custom popen, before
execl(bin/sh -c command null) redir stdin and stdout, create third notify
pipe, notify parent when enviorment variables are registered in child,
child waits until any 1 charactor is written to notify pipe, parent write's
to child's stdin, notify's child when write is finish, child runs execl on
command, parent waits for child to finish, after child exits() parent reads
stdout of child and let's the webserver take it on it's merry little way to
the client adding all the server specific header fields and all that.
It works with my own custom "cgi" module above, but not php-cgi, for posts
only. It works on get's with both.
Thanks in advance, this is driving me nuts! :)
Oh, btw, I have both:
php-cgi --version
PHP 5.0.4 (cgi-fcgi) (built: May 9 2005 11:20:57)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v2.0.4-dev, Copyright (c) 1998-2004 Zend Technologies // came
with fedora
php-cgi2 --version
PHP 5.1.2 (cgi) (built: Jan 31 2006 00:42:07)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies // I just
installed and tried to see if it would make a difference.
to work with, and can get and install any other version if needed.
Thanks again!
Haha, after looking over the enviorment variables one last time I noticed it
was setting the content length to zero, my fault. After fixing this, it
seems to be working! Yay, yet another webserver with php support :)
Matthew wrote:
Sara Golemon wrote:
Hello all, I hope this is the right place to write about this. I've been
trying now for quite some time to integrate php into my non-apache
server (completely c++ written by me).Sounds like you want to use sapi/embed (or write a SAPI implementation of
your own which is notably more involved). Start with Wez's slides to get
a general idea, if you have questions later on, you can ask here or on
pecl-dev which is more non-core oriented than internals.-Sara
http://www.php-kongress.de/2003/slides/internals_track/wez_embedding-php.pdf
Thank you for the quick response Sara! After looking in to this, I decided
embedding it in might not be the best option after all. Instead, I decided
to go with the php-cgi method, and am now facing I believe one last
problem standing between me and full php in my webserver. I first removed
the .sh script that's generated, and created my own little p_open that
pipes stdin/stdout so I can read/write from the server. I export a good
chunk of enviorment variables (listed below) after the fork in the child
process before the execl of the php-cgi command, which seem to get most of
the job done. I can GET php pages just fine (including more advanced
things like phpBB), but POST is a whole different story, I can't get ANY
post data.Now, to do posts, I'm writing the post data onto stdin of the child
process, which seems to be cgi/1.1 spec. I created my own very tiny c++
program to test it:
#include <iostream>
#include <fstream>
int main() {std::string x; std::cin >> x; //read from stdin - comes from server std::cout << "Content-Type: text/html" << "\r\n\r\n" << "You
entered: " << x << std::endl; //write to stdout - piped back to server
return 0;
}compiled it, and tested it by sending a post through that program, it
echo'd the response to the web client containing all the POST data.To make sure it was correct, I put this small binary in apache's cgi dir,
created a small post input form, posted to it, it echo'd exactly the same
thing it did when run through my server through apache (eg: the raw
unformatted post input).So, am I missing something? Do I need to set another enviorment variable
to get the php-cgi module to read post data from stdin as per cgi/1.1? (as
far as I can tell....)Enviorment variables set:
putenv(SCRIPT_NAME=/testphp.php)
putenv(REQUEST_METHOD=POST)
putenv(CONTENT_LENGTH=0)
putenv(CONTENT_TYPE=application/x-www-form-urlencoded)
putenv(POST_DATA=p_email=asdf&p_test=woork)
putenv(SCRIPT_NAME=/testphp.php)
putenv(SERVER_NAME=localhost:5555)
putenv(SERVER_PORT=5555)
putenv(REMOTE_ADDR=127.0.0.1)
putenv(DOCUMENT_ROOT=/home/user/ant/httpd/)
putenv(SCRIPT_NAME=/testphp.php)
putenv(PHP_SELF=/testphp.php)
putenv(SCRIPT_FILENAME=/home/user/ant/httpd/testphp.php)
putenv(DOCUMENT_NAME=testphp.php)
putenv(SERVER_PROTOCOL=HTTP/1.1)
putenv(SERVER_SOFTWARE=ANT-1.0)
putenv(GATEWAY_INTERFACE=CGI/1.1)
putenv(HTTP_USER_AGENT=User-Agent: Mozilla/5.0 (X11; U; Linux x86_64;
en-US; rv:1.7.8) Gecko/20050524 Fedora/1.0.4-4 Firefox/1.0.4 )
putenv(HTTP_ACCEPT=text/xml,application/xml,application/xhtml+xml,text/html;q
0.9,text/plain;q=0.8,image/png,/;q=0.5)
putenv(HTTP_ACCEPT_LANGUAGE=en-us,en;q 0.5)
putenv(HTTP_ACCEPT_CHARSET=ISO-8859-1,utf-8;q 0.7,*;q=0.7)
putenv(REDIRECT_STATUS=200)
putenv(HTTP_ACCEPT_ENCODING=gzip,deflate)Method(s) tried for sending post data to php-cgi: (At the same time, and
seperately)
write(childstdin, poststring.c_str(), poststring.size());
command.append("php-cgi < echo ");
command.append(poststring);
command.append(""");
pipe_command(command); // export variables, run custom popen, before
execl(bin/sh -c command null) redir stdin and stdout, create third notify
pipe, notify parent when enviorment variables are registered in child,
child waits until any 1 charactor is written to notify pipe, parent
write's to child's stdin, notify's child when write is finish, child runs
execl on command, parent waits for child to finish, after child exits()
parent reads stdout of child and let's the webserver take it on it's merry
little way to the client adding all the server specific header fields and
all that.It works with my own custom "cgi" module above, but not php-cgi, for posts
only. It works on get's with both.Thanks in advance, this is driving me nuts! :)
Oh, btw, I have both:
php-cgi --version
PHP 5.0.4 (cgi-fcgi) (built: May 9 2005 11:20:57)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v2.0.4-dev, Copyright (c) 1998-2004 Zend Technologies // came
with fedoraphp-cgi2 --version
PHP 5.1.2 (cgi) (built: Jan 31 2006 00:42:07)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies // I just
installed and tried to see if it would make a difference.to work with, and can get and install any other version if needed.
Thanks again!