create your own php extension, step by step - phpday 2012 verona
DESCRIPTION
Ever been interested by contributing to the PHP core team? In this workshop you will not only learn how (easy it is) to create your own PHP extension from scratch but you will also strengthen your knowledge of PHP by disecting its internals. After this workshop, you will be able to create an extension on your own, whether it is to optimize the most CPU intensive parts of your code, to create new bindings to C libraries or just to leverage your PHP knowledge. And what if PHP was a web framework for the C developer? This workshop requires a bit of C knowledge and preferably a *nix system.TRANSCRIPT
![Page 1: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/1.jpg)
Create your own PHP extension, step by stepPatrick Allaert, Derick Rethans, Rasmus Lerdorf
phpDay 2012 Verona, Italy
![Page 2: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/2.jpg)
Patrick Allaert● Founder of Libereco● Playing with PHP/Linux for +10 years● eZ Publish core developer● Author of the APM PHP extension● @patrick_allaert● [email protected]● http://github.com/patrickallaert/● http://patrickallaert.blogspot.com/
![Page 3: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/3.jpg)
Derick Rethans
● Dutchman living in London● PHP Engineer/Evangelist for 10gen (the MongoDB
people), where I also work on the MongoDB PHP driver.
● Author of Xdebug● Author of the mcrypt, input_filter, dbus, translit
and date/time extensions
![Page 4: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/4.jpg)
Workshop overview
● Brief reminders about PHP architecture● Configure your environment● Grab the example extension● Do some exercises while seeing a bit of theory
![Page 5: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/5.jpg)
PHP architecture
![Page 6: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/6.jpg)
Configuring your environment
● Debian-like:
$ sudo apt-get install php5-dev
![Page 7: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/7.jpg)
Download the sample extension
a) Using git:
$ git clone git://github.com/patrickallaert/PHP_Extension_Workshop.git
b) Download archive at: https://github.com/patrickallaert/PHP_Extension_Workshop/downloads
![Page 8: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/8.jpg)
Minimal C code (myext.c)#ifdef HAVE_CONFIG_H#include "config.h"#endif
#include "php.h"#include "php_ini.h"#include "ext/standard/info.h"#include "php_myext.h"
zend_module_entry myext_module_entry = { STANDARD_MODULE_HEADER, "myext", NULL, /* Function entries */ NULL, /* Module init */ NULL, /* Module shutdown */ NULL, /* Request init */ NULL, /* Request shutdown */ NULL, /* Module information */ "0.1", /* Replace with version number for your extension */ STANDARD_MODULE_PROPERTIES};
#ifdef COMPILE_DL_MYEXTZEND_GET_MODULE(myext)#endif
![Page 9: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/9.jpg)
Compilation
Prepare build environment:
1. $ phpize
Configure the extension:
2. $ ./configure
Compile it:
3. $ make
Install it (may require root):
4. $ make install
![Page 10: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/10.jpg)
Verify installation
$ php -d extension=myext.so -m
You should see “myext” as part of the loaded extensions.
![Page 11: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/11.jpg)
Minimal config.m4dnl config.m4 for myext
PHP_ARG_ENABLE(myext, whether to enable myext support,
[ --enable-myext Enable myext support])
if test "$PHP_MYEXT" != "no"; then
PHP_NEW_EXTENSION(myext, myext.c, $ext_shared)
fi
![Page 12: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/12.jpg)
Exercise one: fibonacci (1/7)
● F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1
![Page 13: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/13.jpg)
Exercise one: fibonacci (2/7)
function fibo($n) { switch ($n) { case 0: case 1: return $n; }
return fibo($n-2) + fibo($n-1);}
![Page 14: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/14.jpg)
Exercise one: fibonacci (3/7)
![Page 15: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/15.jpg)
Exercise one: fibonacci (4/7)
![Page 16: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/16.jpg)
Exercise one: fibonacci (5/7)
![Page 17: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/17.jpg)
Exercise one: fibonacci (6/7)
![Page 18: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/18.jpg)
Exercise one: fibonacci (7/7)
Compile:
$ make
Install:
$ make install
Test:
$ php -d extension=myext.so \ -r 'echo fibonacci(35), “\n”;'
9227465
![Page 19: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/19.jpg)
Exercise one: fibonacci solution
The full changes required to implement the fibonacci function are available at:
http://tinyurl.com/PHP-ext-fibonacci
![Page 20: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/20.jpg)
zend_parse_parameters
● Handles the conversion of PHP userspace variables into C ones.
● Generate errors in the case of missing parameters or if the type is wrong.
![Page 21: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/21.jpg)
zend_parse_parameters● Second parameter describes
the type of the parameter(s) as a string composed of characters having all a special meaning.
● To mark the start of optional parameter(s), a pipe (“|”) character is used.
Type Code
Variable type
Boolean b zend_bool
Long l long
Double d double
String s char *, int (length)
Path p char *, int (length)
Class name
C zend_class_entry*
Resource r zval*
Array a zval*
Object o zval*
zval z zval*
Zval pointer
Z zval**
Callback f zend_fcall_info, zend_fcall_info_cache
![Page 22: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/22.jpg)
zend_parse_parameters examples● sleep(), usleep(), func_get_arg():
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &long)
● bin2hex(), quotemeta(), ord(), ucfirst():zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len)
● str*pos():zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &needle, &offset)
● var_dump():zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc)
● file_put_contents()zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pz/|lr!", &filename, &filename_len, &data, &flags, &zcontext)
![Page 23: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/23.jpg)
OpenGrok (1/2)
● Your best friend to browse PHP's source code:http://lxr.php.net/
![Page 24: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/24.jpg)
OpenGrok (2/2)
![Page 25: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/25.jpg)
zval (=== _zval_struct)struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount__gc; zend_uchar type; /* active type */ zend_uchar is_ref__gc;};
typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj;} zvalue_value;
![Page 26: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/26.jpg)
Types● IS_NULL● IS_LONG● IS_DOUBLE● IS_BOOL● IS_ARRAY● IS_OBJECT● IS_STRING● IS_RESOURCE● IS_CONSTANT● IS_CONSTANT_ARRAY● IS_CALLABLE
● http://lxr.php.net/xref/PHP_TRUNK/Zend/zend.h#IS_NULL
![Page 27: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/27.jpg)
Access macrosZ_TYPE(zval) (zval).typeZ_LVAL(zval) (zval).value.lvalZ_BVAL(zval) ((zend_bool)(zval).value.lval)Z_DVAL(zval) (zval).value.dvalZ_STRVAL(zval) (zval).value.str.valZ_STRLEN(zval) (zval).value.str.lenZ_ARRVAL(zval) (zval).value.htZ_OBJVAL(zval) (zval).value.objZ_OBJ_HANDLE(zval) Z_OBJVAL(zval).handleZ_OBJ_HT(zval) Z_OBJVAL(zval).handlersZ_RESVAL(zval) (zval).value.lval
Z_TYPE_P(zval_p) Z_TYPE(*zval_p)Z_LVAL_P(zval_p) Z_LVAL(*zval_p)Z_BVAL_P(zval_p) Z_BVAL(*zval_p)Z_DVAL_P(zval_p) Z_DVAL(*zval_p)Z_STRVAL_P(zval_p) Z_STRVAL(*zval_p)Z_STRLEN_P(zval_p) Z_STRLEN(*zval_p)Z_ARRVAL_P(zval_p) Z_ARRVAL(*zval_p)Z_RESVAL_P(zval_p) Z_RESVAL(*zval_p)Z_OBJVAL_P(zval_p) Z_OBJVAL(*zval_p)Z_OBJ_HANDLE_P(zval_p) Z_OBJ_HANDLE(*zval_p)Z_OBJ_HT_P(zval_p) Z_OBJ_HT(*zval_p)
http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.h#Z_LVAL
![Page 28: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/28.jpg)
Exercise two: my_dump($val) (1/2)
● Create a very simple my_dump($val) function:● my_dump(null); // null value!
● my_dump(42); // Long: 42
● my_dump(123.456); // Double: 123.456
● my_dump(true); // Boolean: true
● my_dump(“hello”); // String: hello
![Page 29: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/29.jpg)
Exercise two: my_dump($val) (2/2)● Hints:● Define a pointer to a zval:zval *val;
● Use “z” with zend_parse_parameters()
● Switch/case based on the type of val (Z_TYPE_P(uservar))
● Use php_printf() to print, except for strings from zval, since they may contain NULL characters:PHPWRITE(const char *, size_t);
![Page 30: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/30.jpg)
Exercise two: solutionPHP_FUNCTION(my_dump) { zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", val) == FAILURE) { return; } switch (Z_TYPE_P(val)) { case IS_NULL: php_printf("NULL"); break; case IS_BOOL: php_printf("Boolean: %s", Z_LVAL_P(val) ? "true" : "false"); break; case IS_LONG: php_printf("Long: %ld", Z_LVAL_P(val)); break; case IS_DOUBLE: php_printf("Double: %f", Z_DVAL_P(val)); break; case IS_STRING: php_printf("String: "); PHPWRITE(Z_STRVAL_P(val), Z_STRLEN_P(val)); break; default: php_printf("Not supported"); }}
![Page 31: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/31.jpg)
PHP life cycles
● 4 functions (2 initializations, 2 shutdowns ones) let you do stuff at specific moments of the PHP life cycles:● PHP_MINIT_FUNCTION● PHP_MSHUTDOWN_FUNCTION● PHP_RINIT_FUNCTION● PHP_RSHUTDOWN_FUNCTION
![Page 32: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/32.jpg)
PHP life cycles - CLI
● Credits: Extending and Embedding PHP by Sara Golemon (2006 June 9th)
![Page 33: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/33.jpg)
PHP life cycles – Web server(prefork)
● Credits: Extending and Embedding PHP by Sara Golemon (2006 June 9th)
![Page 34: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/34.jpg)
PHP life cycles - Web server(multi thread)
● Credits: Extending and Embedding PHP by Sara Golemon (2006 June 9th)
![Page 35: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/35.jpg)
Exercise three: MyClass (1/10)● Steps:
● Create a class named “MyClass”● Create a class constant● Add some properties with various visibilities/modifiers● Add some methods
![Page 36: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/36.jpg)
Exercise three: MyClass (2/10)
![Page 37: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/37.jpg)
Exercise three: MyClass (3/10)
● http://tinyurl.com/PHP-ext-MyClass-1
![Page 38: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/38.jpg)
Exercise three: MyClass (4/10)● Declaring a class constant can be made from a C type:
● zend_declare_class_constant_null();● zend_declare_class_constant_long();● zend_declare_class_constant_bool();● zend_declare_class_constant_double();● zend_declare_class_constant_stringl();● zend_declare_class_constant_string();
● Or from a zval:● zend_declare_class_constant();
![Page 39: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/39.jpg)
Exercise three: MyClass (5/10)
● http://tinyurl.com/PHP-ext-MyClass-2
![Page 40: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/40.jpg)
Exercise three: MyClass (6/10)● Creating class properties can be made from a C type:
● zend_declare_property_long();
● zend_declare_property_bool();
● zend_declare_property_double();
● zend_declare_property_stringl();
● zend_declare_property_string();
● Or from a zval:● zend_declare_property();
● Visibility:● ZEND_ACC_PUBLIC, ZEND_ACC_PROTECTED, ZEND_ACC_PRIVATE
● Modifiers:● ZEND_ACC_STATIC, ZEND_ACC_ABSTRACT, ZEND_ACC_FINAL
![Page 41: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/41.jpg)
Exercise three: MyClass (7/10)
● http://tinyurl.com/PHP-ext-MyClass-3
![Page 42: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/42.jpg)
Exercise three: MyClass (8/10)
![Page 43: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/43.jpg)
Exercise three: MyClass (9/10)
![Page 44: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/44.jpg)
Exercise three: MyClass (10/10)
● http://tinyurl.com/PHP-ext-MyClass-4
![Page 45: Create your own PHP extension, step by step - phpDay 2012 Verona](https://reader033.vdocuments.mx/reader033/viewer/2022051513/547b255db37959652b8b4c66/html5/thumbnails/45.jpg)
Questions?