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

Extending php (7), the basics

Jan 22, 2018

Download

Engineering

Pierre Joye
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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