>백엔드 개발 >PHP 튜토리얼 >내가 항상 include 대신 include_once를 사용하는 실수

내가 항상 include 대신 include_once를 사용하는 실수

黄舟
黄舟원래의
2017-06-25 11:47:322285검색

include_once를 includeinclude_once의 차이점을 알게 된 이후부터 반복 로딩을 피하기 위해 한 번만 로딩하는 줄 알고 계속해서 로딩이 되었는지 확인할 수 없는 것 같습니다. . 내가 항상 틀렸다는 것이 밝혀졌습니다.

실제로 여러 사람이 프로젝트를 개발하는 경우에는 include_once가 더 좋습니다.

include_once 실행 순서

파일의 절대 경로를 구문 분석해 보세요. , EG(included_files)를 확인하고, 존재하면 반환하고, 존재하지 않으면 계속합니다. 파일을 열고, 파일의 열린 경로(열린 경로)를 가져오고, 열린 경로를 EG(included_files)로 가져와서 여부를 확인합니다. 존재하면 반환하고, 존재하지 않으면 계속합니다. 파일 컴파일(compile_file

최근에 apc.include_once_override에 대해 여러 번 논의했지만 이 APC 구성 항목은 제대로 구현된 적이 없습니다.

여기서 저는 이 문제의 원인과 우리를 위한 몇 가지 영감을 공유하고 싶습니다.

include 또는 include_once(이하 모두 include require_once)를 사용할지 여부에 관해 이 논의는 매우 길어졌으며 결론은 항상 이러했습니다. 즉, include_once 대신 include를 사용해 보세요. 과거에 가장 일반적인 이유는 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)를 검색하고, 존재하는 경우 해당 파일이 포함되었음을 의미하고, 그렇지 않으면 파일을 열어 파일의 Open_path를 가져옵니다. 예를 들어 위의 예에서 이 파일은 다음 위치에 있습니다. "/tmp2/2.php".

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

1. 파일의 절대 경로를 구문 분석해 봅니다. 구문 분석에 성공하면 EG(included_files)를 확인하고, 존재하면 (included_files) 검색을 반환하고, 존재하지 않으면 반환합니다. 계속해서 4. 파일 컴파일하기(compile_file

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

사용 중 APC는 APC 중에 compile_file의 포인터를 하이재킹하여 컴파일 결과를 직접 가져옵니다. 캐시에서, 실제 파일 열기를 피하고 열기 위한 시스템 호출을 피합니다.

그러나 코드에서 include_once를 사용하면 compile_file 이전에 PHP가 이미 파일 열기를 시도한 다음 APC가 하이재킹한 컴파일 파일을 입력했습니다. 이런 방식으로 추가 열기 작업이 발생합니다. APC는 include_once_override를 도입했습니다. include_once_override가 켜져 있으면 APC는 PHP의 ZEND_INCLUDE_OR_EVAL opcode 핸들러를 하이재킹하고 stat를 통해 파일의 절대 경로를 확인한 다음, 로드되지 않은 것으로 나타났습니다.

하지만 불행히도 제가 말했듯이 APC의 include_once_override는 제대로 구현되지 않았으며 다음과 같은 정의되지 않은 문제가 있을 것입니다.

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

그러면 b.php

<?phpclass B {}?>

다음과 같은 내용으로 "/tmp/b.php"에 배치됩니다.

Fatal error - include() : Cannot redeclare class

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

rrreee

(Postscript 2012-09-15 02: 07: 20: 이 APC 버그를 수정했습니다. #63070) 이러한 기술적인 요소를 제외하고 저는 항상 include_once 대신 include_once를 사용해야 한다고 믿어왔습니다. 왜냐하면 우리는 스스로 완전히 계획을 세울 수 있고 파일은 한 번만 로드될 수도 있기 때문입니다. 이 시점에서.

include_once를 사용하는 것은 코드에 대한 자신감이 없다는 것을 증명할 뿐입니다.

그러므로 더 이상 include_once를 사용하지 않는 것이 좋습니다

위 내용은 내가 항상 include 대신 include_once를 사용하는 실수의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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