fopen();本地文件上“不接受远程主机文件访问”?

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

我正在使用 Tcpdf 模块和 PHP 从订购系统创建动态 PDF 发票。

然后,脚本应将发票保存到名为“发票”的文件夹中。该文件夹存在,并且“每个人”(Windows) 都有完全权限。

我使用的代码是这样的:

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

这使用 fopen 来保存文件。

但是我收到的错误是:

Warning: fopen(): remote host file access not supported, file://invoices/Delivery Note.pdf

这是本地文件,而不是远程文件。

我尝试添加一个 / 前缀,如下所示:

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

但是后来我收到了这个错误:

Warning: fopen(file:///invoices/Delivery Note.pdf): failed to open stream: No such file or directory

我创建了文件,并将其留空,但还是出现与上面相同的错误。

有谁知道为什么我会收到此错误?

php fopen
8个回答
41
投票

从 php 脚本您可以使用:

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

9
投票

在 vtiger 6.2 中升级到 tcpdf 6.2.6 后,我遇到了同样的问题,用 pdf 发送电子邮件。

所以我更改了文件:

 libraries/tcpdf/include/tcpdf_static.php

我已经注释了 fopenLocal() 中的代码并更改了该行

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

参见:

  /**
         * 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);
        }

更改后,它起作用了。


5
投票

user1007017
类似,但只需注释如下所示的行(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);
    }

3
投票

我建议使用以下内容,正如 Gerd 也建议的那样,但请确保使用绝对路径:

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

路径必须是绝对路径,而不是相对路径。此 PHP 错误报告解释了原因:https://bugs.php.net/bug.php?id=28820

file:// 包装器不支持相对路径的原因归结为如何处理 UNC 路径(更具体地说,对于 Windows 安装,如何将 / 模糊地解释为 \)。

例如:

文件://foo/bar

可以解释为当前工作目录中的相对 URI:foo/bar,或者可以解释为 UNC:oo ar(在计算机上共享

bar
foo
)。

出于这个原因和一些内部原因,显式调用时 file:// 包装器仅限于绝对路径。 对于相对路径,可以使用 realpath() {就像您在报告中所做的那样},或者省略文件的显式命名包装纸。

您可以避免修改 TCPDF 代码并担心任何升级会替换您修改的代码。


0
投票

我发现问题是 fopen 的路径必须来自文档根目录,而不是来自 PHP 脚本位置。

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

例如,如果 PHP 脚本位于“script”文件夹内,并且您想在“invoice”文件夹内创建 pdf,则脚本需要具有“\script\invoice\invoice.pdf”。


0
投票

在 prestashop 中你可以这样做 $pdf->Output(_PS_ROOT_DIR_.'/modules/xxx/ticket.pdf', 'F');


0
投票

你可以使用这个脚本

$pdf->输出(目录名(FILE,2).'/发票/交货单.pdf','F');


-2
投票

试试这个

$pdf->Output($_SERVER['DOCUMENT_ROOT'].'/invoices/Delivery Note.pdf', 'F');
© www.soinside.com 2019 - 2024. All rights reserved.