Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
PHP EXTENSIONS
Making the language even better
Congratulations!
• You’ve decided to learn “down the stack”
• You’ll learn more than you do “across the stack”
• Your brai...
WARNING!
The things shown here to apply to PHP 5.4 – PHP 5.x
Why do extensions?
• Talk to a C or C++ library
• Modify the way the engine works (zend extensions
usually)
• Make slow pa...
But I want to
change the
engine!
Baby steps, baby steps
Wrapper
Extension
Speed and/or
Algorithm
Extension
Zend
Extension
SAPI
Engine - Lexer,
AST, Parser
But I don’t know C!
1. compiled
2. strictly typed
3. php internals do “hard” stuff
4. copy and paste! boilerplate and macr...
But I want to learn C
Also try:
• http://www.learn-c.org/
• http://c.learncodethehardway.org/book/
• http://aelinik.free.fr/c/
Practice Practice...
Preparing to
Compile
The big list
Quick Setup Needs
1. compiler
2. sdk
3. tools
4. dependencies
5. code
phpize is your friend!
How to Compile an Extension
1. phpize
2. ./configure
3. make
4. make install
5. make test
configure might require –with-ph...
But wait – there’s more!
• Compile your own PHP source, use a –prefix
 /usr/local/php-5.6-debug-zts is one I use
 I also...
Rasmus to the Rescue!
• https://github.com/rlerdorf/php7dev/blob/master/README.md
tl;dr
1. install virtualbox
2. install v...
How to Play along
git clone https://github.com/auroraeosrose/php-extensions-
code.git
git clone git://github.com/auroraeos...
Let’s write an
extension!
But wait – there’s more….
1. Set up compile environment
2. Write a module definition
3. Learn about the PHP lifecycle
4. Learn about zvals
5. Add fu...
DOIN IT RONG
Which do YOU want?
1. Do something you can’t do in userland
2. Utilize a C library
3. Make slow code faster
Maybe you should just use ffi!
St...
What is FFI?
• Foreign function interface
• Java calls it JNI
• HHVM calls it HNI
• Python calls it “ctypes” (do not ask, ...
FFI
Oh wait…
• php’s ffi is rather broken (last release is 2004-01-20)
• php’s ffi has no maintainer (ilia and wez were doing
...
1. I hate parsing URIs
2. PHP’s parse_url is… not the best
3. How about an extension that wraps something
that parses uris...
Google says…
C library to the rescue!
• uriparser.sourceforge.net
• strictly RFC 3986 compliant
• available on many systems as packages...
1. Think about what the API should be
2. Look at the C APIs but don’t mimic them
3. Write an example of how you WANT it to...
1. This is copy and paste
1. config.m4 & config.w32
2. macros for version api changes if necessary
3. main module file (ph...
Configure files
Module struct
Scaffolding rules
1. make sure you name your files in a standard way
2. document! use a license header, proto statements
3...
php –d extension=myext.so –m
The scaffold extension should show up in the list
Make sure to
1. define a version constant
2...
1. run-test.php
2. make test will magically have output
more at http://qa.php.net/write-test.php and docs
at http://qa.php...
PHPT tests
Let’s take a break here for
some semi-live demos…
Zval
The guts behind PHP’s type system
Typing systems compared
Static Typing (C)
• Variables must be declared
before use
• Variables must be given a
type at decl...
zval
long any numeric
double numeric with decimal
char* + int
(length) strings, binary
Hashtable dictionaries, arrays,structs
o...
How do I get C types from a ZVAL?
Z_LVAL(zval) Z_LVAL_P(zval_p) Z_LVAL_PP(zval_pp)
Z_BVAL(zval) Z_BVAL_P(zval_p) Z_BVAL_PP...
My extension
does nothing!
Back to our regularly schedule content
1. tell it to link to our C library
2. add a function
3. learn how to get data
4. learn how to return data
Step 8. Actuall...
I hate autotools…
• Also known as the gnu build system
• provider of much pain, but much good use as well
• autoconf – gen...
Anatomy of a Function
Wait – what was that?
• Define your function in C
 use a special call to parse parameters passed by the
user
 use a spec...
php type code
c type
array or object a zval *
boolean b zend_bool
class C zend_class_entry *
double d double
callable f ze...
zend_parse_parameters
type code
variable args (any) * int, zval***
variable args (1 or more) + int, zval***
| anything aft...
return_value
RETURN_RESOURCE(l)
RETURN_BOOL(b)
RETURN_NULL()
RETURN_LONG(l)
RETURN_DOUBLE(d)
RETURN_STRING(s, duplicate)
R...
Complex Data
array_init()
add_(index|assoc)_long()
add_(index|assoc)_bool()
add_(index|assoc)_string()
object_init()
add_p...
Now to visit the attach-library
branch…
1. namespaces
2. classes
3. methods
4. constants
Step 9. Make it shiny
Classes
1. name, parent, and flags
2. hashtables of methods, default methods, static
methods
3. hashtables of static prope...
add-basic-class branch
Lifecycle
Let’s take a moment to learn about how PHP works
internally
Lifecycle
PHP stops
MSHUTDOWN – for each extension
RSHUTDOWN – for each request
cleanup after test.php
RINIT – for each re...
Lifecycle Threaded
PHP stops
MSHUTDOWN – for each extension
request index.php request foo.php
RINIT – for each request
• e...
Class Properties
add-class-properties branch
Class Constants
add-class-constants branch
My class does
nothing!
Methods are where it’s at
Class Methods
add-class-methods branch
Alter $this
manipulate this branch
Abstract, Interface, Trait
Class Method
ZEND_ACC_IMPLICIT_ABSTRACT_CLA
SS
ZEND_ACC_STATIC
ZEND_ACC_EXPLICIT_ABSTRACT_CLA
S...
1. globals
2. memory management
3. custom objects
4. object handlers
5. thread safety
Step 10: Advanced topics
1. in your header – use
ZEND_BEGIN|END_MODULE_GLOBALS
2. create the global access macro in your header
(copy and paste)
3....
emalloc( )
• allocates the specified number of bytes
safe_emalloc()
• like emalloc but adds a special protection against o...
1. clean up what you emalloc (C level destructor)
2. read wiki on how to make them extendable!
Object Handlers (black magic)
https://wiki.php.net/internals/engine/objects
TSRM
thread safe resource manager
ZTS
zend thread safety
• tsrm_lsTSRMLS_C
• void ***tsrm_lsTSRMLS_D
• , tsrm_lsTSRMLS_CC
...
1. http://edit.php.net
2. http://svn.php.net/viewvc/phpdoc/en/trunk/reference/
3. PhD is awesomesauce
• http://doc.php.net...
Stuff I didn’t talk about
1. resources (use custom objects instead)
2. ini entries (just DON’T)
3. threading and parallel ...
PHP 7 is coming!
gophp7-ext and php extension ecosystems
About Me
 http://emsmith.net
 auroraeosrose@gmail.com
 twitter - @auroraeosrose
 IRC – freenode – auroraeosrose
 #php...
Questions?
HELP WITH DOCS!
http://edit.php.net
http://wiki.php.net/internals
HELP WITH THE FUTURE
http://gophp7.org/gophp7...
Php extensions
Php extensions
Php extensions
Php extensions
Upcoming SlideShare
Loading in …5
×

Php extensions

1,635 views

Published on

Writing extensions for PHP

Published in: Internet
  • Be the first to comment

  • Be the first to like this

Php extensions

  1. 1. PHP EXTENSIONS Making the language even better
  2. 2. Congratulations! • You’ve decided to learn “down the stack” • You’ll learn more than you do “across the stack” • Your brain will hurt a bit • This will require you to be involved in your own learning process • It is HARD WORK to be good at anything new
  3. 3. WARNING! The things shown here to apply to PHP 5.4 – PHP 5.x
  4. 4. Why do extensions? • Talk to a C or C++ library • Modify the way the engine works (zend extensions usually) • Make slow parts of code run faster
  5. 5. But I want to change the engine! Baby steps, baby steps
  6. 6. Wrapper Extension Speed and/or Algorithm Extension Zend Extension SAPI Engine - Lexer, AST, Parser
  7. 7. But I don’t know C! 1. compiled 2. strictly typed 3. php internals do “hard” stuff 4. copy and paste! boilerplate and macros 5. cairo, pecl_http, date 6. Don’t do the hard stuff first! lxr.php.net
  8. 8. But I want to learn C
  9. 9. Also try: • http://www.learn-c.org/ • http://c.learncodethehardway.org/book/ • http://aelinik.free.fr/c/ Practice Practice Practice!
  10. 10. Preparing to Compile The big list
  11. 11. Quick Setup Needs 1. compiler 2. sdk 3. tools 4. dependencies 5. code phpize is your friend!
  12. 12. How to Compile an Extension 1. phpize 2. ./configure 3. make 4. make install 5. make test configure might require –with-php-config=/path/to/something but…
  13. 13. But wait – there’s more! • Compile your own PHP source, use a –prefix  /usr/local/php-5.6-debug-zts is one I use  I also have 20 php’s installed  • We want developer specific flags  --enable-maintainer-zts and --enable-debug  optionally –enable-gcov • install gdb and valgrind and optionally lcov • this is easy on Ubuntu and similar systems where packages are easy to get • You can also compile php with clang instead of gcc and do things like use static analysis
  14. 14. Rasmus to the Rescue! • https://github.com/rlerdorf/php7dev/blob/master/README.md tl;dr 1. install virtualbox 2. install vagrant 3. git clone https://github.com/rlerdorf/php7dev.git 4. cd php7dev 5. vagrant up 6. vagrant ssh 7. sudo newphp 56 debug zts
  15. 15. How to Play along git clone https://github.com/auroraeosrose/php-extensions- code.git git clone git://github.com/auroraeosrose/php- extensions-code.git git checkout scaffolding bookmark lxr.php.net – you will be using it a lot phpize ./configure make make test
  16. 16. Let’s write an extension! But wait – there’s more….
  17. 17. 1. Set up compile environment 2. Write a module definition 3. Learn about the PHP lifecycle 4. Learn about zvals 5. Add functions 6. ??? 7. Profit! Every Other Extensions Talk
  18. 18. DOIN IT RONG
  19. 19. Which do YOU want?
  20. 20. 1. Do something you can’t do in userland 2. Utilize a C library 3. Make slow code faster Maybe you should just use ffi! Step 1. Why?
  21. 21. What is FFI? • Foreign function interface • Java calls it JNI • HHVM calls it HNI • Python calls it “ctypes” (do not ask, stupidest name ever) • C# calls it P/Invoke • Ruby calls it FFI • PHP calls it…
  22. 22. FFI
  23. 23. Oh wait… • php’s ffi is rather broken (last release is 2004-01-20) • php’s ffi has no maintainer (ilia and wez were doing it) • It needs some TLC • Are you interested and not afraid? See me!
  24. 24. 1. I hate parsing URIs 2. PHP’s parse_url is… not the best 3. How about an extension that wraps something that parses uris in an excellent fashion 4. RESEARCH TIME Step 2. What
  25. 25. Google says…
  26. 26. C library to the rescue! • uriparser.sourceforge.net • strictly RFC 3986 compliant • available on many systems as packages • cross platform • documented http://uriparser.sourceforge.net/doc/html/
  27. 27. 1. Think about what the API should be 2. Look at the C APIs but don’t mimic them 3. Write an example of how you WANT it to work 4. Write more then one example! 5. Turn these examples into your first tests 6. Yes this is TDD Step 3. How
  28. 28. 1. This is copy and paste 1. config.m4 & config.w32 2. macros for version api changes if necessary 3. main module file (php_{$ext}.c) 4. main header file (php_{$ext}.h) 2. Compile it and test! Step 6. Extension Scaffolding
  29. 29. Configure files
  30. 30. Module struct
  31. 31. Scaffolding rules 1. make sure you name your files in a standard way 2. document! use a license header, proto statements 3. read the coding standards http://lxr.php.net/xref/PHP_5_6/CODING_STANDA RDS 4. FOLLOW THE CODING STANDARDS 5. use version control early on – github is easy!
  32. 32. php –d extension=myext.so –m The scaffold extension should show up in the list Make sure to 1. define a version constant 2. read and use PHP code standards Check if it works
  33. 33. 1. run-test.php 2. make test will magically have output more at http://qa.php.net/write-test.php and docs at http://qa.php.net/phpt_details.php Step 7. Write the test
  34. 34. PHPT tests
  35. 35. Let’s take a break here for some semi-live demos…
  36. 36. Zval The guts behind PHP’s type system
  37. 37. Typing systems compared Static Typing (C) • Variables must be declared before use • Variables must be given a type at declaration • “compile time” checking Dynamic Typing (PHP) • Variables don’t have to be declared before use • Variables can change types • “run time” checking
  38. 38. zval
  39. 39. long any numeric double numeric with decimal char* + int (length) strings, binary Hashtable dictionaries, arrays,structs object any complicated type
  40. 40. How do I get C types from a ZVAL? Z_LVAL(zval) Z_LVAL_P(zval_p) Z_LVAL_PP(zval_pp) Z_BVAL(zval) Z_BVAL_P(zval_p) Z_BVAL_PP(zval_pp) Z_DVAL(zval) Z_DVAL_P(zval_p) Z_DVAL_PP(zval_pp) Z_STRVAL(zval) Z_STRVAL_P(zval_p) Z_STRVAL_PP(zval_pp) Z_STRLEN(zval) Z_STRLEN_P(zval_p) Z_STRLEN_PP(zval_pp) Z_ARRVAL(zval) Z_ARRVAL_P(zval_p) Z_ARRVAL_PP(zval_pp) Z_OBJVAL(zval) Z_OBJVAL_P(zval_p) Z_OBJVAL_PP(zval_pp) Z_OBJ_HANDLE(zv al) Z_OBJ_HANDLE_P(zval _p) Z_OBJ_HANDLE_PP(zval_ pp) Z_OBJ_HT(zval) Z_OBJ_HT_P(zval_p) Z_OBJ_HT_PP(zval_pp) Z_OBJCE(zval) Z_OBJCE_P(zval_p) Z_OBJCE_PP(zval_pp) Z_OBJPROP(zval) Z_OBJPROP_P(zval_p) Z_OBJPROP_PP(zval_pp) Z_TYPE(zval) Z_TYPE_P(zval_p) Z_TYPE_PP(zval_pp)
  41. 41. My extension does nothing! Back to our regularly schedule content
  42. 42. 1. tell it to link to our C library 2. add a function 3. learn how to get data 4. learn how to return data Step 8. Actually do something
  43. 43. I hate autotools… • Also known as the gnu build system • provider of much pain, but much good use as well • autoconf – generates a configure script (we cheat with phpize on shared extensions)  makes a configure we run to set up our information, mainly a config.h file • automake – creates makefiles • libtool – creates static and dynamic libraries • Windows? Well php wrote it’s own version of autotools – in jscript (windows javascript variant)
  44. 44. Anatomy of a Function
  45. 45. Wait – what was that? • Define your function in C  use a special call to parse parameters passed by the user  use a special zval to return data to the user • Tell PHP your extension provides this function  put it in your “giant struct of doom” that lists them all  send it to php when in your module struct • Tell PHP what arguments your extension provides  If your argument information and zpp argue users will be angry  Yes it sucks you can’t just do one 
  46. 46. php type code c type array or object a zval * boolean b zend_bool class C zend_class_entry * double d double callable f zend_fcall_info andzend_fcall_info_cache array or HASH_OF(object) H HashTable* array h HashTable* integer l long (NOT INT) integer L long with LONG_MAX, LONG_MIN limits object o zval * object of specific type O zval *, zend_class_entry string (no null bytes) p char*, int resource r zval * string (possible null bytes) s char*, int actual zval z zval * actual zval Z zval**
  47. 47. zend_parse_parameters type code variable args (any) * int, zval*** variable args (1 or more) + int, zval*** | anything after is optional, use defaults / use SEPARATE_ZVAL_IF_NOT_REF doesn’t apply to b, l, and d ! C NULL for zval null
  48. 48. return_value RETURN_RESOURCE(l) RETURN_BOOL(b) RETURN_NULL() RETURN_LONG(l) RETURN_DOUBLE(d) RETURN_STRING(s, duplicate) RETURN_STRINGL(s, l, duplicate) RETURN_EMPTY_STRING() RETURN_ZVAL(zv, copy, dtor) RETURN_FALSE RETURN_TRUE RETVAL_RESOURCE(l) RETVAL_BOOL(b) RETVAL_NULL() RETVAL_LONG(l) RETVAL_DOUBLE(d) RETVAL_STRING(s, duplicate) RETVAL_STRINGL(s, l, duplicate) RETVAL_EMPTY_STRING() RETVAL_ZVAL(zv, copy, dtor) RETVAL_FALSE RETVAL_TRUE
  49. 49. Complex Data array_init() add_(index|assoc)_long() add_(index|assoc)_bool() add_(index|assoc)_string() object_init() add_property_long() add_property_bool() add_property_string()
  50. 50. Now to visit the attach-library branch…
  51. 51. 1. namespaces 2. classes 3. methods 4. constants Step 9. Make it shiny
  52. 52. Classes 1. name, parent, and flags 2. hashtables of methods, default methods, static methods 3. hashtables of static properties, default properties, and properties 4. object handlers 5. union of either file information, or internal structures (for internal classes)
  53. 53. add-basic-class branch
  54. 54. Lifecycle Let’s take a moment to learn about how PHP works internally
  55. 55. Lifecycle PHP stops MSHUTDOWN – for each extension RSHUTDOWN – for each request cleanup after test.php RINIT – for each request execute test.php MINIT – for each extension request/parse test.php PHP starts php test.php
  56. 56. Lifecycle Threaded PHP stops MSHUTDOWN – for each extension request index.php request foo.php RINIT – for each request • execute test.php RSHUTDOWN – for each request • cleanup after test.php RINIT – for each request • execute test.php RSHUTDOWN – for each request • cleanup after test.php MINIT – for each extension apache starts
  57. 57. Class Properties
  58. 58. add-class-properties branch
  59. 59. Class Constants
  60. 60. add-class-constants branch
  61. 61. My class does nothing! Methods are where it’s at
  62. 62. Class Methods
  63. 63. add-class-methods branch
  64. 64. Alter $this
  65. 65. manipulate this branch
  66. 66. Abstract, Interface, Trait Class Method ZEND_ACC_IMPLICIT_ABSTRACT_CLA SS ZEND_ACC_STATIC ZEND_ACC_EXPLICIT_ABSTRACT_CLA SS ZEND_ACC_ABSTRACT ZEND_ACC_FINAL_CLASS ZEND_ACC_FINAL ZEND_ACC_INTERFACE ZEND_ACC_PUBLIC ZEND_ACC_TRAIT ZEND_ACC_PROTECTED ZEND_ACC_PRIVATE ZEND_ACC_CTOR ZEND_ACC_DTOR ZEND_ACC_CLONE spl_ce_FilterIterator->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; PHP_ME(DateTime, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
  67. 67. 1. globals 2. memory management 3. custom objects 4. object handlers 5. thread safety Step 10: Advanced topics
  68. 68. 1. in your header – use ZEND_BEGIN|END_MODULE_GLOBALS 2. create the global access macro in your header (copy and paste) 3. ZEND_DECLARE_MODULE_GLOBALS in every file where you will use them 4. use the macro to access COUNTER_G(basic_counter_value)); } 5. Create ginit/gshutdown functions if your globals need initializing , etc Global Variables (threads = evil)
  69. 69. emalloc( ) • allocates the specified number of bytes safe_emalloc() • like emalloc but adds a special protection against overflows efree( ) • releases the specified block of memory back to the system estrdup( ) • allocate a buffer and copy the string into that buffer estrndup( ) • same as estrdup when you already know the length of the string ecalloc( ) • allocates the number of bytes and initializes them to zero erealloc( ) • resizes the specified block of memory https://wiki.php.net/internals/zend_mm
  70. 70. 1. clean up what you emalloc (C level destructor) 2. read wiki on how to make them extendable!
  71. 71. Object Handlers (black magic) https://wiki.php.net/internals/engine/objects
  72. 72. TSRM thread safe resource manager ZTS zend thread safety • tsrm_lsTSRMLS_C • void ***tsrm_lsTSRMLS_D • , tsrm_lsTSRMLS_CC • , void ***tsrm_lsTSRMLS_DC
  73. 73. 1. http://edit.php.net 2. http://svn.php.net/viewvc/phpdoc/en/trunk/reference/ 3. PhD is awesomesauce • http://doc.php.net/phd/ 4. email pecl-dev@lists.php.net 1. who you are 2. what you wrote (with links to your code!) 3. why you think it should be in pecl 5. poke me (or other devs) Document, PECL, release
  74. 74. Stuff I didn’t talk about 1. resources (use custom objects instead) 2. ini entries (just DON’T) 3. threading and parallel processing 4. engine hooking 5. streams and transports
  75. 75. PHP 7 is coming! gophp7-ext and php extension ecosystems
  76. 76. About Me  http://emsmith.net  auroraeosrose@gmail.com  twitter - @auroraeosrose  IRC – freenode – auroraeosrose  #phpmentoring  #gophp7-ext
  77. 77. Questions? HELP WITH DOCS! http://edit.php.net http://wiki.php.net/internals HELP WITH THE FUTURE http://gophp7.org/gophp7-ext

×