Confluence 에 심각한 보안 취약점이 발견되었으니 사용자분들은 업그레이드 하세요.!
Skip to end of metadata
Go to start of metadata

PHP7 Extension은 기존의 PHP5와 약간의 함수명이 바뀐 부분이 있어서 그냥 만들면서 하나하나 정리할 용도로 작성합니다.

여기서 작성할 Extension의 이름은 garlic 이라고 가정하고 진행하겠습니다. (smile)


참고할 URL

PHP 코어 : Zend 엔진 해킹 가이드 http://php.net/manual/kr/internals2.php

PHP Yaf : https://github.com/laruence/yaf : C로 만들어진 PHP Framework. Phalcon은 Zephir라는 언어로 작성되어있어서 참고하기 힘들지만, 해당 프레임워크는 참고할만 합니다. 특히 객체지향 C extension 만들 때 참고하기 좋은 소스입니다.


config.m4

작성할 config.m4 파일입니다. config.m4 파일은 phpize 라는 명령어를 통해 ./configure 파일을 생성합니다. 그리고 ./configure는 Makefile을 생성해서 빌드할 수 잇도록 도와줍니다.

config.m4의 문법은 GNU Autoconf 문법을 기반으로 PHP Extension 작성을 위한 매크로로 구성되어있습니다.


config.m4
PHP_ARG_ENABLE(garlic, whether to enable php-garlic,
[  --enable-garlic     Enable php-garlic])

dnl Check whether the extension is enabled at all
if test "$PHP_GARLIC" = "yes"; then

  dnl Finally, tell the build system about the extension and what files are needed

  AC_DEFINE(HAVE_GARLIC, 1, [Whether you have php-garlic])

  PHP_NEW_EXTENSION(garlic, php_garlic.c, $ext_shared)
  PHP_SUBST(GARLIC_SHARED_LIBADD)

fi

위에서 PHP_NEW_EXTENSION 부분에 사용할 c파일을 정의하시면 됩니다.

PHP_ADD_INCLUDE

이 옵션은 c 소스의  #include 구문에서 불러올 경로를 설정할 수 있습니다.

다음과 같이 사용가능합니다. otherlibrary 하위에는 .c파일과 .h 파일들이 정의되어있으며 이 파일들은 #include를 통해 바로 불러 올 수 있게합니다.

config.m4
PHP_ADD_INCLUDE(lib/otherlibrary)

php_garlic.c에 대응하는 헤더 파일은 다음과 같이 작성합니다. 

php_garlic.h
#ifndef PHP_GARLIC_H
#define PHP_GARLIC_H

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <php.h>
#include <php_ini.h>
#include <SAPI.h>
#include <ext/standard/info.h>
#include <Zend/zend_extensions.h>
#include <Zend/zend_exceptions.h>
#include <Zend/zend_interfaces.h>

#define PHP_GARLIC_VERSION "0.0.1"
#define PHP_GARLIC_EXTNAME "garlic"

#ifndef PHP_GARLIC_VERSION_STRING
#define PHP_GARLIC_VERSION_STRING "unknown"
#endif

#define GARLIC_NS "Garlic"

static PHP_MINFO_FUNCTION(garlic);
static PHP_MINIT_FUNCTION(garlic);

extern zend_module_entry garlic_module_entry;

#endif  /* PHP_GARLIC_H */


PHP_MINFO_FUNCTION은 phpinfo()를 호출했을 때 출력되는 정보를 작성하는 매크로입니다.

PHP_MINIT_FUNCTION은 Extension이 로드될때 호출되는 내용을 작성하는 매크로입니다.


그리고 php_garlic.c는 다음과 같이 작성합니다.

php_garlic.c
#include "php_garlic.h"

// 사용할 함수들을 선언합니다.
static zend_function_entry tf_functions[] = {
    {NULL, NULL, NULL}
};

// the following code creates an entry for the module and registers it with Zend.
zend_module_entry garlic_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    PHP_GARLIC_EXTNAME,
    tf_functions,
    PHP_MINIT(garlic), // 사용하지 않으면 NULL을 넣으면 됩니다.
    NULL, // 원래 여기에도 들어갈 녀석이 있음.
    NULL,
    NULL,
    PHP_MINFO(garlic), // phpinfo 호출시 사용할 함수.
#if ZEND_MODULE_API_NO >= 20010901
    PHP_GARLIC_VERSION,
#endif
    STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(garlic)

static PHP_MINFO_FUNCTION(garlic)
{
    // 2칸짜리 표를 만듭니다.
    php_info_print_table_start();
    php_info_print_table_row(2, "Garlic Support", "enabled");
    php_info_print_table_row(2, "Garlic Module Version", PHP_GARLIC_VERSION);
    php_info_print_table_end();

    // 3칸짜리 표를 만듭니다.
    php_info_print_table_start();
    php_info_print_table_header(3, "Version Info", "Compiled", "Linked");
    php_info_print_table_row(3, "Garlic Library", PHP_GARLIC_VERSION_STRING, "1.0.0");
    php_info_print_table_end();

    DISPLAY_INI_ENTRIES();
}

static PHP_MINIT_FUNCTION(garlic)
{
    /* Extension 초기화시 동작할 로직들 */

    // Garlic\VERSION 상수를 선언합니다.
    REGISTER_NS_STRING_CONSTANT("Garlic", "VERSION", "1.0.0", CONST_PERSISTENT | CONST_CS);

    /* 클래스를 선언한다던가 하는 작업이 여기에 들어갑니다. */

    return SUCCESS;
}


 여기서 제일 중요한 부분은 PHP_MINIT_FUNCTION 입니다. 함수를 선언한다던가, 클래스를 선언한다던가 하는 작업은 모두 여기에 들어갑니다. 위에 예시에는 Namespace를 포함한 상수를 선언하는 로직을 추가해놓았습니다.

Class 작성하기



Class Methods 작성하기




  • No labels