27

I am using the Tcpdf module and PHP to create dymanic PDF invoices from an ordering system.

The script should then save the invoice into a folder called "invoices". The folder exists, and there are full permissions for "everyone" (Windows).

The code I am using is this:

$pdf->Output('invoices/Delivery Note.pdf', 'F');

This uses fopen to save the file.

However the error I am getting is: Warning: fopen(): remote host file access not supported, file://invoices/Delivery Note.pdf

This is a local file, not a remote one.

I attempted adding a / prefix like this:

$pdf->Output('/invoices/Delivery Note.pdf', 'F');

but then I get this error instead: Warning: fopen(file:///invoices/Delivery Note.pdf): failed to open stream: No such file or directory

I created the file, and left it empty, but the same error as above.

Does anyone know why I am getting this error?

user2924019
  • 1,983
  • 4
  • 29
  • 49

8 Answers8

41

From php-Script you can use:

$pdf->Output(__DIR__ . '/invoices/Delivery Note.pdf', 'F');
Gerd
  • 591
  • 5
  • 5
  • this is a better answer than the one selected as it will be still working after updating TCPDF. Thanks! – jrgd May 09 '16 at 13:45
  • Whilst I agree that commenting out the code in tcpdf_static.php is a bad idea, I would argue that specifying the output location relative to DOCUMENT_ROOT is a better idea than specifying the output location relative to the location of the script that is running. Not much in it though I guess. – JamesG May 10 '16 at 11:00
9

After upgrading to the tcpdf 6.2.6 in vtiger 6.2 I've had the same problem, sending e-mail with pdf.

So I have changed the file:

 libraries/tcpdf/include/tcpdf_static.php

I have commented the code in fopenLocal() and changed the line

 fopen($_SERVER['DOCUMENT_ROOT'].$filename, $mode);

see:

  /**
         * Wrapper to use fopen only with local files
         * @param filename (string) Name of the file to open
         * @param $mode (string) 
         * @return Returns a file pointer resource on success, or FALSE on error.  
         * @public static
         */
        public static function fopenLocal($filename, $mode) {
    //      if (strpos($filename, '://') === false) {
    //          $filename = 'file://'.$filename;
    //      } elseif (strpos($filename, 'file://') !== 0) {
    //          return false;
    //      }
            return fopen($_SERVER['DOCUMENT_ROOT'].$filename, $mode);
        }

After changing this, it worked.

user 1007017
  • 391
  • 2
  • 10
5

similar to user1007017, but just comment the line like shown below (tcpdf 6.2.11)

public static function fopenLocal($filename, $mode) {
        if (strpos($filename, '://') === false) {
            //$filename = 'file://'.$filename;
        } elseif (stream_is_local($filename) !== true) {
            return false;
        }
        return fopen($filename, $mode);
    }
Hilarius L. Doren
  • 757
  • 1
  • 12
  • 29
  • You sir are a life saver even after all these years! I have spent hours trying to figure this issue out. Your solution works perfectly. Had to also use @gerd solution of __DIR__ . but now working... – Woody Oct 11 '20 at 22:51
3

I suggest using the following as Gerd has also suggested but make sure you use an absolute path:

$pdf->Output(__DIR__ . '/invoices/Delivery Note.pdf', 'F');

The path must be an absolute path & not a relative path. This PHP bug report explains why: https://bugs.php.net/bug.php?id=28820

The reason relative paths are not supported with the file:// wrapper comes down to a compromise in how UNC paths are dealt with (and more specifically how / are fuzzily interpreted as \ for windows installations).

For Example:

file://foo/bar

Could be interpreted as a relative URI: foo/bar from the current working directory, OR it could be interpreted as a UNC: \foo\bar (share bar on computer foo).

For this and a few internal reasons the file:// wrapper is limited to absolute paths when called explicitly. For relative paths either use realpath() {as you did in your report}, or omit the explicit naming of the file wrapper.

You can then avoid modifying the TCPDF code and worrying about any upgrades replacing your modified code.

mattferderer
  • 894
  • 9
  • 17
0

I found the issue was that the path for fopen has to be from the document root, and not from the PHP script location.

C:\Website\www\script\invoice\invoice.pdf

For example if the PHP script is inside the "script" folder, and you want to create the pdf inside the "invoice" folder, the script needs to have "\script\invoice\invoice.pdf".

user2924019
  • 1,983
  • 4
  • 29
  • 49
0

In prestashop you can do it in this way $pdf->Output(_PS_ROOT_DIR_.'/modules/xxx/ticket.pdf', 'F');

0

you can use this script

'$'pdf->Output(dirname(FILE,2). '/invoices/Delivery Note.pdf', 'F');

  • $pdf->Output(dirname(__FILE__,2). '/invoices/Delivery Note.pdf', 'F'); – liamsi hafil Aug 14 '23 at 21:52
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 16 '23 at 09:58
-2

try this

$pdf->Output($_SERVER['DOCUMENT_ROOT'].'/invoices/Delivery Note.pdf', 'F');
Navjot Singh
  • 514
  • 4
  • 14
  • 1
    Still the same error: `Warning: fopen(file://E:/Websites/*******/www/invoices/Delivery Note.pdf): failed to open stream: No such file or directory` – user2924019 Mar 04 '15 at 12:04
  • echo $_SERVER['DOCUMENT_ROOT'].'/invoices/Delivery Note.pdf' then hit printed url in your window explorer and check you get file or not. – Navjot Singh Mar 04 '15 at 12:07
  • I also used touch() with the same path to create an empty file, it works, but fopen can't access it still – user2924019 Mar 04 '15 at 12:22
  • I tried this way before reading this post and it doesn't work – edisonmecaj May 03 '16 at 11:55