[Php] require_once를 사용하는 것이 왜 그렇게 나쁜가요?


Answers

이 스레드는 이미 "솔루션 게시"가 있었기 때문에 나를 싫어하게 만듭니다. 모든 의도와 목적으로 잘못되었습니다. 열거하자 :

  1. 정의는 PHP에서 정말 비쌉니다. 이를 직접 보거나 직접 테스트 할 수 있지만 PHP에서 전역 상수를 정의하는 유일한 효율적인 방법은 확장을 사용하는 것입니다. (클래스 상수는 실제로 현명한 꽤 현명한 성능이지만, 이것은 논점입니다. 왜냐하면 2)

  2. require_once() 적절하게 사용하고 있다면, 즉 클래스를 포함하기 위해 정의가 필요하지 않습니다. class_exists('Classname') 만 확인하십시오. 포함하는 파일에 코드가 포함되어있는 경우 (즉, 절차 적 방식으로 사용하는 경우 require_once() 가 반드시 필요한 이유는 없습니다. 파일을 포함시킬 때마다 서브 루틴 호출을한다고 가정합니다.

그래서 잠시 동안 많은 사람들이 그들의 포함을 위해 class_exists() 메소드를 사용했습니다. 그것은 추한 것 때문에 맘에 들지 않지만 좋은 이유가 있습니다 : require_once() 는 최신 버전의 PHP보다 먼저 비효율적이었습니다. 그러나 그것은 고쳐졌고, 조건부로 컴파일해야하는 여분의 바이트 코드와 추가 메서드 호출이 내부 해시 테이블 검사를 훨씬 능가 할 것이라는 것이 나의 주장이다.

이제, 입장료 : 테스트 시간이 거의 필요치 않기 때문에 테스트하기가 어렵습니다.

인터프리터가 구문 분석 모드로 전환 할 때마다 opcode를 생성 한 다음 다시 돌아와야하기 때문에 일반적으로 PHP에서는 비용이 많이 든다. 100 개 이상의 포함을 사용하면 실적에 큰 영향을 미칩니다. require_once를 사용하거나 사용하지 않는 것이 중요한 질문 인 이유는 opcode 캐시가 어려워지기 때문입니다. 이것에 대한 설명은 여기에서 찾을 수 있습니다.하지만이 점은 다음과 같습니다.

  • 구문 분석하는 동안 요청의 전체 수명 동안 필요한 포함 파일을 정확히 알고 있다면 처음부터 require() 하고 opcode 캐시가 다른 모든 것을 처리합니다.

  • opcode 캐시를 실행하지 않는다면 어려운 위치에 있습니다. 모든 인클루드를 하나의 파일로 인라인 (개발 중에는 프로덕션에서만 수행하지 않음)하면 시간을 구문 분석하는 데 확실히 도움이 될 수 있지만 수행하는 데에는 어려움이 있습니다. 또한 파일에 포함 할 내용을 정확히 알아야합니다. 의뢰.

  • 자동로드는 매우 편리하지만 속도가 느립니다. 왜냐하면 자동로드 논리가 포함이 완료 될 때마다 실행되어야하기 때문입니다. 실제로, 하나의 요청에 대해 여러 개의 특수 파일을 자동로드하면 문제가 너무 많이 발생하지 않지만 필요한 모든 파일을 자동로드하지 않아야합니다.

  • 어쩌면 10 개가 포함 된 경우 (이것은 엔벨로프 계산의 뒤에 있습니다),이 모든 것이 가치가 없습니다. 데이터베이스 쿼리 나 다른 것을 최적화하십시오.

Question

더 나은 PHP 코딩 방법에 대해 읽은 모든 것은 속도 때문에 require_once 사용하지 말라는 것을 계속 말합니다.

왜 이런거야?

require_once 와 똑같은 일을하는 적절한 / 더 좋은 방법은 무엇입니까? 중요한 경우 PHP5를 사용하고 있습니다.




*_once() 함수는 모든 상위 디렉토리를 포함하여 포함하고있는 파일이 이미 포함되어 있는지 확인합니다. 그것은 경기 침체의 원인의 일부입니다.

Siege 와 같은 도구를 벤치마킹에 사용하는 것이 좋습니다. 제안 된 모든 방법을 시도하고 응답 시간을 비교할 수 있습니다.

Tech Your Universe의 require_once() 에 대한 추가 정보.




PEAR 문서에는 require, require_once, include 및 include_once에 대한 권장 사항이 있다고 생각합니다. 나는 그 지침을 따른다. 귀하의 신청서가 더 분명합니다.




코딩을 피하기 위해 이러한 코딩 관행에 대한 링크를 제공 할 수 있습니까? 내가 아는 한, 그것은 완전한 논쟁 거리가 아닙니다 . 필자는 소스 코드를 직접 보지 않았지만 includeinclude_once 의 유일한 차이점은 include_once 가 파일 이름을 배열에 추가하고 매번 배열을 검사한다는 것입니다. 그 배열을 정렬 된 상태로 유지하는 것은 쉬울 것입니다. 따라서 검색은 O (log n)이어야하며 중형 어플리케이션은 두 개 정도만 포함됩니다.




네, 보통 ol 'require ()보다 약간 비쌉니다. 요점은 당신이 중복을 포함하지 않을 정도로 코드를 체계적으로 관리 할 수 ​​있다면 * _once () 함수를 사용하지 말라는 것입니다.

하지만 _once () 함수를 사용하면 앱을 종료하지 않습니다. 기본적으로, 귀하의 포함을 구성 할 필요가 없다는 핑계로 사용하지 마십시오 . 어떤 경우에는 그것을 사용하는 것을 여전히 피할 수 없으며 큰 문제가 아닙니다.




필자가 개인적으로 require_once (또는 include_once)를 사용하는 것은 require_once가 이미 해당 파일을 포함하고 있으며 포함 된 두 파일의 오류를 억제하면 (예 : 함수 / 클래스 / 등의 중복 선언과 같은) 치명적인 오류를 발생시키지 않으므로 사용자를 확인하기 때문에 바람직하지 않습니다. .

파일을 포함해야하는지 알고 있어야합니다.




그것은 나쁜 기능을 사용하지 않습니다. 전반적인 코드 기반에서 언제 어떻게 사용하는지에 대한 잘못된 이해입니다. 아마도 오해의 개념에 조금 더 많은 내용을 추가 할 것입니다.

사람들은 require_once가 느린 함수라고 생각해서는 안됩니다. 코드를 편입해야합니다. require_once()require() 의 속도는 문제가 아닙니다. 그것은 맹목적으로 그것을 사용하여 발생할 수있는 경고를 방해 성능에 대한이야. 컨텍스트에 대한 고려없이 광범위하게 사용되는 경우 엄청난 메모리 낭비 또는 낭비되는 코드가 발생할 수 있습니다.

내가보기에는 정말 거대한 모 놀리 식 프레임 워크가 모든 잘못된 방법으로 require_once() 를 사용할 때, 특히 복잡한 객체 지향 환경에서 특히 그렇습니다.

많은 라이브러리에서 볼 수있는 모든 클래스의 맨 위에서 require_once() 를 사용하는 예제를 살펴 보겠습니다.

require_once("includes/usergroups.php");
require_once("includes/permissions.php");
require_once("includes/revisions.php");
class User{
  //user functions
}

따라서 User 클래스는 다른 세 클래스를 모두 사용하도록 설계되었습니다. 공정! 하지만 방문자가 사이트를 탐색하고 로그인하지 않고 프레임 워크가로드되는 경우 require_once("includes/user.php"); 매 요청마다.

그것은 특별한 요청 중에 사용하지 않을 1 + 3 개의 불필요한 클래스를 포함합니다. 이것은 비 대한 프레임 워크가 5MB 이하가 아닌 요청 당 40MB를 사용하는 방식입니다.

오용 될 수있는 다른 방법은 클래스가 다른 많은 사람들에 의해 재사용 될 때입니다! helper 함수를 사용하는 약 50 개의 클래스가 있다고 가정 해보십시오. helpers 가로드 될 때 해당 클래스에서 helpers 를 사용할 수 있도록하려면 다음을 수행하십시오.

require_once("includes/helpers.php");
class MyClass{
  //Helper::functions();//etc..
}

여기에 그 자체로 잘못된 것은 없습니다. 그러나 한 페이지 요청이 비슷한 종류의 15 개 클래스를 포함하면 발생합니다. require_once 15 번 실행하거나 멋진 시각적 효과를 require_once 다음을 수행하십시오.

require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");

require_once ()를 사용하면 이러한 불필요한 행을 구문 분석하는 것 외에 기술적으로 14 번 해당 함수를 실행하는 성능에 영향을 미칩니다. 그 비슷한 문제를 가진 10 개의 다른 클래스들과 함께, 그것보다는 무의미한 반복적 인 코드의 100+ 라인을 설명 할 수 있습니다.

그것으로 아마도 require("includes/helpers.php"); 사용할 가치가 있습니다 require("includes/helpers.php"); 대신 앱이나 프레임 워크의 부트 스트랩에서. 그러나 모든 것이 상대적이므로, helpers 클래스의 가중치 대 사용 빈도가 require_once() 의 15-100 줄을 저장하는 데 가치가 있는지 여부는 모두 다릅니다 . 그러나 주어진 요청에서 helpers 파일을 사용하지 않을 확률이 아무 것도 없다면 require 는 반드시 메인 클래스에 있어야합니다. 각 클래스에 require_once 를 별도로 require_once 자원 낭비가됩니다.

require_once 함수는 필요할 때 유용하지만 모든 클래스를로드하기 위해 어디에서나 사용할 수있는 모 놀리 식 솔루션으로 간주해서는 안됩니다.