http://www.thinkphp.cn/topic/10421.html
PHP의 컴파일과 실행은 분리되어 있습니다. 즉, 컴파일이 먼저 완료됩니다 , 그런 다음 실행합니다. 많은 사람들이 이렇게 말할 것입니다. 실제로 C++에서도 마찬가지입니다. 그러나 이러한 PHP 분리는 우리에게 많은 편리함을 제공할 수 있지만 물론 많은 단점도 있습니다.
먼저 전체 프로세스에 대해 이야기해 보겠습니다. ①php는 컴파일 함수 zend_compile_file()을 호출하여 컴파일합니다. 이 기능의 구체적인 구현에는 실제로 어휘 분석(Lex 구현)과 구문 분석(Yacc 구현)이라는 두 가지 주요 프로세스가 포함됩니다. 이 함수를 실행하면 PHP 스크립트 컴파일이 완료됩니다. 이 함수의 입력은 php 스크립트 파일이고 출력은 op_array입니다. 간단히 말하면 Sun City의 컴파일 프로세스는 스크립트를 php 가상 머신에서 처리할 수 있는 명령으로 구문 분석하는 것입니다.
op_array는 이러한 명령어로 구성된 배열일 뿐입니다(이는 하나씩 명령이기도 한 일부 컴파일된 언어에서 생성된 어셈블리 코드와 매우 유사합니다). ②: 그런 다음 PHP 가상 머신은 zend_execute() 함수를 호출하여 실행합니다. 이 함수의 입력은 위의 컴파일 단계에서 생성된 op_array이며, 여기서 각 명령을 구문 분석하고 처리합니다. 총 약 150개의 op 명령이 있으므로 이 150개의 명령을 처리해야 합니다. 여기서 매우 흥미로운 질문이 제기됩니다. 이 150개의 명령을 어떻게 처리합니까? 우선, 각 명령에는 해당하는 명령이 있습니다.
처리용 프로세서. 따라서 가상 머신은 op_array의 각 명령 유형에 따라 처리를 위해 해당 프로세서에 배포됩니다. 여기에 두 가지 작은 질문이 있습니다. 1: 여기서 프로세서는 무엇입니까? 2: 어떻게 배포되나요? 이 두 가지 질문에 대답하려면 배포 메커니즘에서 설명해야 합니다. PHP 가상 머신에서 명령을 배포하는 메커니즘에는 CALL, SWITCH 및 GOTO의 세 가지 메커니즘이 있습니다. PHP는 기본적으로 모두 opcode 프로세서인 CALL 메서드를 사용합니다. 함수로 정의되며,
그런 다음 가상 머신에 의해 시스템이 호출됩니다. 이 방법은 전통적인 방법이며 일반적으로 가장 안정적인 방법으로 간주됩니다. SWITCH 방법과 GOTO 방법은 실행을 위해 해당 처리 논리(세그먼트)에 opcode를 배포하는 데 사용됩니다. . 이제 위의 두 질문에 답해 보겠습니다. 1: 프로세서는 실제로 op 명령의 논리를 처리합니다. 명령이 어떻게 배포되는지에 따라 함수 또는 논리 세그먼트의 형태로 존재할 수 있습니다. 2: 배포 방법에는 call, switch, goto 세 가지가 있습니다. 어느 것이 더 효율적인가요? 사실 위의 설명을 통해 이미 대략적인 이해가 가능합니다. switch와 goto 모두 zend_execute() 함수에 직접 실행될 수 있는 해당 논리 세그먼트를 가지고 있습니다. 호출은 zend_execute() 함수에서 함수 호출을 실행하는 것입니다. 분명한
참고: 함수 호출 효율이 가장 낮습니다. 한 번 호출하면 스택에 푸시해야 합니다! 따라서 효율성 측면에서 통화가 가장 낮습니다. switch 및 goto의 경우: 예를 들어 세 번째 명령을 실행하려는 경우: switch는 먼저 그것이 처음 두 개인지 판단해야 하지만 goto는 전혀 판단할 필요가 없으며 세 번째 명령의 논리 코드 세그먼트로 직접 점프합니다. 실행을 위해서는 Switch보다 낫습니다. 따라서 위에서 아래로의 순차적 판단 손실이 줄어듭니다. 따라서 Goto 효율성은 Switch보다 높습니다. 따라서 이 세 가지 배포 방법은 일반적으로 주제에서 벗어납니다. PHP는 기본적으로 호출을 수행하므로 PHP의 성능을 더욱 짜내려면 명령 배포 방법을 goto로 변경할 수 있습니다. 그러나 goto 메소드를 사용하면 실행 속도가 향상되지만 실제로 컴파일 속도는 가장 느립니다. PHP의 컴파일과 실행 분리의 약점에 대해 이야기해보겠습니다. 사실 이는 약점이라고 볼 수는 없습니다.
엔진(php의 가상 머신)은 컴파일과 실행을 엄격하게 분리하지만 Suncity 사용자의 경우 PHP 스크립트 요청을 실행할 때마다 컴파일 -> 이 두 단계를 실행해야 하기 때문에 마치 분리되지 않은 것처럼 보입니다. 빠진 무대가 없습니다.따라서 이를 C++ 같은 컴파일 언어와 비교할 수 있습니다. 동일한 요청을 100번 실행 ①C++의 경우 초기 단계에서 한 번만 컴파일하면 되므로 이후에는 다시 컴파일되지 않습니다. 반복 컴파일 후에는 실행만 하면 되므로 손실은 다음과 같습니다. 1 컴파일 + 100 실행 ②PHP의 경우 컴파일해야 합니다. 매번 + 실행이므로 손실은 다음과 같습니다. 100개의 컴파일 + 100개의 실행 분명히: 양적 관점에서 보면 해석된 언어는 컴파일된 언어보다 훨씬 더 많은 것을 소비합니다. 직설적으로 말하면, PHP 컴파일과 실행의 분리는 실제 분리가 아닙니다. C++ 종류는 실제 분리입니다. PHP는 오랫동안 이 문제를 알고 있었기 때문에 이 문제를 해결할 수 있는 방법을 생각해냈습니다. 바로 eAccelerator입니다. 주요 아이디어는 다음과 같습니다: 스크립트가 처음 실행되면 컴파일된 스크립트가 특정 방식으로 저장됩니다. 우리가 지정한 캐시 유효 시간 내에 스크립트가 두 번째 실행되면 더 이상 그렇지 않습니다. 반복적인 컴파일 작업을 수행하지만, 이전에 저장된 컴파일 파일을 직접 호출하여 실행하면 프로그램 성능이 크게 향상됩니다. 이 방법은 PHP의 효율성을 어느 정도 향상시키지만, 궁극적인 방법은 컴파일된 언어로 변경하는 것입니다. 마지막으로 PHP 컴파일의 분리에 대해 이야기해 보겠습니다. 장점; 이 장점은 실제로 사용자를 위한 것이 아니라 프로그래머를 위한 것입니다. 이 두 단계가 분리되어 있기 때문에 http://tyangcdh.com에서 하고 싶은 몇 가지 작업을 여기서 수행할 수 있습니다. 예를 들어 파일을 암호화하고 복호화하려는 경우 사용자가 소스 코드를 볼 수 없도록 일부 PHP 스크립트 소스 코드 파일을 암호화하려고 합니다. 동시에, 이 암호화된 소스 코드 파일은 PHP 가상 머신에 의해 구문 분석되고 처리될 수 있습니다. 물론, 이를 달성하려면 먼저 암호화 및 암호 해독 알고리즘에 대해 생각하고 이것이 가역적인 프로세스인지 확인해야 합니다. 이제 PHP 소스 코드 파일을 암호화했으므로 암호화된 파일의 접미사 6을 정의해야 합니다.
그래서 질문은: 어떻게 PHP 가상 머신이 이 접미사가 붙은 파일을 처리할 수 있도록 할 수 있을까요? 이를 위해서는 위에서 언급한 컴파일과 실행의 분리가 필요합니다. 기억하세요: 컴파일 단계의 입력은 PHP 소스 파일이고 출력은 op_array입니다. 좋아, 이 단계에서는 소란을 피우자. 주요 아이디어는 다음과 같습니다. 먼저 컴파일 함수 zend_compile_file()에서 입력 파일의 접미사를 확인합니다. 일반 .php이면 일반 논리를 따르고, *.buaa이면 먼저 암호를 해독한 다음 따릅니다. 정상적인 논리. 하~ 참 간단해요. 물론 이 프로세스는 말한 것처럼 간단하지 않으며 zend_compile_file() 함수를 직접 수정할 수 없습니다. 결국 이 프로세스를 처리하려면 모듈을 직접 확장하고 구현해야 합니다.
위에서는 PHP의 측면을 포함하여 몇 가지 원칙을 소개했습니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.