Drupal9自定义模块通过Libraries API加载自定义PHP类库问题求助
问题原因
你遇到的Undefined index: installed报错和libraries_load()加载失败问题,核心原因是未通过Libraries API要求的钩子声明自定义库的元信息。libraries_get_libraries()仅会扫描所有合法的libraries目录返回路径,不需要额外声明,但libraries_load()需要提前知道库的待加载文件、安装检测规则等配置才能正常工作。
基于Libraries API的修复方案
步骤1:实现hook_libraries_info()声明库配置
在你的demo模块根目录新建demo.module文件(如果已有则直接追加代码),内容如下:
<?php /** * Implements hook_libraries_info(). */ function demo_libraries_info() { $libraries['demolib'] = [ 'name' => 'Demo自定义PHP库', 'version' => '1.0.0', // 声明需要加载的PHP文件 'files' => [ 'php' => [ 'DemoLib.php', ], ], // 声明库的安装检测逻辑,修复installed索引不存在的报错 'installed' => function ($library) { return file_exists($library['library path'] . '/DemoLib.php'); }, ]; return $libraries; }
步骤2:清空Drupal缓存
Drupal的钩子注册需要清理缓存后才会生效,可通过后台「配置-性能-清除所有缓存」或Drush命令drush cr完成。
步骤3:测试库加载
修改DemoController.php的测试方法:
public function showdemo() { $library = libraries_load('demolib'); if (!empty($library['loaded'])) { $demoLib = new \DemoLib(); $content = $demoLib->showHello(); } else { $content = $this->t('自定义库加载失败'); } return ['#markup' => $content]; }
更适配你多站点架构的轻量替代方案
如果不想依赖Libraries API,完全可以利用Drupal的站点路径判断能力实现自定义库的优先级加载,适配你们「开发站点自有库优先、生产环境复用sites/all库」的规则,无需额外配置:
public function showdemo() { // 获取当前站点的根路径(例:sites/dev-repository1) $sitePath = \Drupal::service('site.path'); $libFileName = 'demolib/DemoLib.php'; // 优先加载站点私有库,不存在则加载sites/all的公共库 if (file_exists($sitePath . '/libraries/' . $libFileName)) { require_once $sitePath . '/libraries/' . $libFileName; } elseif (file_exists('sites/all/libraries/' . $libFileName)) { require_once 'sites/all/libraries/' . $libFileName; } else { return ['#markup' => $this->t('未找到自定义库文件')]; } $demoLib = new \DemoLib(); return ['#markup' => $demoLib->showHello()]; }
该方案不需要额外依赖第三方模块,也不需要处理钩子、缓存等额外逻辑,更适合你方多站点批量部署的场景。
内容的提问来源于stack exchange,提问作者Marko Cundeković
相关产品推荐
相关产品推荐

