desenvolvimento de extensões pecl

24
 Desenvolvimento de extensões PECL Erick Belluci Tedeschi - @ericktedeschi 1ª PHP UnConference Brasil

Upload: erick-belluci-tedeschi

Post on 03-Jul-2015

2.554 views

Category:

Technology


0 download

DESCRIPTION

1ª PHP UnConference Brasil 2009 (evento dentro do PHP Conference Brasil 2009) - Desenvolvimento de Extensões PECL

TRANSCRIPT

Page 1: Desenvolvimento de Extensões PECL

   

Desenvolvimento de extensões PECL

Erick Belluci Tedeschi - @ericktedeschi

1ª PHP UnConference Brasil

Page 2: Desenvolvimento de Extensões PECL

   

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

Page 3: Desenvolvimento de Extensões PECL

   

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 (built­in 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:

Page 4: Desenvolvimento de Extensões PECL

   

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

Page 5: Desenvolvimento de Extensões PECL

   

Ambiente de Desenvolvimento (*nix)

Requisitos necessários para compilar extensões:

Ubuntu: m4 e build­essential

­ 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/flex­2.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:Libcurses­dev, libxml­dev, etc...

Page 6: Desenvolvimento de Extensões PECL

   

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

Page 7: Desenvolvimento de Extensões PECL

   

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:

Page 8: Desenvolvimento de Extensões PECL

   

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 $ */

Page 9: Desenvolvimento de Extensões PECL

   

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"

Page 10: Desenvolvimento de Extensões PECL

   

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 */}

Page 11: Desenvolvimento de Extensões PECL

   

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

Page 12: Desenvolvimento de Extensões PECL

   

Esqueleto da Extensão - MINIT/MSHUTDOWN

PHP_MINIT_FUNCTION(extname){

REGISTER_INI_ENTRIES();return SUCCESS;

}

PHP_MSHUTDOWN_FUNCTION(extname){

UNREGISTER_INI_ENTRIES();return SUCCESS;

}

Page 13: Desenvolvimento de Extensões PECL

   

PHP_RINIT_FUNCTION(extname){

return SUCCESS;}

PHP_RSHUTDOWN_FUNCTION(extname){

return SUCCESS;}

Esqueleto da Extensão - RINIT/RSHUTDOWN

Page 14: Desenvolvimento de Extensões PECL

   

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[] */

};

Page 15: Desenvolvimento de Extensões PECL

   

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

};

Page 16: Desenvolvimento de Extensões PECL

   

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...

Page 17: Desenvolvimento de Extensões PECL

   

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}

Page 18: Desenvolvimento de Extensões PECL

   

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);

Page 19: Desenvolvimento de Extensões PECL

   

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

Page 20: Desenvolvimento de Extensões PECL

   

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;}

Page 21: Desenvolvimento de Extensões PECL

   

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 */}

Page 22: Desenvolvimento de Extensões PECL

   

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);}

Page 23: Desenvolvimento de Extensões PECL

   

Live DEMO

Page 24: Desenvolvimento de Extensões PECL

   

die()

Erick Belluci Tedeschi ­ @ericktedeschi

htp://itatux.blogspot.comhttp://oerick.comhttp://www.linkedin.com/in/ericktedeschi