我想在我的 php 网站中使用 dompdf,我尝试在没有 Composer 的情况下包含该库,但我无法让它工作。
我尝试测试的代码是:
<?php
include "../../plugins/dompdf/Autoloader.php";
$dompdf = new Dompdf();
$dompdf->loadHtml('hello world');
// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape');
// Render the HTML as PDF
$dompdf->render();
?>
但我收到错误:
Fatal error: Class 'Dompdf' not found ...
谁能解释一下如何在服务器中不安装composer的情况下包含该库?
谢谢你。
正确的包含就像魅力一样,正如 Samrap 所说,我包含了错误的文件。
现在代码是:
<?php
//Configure the directory where you have the dompdf
require_once "../../plugins/dompdf/autoload.inc.php";
use Dompdf\Dompdf;
//$dompdf = new dompdf();
//$dompdf = new DOMPDF();
$dompdf = new Dompdf();
$dompdf->loadHtml('hello world');
// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape');
// Render the HTML as PDF
$dompdf->render();
// Output the generated PDF to Browser
$dompdf->stream();
?>
谢谢 Samrap 的帮助。
您需要错误的自动加载文件。文档明确指出要包含此文件以进行自动加载:
require_once 'dompdf/autoload.inc.php';
如果您查看该文件,您会发现它确实需要
Autoloader.php
,但也执行一些其他引导任务。
我意识到这是一个非常古老的问题,但我遇到了同样的问题,找到了此页面,并且必须为我的具体情况找到不同的解决方案。我将其发布在这里是因为我的解决方案不仅与 DOMPDF 相关,而且更多的是在没有 Composer 的情况下自动加载 .php 库文件的通用解决方案。
所以,要明确的是,我的情况如下:
vendor
目录和多个 autoload*.php
文件,但是我无法准确确定哪个使用了,哪个没用;autoload
对我不起作用;所以我制作了自己的简单自动加载,这是整个解决方案:
autoloaderbypasscomposer.php
class CQAutoloaderBypassComposer
{
private static $hInstance = NULL;
private $strRootDir;
private $arrComposerMappings;
private $arrPHPFileList;
private $arrErrors;
function __construct()
{
$this->arrComposerMappings = array();
$this->arrPHPFileList = array();
$this->arrErrors = array();
// TODO: set here the directory path where the 'vendor' big directory is.
// the idea is that this class cannot find this automatically
// DO NOT add a slash or backslash at the end !
$this->strRootDir = realpath(APPPATH . '../vendor');
// ... and now the class will start to search all subfolders and parse
// 'composer.json' files to get informations.
// On top of that, we will also get a list of all PHP files,
// just in case some .json files are missing and we still need to load
// some file/class
$this->ScanDirs($this->strRootDir);
}
private function ScanDirs($strDir)
{
$arrFileList = glob($strDir . DIRECTORY_SEPARATOR . '*');
if (is_array($arrFileList)){
foreach ($arrFileList as $strFileName){
if ($strFileName != '.' && $strFileName != '..'){
if (is_dir($strFileName)) $this->ScanDirs($strFileName);
else{
$nPointPos = strrpos($strFileName, '.');
$strExt = ($nPointPos === false ? '' : strtolower(substr($strFileName, $nPointPos + 1)));
switch ($strExt)
{
case 'json':{
if (basename($strFileName) == 'composer.json'){
try {
$arrJSONComposer = json_decode(file_get_contents($strFileName), true);
}catch(Exception $kEx){
$arrJSONComposer = array();
}
if (isset($arrJSONComposer['name']) && isset($arrJSONComposer['autoload']['psr-4'])){
foreach ($arrJSONComposer['autoload']['psr-4'] as $strNamespace => $strDir)
$this->arrComposerMappings[$strNamespace] = $arrJSONComposer['name'] . '/' . $strDir;
}
}
}break;
case 'php':{
$this->arrPHPFileList[] = $strFileName;
}break;
}
}
}
}
}
}
static function GetInstance()
{
if (self::$hInstance === NULL) self::$hInstance = new CQAutoloaderBypassComposer();
return self::$hInstance;
}
function SimpleQuickAutoloader($strClass)
{
// step 1: search according to composer info
foreach ($this->arrComposerMappings as $strNamespace => $strDir){
if (strpos($strClass, $strNamespace) === 0){
// yep, found. Now we need to unpack to see what to actually load
$strFileToLoad = $this->strRootDir . '/' . $strDir . '/' .
substr($strClass, strlen($strNamespace)) . '.php';
if (file_exists($strFileToLoad)){
require_once $strFileToLoad;
return; // end here
}else{
// file is missing for some reason. Add to error list so we can debug later
$this->arrErrors[] = 'ERROR (1): file is missing: ' . $strFileToLoad;
}
}
}
// step 2: we either don't have composer.json informations or the class
// we want to load is not found in a dir/file with the same name.
// We need to try to figure which file we need to load
$arrClassPath = explode('\\', $strClass);
$strFileToSearch = $arrClassPath[count($arrClassPath) - 1] . '.php';
foreach ($this->arrPHPFileList as $strFilename){
if (strtolower(basename($strFilename)) == strtolower($strFileToSearch) &&
is_int(strpos(strtolower($strFilename), strtolower($arrClassPath[0]))))
{
require_once $strFilename;
return; // end here
}
}
// if we are here, we failed to find the necessary file
$this->arrErrors[] = 'ERROR (2): cannot load: ' . $strClass;
// there are more methods to search (read each file contents and search
// for that specific class definition), however i'll stop here for now
}
function GetErrors()
{
return $this->arrErrors;
}
}
修改一行代码以指定放置库的
vendor
目录(或任何其他目录)的位置(服务器上的本地目录路径)。只需搜索 TODO: set here the directory
注释,您就会找到 $this->strRootDir
变量;将项目中的任何路径放在那里;
包含该文件,然后调用
spl_autoload_register
以便在需要加载某个新类时调用该类的函数:
require_once 'autoloaderbypasscomposer.php';
spl_autoload_register(array(CQAutoloaderBypassComposer::GetInstance(), 'SimpleQuickAutoloader'));
use Dompdf\Dompdf;
$kDOMPDF = new Dompdf();
... etc etc ...
请记住,我的解决方案并非万无一失,您使用她的风险由您自己承担。然而,我想说她在 99% 的情况下都有效,而且很容易改进。
composer.json
文件并解析它们以提取有用的信息;.php
文件并列出它们,因为大多数情况下类是在同名文件中定义的。composer.json
文件似乎包含在所有库中(至少在下载 DOMPDF 时),即使您手动下载它们。
一旦我的班级有了这些信息,她将能够根据类名和类路径确定需要加载哪些文件。唯一不可能的情况是 .php 文件名与其中包含的类名不同。但为此也可以编写一些额外的代码来解决这个问题。
享受:)