• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • dl()

    (PHP 4, PHP 5, PHP 7)

    运行时载入一个 PHP 扩展

    说明

    dl(string $library): bool

    载入指定参数$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:php5加载。

    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 #1dl()例子

    <?php
    // 加载一个扩展的例子,基于操作系统
    if (!extension_loaded('sqlite')) {
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
            dl('php_sqlite.dll');
        } else {
            dl('sqlite.so');
        }
    }
    // 或者,使用常量 PHP_SHLIB_SUFFIX 
    if (!extension_loaded('sqlite')) {
        $prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
        dl($prefix . 'sqlite.' . PHP_SHLIB_SUFFIX);
    }
    ?>
    

    更新日志

    版本说明
    7.0.0PHP-FPM 模式下已禁用dl()
    5.3.9尽管不推荐,但 PHP-FPM 模式下启用了dl()
    5.3.0由于稳定性,dl()在某些 SAPI 中被禁用。仅仅允许dl()的 SAPI 为 CLI 和 Embed。使用扩展加载指令作为替代。

    注释

    Note:

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

    Note:

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

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

    参见

    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');
    ?>
    
    It would be nice to know which SAPIs removed the function. 
    Telling me 'This function has been removed from some SAPIs in PHP 5.3.' is pretty much useless and I feel mocked. Or do the writers of the documentation don't know from which SAPIs it has been removed?
    Like with eval(), the only correct way to use dl() is to not use it.
    Test if a function(s) you intend to use are available.
    If not, complain to the user or implement a workaround.
    Not to mention dl() issues in a multithreading environment.
    <?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()
    ?>
    
    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()
    ?>
    
    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.
    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/..."