PHP - 스트림을 열 수 없습니다: 해당 파일이나 디렉터리가 없습니다
P粉145543872
P粉145543872 2023-08-23 16:30:33
0
2
587
<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>문제의 근본 원인을 신속하게 찾는 좋은 프로세스는 무엇입니까? </p>
P粉145543872
P粉145543872

모든 응답(2)
P粉362071992

(매우 좋음) 기존 답변에 추가되었습니다

공유 호스팅 소프트웨어

open_basedir 可能会难倒您,因为它可以在 Web 服务器配置中指定。虽然如果您运行自己的专用服务器,这很容易解决,但有一些共享托管软件包(如 Plesk、cPanel 等)可以在每个域的基础上配置配置指令。由于该软件会构建配置文件(即 httpd.conf) 호스팅 소프트웨어가 재부팅 시 해당 파일을 덮어쓰므로 해당 파일을 직접 변경할 수 없습니다.

Plesk를 사용하면 제공해야 하는 내용을 다룰 수 있는 위치를 제공합니다 httpd.conf(称为 vhost.conf). 서버 관리자만 이 파일에 쓸 수 있습니다. Apache 구성은 다음과 같습니다

으아악

서버 관리자에게 문의하여 사용하는 호스팅 및 웹 서버 소프트웨어에 대한 설명서를 참조하세요.

파일 권한

웹 서버를 통해 파일을 실행하는 것은 명령줄이나 크론 작업 실행과 매우 다르다는 점에 유의하는 것이 중요합니다. 가장 큰 차이점은 웹 서버에 자체 사용자와 권한이 있다는 것입니다. 이 사용자는 보안상의 이유로 엄격히 제한됩니다. 예를 들어 Apache는 일반적으로 apachewww-datahttpd입니다(서버에 따라 다름). cron 작업 또는 CLI 실행에는 이를 실행하는 사용자가 갖고 있는 모든 권한이 있습니다. 즉, 루트로 실행되는 PHP 스크립트는 루트 권한으로 실행됩니다.

사람들은 다음을 수행하여 권한 문제를 해결하는 경우가 많습니다(Linux 예)

으아악

이제 파일이나 디렉토리가 모두 쓰기 가능하므로 이는 현명한 아이디어가 아닙니다. 서버를 소유하고 있고 유일한 사용자인 경우 이는 큰 문제가 아니지만 공유 호스팅 환경에 있는 경우 서버의 모든 사람에게 액세스 권한을 부여하게 됩니다.

접속이 필요한 사용자를 식별하고 해당 사용자에게만 접속 권한을 부여하면 됩니다. 액세스가 필요한 사용자를 파악한 후에는 확인해야 합니다

  1. 이 사용자는 파일 을 소유하고 있으며 상위 디렉터리 (특히 파일에 쓰는 경우 상위 디렉터리)를 소유할 가능성이 높습니다. 대부분의 공유 호스팅 환경에서는 사용자가 루트 디렉터리의 모든 파일을 소유해야 하므로 이는 문제가 되지 않습니다. Linux 예제는 아래에 나와 있습니다

    으아악
  2. 이 사용자(및 이 사용자만)에게 액세스 권한이 있습니다. Linux에서 좋은 방법은 chmod 600(只有所有者可以读写)或 chmod 644(소유자는 쓸 수 있지만 누구나 읽을 수 있음)

여기에서 Linux/Unix 권한 및 사용자에 대한 더 폭넓은 토론을 읽을 수 있습니다

P粉268654873

이 오류가 발생할 수 있는 이유는 다양하므로 먼저 확인해야 할 사항에 대한 좋은 체크리스트가 도움이 될 수 있습니다.

다음 줄의 문제를 해결한다고 가정해 보겠습니다.

으아악


체크리스트


1. 파일 경로에 오타가 있는지 확인하세요

  • 수동 점검(경로를 육안으로 점검)
  • 또는 require*include* 호출을 자체 변수로 이동하고, 에코하고, 복사한 후 터미널에서 액세스해 보세요.

    으아악

    그런 다음 터미널에서:

    require "/path/to/file"


2. 상대경로와 절대경로 고려사항의 파일경로가 맞는지 확인해보세요

모범 사례:

런타임에 절대 경로를 생성하면서 콘텐츠를 이동할 때 스크립트를 강력하게 만들려면 다음 두 가지 옵션이 있습니다.

    현재 파일의 디렉터리를 반환하려면
  1. 마법 상수require __DIR__ 。 “/相对/路径/来自/当前/文件”__DIR__를 사용하세요.
  2. 상수를 직접 정의하세요. SITE_ROOT

      웹사이트 디렉터리의 루트에 파일을 만듭니다. 예를 들어
    • config.php
    • Write

      에서 config.php

      $path = "/path/to/file";
      
      echo "Path : $path";
      
      require "$path";
    • 사이트 루트 폴더를 참조하려는 모든 파일에

      를 포함시킨 다음 어디에서나 config.php,然后在任意位置使用 SITE_ROOT 상수를 사용하세요. p>

      cat <file path pasted>

이 두 가지 방법은 포함 경로와 같은 ini 설정에 의존하지 않으므로 애플리케이션의 이식성을 더욱 높여줍니다.


3. 포함 경로를 확인하세요

상대적이지도 않고 절대적이지도 않은 파일을 포함하는 또 다른 방법은 include 경로를 사용하는 것입니다. 이는 Zend Framework와 같은 라이브러리나 프레임워크의 경우에 자주 발생합니다.

그러한 포함은 다음과 같습니다:

으아악

이 경우 "Zend"가 위치한 폴더가 포함 경로의 일부인지 확인해야 합니다.

다음 명령을 사용하여 포함 경로를 확인할 수 있습니다.

으아악

다음 명령을 사용하여 폴더를 추가할 수 있습니다:

으아악


4. 서버가 파일에 액세스할 수 있는지 확인하세요

요약하자면, 서버 프로세스(Apache 또는 PHP)를 실행하는 사용자에게는 파일을 읽거나 쓸 수 있는 권한이 전혀 없을 수도 있습니다.

서버가 어떤 사용자로 실행되고 있는지 확인하려면 posix_getpwuid를 사용할 수 있습니다.

으아아아

파일의 권한을 찾으려면 터미널에 다음 명령을 입력하세요.

으아아아

그리고 권한 표기

도 확인해 보세요.


5. PHP 설정 확인

위의 방법 중 어느 것도 작동하지 않으면 일부 PHP 설정으로 인해 파일에 액세스하지 못하는 것이 문제일 수 있습니다.

다음 세 가지 설정이 관련될 수 있습니다.

  1. open_basedir
    • 이렇게 설정하면 PHP는 지정된 디렉터리 외부의 파일에 액세스할 수 없습니다(심볼릭 링크를 통해서도 액세스할 수 없음).
    • 그러나 기본 동작은 설정하지 않는 것이며 이 경우에는 제한이 없습니다
    • phpinfo()phpinfo()进行检查> 或使用 ini_get("open_basedir")를 호출하거나 ini_get("open_basedir")를 사용하여 확인할 수 있습니다
    • php.ini 파일이나 httpd.conf 파일을 편집하여 설정을 변경할 수 있습니다
  2. 안전 모드
    • 이 기능을 활성화하면 제한될 수 있습니다. 그러나 이는 PHP 5.4에서 제거되었습니다. 아직 안전 모드를 지원하는 버전을 사용하고 있다면 아직 지원되는 버전의 PHP로 업그레이드하세요.
  3. allow_url_fopen 및allow_url_include
    • 이 기능은 네트워크 프로세스(예: http://)를 통해 파일을 포함하거나 열 때만 작동하며 로컬 파일 시스템에 파일을 포함하려고 할 때는 작동하지 않습니다
    • ini_get("allow_url_include") 检查并使用 ini_set("allow_url_include", "1") 설정
    • 을 사용하여 설정할 수 있습니다.


극한 상황

위의 방법으로 문제를 진단할 수 없는 경우 다음과 같은 특별한 상황이 발생할 수 있습니다.


1. 포함 경로에 의존하는 라이브러리 포함

상대 또는 절대 경로를 사용하여 Zend 프레임워크와 같은 라이브러리를 포함할 수 있습니다. 예:

으아아아

그러나 여전히 동일한 유형의 오류가 발생합니다.

이는 성공적으로 포함시킨 파일 자체에 다른 파일의 포함 문이 있고 두 번째 포함 문에서는 포함 경로에 라이브러리 경로를 추가했다고 가정하기 때문에 발생합니다.

예를 들어 앞서 언급한 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 컨텍스트 유형을 할당하려면 다음을 실행하세요.

으아악

파일이 홈 디렉터리에 있는 경우 httpd_enable_homedirs 부울:

도 열어야 합니다. 으아악

그럼에도 불구하고 전략에 따라 SELinux가 파일에 대한 액세스를 거부하는 데에는 여러 가지 이유가 있을 수 있습니다. 그래서 이것을 조사해야합니다. 여기는 웹 서버용 SELinux 구성을 위한 튜토리얼입니다.


3. 심포니

Symfony를 사용 중이고 서버에 업로드할 때 이 오류가 발생하는 경우 app/cache가 업로드된 이후 앱의 캐시가 재설정되지 않았거나 캐시가 아직 삭제되지 않았을 가능성이 있습니다.

다음 콘솔 명령을 실행하여 이 문제를 테스트하고 해결할 수 있습니다.

으아악


4. Zip 파일의 비ACSII 문자

이 오류는 zip에 있는 일부 파일의 파일 이름에 ASCII가 아닌 문자(예: "é")가 포함된 경우 zip->close()를 호출할 때도 발생합니다.

가능한 해결책은 대상 파일을 생성하기 전에 파일 이름을 utf8_decode()로 묶는 것입니다.

이 문제를 식별하고 해결책을 제안한 Fran Cano에게 감사드립니다

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿