如何在没有composer的情况下包含dompdf

问题描述 投票:0回答:3

我想在我的 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的情况下包含该库?

谢谢你。

php dompdf
3个回答
5
投票

正确的包含就像魅力一样,正如 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 的帮助。


4
投票

您需要错误的自动加载文件。文档明确指出要包含此文件以进行自动加载:

require_once 'dompdf/autoload.inc.php';

如果您查看该文件,您会发现它确实需要

Autoloader.php
,但也执行一些其他引导任务。


0
投票

我意识到这是一个非常古老的问题,但我遇到了同样的问题,找到了此页面,并且必须为我的具体情况找到不同的解决方案。我将其发布在这里是因为我的解决方案不仅与 DOMPDF 相关,而且更多的是在没有 Composer 的情况下自动加载 .php 库文件的通用解决方案。

所以,要明确的是,我的情况如下:

  1. 我想在我的项目中的特定位置加载和使用 DOMPDF(但就像我说的,它可能是 DOMPDF 之外的其他任何东西);
  2. 我的项目相当大,而且相当丑陋,因为他是由多个程序员开发了多年的,总体来说一团糟;
  3. 我的项目包含多个
    vendor
    目录和多个
    autoload*.php
    文件,但是我无法准确确定哪个使用了,哪个没用;
  4. DOMPDF 的
    autoload
    对我不起作用;
  5. 我最终想要最简单的解决方案。

所以我制作了自己的简单自动加载,这是整个解决方案:

解决方案

  1. 将以下源代码写入文件中,比方说
    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;
    }
}

  1. 修改一行代码以指定放置库的

    vendor
    目录(或任何其他目录)的位置(服务器上的本地目录路径)。只需搜索
    TODO: set here the directory
    注释,您就会找到
    $this->strRootDir
    变量;将项目中的任何路径放在那里;

  2. 包含该文件,然后调用

    spl_autoload_register
    以便在需要加载某个新类时调用该类的函数:

require_once 'autoloaderbypasscomposer.php';

spl_autoload_register(array(CQAutoloaderBypassComposer::GetInstance(), 'SimpleQuickAutoloader'));
  1. 就这样,您就可以开始使用这些库了,在本例中:
use Dompdf\Dompdf;

$kDOMPDF = new Dompdf();
... etc etc ...

请记住,我的解决方案并非万无一失,您使用她的风险由您自己承担。然而,我想说她在 99% 的情况下都有效,而且很容易改进。

进一步说明

我的班级所做的是首先在所有子目录中搜索:
  1. composer.json
    文件并解析它们以提取有用的信息;
  2. .php
    文件并列出它们,因为大多数情况下类是在同名文件中定义的。

composer.json
文件似乎包含在所有库中(至少在下载 DOMPDF 时),即使您手动下载它们。 一旦我的班级有了这些信息,她将能够根据类名和类路径确定需要加载哪些文件。唯一不可能的情况是 .php 文件名与其中包含的类名不同。但为此也可以编写一些额外的代码来解决这个问题。

享受:)

© www.soinside.com 2019 - 2024. All rights reserved.