Upload
erick-belluci-tedeschi
View
2.551
Download
0
Embed Size (px)
DESCRIPTION
1ª PHP UnConference Brasil 2009 (evento dentro do PHP Conference Brasil 2009) - Desenvolvimento de Extensões PECL
Citation preview
Desenvolvimento de extensões PECL
Erick Belluci Tedeschi - @ericktedeschi
1ª PHP UnConference Brasil
Agenda
PHP LifeCycle Estrutura ZVAL Ambiente de Desenvolvimento (*nix) ext_skel (Esqueleto de uma extensão) API Zend Aceitando parâmetros Exemplo: Função recebendo parâmetro e retornando valor
* Live DEMO :D
PHP Page Life Cycle
Processo do Apache
LoadModule php5_module
mysql,sockets,curl,curses,etc...
MINIT
RINIT
Script Execution
RSHUTDOWN
MSHUTDOWN
Inicia WebServer
Carrega módulo do PHP
PHP Carrega suas extensões (builtin e php.ini)
Carrega constantes, ini entries, resources, etc...
Inicializa autoglobals, symbol table, log, etc...
Libera memória...
Libera memória... (ini entries, resources, etc...)
Ciclo de vida de uma requisição de página (script) PHP originada de um WebServer:
Estrutura ZVAL
typedef struct _zval_struct { zvalue_value value; zend_uint refcont; zend_uchar type; zend_uchar is_ref;} zval;
typedef union _zvalue_value { long lval; // Long,Bool,Resource double dval; // Double struct { char *val; long length; } str; // String HashTable *ht; // Array zend_object_value obj; // Object} zvalue_value;
IS_NULLIS_BOOLIS_LONGIS_DOUBLEIS_STRINGIS_ARRAYIS_OBJECTIS_RESOURCE
Ambiente de Desenvolvimento (*nix)
Requisitos necessários para compilar extensões:
Ubuntu: m4 e buildessential
autoconf 2.13 (http://ftp.gnu.org/gnu/autoconf)
automake 1.4 (http://ftp.gnu.org/gnu/automake)
libtool 1.4.x+ (except 1.4.2) (http://ftp.gnu.org/gnu/libtool)
bison 1.28 (http://ftp.gnu.org/gnu/bison)
flex 2.5.4 (http://prdownloads.sourceforge.net/flex/flex2.5.4a.tar.gz?download)
re2c 0.13.4+ (http://re2c.org)
* Caso a extensão faça uso de alguma bilioteca externa, a mesma deve ser instalada:Libcursesdev, libxmldev, etc...
Esqueleto da Extensão
Arquivos básicos que compõe a extensão:
Obrigatórios:
config.m4 Arquivo de configuração *unix config.w32 Arquivo de configuração Windows php_EXTNAME.h Cabeçalho (includes, structs, protótipo de funções, macros, etc...) EXTNAME.c – Esqueleto da extensão e implementação das funções/classes
Opcionais:
CREDITS 1ª linha Nome da Extensão 2ª linha em diante nome dos colaboradores EXPERIMENTAL Não estável EXTNAME.php – Teste básico da extensão tests – Diretório onde ficam os casos de teste escritos para a extensão
Obs.: EXTNAME é o nome da extensão criada
Esqueleto da Extensão
cabeçalho Licença, Créditos, Descrição, etc...
includes API e bibliotecas externas
funções Funções existentes na extensão
MINFO Informações do módulo (phpinfo())
MINIT Tarefas a serem executadas ao carregar a extensão
MSHUTDOWN Libera memórias das tarefas executadas no MINIT
RINIT Tarefas a serem executadas na requisição do script PHP
RSUTDOWN Libera memória das tarefas executadas no RINIT
function_entry Registra as funções para a extensão
module_entry Entrada do módulo no PHP
Estrutura interna do código fonte de uma extensão:
Esqueleto da Extensão - Cabeçalho
/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2008 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | [email protected] so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Fulano de Tal < fulano at tal dot com > | +----------------------------------------------------------------------+*/
/* $Id: header 252479 2008-02-07 19:39:50Z iliaa $ */
Esqueleto da Extensão - Includes
/* Créditos … */
#ifdef HAVE_CONFIG_H#include "config.h"#endif
#include "php.h"#include "php_ini.h"#include "ext/standard/info.h"#include "php_ssp.h"
Esqueleto da Extensão - Funções
// Exemplo de funções definidas para o “user space”.PHP_FUNCTION(mysql_connect){ /* código da função */}
PHP_FUNCTION(mysql_close){ /* código da função */}
// Exemplo da implementação de classes para o “user space”.PHP_METHOD(Cachorro, __construct){ /* código do construtor */}
PHP_METHOD(Cachorro, latir){ /* código do método */}
static PHP_MINFO_FUNCTION(libxml){
php_info_print_table_start();php_info_print_table_row(2, "libXML support", "active");php_info_print_table_row(2, "libXML Compiled Version", LIBXML_DOTTED_VERSION);php_info_print_table_row(2, "libXML Loaded Version", (char *)xmlParserVersion);php_info_print_table_row(2, "libXML streams", "enabled");php_info_print_table_end();
}
Esqueleto da Extensão - MINFO
Esqueleto da Extensão - MINIT/MSHUTDOWN
PHP_MINIT_FUNCTION(extname){
REGISTER_INI_ENTRIES();return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(extname){
UNREGISTER_INI_ENTRIES();return SUCCESS;
}
PHP_RINIT_FUNCTION(extname){
return SUCCESS;}
PHP_RSHUTDOWN_FUNCTION(extname){
return SUCCESS;}
Esqueleto da Extensão - RINIT/RSHUTDOWN
Esqueleto da Extensão – Function Entry
const zend_function_entry extname_functions[] = {PHP_FE(extname_abrir, NULL)PHP_FE(extname_colar, NULL)PHP_FE(extname_recortar, NULL){NULL, NULL, NULL} /* Must be the last line in extname_functions[] */
};
Esqueleto da Extensão – Module Entry
zend_module_entry extname_module_entry = {#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,#endif
"extname",extname_functions,PHP_MINIT(extname),PHP_MSHUTDOWN(extname),PHP_RINIT(extname),PHP_RSHUTDOWN(extname),PHP_MINFO(extname),
#if ZEND_MODULE_API_NO >= 20010901"0.1", /* Replace with version number for your extension */
#endifSTANDARD_MODULE_PROPERTIES
};
API ZEND – Manipulação ZVAL
Macros para manipulação de ZVAL
ZVAL_RESOURCE(zval, 234)ZVAL_NULL(zval)ZVAL_BOOL(zval, 1)ZVAL_LONG(zval, 1234)ZVAL_DOUBLE(zval, 34.5);ZVAL_STRING(zval, “Fulano”, 0)ZVAL_EMPTY_STRING(zval)ZVAL_FALSE(zval) // = ZVAL_BOOL(zval, 0);ZVAL_TRUE(zval) // = ZVAL_BOOL(zval, 1);
Macros para manipulação do valor de retorno da função
RETVAL_RESOURCE(234) // ZVAL_RESOURCE(return_value, 234) RETVAL_BOOL(1) // = ZVAL_BOOL(return_value, 1)RETVAL_NULL() // = ZVAL_NULL(return_value)RETVAL_LONG(1234) // = ZVAL_LONG(return_value, 1234)RETVAL_DOUBLE(34.5) // = ZVAL_DOUBLE(return_value, 34.5)RETVAL_STRING(“Fulano”, 0) // = ZVAL_STRING(return_value, “Fulano”, 0)RETVAL_FALSERETVAL_TRUEetc...
API ZEND – Manipulação Arrays
int add_assoc_long(zval *arg, char *key, long n);int add_assoc_null(zval *arg, char *key);int add_assoc_bool(zval *arg, char *key, int b);int add_assoc_resource(zval *arg, char *key, int r);int add_assoc_double(zval *arg, char *key, double d);int add_assoc_string(zval *arg, char *key, char *str, int dup);int add_assoc_stringl(zval *arg, char *key, char *str, uint len, int dup);int add_assoc_zval(zval *arg, char *key, zval *value);
PHP_FUNCTION(retorna_array){ array_init(return_value); add_assoc_long(return_value, “Numero”, 1234); add_assoc_bool(return_value, “Verdade”, 1); add_assoc_double(return_value, “Peso”, 27.4);}
<?php print_r(retorna_array()); ?>Resultado{ [Numero] => 1234 [Verdade] => 1 [Peso] => 27.4}
API ZEND – Manipulação Arrays
Adiciona com um número de índice específico
int add_index_long(zval *arg, uint idx, long n);int add_index_null(zval *arg, uint idx);int add_index_bool(zval *arg, uint idx, int b);int add_index_resource(zval *arg, uint idx, int r);int add_index_double(zval *arg, uint idx, double d);int add_index_string(zval *arg, uint idx, char *str, int duplicate);int add_index_stringl(zval *arg, uint idx, char *str, uint length, int duplicate);int add_index_zval(zval *arg, uint idx, zval *value);
Adiciona no próximo índice
int add_next_index_long(zval *arg, long n);int add_next_index_null(zval *arg);int add_next_index_bool(zval *arg, int b);int add_next_index_resource(zval *arg, int r);int add_next_index_double(zval *arg, double d);int add_next_index_string(zval *arg, char *str, int duplicate);int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate);int add_next_index_zval(zval *arg, zval *value);
Aceitando Parâmetros
Syntax: zend_parse_parameters(num_args, “format args”, &arg1, &arg2, ...)
l Long long *d double double *b Boolean zend_bool *a array zval **o Object zval **O Object zval **, zend_class_Entry *
Força ser da classe/tipo determinadas String char **, int * Sempre recebe string e tamanhor resource zval **z zval zval **Z zval-ref zval ***
| Restante (parte direita) são opcionais! Proximo parametro retorna NULL se o tipo é IS_NULL
Aceitando Parâmetros – Exemplo 1
PHP_FUNCTION(exemplo1){ /* Definição das variáveis */ char *nome; int nome_len;
/* Pegando os parâmetros */ if (zend_parse_parameters(1 TSRMLS_CC, “s”, &nome, &nome_len) == FAILURE) { return; }
/* Código da função... */ php_printf(“Nome: %s”, nome);
/* Retorno de valor */ RETVAL_NULL;}
Aceitando Parâmetros – Exemplo 2
PHP_FUNCTION(tipovar){ /* Declaração das variáveis */
zval *variavel; /* Recebendo parâmetros */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &variavel) == FAILURE) {
return; } /* Código da função */ switch (Z_TYPE_P(variavel)) { case IS_LONG: php_printf("Inteiro\n"); break; case IS_ARRAY: php_printf("Matriz\n"); break; default: php_printf("Tipo desconhecido\n"); break; }
/* Retorno de valor */}
Retornando Valor – Exemplo 3
PHP_FUNCTION(numeroCao){ /* Declaração das variáveis */
/* Recebendo parâmetros */
/* Código da função */
/* Retorno de valor */ RETVAL_LONG(666);}
Live DEMO
die()
Erick Belluci Tedeschi @ericktedeschi
htp://itatux.blogspot.comhttp://oerick.comhttp://www.linkedin.com/in/ericktedeschi