PHP-src/PHP-Internals 메인 엔트리 포인트는 어디에 있나요?



(1)

PHP의 소스 에서 PHP 프로그램을 실행 / 해석하기위한 주요 진입 점으로 사용되는 코드의 기능 또는 비트는 무엇입니까? 끈적 거리거나 책을 읽은 것을 토대로 PHP는 일종의 서버와 작동하도록 설계되었습니다 (CLI 명령조차도 "명령 줄 SAPI"를 시작하여 작동합니다).이 서버는 설계된 미니 서버의 역할을합니다 단일 요청을 처리하기 위해), 그리고 서버가 PHP에 프로그램을 실행하도록 요청할 것입니다.

PHP 확장의 진입 점 역할을하는 minitrinit lifecycle 함수에 대해 알고 있습니다 .

내가 알지 못하는 것은 PHP 소스 코드가 어디서이 대화를하는지입니다.

이봐 요,이 파일 / 문자열에는 PHP 프로그램이 있습니다. 나는 그것을 실행해야한다.

나는 여기서 어떤 구체적인 임무도 성취하려고 노력하지 않고있다. PHP의 내부 구조가 어떻게 작동 하는지를 이해하려고 노력하고 있으며, 실행을 시작할 수있는 주요 진입 점을 찾으려고합니다.


일부 SAPI 코드의 시작점은 어디입니까?

CLI 는 독립 실행 형 응용 프로그램입니다. C로 작성된 다른 응용 프로그램과 마찬가지로 해당 항목은 main() 함수 (파일 sapi/cli/php_cli.c , 줄 1200 )입니다.

int main(int argc, char *argv[])

Windows 용 CLI에는 두 가지 버전이 있습니다. 그 중 하나는 콘솔 응용 프로그램이고 위에서 설명한 main() 함수로 시작하고 다른 하나는 Windows GUI 응용 프로그램입니다 (시작시 콘솔을 만들지 않고 메시지 상자를 사용합니다 WinMain() 함수 (파일 sapi/cli/php_cli.c , 줄 1198 )로 시작하는 sapi/cli/php_cli.c ).
main()WinMain() 은 같은 코드를 사용합니다. 그들은 PHP_CLI_WIN32_NO_CONSOLE 심볼이 정의되어 있는지를 체크함으로써 서로 다른 이름과 다른 코드 조각을 가지고 있습니다. 이 파일은 Windows GUI 응용 프로그램을 생성하는 데 사용되는 sapi/cli/cli_win32.c 파일에 정의되어 있습니다.
</Windows>

CGI 버전은 독립 실행 형 콘솔 응용 프로그램이기도합니다. 엔트리 포인트는 sapi/cgi/cgi_main.c 파일 1792main() 함수이기도합니다.

마찬가지로 FPM 버전은 sapi/fpm/fpm/fpm_main.c 파일의 main() 으로 시작됩니다 main() 1570 행).

Apache2 처리기 는 동적으로로드 할 수있는 모듈입니다 (Windows에서는 .dll , Unix 계열 시스템에서는 .so ). 웹 서버에서 게시 한 이벤트 (서버 시작, 사전로드 / 이전 구성로드, 프로세스 요청 등)에 대한 이벤트 핸들러로 일부 함수를 등록합니다. 이러한 핸들러는 sapi/apache2handler/sapi_apache2.c 파일의 php_ap2_register_hook() 함수에 의해 sapi/apache2handler/sapi_apache2.c 행에 등록됩니다.
(로드 가능한 모듈을 Apache와 통합하는 방법에 대한 자세한 내용은 Apache 설명서를 참조하십시오 .)

흥미로운 핸들러는 HTTP 요청을 처리하기 위해 호출되는 php_handler() 함수입니다.

비슷한 방식으로, 모든 SAPI에는 진입 점 ( main() 또는 웹 서버에 의해 호출되는 함수)이 있습니다.

이러한 엔트리 포인트는 모두 비슷한 처리를 수행합니다.

  • 스스로 초기화하십시오.
  • 명령 줄 인수를 구문 분석합니다 ( CLI , CGI 또는 다른 종류의 독립 실행 형 응용 프로그램 인 경우에만 해당).
  • php.ini 및 / 또는 다른 구성을 읽습니다 (Apache 모듈 구성은 .htaccess 에서 재정의 할 수 있음).
  • 입력 파일을 사용하여 스트림을 생성하고 main/main.c 파일에 정의 된 php_execute_script() 함수에 전달합니다 php_execute_script() php_execute_script() 행).
  • 종료 코드를 호출 프로세스 (쉘 또는 웹 서버)로 리턴하십시오.

실제로 PHP 스크립트를 실행하는 코드는 어디에 있습니까?

php_execute_script() 함수는 래퍼입니다. php.ini 설정 항목 인 auto_prepend_fileauto_prepend_file 해석하고, 파일 목록을 준비하고 (auto-prepend file, main script, auto-append file), 목록을 처리하는 zend_execute_scripts() 전달합니다.

php_execute_script() 가 항상 호출되는 것은 아니며, CLI의 일부 SAPI 및 명령 줄 인수는 zend_execute_scripts() 직접 호출합니다.

zend_execute_scripts() 는 흥미로운 일이 일어나는 곳입니다.

PHP 파일을 compiles 하고 op_arrayOP 코드 목록을 반환합니다. 컴파일이 성공하면 (반환 된 op_arrayNULL 이 아닙니다) OP 코드를 executes 합니다. 예외 처리 및 정리도 있지만 지루한 작업이지만 중요합니다. 그럼에도 구문 분석과 실행.

편집은 지루한 과정입니다. 이것은 Zend/zend_language_parser.c 파일에 정의 된 zendparse() 함수에 의해 수행됩니다. zendparse() 함수와 Zend/zend_language_parser.c 파일의 정의는 Git repo에서 볼 수 없습니다. 파서는 Zend/zend_language_parser.yZend/zend_language_scanner.l 에서 언어 구문 규칙과 어휘 토큰의 정의를 읽는 bisonre2c 를 사용하여 생성되고 Zend/zend_language_scanner.l 파일에 실제 컴파일러가 생성됩니다.

그러나 repo에서 열심히 노력하지 않더라도 컴파일 프로세스의 흥미로운 부분이 위에서 언급 한 파일에 표시됩니다.

컴파일 된 스크립트 (OP 코드 목록)의 실행은 Zend/zend_vm_execute.h 파일에 정의 된 함수 zend_execute() 의해 수행됩니다. 이것은 또한 생성 된 파일이며 흥미로운 부분은 PHP 스크립트에 의해 생성된다는 것입니다.

생성기 스크립트 ( Zend/zend_vm_gen.php )는 zend_vm_def.hzend_vm_execute.skl 을 사용하여 zend_vm_def.hzend_vm_execute.skl 를 생성합니다.

zend_vm_def.h 는 각 OP 코드를 처리하기 위해 실행되는 실제 인터프리터 코드를 포함합니다.

PHP 코어 또는 번들 확장 중 하나에서 제공하는 일부 기능 코드는 어디에 있습니까?

확장 기능이 제공하는 PHP 함수 및 함수의 코드는 어떻게 든 쉽게 따라 할 수 있습니다. PHP 코어에 포함 된 함수는 ext/standard 디렉토리의 파일에 있으며 다른 확장자에서 제공하는 함수는 해당 ext 하위 디렉토리의 파일에 있습니다.

이 파일에서 PHP 함수를 구현하는 C 함수는 PHP_FUNCTION() 매크로를 사용하여 선언됩니다. 예를 들어 PHP 함수 strpos() 의 구현은 1948 줄의 ext/standard/string.c 파일에서 시작합니다. strstr() 의 별명 인 strchr() 함수는 ext/standard/basic_functions.c 행의 ext/standard/basic_functions.c 파일에있는 PHP_FALIAS() 매크로를 사용하여 선언됩니다.

등등.





php-internals