복붙노트

PHP - 스트림을 열지 못했습니다 : 해당 파일이나 디렉토리가 없습니다

PHP

PHP - 스트림을 열지 못했습니다 : 해당 파일이나 디렉토리가 없습니다

PHP 스크립트에서 include_once, require_once 또는 심지어 move_uploaded_file ()과 같은 include (), require (), fopen () 또는 파생물 호출 여부에 관계없이 오류 또는 경고가 발생하는 경우가 많습니다.

문제의 근본 원인을 빨리 찾을 수있는 좋은 프로세스는 무엇입니까?

해결법

  1. ==============================

    1.

    이 오류가 발생할 수있는 많은 이유가 있으므로 먼저 확인해야 할 사항에 대한 좋은 체크리스트가 상당히 도움이됩니다.

    우리는 다음 줄의 문제를 해결하고 있다고 가정 해 봅시다.

    require "/path/to/file"
    

    모범 사례 :

    런타임시 절대 경로를 생성하는 동안 스크립트를 강력하게 만들려면 다음과 같은 두 가지 옵션이 있습니다.

    이 두 가지 방법은 포함 경로와 같은 ini 설정에 의존하지 않으므로 응용 프로그램을 더 이식성있게 만듭니다.

    상대적으로 또는 순전히 절대적으로 파일을 포함하는 또 다른 방법은 포함 경로에 의존하는 것입니다. Zend 프레임 워크와 같은 라이브러리 나 프레임 워크의 경우가 종종 있습니다.

    이러한 포함은 다음과 같습니다.

    include "Zend/Mail/Protocol/Imap.php"
    

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

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

    echo get_include_path();
    

    다음과 함께 폴더를 추가 할 수 있습니다.

    set_include_path(get_include_path().":"."/path/to/new/folder");
    

    아마도 서버 프로세스 (Apache 또는 PHP)를 실행하는 사용자는 해당 파일을 읽거나 쓸 수있는 권한이 없습니다.

    서버가 실행중인 사용자를 확인하려면 posix_getpwuid를 사용할 수 있습니다.

    $user = posix_getpwuid(posix_geteuid());
    
    var_dump($user);
    

    파일에 대한 사용 권한을 확인하려면 터미널에서 다음 명령을 입력하십시오.

    ls -l <path/to/file>
    

    허락 기호 상징 표기법보기

    위의 작업 중 어느 것도 작동하지 않는다면 PHP 설정에 따라 해당 파일에 액세스 할 수 없게되는 것일 수 있습니다.

    세 가지 설정이 적절할 수 있습니다.

    위의 원인 중 어느 것도 문제를 진단 할 수없는 경우 발생할 수있는 몇 가지 특별한 상황이 있습니다.

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

    require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
    

    하지만 여전히 같은 종류의 오류가 발생합니다.

    이것은 (성공적으로 포함 된) 파일 자체가 다른 파일에 대한 include 문을 가지고 있고 두 번째 include 문이 해당 라이브러리의 경로를 포함 경로에 추가했다고 가정하기 때문에 발생할 수 있습니다.

    예를 들어 앞서 언급 한 Zend 프레임 워크 파일에는 다음과 같은 내용이 포함될 수 있습니다.

    include "Zend/Mail/Protocol/Exception.php" 
    

    이것은 상대 경로에 의한 포함도 아니며 절대 경로에 의한 것도 아닙니다. Zend 프레임 워크 디렉토리가 포함 경로에 추가되었다고 가정합니다.

    이 경우 유일한 실용적인 솔루션은 포함 경로에 디렉토리를 추가하는 것입니다.

    Security-Enhanced Linux를 실행중인 경우 서버에서 파일에 대한 액세스를 거부하여 문제의 원인 일 수 있습니다.

    시스템에서 SELinux가 활성화되어 있는지 확인하려면 터미널에서 sestatus 명령을 실행하십시오. 명령이 존재하지 않으면 SELinux가 시스템에 없습니다. 그것이 존재한다면, 그것이 시행되는지 아닌지를 말해야합니다.

    SELinux 정책이 문제의 원인인지 확인하려면 일시적으로 전원을 끄십시오. 그러나 이것이 보호를 완전히 불가능하게 할 것이기 때문에 조심하십시오. 프로덕션 서버에서는이 작업을 수행하지 마십시오.

    setenforce 0
    

    SELinux가 꺼져있는 상태에서 더 이상 문제가 없으면 이것이 근본 원인입니다.

    이를 해결하려면 SELinux를 적절하게 구성해야합니다.

    다음 컨텍스트 유형이 필요합니다.

    예를 들어 웹 사이트 루트 디렉토리에 httpd_sys_content_t 컨텍스트 유형을 할당하려면 다음을 실행합니다.

    semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
    restorecon -Rv /path/to/root
    

    파일이 홈 디렉토리에있는 경우 httpd_enable_homedirs 부울을 활성화해야합니다.

    setsebool -P httpd_enable_homedirs 1
    

    어떤 경우 든 SELinux가 정책에 따라 파일에 대한 액세스를 거부하는 데는 여러 가지 이유가있을 수 있습니다. 그래서 그것에 대해 문의해야합니다. 다음은 SELinux를 웹 서버로 구성하는 방법에 대한 자습서입니다.

    Symfony를 사용 중이고 서버에 업로드 할 때이 오류가 발생하면 app / cache가 업로드되었거나 캐시가 지워지지 않아서 앱의 캐시가 재설정되지 않았을 수 있습니다.

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

    cache:clear
    

    분명히이 오류는 zip-> close ()를 호출 할 때 zip 내의 일부 파일이 "é"와 같이 파일 이름에 ASCII가 아닌 문자가있을 때도 발생할 수 있습니다.

    잠재적 인 해결책은 대상 파일을 만들기 전에 utf8_decode ()에 파일 이름을 래핑하는 것입니다.

    이 문제에 대한 해결책을 밝히고 제안한 Fran Cano의 공로

  2. ==============================

    2.

    (정말로 좋은) 기존 답변에 추가하려면

    open_basedir은 웹 서버 설정에서 지정 될 수 있기 때문에 당신을 그루핑 할 수 있습니다. 자신의 전용 서버를 운영하는 경우 쉽게 해결할 수 있지만 Plesk, cPanel 등의 공유 호스팅 소프트웨어 패키지가 있으므로 도메인별로 구성 지시문을 구성 할 수 있습니다. 소프트웨어가 구성 파일 (예 : httpd.conf)을 작성하기 때문에 호스팅 소프트웨어가 다시 시작할 때 파일을 덮어 쓰게되므로 파일을 직접 변경할 수 없습니다.

    Plesk를 사용하면 vhost.conf라는 httpd.conf 파일을 무시할 수 있습니다. 서버 관리자 만이 파일을 쓸 수 있습니다. Apache 구성은 다음과 같습니다.

    <Directory /var/www/vhosts/domain.com>
        <IfModule mod_php5.c>
            php_admin_flag engine on
            php_admin_flag safe_mode off
            php_admin_value open_basedir "/var/www/vhosts/domain.com:/tmp:/usr/share/pear:/local/PEAR"
        </IfModule>
    </Directory>
    

    서버 관리자가 사용하는 호스팅 및 웹 서버 소프트웨어에 대한 설명서를 참조하십시오.

    웹 서버를 통해 파일을 실행하는 것은 명령 행 또는 cron 작업 실행과 매우 다르다는 점에 유의해야합니다. 가장 큰 차이점은 웹 서버에 자체 사용자 및 권한이 있다는 점입니다. 보안상의 이유로 사용자는 매우 제한적입니다. 예를 들어, Apache는 종종 아파치, www-data 또는 httpd (서버에 따라 다름)입니다. cron 작업 또는 CLI 실행에는 사용자가 실행하는 권한이 있습니다. 즉, 루트 권한으로 PHP 스크립트를 실행하면 루트 권한으로 실행됩니다.

    많은 사람들이 다음을 수행하여 권한 문제를 해결할 것입니다 (Linux 예제)

    chmod 777 /path/to/file
    

    이것은 파일이나 디렉토리가 이제 세계에 쓰기가 가능하기 때문에 현명한 아이디어는 아닙니다. 서버를 소유하고있는 유일한 사용자라면 큰 문제는 아니지만 공유 호스팅 환경에서 서버 액세스 권한을 가진 모든 사람에게 방금 액세스 권한을 부여했습니다.

    필요한 것은 액세스가 필요한 사용자를 결정하고 액세스 권한을 부여하는 것입니다. 어떤 사용자에게 액세스해야하는지 알고 나면

    Linux / Unix 권한과 사용자에 대한 더 자세한 토론을 여기서 읽을 수 있습니다.

  3. ==============================

    3.

    그게 내 사건 이었어. 실제로는 질문 # 4485874에 연결되지만 잠시 후에 여기에서 설명하겠습니다. path / to / script.php? parameter = value를 요구하려고 할 때, PHP는 script.php? parameter = value라는 파일을 찾는다. 왜냐하면 UNIX는 당신에게 이와 같은 경로를 허용하기 때문이다. 포함 된 스크립트에 일부 데이터를 전달해야하는 경우 $ variable = ... 또는 $ GLOBALS [] = ... 또는 다른 방식으로 선언하십시오.

  4. ==============================

    4.

    또 다른 가능한 원인 : 텍스트 편집기에서 파일의 이름 바꾸기 및 / 또는 이동. 나는이 오류를 던지면서 새 파일을 만든 파일을 지우고 문제를 해결할 때까지 위의 모든 단계를 성공했다.

  5. from https://stackoverflow.com/questions/36577020/php-failed-to-open-stream-no-such-file-or-directory by cc-by-sa and MIT lisence