I probably over did my past post.
Let me simply ask, do you think there is technical merit (worth while)
to create a patch which offers multi-directory DLL loading support for
the PHP.INI extension_dir= option?
Example:
extension_dir="./ext;c:/myserver/bin;c:/otherext"
Reasons:
Currently, it only allows for a single folder and this present some
support issues.
But offering multi-directory support, PHP can:
1) Reduce extension DLL (non-PHP related) dependency issues,
2) Better support for PHP integration with Application Servers, and
3) Better support for security isolation, sand-boxing applications.
Do you see a technical reason why this is not a good idea? Would it be
transparent enough that it would not cause issues with current extensions?
TIA
--
Hector
Hector Santos wrote:
I'm relatively new to PHP development. I hope this is the appropriate
area for this question since I was thinking maybe I could use the
opportunity to get involved with the internals by making a patch
regarding how DLLs are loaded.
Specifically, the extension_dir="path" directive which only allows a
single path for finding dlls.
I'm nearly done with a new Windows-based PHP extension (php_wildcat.dll)
and one of the issues was DLL dependencies.
The PHP extension offers direct SDK/API support for our application
server and all our DLLs are in a specific server folder.
The installation of the Extension is preferred to be placed in our
server folder so ideally, something like so would be ideal:
extension_dir="./ext;c:/wildcat"
But of course, this isn't supported and it will not work, in fact, it
fails the loading of other PHP extensions.
The official method of placing extensions in the PHP "./Ext" requires
that we alter our long (12 years) recommended policy of a) not copying
our DLLS to other folders (for auto update/version control reasons) or
not requiring of adding the server folder in the Windows PATH.
I came up with an somewhat "kludgy" solution but I somewhat feel this
has to be a common PHP extension issues with extension authors, thus
maybe I must of a missed something where I don't have to do any of this.
The solution I came up with is to use DELAY LOADING where the extension
is compiled and linked with delayed loading of implicit dlls.
For example: the extension is compiled/linked using pragma directives
like so:
#define USE_DELAY_LOADING
...
#ifdef USE_DELAY_LOADING
# pragma comment(lib, "delayimp.lib")
# pragma comment(linker, "/delayload:wcsrv2.dll")
# pragma comment(linker, "/delayload:door32.dll")
#endif
delayimp.lib is part of the VC6.0 C/C++ runtime library and it handles
the delayed implicit loading of dlls. The DLLs above are part of our
RPC server API interface.
Now, our RPC server folder is recorded in the registry so using the dll
entry point DllMain(), the registry location is read and this is used
to add to the process environment path. So I have this at the end of my
PHP_WILDCAT.CPP code:
#ifdef USE_DELAY_LOADING
#define GETENV GetEnvironmentVariable
#define SETENV SetEnvironmentVariable
BOOL GetRegistry(const TCHAR *key,
const TCHAR *name,
DWORD type,
void *data,
DWORD datasize)
{
BOOL ok = FALSE;
HKEY k;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
key, 0, KEY_READ, &k) == ERROR_SUCCESS) {
DWORD t;
if (RegQueryValueEx(k, (TCHAR *)name, NULL,
&t, (BYTE *)data, &datasize) == ERROR_SUCCESS) {
ok = t == type;
}
RegCloseKey(k);
}
return ok;
}
BOOL GetRegistryString(const TCHAR *name,
TCHAR *data,
DWORD datasize,
const TCHAR *key = "SOFTWARE\\SSI\\Wildcat")
{
return GetRegistry(key, name, REG_SZ, data, datasize);
}
BOOL PrepareWildcatPath()
{
char srvPath[MAX_PATH]={0};
if (GetRegistryString("ServerDirectory",srvPath,MAX_PATH-1)) {
char ePath[1024*4] = {0};
strcpy(ePath,srvPath);
strcat(ePath,";");
DWORD dw = strlen(ePath);
return (GETENV("PATH",&ePath[dw],sizeof(ePath)-dw) &&
SETENV("PATH",ePath));
}
return FALSE;
}
////////////////////////////////////////////////////////////////////
// DllMain
////////////////////////////////////////////////////////////////////
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
PrepareWildcatPath();
break;
}
return TRUE;
}
#endif
This works really well. We can install PHP*.DLLs in the PHP "./EXT"
folder and when the extension is loaded by PHP, all of its dependencies
are now resolved during the temporary PHP runtime residence time.
I could of gone deeper (and more elegant without having to alter the
process PATH) by using the delayimp.lib helper hooks available which
will issue a callback for the delayed implicit dlls. But seems overly
complexed and before I begin on that I wanted so see if a) there was
already a method to address this and/or b) I could patch PHP to offer an
multi-path extension_dir method.
Ideally we would love to keep our specific PHP*.DLL files in our server
folder and have extension_dir defined to look at multiple paths.
Comments?
TIA
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php