extending php (7), the basics

41
Extending PHP (7.x) How to, when and when not

Upload: pierre-joye

Post on 22-Jan-2018

391 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: Extending php (7), the basics

Extending PHP (7.x)How to, when and when not

Page 2: Extending php (7), the basics

Pierre Joye@[email protected]://www.slideshare.net/pierrej

PHP Core developerContributors to numerous OSS projects

Portability fan

Page 3: Extending php (7), the basics

hiring@BK

Kdev – devops – sysops –

Page 4: Extending php (7), the basics

When to use custom extensions?

Page 5: Extending php (7), the basics

PHP 7 is fast.

Page 6: Extending php (7), the basics

PHP will be even faster.

Page 7: Extending php (7), the basics

OpCache rocks.

Page 8: Extending php (7), the basics

IOs are slow.

Page 9: Extending php (7), the basics

Streams are easy.

Page 10: Extending php (7), the basics

File Ops are easy.

Page 11: Extending php (7), the basics
Page 12: Extending php (7), the basics
Page 13: Extending php (7), the basics

zval

• Integer > zend_long

• Booleans > types, IS_TRUE/IS_FALSE

• Strings > zend_string

• Float > double

• Object > zend_object

• Resource

Hash Tables

• Array (zval > array > hash table)

• Functions table

• Classes, properties, etc.

Classes

• Classes declaration

Page 14: Extending php (7), the basics

Zend/zend_types.hyour best friend.

Page 15: Extending php (7), the basics

typedef struct _zval_struct zval;

struct _zval_struct {

zend_value value; /* value */

union {

struct {

ZEND_ENDIAN_LOHI_4(

zend_uchar type, /* active type */

zend_uchar type_flags,

zend_uchar const_flags,

zend_uchar reserved) /* call info for EX(This)*/

} v;

uint32_t type_info;

} u1;

....

};

Page 16: Extending php (7), the basics

Hash tables

Page 17: Extending php (7), the basics

Hash tables are not arrays!

Page 18: Extending php (7), the basics

Hash tables elements can contain ANYTHING

Page 19: Extending php (7), the basics

Zend/zend_hash.hYour second best buddy

Page 20: Extending php (7), the basics

Let get started

Page 21: Extending php (7), the basics

Requirements *nix

• Common• A shell

• editor

• Gcc 5+

• php7-dev

• Autoconf, autotools and co

Page 22: Extending php (7), the basics

Requirements Windows

• Common• A shell

• php-sdk (http://windows.php.net/downloads/php-sdk/)

• vc (14+) for Windows

• php binary tools (http://windows.php.net/downloads/php-sdk/)

• Setup your sdk structure according to https://wiki.php.net/internals/windows/stepbystepbuild

Page 23: Extending php (7), the basics

Extension directory structure

myextconfig.w32

Build script for windows

config.m4

Build script for *nix

php_myext.c

Implementation

php_myext.h

Interface & meta data

Tests

myext testsmyext.phpt

Page 24: Extending php (7), the basics

config.w32

// $Id$ // vim:ft=javascript

ARG_ENABLE("myext", "myext support", "yes");

if (PHP_MYEXT == "yes") {

EXTENSION("myext", "php_myext.c");

}

Page 25: Extending php (7), the basics

config.m4

dnl Tell PHP about the argument to enable the hello extension

PHP_ARG_ENABLE(myext, Whether to enable the myext extension, [ --enable-myext Enable myext])

if test "$PHP_MYEXT" != "no"; then

PHP_NEW_EXTENSION(myext, php_myext.c, $ext_shared)

fi

Page 26: Extending php (7), the basics

Our first function

function myext_hello() {

echo "Hello Manila!";

}

Page 27: Extending php (7), the basics

php_myext.h

#define PHP_MYEXT_EXTNAME "myext“

#define PHP_MYEXT_VERSION "0.0.1"

PHP_FUNCTION(myext_hello);

Page 28: Extending php (7), the basics

php_myext.c

#include <php.h>

#include "php_myext.h"

include php common interfaces and types

Page 29: Extending php (7), the basics

php_myext.c

Define myext_hello functions and commons hooks&data for myext

zend_function_entry myext_functions[] = {

PHP_FE(myext_hello, NULL)

PHP_FE_END

};

zend_module_entry myext_module_entry = {

STANDARD_MODULE_HEADER,

PHP_MYEXT_EXTNAME,

myext_functions,

NULL,

NULL, NULL, NULL, NULL,

PHP_MYEXT_VERSION,

STANDARD_MODULE_PROPERTIES,

};

Page 30: Extending php (7), the basics

zend_value

Define myext_hello functions and commons hooks&data for myext

typedef union _zend_value {

zend_long lval; /* long value */

double dval; /* double value */

zend_refcounted *counted;

zend_string *str;

zend_array *arr;

zend_object *obj;

zend_resource *res;

zend_reference *ref;

zend_ast_ref *ast;

zval *zv; void *ptr;

zend_class_entry *ce;

zend_function *func;

struct { uint32_t w1; uint32_t w2; }ww;

} zend_value;

Page 31: Extending php (7), the basics

php_myext.c

print „Hello Manilla!\n“ to php standard output

PHP_FUNCTION(myext_hello) {

php_printf("Hello Manila!\n");

};

Page 32: Extending php (7), the basics

First build

All platforms:

$ phpize

$ configure –enable-myext

For *nix flavors:

$ make

For Windows:

$ nmake

Page 33: Extending php (7), the basics

first function, with a string argument

function myext_print(string $mystring) {

echo "Hello " . $mystring . "!\n";

}

Page 34: Extending php (7), the basics

first function, with a string argument

PHP_FUNCTION(myext_print) {

char *mystring;

size_t mystring_len;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &mystring, &mystring_len) ==

FAILURE) {

return;

}

php_printf("Hello %s!! (%i)\n", mystring, mystring_len);

return

}

Page 35: Extending php (7), the basics

first function, with an integer argument

function myext_integer(int $myint) {

if ($myint > 0) {

for ($i = 0; $i < $myint; $i++) {

echo "Hello " . $i . "!\n";

}

}

}

Page 36: Extending php (7), the basics

first function, with an integer argument

PHP_FUNCTION(myext_print_integer) {

zend_long lval;

int i;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,

"l", &lval) == FAILURE) {

return;

}

if (lval > 0) {

for (i=0; i < lval; i++) {

php_printf("Hello %i\n",i);

}

}

return;

}

Page 37: Extending php (7), the basics

first function, with an array argument

function myext_print_array(array $myarray) {

foreach ($myarray as $val) {

echo "hello ". $val . "\n";

}

}

Page 38: Extending php (7), the basics

first function, with an array argument

PHP_FUNCTION(myext_print_array) {

zval *myarray = NULL;

zend_string *key;

zend_ulong num_key;

zval *val;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &myarray) ==

FAILURE) {

return;

}

ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(myarray), num_key, key,

val) {

php_printf("Hello %s\n", Z_STRVAL_P(val));

}

ZEND_HASH_FOREACH_END();

return;

}

Page 39: Extending php (7), the basics

home work

• First class

• Zend Memory Manager• Use tools like valgrind

• Use external libraries

• Debugging using gdb or vs debugger

Page 40: Extending php (7), the basics
Page 41: Extending php (7), the basics

resources

• https://wiki.php.net/phpng-upgrading

• https://nikic.github.io/

• https://wiki.php.net/internals/

• http://www.phpinternalsbook.com/

• http://jpauli.github.io/

• https://github.com/php/php-src