Howdy,
I'm new to the forums and I've got a question. I've been doing some research including drudging through PHP, Apache, and apr source code to try to figure out the answer; I'll continue to do this but I figure that maybe some experienced folks have some ideas.
My desire is to load up a PHP shared object into my server project so that the server can execute PHP code like Apache does. I can build PHP with a shared object for the Apache webserver...easy, piece of cake. When I load in this shared object in my own project manually, I get this error message from the dlerror() function of the dlfcn.h stuff:
undefined symbol: ap_loaded_modules
The ap_loaded_modules stuff seems to be a pretty deep aspect of the libraries that are a part of the Apache project. I suspect that given enough time, I can probably include all of the necessary Apache source code into my own project to get this stuff working, but I'd rather not do that.
I noticed that in the PHP source directory structure that this Apache shared object interface is used in $PHP/sapi/apache2handler, specifically php_functions.c. And there isn't much of this code, so this leads me to believe that it might be possible to build a more generic PHP shared object file that I can use, avoiding the need to make use of Apache's module loading stuff.
So my question(s) is/are: Is it possible to build a generic (non-Apache dependent) shared object of PHP? If not, how might I approach the problem of making this possible?
Many thanks!
-Ray
Possible to make an independent shared object of PHP?
Moderator: General Moderators
Hello,
Turns out that I figured out the answer to my question, although I now have more. I built PHP like so:
and it created a libphp4.so in the .lib directory. I copied this to a convenient place. I can successfully load this shared object (with dlopen()) and get the address (and set up the prototype) for the 'php_embed_init()' function defined in php_embed.h. Now, I don't know what to do from here.
The prototype for php_embed_init() is like so:
In my case, PTSRMLS_DC is NULL. So, when I call php_embed_init, I just pass the argc and argv values passed in from my main(). When I run my program, I passed in the name of a file that has PHP code in it like so:
My hello.php function has this code in it:
I was hoping that I'd miraculously see at least a 'hello world' pop out on my terminal, but I'm not that lucky.
Has anybody had any experience with using the php_embed stuff? What else should I be setting up and doing in order to get some PHP code to execute, now that I got the shared object loading working?
Thanks!
-Ray
P.S. Here is my source code so far:
so.h
so.cpp
test_so.cpp
Makefile
Turns out that I figured out the answer to my question, although I now have more. I built PHP like so:
Code: Select all
./configure --with-mysql --enable-embed
makeThe prototype for php_embed_init() is like so:
Code: Select all
int php_embed_init(int argc, char **argv PTSRMLS_DC);Code: Select all
%> ./test_so hello.phpCode: Select all
<?php
$fh = fopen("e;log.out"e;, "e;w"e;);
print "e;Hello world! (from hello.php)\n"e;;
fwrite($fh, "e;Hello world! (from hello.php)\n"e;);
flose($fh);
?>Has anybody had any experience with using the php_embed stuff? What else should I be setting up and doing in order to get some PHP code to execute, now that I got the shared object loading working?
Thanks!
-Ray
P.S. Here is my source code so far:
so.h
Code: Select all
#ifndef SO_H
#define SO_H
#include <stddef.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <dlfcn.h>
#include <string.h>
//typedef void(*Misc)(char * buffer); // temporary test
typedef void(*Init)(int, char **);
struct module
{
void *so; // shared object handle
Init init;
};
typedef struct module module;
// function for checking libdl errors
int dlok(const char *msg);
// loads module into the struct module
void* loadmodule(module *mod, const char *soname);
// unloads the module
int unloadmodule(module *mod);
#endifCode: Select all
#include "e;so.h"e;
// function for checking libdl errors
int dlok(const char *msg)
{
char *err;
int unsigned ret = 1;
if ( (err = dlerror()) )
{
printf("e;%s: %s\n"e;, msg, err);
ret = 0;
}
return ret;
}
// loads module into the struct module
void* loadmodule(module *mod, const char *soname)
{
printf("e;Loading %s ...\n"e;, soname);
// load the library, resolve symbols as they are needed
mod->so = dlopen(soname, RTLD_LAZY);
if ( mod->so )
{
// get the initialization functions address
mod->init = (Init)dlsym(mod->so, "e;php_embed_init"e;);
if ( !dlok("e;\\-php_embed_init() not found"e;)) return 0;
}
else
printf("e;dlopen failure: %s\n"e;, dlerror());
return mod->so;
}
// unloads the module
int unloadmodule(module *mod)
{
return dlclose(mod->so);
}Code: Select all
#include "e;so.h"e;
char moduledirї] = "e;./modules"e;;
#define PARENT_DIR "e;.."e;
#define CURRENT_DIR "e;."e;
int main(int argc, char *argvї])
{
//------ load the shared object
// pointers for a directory and an entry
DIR *dir;
struct dirent *ep;
// temporary buffer
char bufferї200];
// a module
module mod;
// grab the directory
dir = opendir(moduledir);
bool dophp = false;
if ( dir )
{
// read all the entries -- asume there are only shared objects inside
while ( (ep = readdir(dir)) )
{
if ( !strcmp(ep->d_name, PARENT_DIR) || !strcmp(ep->d_name, CURRENT_DIR) ) continue;
// try to load
sprintf(buffer, "e;%s/%s"e;, moduledir, ep->d_name);
if ( loadmodule(&mod, buffer) )
{
dophp = true;
printf("e;successfully loaded module\n"e;);
}
else
printf("e;module loading failure\n"e;);
}
closedir(dir);
}
else
{
perror("e;Error opening dir \"e;./modules\"e;\n"e;);
return -1;
}
if ( dophp )
{
printf("e;Getting ready to run the PHP ...\n"e;);
(*mod.init)(argc,argv);
unloadmodule(&mod);
}
return 0;
}Code: Select all
TOOL=gcc
INC=include
SRC=src
all: test_so.o so.o
$(TOOL) -lgcc -lstdc++ -ldl -o test_so so.o test_so.o
so.o: $(SRC)/so.cpp $(INC)/so.h
$(TOOL) -I$(INC) -c -Wall $(SRC)/so.cpp
test_so.o: test_so.cpp $(INC)/so.h
$(TOOL) -I$(INC) -c -Wall test_so.cpp
clean:
rm test_so test_so.o so.o- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
undefined symbol: ap_loaded_modules
I am facing the same problem of "undefined symbol: ap_loaded_modules" when trying to run php scripts in commandline. Pl let me know if you found any answer for this one.
thanks.
thanks.