-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add SAPI module folder to DLL search path #16718
Comments
PHP extension DLLs (php_amqp.dll) are looked up in the |
J'ai le meme problème |
Well, that is a pretty common problem. For many SAPIs (CLI, CGI), it works fine if you put dependencies of extensions in the folder where php.exe/php-cgi.exe resides. That does usually not work when PHP is run as Webserver module. That might also be relevant for PIE (cc @asgrim). We could tell the system to also look in the folder where the Webserver module resides. quick and dirty patch for apache2handler sapi/apache2handler/sapi_apache2.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c
index 1d85a92ebf..25f94a64c2 100644
--- a/sapi/apache2handler/sapi_apache2.c
+++ b/sapi/apache2handler/sapi_apache2.c
@@ -383,6 +383,13 @@ extern zend_module_entry php_apache_module;
static int php_apache2_startup(sapi_module_struct *sapi_module)
{
+ HMODULE mod;
+ wchar_t filename[1024];
+ GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)php_apache2_startup, &mod);
+ GetModuleFileNameW(mod, filename, 1024);
+ wchar_t *slash = wcsrchr(filename, L'\\');
+ slash[0] = L'\0';
+ SetDllDirectoryW(filename);
return php_module_startup(sapi_module, &php_apache_module);
} We need to thoroughly consider BC and security implications, though. PS: should also pass |
thanks for the ping, I believe PIE does this correctly already:
|
Thanks @asgrim; the relevant item:
This is exactly how it should be done (as good as it gets), but that will (usually) not work with Webserver modules (like apache2handler). Amongst other locations, Windows searches for DLLs where the .exe which needs them is placed. So to make that work for Apache, you either put httpd.exe and php.exe in the same folder (total mess), or you put the folder of php.exe in the Anyhow, I'll submit a PR for this issue soon, and shall also actually try out PIE. :) |
See also https://news-web.php.net/php.internals.win/1237. PS: that message mentions |
On Windows, it is customary to put dependency DLLs in the main PHP folder, i.e. right besides php.exe. If the SAPI is implemented as .exe, dependency lookup works fine, since DLLs are always searched in the folder of the .exe. However, for Webserver modules, this usually does not work, since the Webserver's executable likely resides in a different folder. While there are obviously solutions to this, the Windows error message if a module can't be loaded are confusing, so users and even popular AMP distributions often choose to put the DLLs in the folder of the Webserver (e.g. right besides httpd.exe). That can easily cause more confusion later, when users update to a newer PHP version, which requires more recent dependencies. Thus, to simplify setup and to bring the behavior more in line with CLI and CGI SAPIs, we add the SAPI module folder to the DLL search path. We keep that simple, and do not cater to long paths, and silently don't change the DLL search order in case of unexpected failures. Since we are using `SetDllDirectory()` for all SAPIs, that effectively also prevents DLLs being looked up in the current folder, what might break some scripts, but can also avoid confusion regarding ZTS builds, where the current directory of the process is not necessarily what is reported by `getcwd()`. It is also a small security measure, even stronger than safe DLL search mode[1]. Note that this certainly does not solve all problems related to DLL lookup, e.g. that the application folder is still searched first, and that already loaded DLLs will not be searched and loaded again. But it appears to be a sensible improvement, and hopefully prevents others to put DLLs in folders where they don't belong, in the future. [1] <https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order>
On Windows, it is customary to put dependency DLLs in the main PHP folder, i.e. right besides php.exe. If the SAPI is implemented as .exe, dependency lookup works fine, since DLLs are always searched in the folder of the .exe. However, for Webserver modules, this usually does not work, since the Webserver's executable likely resides in a different folder. While there are obviously solutions to this, the Windows error messages if a module can't be loaded are confusing, so users and even popular AMP distributions often choose to put the DLLs in the folder of the Webserver (e.g. right besides httpd.exe). That can easily cause more confusion later, when users update to a newer PHP version, which requires more recent dependencies. Thus, to simplify setup and to bring the behavior more in line with CLI and CGI SAPIs, we add the SAPI module folder to the DLL search path. We keep that simple, and do not cater to long paths, and silently don't change the DLL search order in case of unexpected failures. Since we are using `SetDllDirectory()` for all SAPIs, that effectively also prevents DLLs being looked up in the current folder, what might break some scripts, but can also avoid confusion regarding ZTS builds, where the current directory of the process is not necessarily what is reported by `getcwd()`. It is also a small security measure, even stronger than safe DLL search mode[1]. Note that this certainly does not solve all problems related to DLL lookup, e.g. that the application folder is still searched first, and that already loaded DLLs will not be searched and loaded again. But it appears to be a sensible improvement, and hopefully prevents others to put DLLs in folders where they don't belong, in the future. [1] <https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order>
Description
I added "extension=amqp" in php.ini file, as well as the php_amqp.dll file in "C:\xampp\php\ext", and 2 additional files
rabbitmq.4.dll and rabbitmq.4.pdb in "C:\xampp\php", but the following error appears:
PHP Warning: PHP Startup: Unable to load dynamic library 'amqp' (tried: C:\xampp\php\ext\amqp (The specified module could not be found), C:\xampp\php\ext\php_amqp.dll (The specified module could not be found)) in Unknown on line 0
PHP Version
PHP 8.2.12
Operating System
Windows 10
The text was updated successfully, but these errors were encountered: