I recently came across this under PHP 4.4.4, it seems that the dl(); function generates an error/warning about registering the function if a test is done on an extension that is pre-loaded in the php.ini file (extension=gd.so).
<?php
$gd_is_shared = "shared-library";
if (function_exists('ImageCreateFromPNG') && !@dl('gd.so')) {
$gd_is_shared = "embedded";
}
print $gd_is_shared;
?>
The only purpose of this test is to determine if it is an embedded extension or a loaded extension.
I don't see this error occur under PHP 5.1.6 or PHP 5.2.0.
The test platform is Mac OS X 10.3.9 and Mac OS X 10.4.8
dl
(PHP 4, PHP 5)
dl — Lädt eine PHP-Erweiterung (Extension) zur Laufzeit
Beschreibung
Lädt die mittels dem Parameter library angegebene PHP-Erweiterung. Der Parameter library ist nur der Dateiname der zu ladenden Erweiterung (Extension), welcher von Ihrer Plattform abhängig ist. Z.B. würde die Extension sockets (wenn als shared module kompiliert, nicht standardmäßig!) auf Unix Plattformen sockets.so, und auf Windows Plattformen php_sockets.dll heißen.
Gibt bei Erfolg TRUE zurück, im Fehlerfall FALSE. Ist die Funktionalität des Ladens von Modulen nicht verfügbar (siehe Anmerkung), oder wurde sie deaktiviert (entweder durch Deaktivieren von enable_dl oder durch aktivieren von safe_mode in der php.ini), wird ein E_ERROR ausgegeben, und die Ausführung gestoppt. Scheitert dl() weil die angegebene Erweiterung nicht geladen werden konnte, wird zusätzlich zu FALSE eine E_WARNING Meldung ausgegeben.
Verwenden Sie extension_loaded() um zu testen, ob die gewünschte Erweiterung bereits verfügbar ist oder nicht. Dies funktioniert sowohl bei eingebauten, als auch bei dynamisch geladenen Erweiterungen (entweder durch php.ini, oder mittels dl()).
Beispiel #1 dl() Beispiel
if (!extension_loaded('gd')) {
if (!dl('gd.so')) {
exit;
}
}
Das Verzeichnis, von wo aus die Erweiterung geladen wird, hängt von Ihrer Plattform ab:
Windows - Wenn nicht explizit in der php.ini angegeben, wird die Erweiterung standardmäßig von c:\php4\extensions\ geladen.
Unix - Wenn nicht explizit in der php.ini angegeben, hängt das standardmäßige Verzeichnis ab von:
- ob PHP mit --enable-debug erstellt wurde oder nicht
- ob PHP mit (experimentellem) ZTS (Zend Thread Safety) Unterstützung erstellt wurde oder nicht
- der aktuellen internen ZEND_MODULE_API_NO (Zend interne Modul API Nummer, welche im Grunde das Datum der letzten größeren Modul API Änderung darstellt, z.B. 20010901).
Hinweis: dl() wird in multithreaded WebServern nicht unterstützt. In solch einer Umgebung verwenden Sie bitte die extensions Anweisung in Ihrer php.ini. Die CGI und CLI Module sind davon jedoch nicht betroffen!
Hinweis: dl() unterscheidet auf Unix Plattformen zwischen Groß- und Kleinschreibung.
Siehe auch Extension Loading Directives and extension_loaded().
dl
29-Dec-2006 10:33
23-Nov-2006 12:57
a note for mag_2000 at front dot ru
the line
$currentExtPath = ini_get('extension_dir');
would be better to be
$currentExtPath = realpath(ini_get('extension_dir'));
I came across some hosts that had ./ set at the extension_dir
31-Dec-2005 06:37
just some note to loading modules, they do not have to
be executable.
some examples below check for this but if an module is
not executable is does not mean you cant use it. it just
needs to be readable NOT executable.
although some modules might need this perhaps for some
reason i cannot think of, so here an example,
<?php
// fails to load mysql although it could be loaded.
if(is_executable("mysql.so")){
dl("mysql.so");
}
// loads mysql
if(is_readable("mysql.so")){
dl("mysql.so");
}
?>
watch out with this, as you can see mysql.so would not be
loaded and the script would fail. because its checked for
executable permissions although these are not needed.
06-Dec-2005 08:13
<?php
function dl_local( $extensionFile ) {
//make sure that we are ABLE to load libraries
if( !(bool)ini_get( "enable_dl" ) || (bool)ini_get( "safe_mode" ) ) {
die( "dh_local(): Loading extensions is not permitted.\n" );
}
//check to make sure the file exists
if( !file_exists( $extensionFile ) ) {
die( "dl_local(): File '$extensionFile' does not exist.\n" );
}
//check the file permissions
if( !is_executable( $extensionFile ) ) {
die( "dl_local(): File '$extensionFile' is not executable.\n" );
}
//we figure out the path
$currentDir = getcwd() . "/";
$currentExtPath = ini_get( "extension_dir" );
$subDirs = preg_match_all( "/\//" , $currentExtPath , $matches );
unset( $matches );
//lets make sure we extracted a valid extension path
if( !(bool)$subDirs ) {
die( "dl_local(): Could not determine a valid extension path [extension_dir].\n" );
}
$extPathLastChar = strlen( $currentExtPath ) - 1;
if( $extPathLastChar == strrpos( $currentExtPath , "/" ) ) {
$subDirs--;
}
$backDirStr = "";
for( $i = 1; $i <= $subDirs; $i++ ) {
$backDirStr .= "..";
if( $i != $subDirs ) {
$backDirStr .= "/";
}
}
//construct the final path to load
$finalExtPath = $backDirStr . $currentDir . $extensionFile;
//now we execute dl() to actually load the module
if( !dl( $finalExtPath ) ) {
die();
}
//if the module was loaded correctly, we must bow grab the module name
$loadedExtensions = get_loaded_extensions();
$thisExtName = $loadedExtensions[ sizeof( $loadedExtensions ) - 1 ];
//lastly, we return the extension name
return $thisExtName;
}//end dl_local()
?>
19-Jul-2005 01:30
WARNING: enable_dl/dl()
*********************
There is an exploit circulating currently which takes advantage of dl() to inject code into Apache which causes all requests to all virtual hosts to be redirected to a page of the attackers choice.
All operators of shared web hosting servers with Apache and PHP should disable dl() by setting enable_dl to off otherwise your servers are vulnerable to this exploit.
This exploit is generally known as flame.so (the object that is loaded into Apache) and flame.php (the php script that loads it).
Google gives more information:
http://www.google.co.nz/search?q=flame.so+flame.php
18-Oct-2003 01:12
If you need to load an extension from the CURRENT local directory because you do not have privelages to place the extension in your servers PHP extensions directory, this function i wrote may be of use to you
<?php
/*
Function: dl_local()
Reference: http://us2.php.net/manual/en/function.dl.php
Author: Brendon Crawford <endofyourself |AT| yahoo>
Usage: dl_local( "mylib.so" );
Returns: Extension Name (NOT the extension filename however)
NOTE:
This function can be used when you need to load a PHP extension (module,shared object,etc..),
but you do not have sufficient privelages to place the extension in the proper directory where it can be loaded. This function
will load the extension from the CURRENT WORKING DIRECTORY only.
If you need to see which functions are available within a certain extension,
use "get_extension_funcs()". Documentation for this can be found at
"http://us2.php.net/manual/en/function.get-extension-funcs.php".
*/
function dl_local( $extensionFile ) {
//make sure that we are ABLE to load libraries
if( !(bool)ini_get( "enable_dl" ) || (bool)ini_get( "safe_mode" ) ) {
die( "dh_local(): Loading extensions is not permitted.\n" );
}
//check to make sure the file exists
if( !file_exists( $extensionFile ) ) {
die( "dl_local(): File '$extensionFile' does not exist.\n" );
}
//check the file permissions
if( !is_executable( $extensionFile ) ) {
die( "dl_local(): File '$extensionFile' is not executable.\n" );
}
//we figure out the path
$currentDir = getcwd() . "/";
$currentExtPath = ini_get( "extension_dir" );
$subDirs = preg_match_all( "/\//" , $currentExtPath , $matches );
unset( $matches );
//lets make sure we extracted a valid extension path
if( !(bool)$subDirs ) {
die( "dl_local(): Could not determine a valid extension path [extension_dir].\n" );
}
$extPathLastChar = strlen( $currentExtPath ) - 1;
if( $extPathLastChar == strrpos( $currentExtPath , "/" ) ) {
$subDirs--;
}
$backDirStr = "";
for( $i = 1; $i <= $subDirs; $i++ ) {
$backDirStr .= "..";
if( $i != $subDirs ) {
$backDirStr .= "/";
}
}
//construct the final path to load
$finalExtPath = $backDirStr . $currentDir . $extensionFile;
//now we execute dl() to actually load the module
if( !dl( $finalExtPath ) ) {
die();
}
//if the module was loaded correctly, we must bow grab the module name
$loadedExtensions = get_loaded_extensions();
$thisExtName = $loadedExtensions[ sizeof( $loadedExtensions ) - 1 ];
//lastly, we return the extension name
return $thisExtName;
}//end dl_local()
?>
06-Jul-2003 05:15
MacOS makes a distinction between dynamically loadable shared libraries and loadable modules of code (bundles). The former has an extension .dylib and the latter has an extension .so. The former is in Mac-O and the latter is in ELF.
Thus PHP's extensions are built as .so whereas the symbol PHP_SHLIB_SUFFIX is bound (currently) to .dylib. I don't think this is the correct behavior, but nonetheless, it is the behavior as of PHP-5.0.0b2-dev. Right now, the config binds to SHLIB_SUFFIX_NAME (which is correctly bound to .dylib on Mac OS X). I imagine this is related to why there is so much trouble getting dl() to work on Mac OS X. (For instance, I have no trouble phpizing in a new shared library, but when compiling in stuff as shared... much evilness!)
BTW, to get dl() to work in Mac OS X you need to install the dlcompat library (via Fink, DarwinPorts, or Gentoo ports). Remember in the case of Fink, you better make sure your environment variables are adjusted to point to where dlcompat (and your other fink libraries) are.
terry
