dl

(PHP 4, PHP 5, PHP 7, PHP 8)

dl在运行时加载 PHP 扩展

描述

dl(string $extension_filename): bool

加载由参数 extension_filename 指定的 PHP 扩展。

使用 extension_loaded() 测试给定扩展是否已经可用。这适用于内置扩展和动态加载的扩展(通过 php.inidl())。

警告

此函数仅适用于 CLI 和嵌入式 SAPI,以及从命令行运行时的 CGI SAPI

参数

extension_filename

此参数是要加载的扩展的文件名,它还取决于您的平台。例如,sockets 扩展(如果编译为共享模块,而不是默认值!)在 Unix 平台上被称为 sockets.so,而在 Windows 平台上被称为 php_sockets.dll

加载扩展的目录取决于您的平台

Windows - 如果没有在 php.ini 中显式设置,则默认情况下扩展将从 C:\php5\ 加载。

Unix - 如果没有在 php.ini 中显式设置,则默认扩展目录取决于

  • PHP 是否使用 --enable-debug 编译
  • PHP 是否使用 ZTS(Zend 线程安全)支持编译
  • 当前内部 ZEND_MODULE_API_NO(Zend 内部模块 API 编号,基本上是主要模块 API 更改发生的日期,例如 20010901
考虑到以上几点,目录默认情况下为 <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。如果加载模块的功能不可用或已被禁用(通过在 php.ini 中将 enable_dl 设置为 off),则会发出 E_ERROR 并且执行停止。如果 dl() 失败,因为指定的库无法加载,除了 false 之外,还会发出 E_WARNING 消息。

示例

示例 #1 dl() 示例

<?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);
}
?>

注释

注意:

dl() 在 Unix 平台上区分大小写。

参见

添加注释

用户贡献的注释 4 个注释

14
shaunspiller at spammenot-gmail dot com
15 年前
dl 很麻烦,因为文件名格式依赖于操作系统,并且如果扩展已经加载,它会报错。此包装函数修复了这些问题

<?php

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

?>

示例

<?php

// 确保我们有 SSL 和 MySQL 支持
load_lib('openssl');
load_lib('mysql');

// 一些罕见的扩展具有与扩展名称不同的文件名,例如图像(gd)库,因此我们像这样指定它们:
load_lib('gd', 'gd2');

?>
-2
mag_2000 at front dot ru
18 年前
<?php

function dl_local( $extensionFile ) {
// 确保我们能够加载库
if( !(bool)ini_get( "enable_dl" ) || (bool)ini_get( "safe_mode" ) ) {
die(
"dh_local(): 加载扩展是不允许的。\n" );
}

// 检查文件是否存在
if( !file_exists( $extensionFile ) ) {
die(
"dl_local(): 文件 '$extensionFile' 不存在。\n" );
}

// 检查文件权限
if( !is_executable( $extensionFile ) ) {
die(
"dl_local(): 文件 '$extensionFile' 不可执行。\n" );
}

// 我们找出路径
$currentDir = getcwd() . "/";
$currentExtPath = ini_get( "extension_dir" );
$subDirs = preg_match_all( "/\//" , $currentExtPath , $matches );
unset(
$matches );

// 确保我们提取了有效的扩展路径
if( !(bool)$subDirs ) {
die(
"dl_local(): 无法确定有效的扩展路径 [extension_dir]。\n" );
}

$extPathLastChar = strlen( $currentExtPath ) - 1;

if(
$extPathLastChar == strrpos( $currentExtPath , "/" ) ) {
$subDirs--;
}

$backDirStr = "";
for(
$i = 1; $i <= $subDirs; $i++ ) {
$backDirStr .= "..";
if(
$i != $subDirs ) {
$backDirStr .= "/";
}
}

// 构造最终的加载路径
$finalExtPath = $backDirStr . $currentDir . $extensionFile;

// 现在我们执行 dl() 来实际加载模块
if( !dl( $finalExtPath ) ) {
die();
}

// 如果模块加载成功,我们需要获取模块名称
$loadedExtensions = get_loaded_extensions();
$thisExtName = $loadedExtensions[ sizeof( $loadedExtensions ) - 1 ];

// 最后,我们返回扩展名称
return $thisExtName;

}
// end dl_local()

?>
-4
anrdaemon at freemail dot ru
7 years ago
就像 eval() 一样,使用 dl() 的唯一正确方法是不使用它。
测试您要使用的函数是否可用。
如果不可用,请向用户发出警告或实施解决方法。
更不用说 dl() 在多线程环境中的问题了。
-5
endofyourself at yahoo dot com
20 years ago
如果您需要从当前本地目录加载扩展,因为您没有权限将扩展放在服务器的 PHP 扩展目录中,那么我编写的这个函数可能对您有用。

<?php
/*
函数: dl_local()
参考: http://us2.php.net/manual/en/function.dl.php
作者: Brendon Crawford <endofyourself |AT| yahoo>
用法: dl_local( "mylib.so" );
返回值: 扩展名称(但不是扩展文件名)
注意:
当您需要加载一个 PHP 扩展(模块、共享对象等)时,可以使用此函数,
但您没有足够的权限将扩展放置在可以加载它的目录中。此函数
将从当前工作目录加载扩展。
如果您需要查看某个扩展中可用的函数,
使用 "get_extension_funcs()”。有关此函数的文档,请参见
"http://us2.php.net/manual/en/function.get-extension-funcs.php"。
*/

function dl_local( $extensionFile ) {
// 确保我们能够加载库
if( !(bool)ini_get( "enable_dl" ) || (bool)ini_get( "safe_mode" ) ) {
die(
"dh_local(): 加载扩展是不允许的。\n" );
}

// 检查文件是否存在
if( !file_exists( $extensionFile ) ) {
die(
"dl_local(): 文件 '$extensionFile' 不存在。\n" );
}

// 检查文件权限
if( !is_executable( $extensionFile ) ) {
die(
"dl_local(): 文件 '$extensionFile' 不可执行。\n" );
}

// 我们找出路径
$currentDir = getcwd() . "/";
$currentExtPath = ini_get( "extension_dir" );
$subDirs = preg_match_all( "/\//" , $currentExtPath , $matches );
unset(
$matches );

// 确保我们提取了有效的扩展路径
if( !(bool)$subDirs ) {
die(
"dl_local(): 无法确定有效的扩展路径 [extension_dir]。\n" );
}

$extPathLastChar = strlen( $currentExtPath ) - 1;

if(
$extPathLastChar == strrpos( $currentExtPath , "/" ) ) {
$subDirs--;
}

$backDirStr = "";
for(
$i = 1; $i <= $subDirs; $i++ ) {
$backDirStr .= "..";
if(
$i != $subDirs ) {
$backDirStr .= "/";
}
}

// 构造最终的加载路径
$finalExtPath = $backDirStr . $currentDir . $extensionFile;

// 现在我们执行 dl() 来实际加载模块
if( !dl( $finalExtPath ) ) {
die();
}

// 如果模块加载成功,我们需要获取模块名称
$loadedExtensions = get_loaded_extensions();
$thisExtName = $loadedExtensions[ sizeof( $loadedExtensions ) - 1 ];

// 最后,我们返回扩展名称
return $thisExtName;

}
// end dl_local()

?>
To Top