>백엔드 개발 >PHP 튜토리얼 >include_once(require_once)는 최대한 사용하지 않는 것이 좋습니다.

include_once(require_once)는 최대한 사용하지 않는 것이 좋습니다.

黄舟
黄舟원래의
2017-06-25 11:54:592119검색

이 글은 include/require)_once를 사용하지 않는 이유에 대한 자세한 분석 및 소개입니다. 필요한 친구는

include 또는 include_once 사용 여부를 참고할 수 있습니다(아래에는 모두 require_once 포함). ) , 이 토론은 매우 길었으며, 과거에 가장 일반적인 이유는 include_once가 로드된 파일 목록을 쿼리하여 존재 여부를 확인한 다음 include_once를 사용하려고 한다는 것이었습니다. 다시 로드하세요.

맞습니다. 이 이유는 맞지만 오늘 제가 이야기하고 싶은 것은 또 다른 이유입니다.

우리는 파일이 로드되었는지 확인하려면 PHP가 파일의 open_path를 가져와야 한다는 것을 알고 있습니다.

코드 복사 코드는 다음과 같습니다.

<?php
set_include_path
("/tmp/:/tmp2/");
include_once("2.php");
?>


PHP가 include_once "2.php"를 보면 이 파일의 실제 경로가 무엇인지 알 수 없으며, 로드된 파일 목록에서 이동할 수 없습니다. 로드되었는지 확인하므로 include_once 구현에서 먼저 파일의 실제 경로를 구문 분석하려고 시도합니다(일반 파일의 경우 이 구문 분석은 getcwd 및 파일 경로를 확인하는 것과 같습니다. 따라서 상대 경로인 경우 일반적으로 성공하지 못합니다.) 구문 분석에 성공하면 EG(include_files)를 검색합니다. 존재하는 경우 포함되었음을 의미하고 그렇지 않으면 파일을 열어서 가져옵니다. 예를 들어 위의 예에서 이 파일은 "/tmp2/2.php"에 존재합니다.

그런 다음 Open_path를 얻은 후 PHP는 로드된 파일 목록으로 이동하여 포함되어 있는지 확인합니다. 포함되지 않은 경우 직접 컴파일하면 더 이상 파일을 열 필요가 없습니다.

1. 파일 경로의 절대값을 구문 분석해 보고 성공적으로 구문 분석할 수 있으면 EG(included_files)를 확인하세요. 존재하면 반환, 존재하지 않으면 계속 진행
2. 파일을 열고 파일의 열린 경로(열린 경로)를 가져옵니다
3. 열린 경로를 가져와서 EG(included_files)에서 검색하고 존재하면 반환합니다. 존재하지 않으면 계속 진행
4. 파일 컴파일(compile_file)

대부분의 경우 문제가 되지 않지만 APC를 사용할 때 문제가 발생합니다...

APC를 사용할 때 APC가 compile_file을 하이재킹합니다. 컴파일된 파일에 대한 포인터를 사용하여 캐시에서 직접 컴파일 결과를 가져오므로 실제 파일을 열지 않고 시스템 호출을 통해 파일을 열 필요가 없습니다.

그러나 코드에서 include_once를 사용하면 compile_file 전에 PHP가 이미 열려고 시도했습니다. 이 문제를 해결하기 위해 APC는 include_once_override를 도입했습니다. 활성화되면 APC는 PHP의 ZEND_INCLUDE_OR_EVAL opcode 핸들러를 하이재킹하여 절대 경로를 결정합니다. stat를 통해 파일을 읽어보고 로드되지 않은 것으로 확인되면 포함할 opcode를 다시 작성하여 까다로운 솔루션을 만듭니다.

그런데 아쉽게도 APC의 include_once_override가 적용되지 않았다는 것입니다. 잘 구현되면 다음과 같은 정의되지 않은 문제가 있을 것입니다.

코드를 복사하세요코드는 다음과 같습니다.

<?php
set_include_path("/tmp");
function a($arg = array()) {
    include_once("b.php");
}
a();
a();
?>


그런 다음 b.php는 "/tmp/b.php"에 배치됩니다. 내용은 다음과 같습니다.

코드는 다음과 같습니다.

<?php
  class B {}
?>


그런 다음 apc.include_once_override가 켜져 있으면 연속 액세스에 다음 오류가 발생합니다.

치명적인 오류 - include(): 클래스 b를 다시 선언할 수 없습니다

이러한 기술적인 요소를 제외하면, 우리는 스스로 완벽하게 계획을 세울 수 있고 파일은 한 번만 로드할 수 있기 때문에 include_once 대신 include를 사용해야 한다고 항상 믿어왔습니다. include_once를 사용하면 코드에 대한 자신감이 없다는 것을 증명할 뿐입니다.그러므로 더 이상 include_once를 사용하지 않는 것이 좋습니다

위 내용은 include_once(require_once)는 최대한 사용하지 않는 것이 좋습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.