1 of 12

PHP Extensions - dark magic in C

8 June, 2018

Travis Stockwell

travis.stockwell@gmail.com

2 of 12

Things you need to know about me . . .

  • I’m old.
  • I like hard problems
  • I cause my own problems
  • “Fast” is the penultimate virtue

3 of 12

Objective

Understand the reason(s) for writing an extension (the virtues and the vices), the basic framework to get started.

4 of 12

Resource(s)

Sara Goleman is the monarch of PHP extensions.

Read Embedding & Extending PHP, even though it’s for PHP5.

5 of 12

Motives

  1. There is some library or OS specific call which cannot be made from PHP directly because of the degree of abstraction inherent in the language.
  2. You want to make PHP itself behave in some unusual way.
  3. You’ve already got some PHP code written, but you know it could be faster, smaller, and consume less memory while running.
  4. You have a particularly clever bit of code you want to sell, and it’s important that the party you sell it to be able to execute it, but not view the source.

6 of 12

PHP internals

7 of 12

Lifecycles

There are two groups of initialization and shutdown:

  • Module level (MINIT/MSHUTDOWN).
  • Request level (RINIT/RSHUTDOWN).

8 of 12

Memory allocation

Traditional

Non-Persistent

Persistent

malloc() / calloc()

emalloc() / ecalloc()

pemalloc() / pecalloc()

strdup() / strndup()

estrdup() / estrndup()

pestrdup() / pestrndup()

free()

efree()

pefree()

realloc()

erealloc()

perealloc()

9 of 12

You’ll need some stuff . . .

  • Compiler: gcc and clang are both excellent choices.
  • Build tools: autoconf, automake, libtool
  • (Optional) parser generators: re2c and bison
  • PHP 7.x with development headers:
    • Either distro packages such as: php7 and php7-devel
    • PHP compiled from source and installed with sudo make install. If compiling from source, then the --enable-debug switch is recommended, as well as the optional re2c and bison packages.

10 of 12

Grab an existing extension and hack

  • cd hello-php-extension
  • phpize
  • ./configure
  • make
  • php -d extension=modules/hello.so --re hello # test
  • # add “extension=hello.so” to /etc/php.d/hello.ini, or the like

11 of 12

Let’s write some code

  • Basic function call: “hello_world()”
  • Function call with a parameter that returns a ‘long’: long fibonacci(long)
  • Function that returns an array: array fibonacci(long)
  • Functions that use persistent data: start_fibonacci(long,long), long next_fibonacci()

12 of 12

Exercises for the student

  • Return a class with members (easy).
  • Return and accept a C pointer as a zval resource (not easy).
  • Hook up your C-pointer/zval to the garbage collector (hard).
  • Try embedding php into your application (harder).
  • Try embedding php into your application as a dynamic library (very hard).