web-dev-qa-db-ja.com

fopen();ローカルファイルで「リモートホストファイルアクセスは許可されません」?

TcpdfモジュールとPHP dymanic PDF注文システムからの請求書を作成するために使用しています。

スクリプトは、請求書を「invoices」というフォルダーに保存する必要があります。フォルダが存在し、「全員」(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

ファイルを作成して空のままにしましたが、上記と同じエラーが発生しました。

このエラーが発生する理由を誰かが知っていますか?

17
user2924019

Php-Scriptから以下を使用できます。

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

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

これを変更した後、うまくいきました。

7
user 1007017

に似ている 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=2882

File://ラッパーで相対パスがサポートされていない理由は、UNCパスの処理方法(具体的には、/がWindowsインストールで/としてあいまいに解釈される方法)の妥協点にあります。

例えば:

file:// foo/bar

相対URIとして解釈できます:現在の作業ディレクトリからのfoo/bar、OR UNCとして解釈できます:\ foo\bar(コンピューターbarfooを共有します)。

これといくつかの内部的な理由から、file://ラッパーは明示的に呼び出されると絶対パスに制限されます。相対パスの場合は、realpath(){asあなたはあなたのレポートで行いました}、またはファイルラッパーの明示的な名前を省略します。

その後、TCPDFコードを変更したり、変更したコードを置き換えるアップグレードについて心配したりする必要がなくなります。

1
mattferderer

私は、fopenのパスがPHPスクリプトの場所からではなく、ドキュメントルートからである必要があることを確認しました。

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

たとえば、PHPスクリプトが「script」フォルダ内にあり、「invoice」フォルダ内にpdfを作成する場合、スクリプトには「\ script\invoice\invoice」が必要です。 pdf」。

0
user2924019

Prestashopでは、次のようにしてこれを行うことができます$ pdf-> Output(_PS_ROOT_DIR _。 '/ modules/xxx/ticket.pdf'、 'F');