0

I'm using:

TCPDF version 6.4.4.

FPDI version 2.3.6

PHP Version 8.1.7 (Running on Apache and Windows Server 2012,a dev environment)

And, I don't think it's relevant but I'm also using tcpdf-extension

These were installed with composer:

{
    "require": {
        "tecnickcom/tcpdf": "6.4.4",
        "setasign/fpdi": "^2.0",
        "naitsirch/tcpdf-extension": "dev-master"
    }
}

I am also using a Java/PHP bridge. This is relevant because it changes the error message, however, I doubt this is the cause of the issue.

The problem I'm having is that Fpdi fails to extend TCPDF. The error message I get looks like this:

PHP Fatal error:  During class fetch: Uncaught Error: Call to a member function invokeBegin()
 on null in http://127.0.0.1:8080/JavaBridge/java/Java.inc:557
Stack trace:
#0 http://127.0.0.1:8080/JavaBridge/java/Java.inc(56): java_Client->invokeMethod(0, 'typeExists', Array)
#1 C:\Program Files (x86)\PHP\v8.1\vendor\setasign\fpdi\src\Tcpdf\Fpdi.php(33):
 java_autoload_function('setasign\\Fpdi\\F...')
...
#8 {main} in C:\Program Files (x86)\PHP\v8.1\vendor\setasign\fpdi\src\Tcpdf\Fpdi.php on line 33

It is failing to fetch a class and the php/java bridge, as a last ditch effort to load it, is attempting to fetch the missing class with a java autoloader, which it fails to do because it's not a java class. Unfortunately, it doesn't give me the full name of the class that's it is trying to load. But this error occurs in setasign\fpdi\src\Tcpdf\Fpdi.php on line 33. Which reads:

class Fpdi extends \TCPDF

My code that invokes this looks like this:

define("COMPOSER_AUTOLOADER","C:\\Program Files (x86)\\PHP\\v8.1\\vendor\\autoload.php");
require_once(COMPOSER_AUTOLOADER);
use setasign\Fpdi\Tcpdf\Fpdi;
class PDF extends Fpdi {
...//functions related to my use case
}

My code that calls this extended class:

                        // initiate PDF
                        $pdf = new PDF($data['orientation'], 'mm', USLETTER, true, 'UTF-8', false);
                        $pdf->setPrintHeader(false);
                        $pdf->setPrintFooter(false);
                        $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
                        $pdf->SetDisplayMode('real');
                        $pdf->SetAutoPageBreak(true, 1);
                        
                        //set margins
                        $pdf->SetMargins(0,0);
                        $pdf->SetHeaderMargin(0);
                        $pdf->SetFooterMargin(0);
                        ...
                        $pdf->AddPage($data['orientation']);
                        ...
                        $pdf->Output('newpdf.pdf', 'I');

Also probably relevant, I set up a test that uses only the TCPDF library without Fpdi and it fails to load the constants that are supposed to be set up in TCPDF_static.php. (USLETTER for instance), but if I manually define that constant, it does load the PDF as expected:

require_once("C:\\Program Files (x86)\\PHP\\v8.1\\vendor\\autoload.php");
use setasign\Fpdi\Tcpdf\Fpdi;
define ('USLETTER',array(  612.000,   792.000));   
$pdf = new TCPDF('', 'in', USLETTER, true, 'UTF-8', false);
...
$pdf->AddPage();
...
$pdf->Output('newpdf.pdf', 'I');

Another detail: this code was working fine with PHP 5.6 and some older versions of TCPDF (6.2.11) and Fpdi (1.4.2). Upgrading to PHP 8.1.7 required updating these libraries.

Why is TCPDF failing to load its constants and, more importantly, why can't Fpdi extend TCPDF?

starshine531
  • 601
  • 5
  • 19
  • Your folder structure looks strange to me. Is `C:\\Program Files (x86)\\PHP\\v8.1\\` your project folder? What happens if you disable the Java bridge? – Jan Slabon Jul 15 '22 at 07:28
  • I was using a constant to define that. I forgot to take out the backslashes that you have to use when defining a windows path. I have updated my question with a more accurate representation of the code. I'll try disabling the bridge and report back. – starshine531 Jul 15 '22 at 15:18
  • PHP Fatal error: Trait "setasign\Fpdi\FpdiTrait" not found in C:\Program Files (x86)\PHP\v8.1\vendor\setasign\fpdi\src\Tcpdf\Fpdi.php on line 33 – starshine531 Jul 15 '22 at 15:27
  • If I add require_once("C:\\Program Files (x86)\\PHP\\v8.1\\vendor\\setasign\\fpdi\\src\\FpdiTrait.php"); *before* I require the composer autoloader, it works. At least to the point where it loads the libraries. I have some more php8.1 incompatibilities in other libraries to workout before I can really test it. – starshine531 Jul 15 '22 at 16:10
  • I have the feeling that you do not use the correct autoload class from composer. You're requiring from a global vendor folder. Why do you do that? Doesn't it make sense to have your vendor folder by project? You should start from scratch, create your composer.json, call `composer install` on it, require its autoload.php and try a simple example. It should work without anything else. – Jan Slabon Jul 17 '22 at 15:55
  • In the end, we decided to use PHP 7.4 instead of 8.1, and this issue has been resolved, thusly. And yes, I am using a global vendor folder. This server only has one project -- the website/webapp -- and it is the only thing we use the server for. We have no need to have separate project folders. – starshine531 Sep 07 '22 at 20:23

0 Answers0