PHP - ストリームを開けません: そのようなファイルまたはディレクトリはありません
P粉145543872
2023-08-23 16:30:33
<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>
(非常に良い)既存の回答に追加
共有ホスティング ソフトウェア
open_basedir
は Web サーバー構成で指定できるため、戸惑うかもしれません。これは独自の専用サーバーを実行すれば簡単に解決できますが、ドメインごとに設定ディレクティブを許可する共有ホスティング パッケージ (Plesk、cPanel など) があります。ソフトウェアは構成ファイル (httpd.conf
) を構築するため、ホスティング ソフトウェアは再起動時にこのファイルを上書きするだけなので、このファイルを直接変更することはできません。Plesk では、提供された
リーリーhttpd.conf
(vhost.conf
と呼ばれる) をオーバーライドする場所が提供されます。サーバー管理者のみがこのファイルに書き込むことができます。 Apacheの設定はこんな感じですサーバー管理者に依頼して、使用しているホスティング ソフトウェアおよび Web サーバー ソフトウェアのマニュアルを参照してください。
ファイル権限
Web サーバー経由でのファイルの実行は、コマンド ラインや cron ジョブの実行とは大きく異なることに注意することが重要です。最大の違いは、Web サーバーに独自のユーザーと権限があることです。このユーザーはセキュリティ上の理由から厳しく制限されています。たとえば、Apache は通常、
apache
、www-data
、またはhttpd
(サーバーによって異なります) です。 cron ジョブまたは CLI の実行には、それを実行しているユーザーが持つあらゆる権限が与えられます (つまり、root として実行される PHP スクリプトは root 権限で実行されます)。多くの場合、次の方法で権限の問題を解決します (Linux の例)
リーリーファイルまたはディレクトリは誰でも書き込み可能になったため、これは賢明なアイデアではありません。あなたがサーバーを所有しており、唯一のユーザーである場合、これは大した問題ではありませんが、共有ホスティング環境にいる場合は、サーバー上の全員にアクセスを許可することになります。
アクセスが必要なユーザーを特定し、そのユーザーにのみアクセスを許可する必要があります。どのユーザーがアクセスを必要としているのかがわかったら、次のことを確認する必要があります。
を所有しており、親ディレクトリ (特にファイルに書き込む場合は親ディレクトリ) を所有している可能性があります。ほとんどの共有ホスティング環境では、ユーザーがルート ディレクトリ内のすべてのファイルを所有する必要があるため、これは問題になりません。 Linux の例を以下に示します リーリー
chmod 600
(所有者のみが読み書きできる) または
chmod 644(所有者は書き込みできるが、全員が読み取れる)
が推奨されます。ここで読むことができます
このエラーが発生する理由は多数考えられるため、最初に何を確認するかについての適切なチェックリストが役に立ちます。
次の行のトラブルシューティングを行っていると仮定します:
リーリー
###リスト######1。ファイルパスにタイプミスがないか確認してください
手動検査 (経路を目視検査する)
include*
の呼び出しを独自の変数に移動し、エコーし、コピーして、次の方法でアクセスしてみます。
リーリー次に、ターミナルで次のようにします:
ああああ/users/tony/htdocs-
- つまり、Web サイトのルートへのパスや入力しているファイルへのパスとは何の関係もありません。
したがって、常に絶対ファイル パスを使用してください
-
###ベストプラクティス:###
- 実行時に絶対パスを生成しながら、コンテンツを移動するときにスクリプトを堅牢にするために、2 つのオプションがあります:
__DIR__ が必要ですを使用してください。 "/相対/パス/from/current/file"
。になります。-
スラッシュで始まらない場合は、インクルード パス (以下を参照) に依存しているか、パスが相対パスであるかのいずれかです。相対パスの場合、PHP は 現在の作業ディレクトリを基準とした相対パス
を計算します。#__DIR__
マジック定数現在のファイルのディレクトリを返します。
SITE_ROOT
定数を定義します:
にconfig.php
を書き込みます ああああ-
config.php- を含め、任意の場所で
-
相対的でも純粋に絶対的でもないファイルをインクルードするもう 1 つの方法は、
include パスサイトのルート フォルダーを参照するすべてのファイルに、
SITE_ROOT
定数を使用します。 ああああ
これら 2 つの実践により、インクルード パスなどの ini 設定に依存しないため、アプリケーションの移植性も高まります。
###3。インクルードパスを確認してください p>
このようなインクルードは次のようになります:
リーリーこの場合、「Zend」が存在するフォルダーがインクルード パスの一部であることを確認する必要があります。
次のコマンドを使用してインクルード パスを確認できます:リーリー
次のコマンドを使用してフォルダーを追加できます:リーリー
###4。サーバーがファイルにアクセスできるかどうかを確認してくださいposix_getpwuid
を使用できます:リーリー
ファイルの権限を確認するには、ターミナルに次のコマンドを入力します。リーリー
and view権限表記
###5。 PHP設定を確認してくださいこれが設定されている場合、PHP は指定されたディレクトリの外にあるファイルに (シンボリック リンク経由であっても) アクセスできなくなります。-
ただし、デフォルトの動作では設定されません。この場合、制限はありません。 -
- phpinfo()
-
######セーフモード###
この機能が有効になっている場合、制限がある可能性があります。ただし、これは PHP 5.4 では削除されました。セーフ モードをサポートするバージョンをまだ使用している場合は、を呼び出すか、
进行检查>ini_get("open_basedir")を使用できます。
php.ini ファイルまたは httpd.conf ファイルを編集して設定を変更できます。を確認して使用します。- 設定します。
-
極端なケース
###1。インクルード パスに依存するライブラリのインクルードしかし、依然として同じ種類のエラーが発生する可能性があります。
これは、(正常に) インクルードしたファイル自体に別のファイルからの include ステートメントが含まれており、2 番目の include ステートメントでは、ライブラリへのパスがインクルード パスに追加されていると想定されているために発生します。
たとえば、前述の Zend フレームワーク ファイルには次のものが含まれる可能性があります:リーリー
相対パス経由でも絶対パス経由でも含まれません。 Zend フレームワーク ディレクトリがインクルード パスに追加されていることが前提となっています。SELinux
がシステムで有効になっているかどうかを確認するには、ターミナルでsestatus
SELinux ポリシーが問題の原因であるかどうかを確認するには、コマンドを実行します。このコマンドが存在しない場合、SELinux はシステムに存在しません。存在する場合は、それが強制されているかどうかが示されるはずです。
SELinux ポリシーを一時的にオフにしてみてください。ただし、これを行うと保護が完全に無効になるので注意してください。運用サーバーではこれを行わないでください。
リーリーSELinux をオフにした後で問題が発生しなくなった場合、これが根本原因です。
この問題を解決するには、
それに応じて SELinux を構成する必要があります。次のコンテキスト タイプが必要です:-
-
-
-
###4。 Zip ファイル内の非 ACSII 文字
zip->close()
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の構成に特化したチュートリアルです。
Symfony を使用していて、サーバーにアップロードするときにこのエラーが発生した場合は、###3。交響曲###
app/cache
がアップロードされたためにアプリのキャッシュがリセットされていないか、キャッシュがリセットされていない可能性があります。クリアされました。次のコンソール コマンドを実行すると、この問題をテストして修正できます:
リーリーどうやら、このエラーは、zip 内の一部のファイルのファイル名に非 ASCII 文字 (例: "é") が含まれている場合に
を呼び出したときにも発生する可能性があります。
考えられる解決策は、ターゲット ファイルを作成する前にファイル名を
utf8_decode()
でラップすることです。
に感謝しますこの問題を特定し、解決策を提案してくれた
Fran Cano