PHP - ストリームを開けません: そのようなファイルまたはディレクトリはありません
P粉145543872
P粉145543872 2023-08-23 16:30:33
0
2
627
<p>PHP スクリプトで、<code>include()</code>、<code>require()</code>、<code>fopen()</code> を呼び出すかどうか。またはその派生クラス (<code> include_once</code>、<code>require_once</code>、さらには <code>move_uploaded_file()</code> など) を使用すると、エラーや警告が頻繁に発生します。 < /p> <ブロック引用> <p>ストリームを開けません: そのようなファイルまたはディレクトリはありません。 </p> </blockquote> <p>問題の根本原因を迅速に見つけるための適切なプロセスは何ですか? </p>
P粉145543872
P粉145543872

全員に返信(2)
P粉362071992

(非常に良い)既存の回答に追加

共有ホスティング ソフトウェア

open_basedir は Web サーバー構成で指定できるため、戸惑うかもしれません。これは独自の専用サーバーを実行すれば簡単に解決できますが、ドメインごとに設定ディレクティブを許可する共有ホスティング パッケージ (Plesk、cPanel など) があります。ソフトウェアは構成ファイル (httpd.conf) を構築するため、ホスティング ソフトウェアは再起動時にこのファイルを上書きするだけなので、このファイルを直接変更することはできません。

Plesk では、提供された httpd.conf (vhost.conf と呼ばれる) をオーバーライドする場所が提供されます。サーバー管理者のみがこのファイルに書き込むことができます。 Apacheの設定はこんな感じです

リーリー

サーバー管理者に依頼して、使用しているホスティング ソフトウェアおよび Web サーバー ソフトウェアのマニュアルを参照してください。

ファイル権限

Web サーバー経由でのファイルの実行は、コマンド ラインや cron ジョブの実行とは大きく異なることに注意することが重要です。最大の違いは、Web サーバーに独自のユーザーと権限があることです。このユーザーはセキュリティ上の理由から厳しく制限されています。たとえば、Apache は通常、apachewww-data、または httpd (サーバーによって異なります) です。 cron ジョブまたは CLI の実行には、それを実行しているユーザーが持つあらゆる権限が与えられます (つまり、root として実行される PHP スクリプトは root 権限で実行されます)。

多くの場合、次の方法で権限の問題を解決します (Linux の例)

リーリー

ファイルまたはディレクトリは誰でも書き込み可能になったため、これは賢明なアイデアではありません。あなたがサーバーを所有しており、唯一のユーザーである場合、これは大した問題ではありませんが、共有ホスティング環境にいる場合は、サーバー上の全員にアクセスを許可することになります。

アクセスが必要なユーザーを特定し、そのユーザーにのみアクセスを許可する必要があります。どのユーザーがアクセスを必要としているのかがわかったら、次のことを確認する必要があります。

  1. このユーザーはファイル

    を所有しており、親ディレクトリ (特にファイルに書き込む場合は親ディレクトリ) を所有している可能性があります。ほとんどの共有ホスティング環境では、ユーザーがルート ディレクトリ内のすべてのファイルを所有する必要があるため、これは問題になりません。 Linux の例を以下に示します リーリー

  2. このユーザー (およびこのユーザーのみ) にはアクセス権があります。 Linux では、

    chmod 600 (所有者のみが読み書きできる) または chmod 644 (所有者は書き込みできるが、全員が読み取れる) が推奨されます。

Linux/Unix の権限とユーザーに関する広範な説明は、

ここで読むことができます

いいねを押す +0
P粉268654873

このエラーが発生する理由は多数考えられるため、最初に何を確認するかについての適切なチェックリストが役に立ちます。

次の行のトラブルシューティングを行っていると仮定します:

リーリー


###リスト###

###1。ファイルパスにタイプミスがないか確認してください

手動検査 (経路を目視検査する)​​

  • または、
  • require*
  • または

    include* の呼び出しを独自の変数に移動し、エコーし、コピーして、次の方法でアクセスしてみます。 リーリー 次に、ターミナルで次のようにします: ああああ

###2。相対パスと絶対パスを考慮したファイル パスが正しいか確認してください


スラッシュ「/」で始まる場合は、Web サイト フォルダーのルート (ドキュメント ルート) ではなく、サーバーのルートを指します。

たとえば、Web サイトのディレクトリは

#__DIR__

マジック定数

現在のファイルのディレクトリを返します。

  1. SITE_ROOT定数を定義します: Web サイト ディレクトリのルート ディレクトリに config.php
  2. などのファイルを作成します。

    config.php

      を書き込みます ああああ
    • サイトのルート フォルダーを参照するすべてのファイルに、
    • config.php
    • を含め、任意の場所で

      SITE_ROOT 定数を使用します。 ああああ

    • これら 2 つの実践により、インクルード パスなどの ini 設定に依存しないため、アプリケーションの移植性も高まります。 ###3。インクルードパスを確認してください p>

    • 相対的でも純粋に絶対的でもないファイルをインクルードするもう 1 つの方法は、
    include パス
  3. に依存することです。これは、Zend Framework などのライブラリやフレームワークによく当てはまります。

このようなインクルードは次のようになります:

リーリー

この場合、「Zend」が存在するフォルダーがインクルード パスの一部であることを確認する必要があります。

次のコマンドを使用してインクルード パスを確認できます:

リーリー

次のコマンドを使用してフォルダーを追加できます:

リーリー

###4。サーバーがファイルにアクセスできるかどうかを確認してください

要約すると、サーバー プロセス (Apache または PHP) を実行しているユーザーには、ファイルの読み取りまたは書き込みの権限がまったくない可能性があります。

サーバーがどのユーザーで実行されているかを確認するには、

posix_getpwuid

を使用できます:

リーリー

ファイルの権限を確認するには、ターミナルに次のコマンドを入力します。

リーリー

and view権限表記


###5。 PHP設定を確認してください

上記の方法がいずれも機能しない場合は、一部の PHP 設定によりファイルにアクセスできないことが問題である可能性があります。

3 つの設定が関連する可能性があります:

  1. open_basedir
      これが設定されている場合、PHP は指定されたディレクトリの外にあるファイルに (シンボリック リンク経由であっても) アクセスできなくなります。
    • ただし、デフォルトの動作では設定されません。この場合、制限はありません。
    • phpinfo() を呼び出すか、进行检查>ini_get("open_basedir") を使用できます。 php.ini ファイルまたは httpd.conf ファイルを編集して設定を変更できます。
    • ######セーフモード###
    この機能が有効になっている場合、制限がある可能性があります。ただし、これは PHP 5.4 では削除されました。セーフ モードをサポートするバージョンをまだ使用している場合は、
  2. まだサポートされている
  3. バージョンの PHP にアップグレードしてください。 これは、ネットワーク プロセス (例: http://) 経由でファイルをインクルードするか開く場合にのみ機能し、ローカル ファイル システムにファイルをインクルードしようとする場合には機能しません
  4. ini_get("allow_url_include") を使用できます。ini_set("allow_url_include", "1")
      を確認して使用します。
    • 設定します。
    • 極端なケース
  5. 上記のどの方法でも問題を診断できない場合は、次のような特殊な状況が発生する可能性があります。


###1。インクルード パスに依存するライブラリのインクルード

相対パスまたは絶対パスを使用して、Zend Framework などのライブラリを含めることができます。例えば:### リーリー

しかし、依然として同じ種類のエラーが発生する可能性があります。

これは、(正常に) インクルードしたファイル自体に別のファイルからの include ステートメントが含まれており、2 番目の include ステートメントでは、ライブラリへのパスがインクルード パスに追加されていると想定されているために発生します。

たとえば、前述の Zend フレームワーク ファイルには次のものが含まれる可能性があります:

リーリー

相対パス経由でも絶対パス経由でも含まれません。 Zend フレームワーク ディレクトリがインクルード パスに追加されていることが前提となっています。

この場合、唯一の現実的な解決策は、ディレクトリをインクルード パスに追加することです。

###2。 SELinux

セキュリティが強化された Linux を実行している場合は、サーバーからのファイルへのアクセスが拒否されるため、これが問題の原因である可能性があります。

SELinux

がシステムで有効になっているかどうかを確認するには、ターミナルで

sestatus
コマンドを実行します。このコマンドが存在しない場合、SELinux はシステムに存在しません。存在する場合は、それが強制されているかどうかが示されるはずです。

SELinux ポリシーが問題の原因であるかどうかを確認するには、

SELinux ポリシーを一時的にオフにしてみてください。ただし、これを行うと保護が完全に無効になるので注意してください。運用サーバーではこれを行わないでください。

リーリー

SELinux をオフにした後で問題が発生しなくなった場合、これが根本原因です。 この問題を解決するには、それに応じて SELinux を構成する必要があります。

次のコンテキスト タイプが必要です:

  • httpd_sys_content_t サーバーに読み取れるようにするファイルの場合
  • httpd_sys_rw_content_t 読み取りおよび書き込みアクセスが必要なファイルの場合
  • httpd_log_t ログ ファイルの場合
  • httpd_cache_t キャッシュ ディレクトリに使用されます

たとえば、httpd_sys_content_t コンテキスト タイプを Web サイトのルートに割り当てるには、次のコマンドを実行します。 リーリー

ファイルがホーム ディレクトリにある場合は、

httpd_enable_homedirs ブール値: もオンにする必要があります。 リーリー

いずれにしても、ポリシーによっては、SELinux がファイルへのアクセスを拒否する理由がいくつか考えられます。したがって、これを調査する必要があります。

こちらは、Webサーバー用のSELinuxの構成に特化したチュートリアルです。


###3。交響曲###

Symfony を使用していて、サーバーにアップロードするときにこのエラーが発生した場合は、

app/cache

がアップロードされたためにアプリのキャッシュがリセットされていないか、キャッシュがリセットされていない可能性があります。クリアされました。

次のコンソール コマンドを実行すると、この問題をテストして修正できます: リーリー

###4。 Zip ファイル内の非 ACSII 文字


どうやら、このエラーは、zip 内の一部のファイルのファイル名に非 ASCII 文字 (例: "é") が含まれている場合に

zip->close()

を呼び出したときにも発生する可能性があります。

考えられる解決策は、ターゲット ファイルを作成する前にファイル名を utf8_decode() でラップすることです。

この問題を特定し、解決策を提案してくれた Fran Cano

に感謝します

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート