我正在使用Tcpdf模块和PHP从订购系统创建动态PDF发票。
然后,脚本应将发票保存到名为"发票"的文件夹中。该文件夹存在,并且对于"每个人都有完整的权限。 (视窗)。
我使用的代码是:
$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
我创建了该文件,并将其留空,但与上面的错误相同。
有谁知道我收到此错误的原因?
答案 0 :(得分:23)
从php-Script您可以使用:
$pdf->Output(__DIR__ . '/invoices/Delivery Note.pdf', 'F');
答案 1 :(得分:7)
升级到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);
}
更改后,它有效。
答案 2 :(得分:3)
类似于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 :(得分:0)
我发现问题是fopen的路径必须来自文档根目录,而不是来自PHP脚本位置。
C:\Website\www\script\invoice\invoice.pdf
例如,如果PHP脚本位于"脚本"文件夹,并且您想在"发票"内创建pdf;文件夹,脚本需要有" \ script \ invoice \ invoice.pdf"。
答案 4 :(得分:0)
我建议使用以下内容,因为Gerd也建议但请确保使用绝对路径:
$pdf->Output(__DIR__ . '/invoices/Delivery Note.pdf', 'F');
路径必须是绝对路径&不是相对路径。此PHP错误报告解释了原因:https://bugs.php.net/bug.php?id=28820
file:// wrapper不支持相对路径的原因归结为如何处理UNC路径(更具体地说,如何/模糊解释为\用于Windows安装)。
例如:
文件://富/酒吧
可以解释为当前工作目录中的相对URI:foo / bar,或者它可以解释为UNC:\ foo \ bar(在计算机
bar
上共享foo
)。 / p>由于这个原因和一些内部原因,文件://包装器在显式调用时仅限于绝对路径。对于相对路径,使用realpath(){就像在报告中那样},或者省略文件包装器的显式命名。
然后,您可以避免修改TCPDF代码,并担心替换修改后的代码的任何升级。
答案 5 :(得分:0)
在prestashop中,您可以通过$ pdf-> Output(_PS_ROOT_DIR _。'/ modules / xxx / ticket.pdf','F');
答案 6 :(得分:-2)
试试这个
$pdf->Output($_SERVER['DOCUMENT_ROOT'].'/invoices/Delivery Note.pdf', 'F');