PHP 选项/信息 函数
在线手册:中文  英文

dl

(PHP 4, PHP 5)

dl运行时载入一个 PHP 扩展

说明

bool dl ( string $library )

载入指定参数 library 的 PHP 扩展。

使用 extension_loaded() 来测试指定的扩展是否已经激活。 这既能用于内建的扩展也可以用于动态加载的扩展(既可以通过 php.ini 也可以通过 dl())。

Warning

在 PHP 5.3 里,此函数被某些 SAPI 移除了。

参数

library

此参数仅仅是要加载的扩展的文件名,依赖于你的平台。 比如,sockets(作为共享模块编译,而不是默认的!)在 Unix 平台上称为 sockets.so 而 在 Windows 平台上是 php_sockets.dll

扩展加载的目录依赖于你的平台:

Windows - 如果没有在 php.ini 里明确设置,扩展默认会从 C:\php4\extensions\ (PHP 4) 或 C:\php5\ (PHP 5)加载。

Unix - 如果没有在 php.ini 里明确设置,默认的扩展目录依赖于

  • PHP 是否通过 --enable-debug 选项构建
  • PHP 是否以(实验性质的)ZTS (Zned 线程安全)支持构建
  • 当前的内部 ZEND_MODULE_API_NO(Zend 内部模块 API 数字,基本上是主要模块修改时的日期)
考虑到上述,目录默认为 <install-dir>/lib/php/extensions/ <debug-or-not>-<zts-or-not>-ZEND_MODULE_API_NO,例如 /usr/local/php/lib/php/extensions/debug-non-zts-20010901/usr/local/php/lib/php/extensions/no-debug-zts-20010901

返回值

成功时返回 TRUE, 或者在失败时返回 FALSE。 如果加载模块的功能是无效或者禁用的(既可以通过设置关闭 enable_dl 设置,也可以通过启用 php.ini 里的 安全模式)将导致一个 E_ERROR 并中断执行。 如果因为指定的库无法加载而导致 dl() 失败,除了返回 FALSE,还会产生一个 E_WARNING 的消息。

范例

Example #1 dl() 例子

<?php
// 加载一个扩展的例子,基于操作系统
if (!extension_loaded('sqlite')) {
    if (
strtoupper(substr(PHP_OS03)) === 'WIN') {
        
dl('php_sqlite.dll');
    } else {
        
dl('sqlite.so');
    }
}

// 或者,PHP_SHLIB_SUFFIX 常量在 PHP 4.3.0 后有效
if (!extension_loaded('sqlite')) {
    
$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' '';
    
dl($prefix 'sqlite.' PHP_SHLIB_SUFFIX);
}
?>

更新日志

版本 说明
5.3.0 由于稳定性, dl() 在某些 SAPI 中被禁用。仅仅允许 dl() 的 SAPI 为 CLI 和 Embed。 使用 扩展加载指令 作为替代。

注释

Note:

当 PHP 以支持 ZTS 构建时,支持 dl()。 使用 扩展加载指令 作为替代。

Note:

在某些 Unix 平台上, dl() 是大小写敏感的。

Note: 当 PHP 运行在 安全模式 时,不能使用此函数。

参见


PHP 选项/信息 函数
在线手册:中文  英文

用户评论:

fabrizim at owlwatch dot com (2013-05-03 20:24:01)

As noted in the documentation:
Changelog 5.3: dl() is now disabled in some SAPIs due to stability issues. The only SAPIs that allow dl() are CLI and Embed. Use the Extension Loading Directives instead.
If using PEAR libraries that try to load extensions, like Image_Transform which will try to load ImageMagik, and the "enable_dl" directive is set to 1 in your php.ini, you may end up with a hard to find error (white screen of death).
One "solution" is to change the enable_dl directive to 0 in the php.ini. It may have adverse affects if you are using php on command line that requires the "dl" function, but I think in most cases its okay.

Anonymous (2010-12-04 10:36:19)

this function errors out as the dl() cannot take the absolute path..."Warning: dl() [function.dl]: Temporary module name should contain only filename in /home/..."

CLI workaround (2009-02-18 15:18:57)

NOTE:  This only works using the CLI

If you need to use dl() with the CLI, but you get this warning:

"PHP Warning:  dl(): Dynamically loaded extensions aren't enabled"

Then the 'enable_dl' setting in the php.ini needs to be set to 'On' - the set_ini() function does not work with this INI option.

If, however, you do not wish (or don't have access) to alter the system php.ini, then you can do the following:

<?php

if ( !ini_get('enable_dl') ) {
    
exec("php -d enable_dl=On $argv[0]");
    exit;
}

?>

This simply calls itself and defines the enable_dl INI entry on the command line so you dont have to start the script with options in the first place (or use another script to call it.)

shaunspiller at spammenot-gmail dot com (2009-01-29 00:34:18)

dl is awkward because the filename format is OS-dependent and because it can complain if the extension is already loaded. This wrapper function fixes that:

<?php

function load_lib($n$f null) {
    return 
extension_loaded($n) or dl(((PHP_SHLIB_SUFFIX === 'dll') ? 'php_' '') . ($f $f $n) . '.' PHP_SHLIB_SUFFIX);
}

?>

Examples:

<?php

// ensure we have SSL and MySQL support
load_lib('openssl');
load_lib('mysql');

// a rare few extensions have a different filename to their extension name, such as the image (gd) library, so we specify them like this:
load_lib('gd''gd2');

?>

buildsmart at daleenterprise dot com (2006-12-29 13:33:36)

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

docey (2005-12-30 21:37:51)

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.

mag_2000 at front dot ru (2005-12-06 11:13:44)

<?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 $loadedExtensionssizeof$loadedExtensions ) - ];
  
 
//lastly, we return the extension name
  
return $thisExtName;

}
//end dl_local()

?>

james at gogo dot co dot nz (2005-07-18 16:30:58)

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

endofyourself at yahoo dot com (2003-10-18 04:12:50)

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 $loadedExtensionssizeof$loadedExtensions ) - ];
  
 
//lastly, we return the extension name
  
return $thisExtName;

}
//end dl_local()

?>

tychay at php dot net (2003-07-05 20:15: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

易百教程