Slide 1

Slide 1 text

Getting Started with PHP Extensions

Slide 2

Slide 2 text

Lochemem Bruno Michael ● PHP enthusiast from Kampala, Uganda ● Functional Programming aficionado ● Graduated college in 2019 ● Maintains PHP userland packages and extensions ● Loves ReactPHP ● Authored a book ● Loves hoops, music, movies, podcasts, and video games

Slide 3

Slide 3 text

So, PHP extensions? ● Written mainly in C/C++ ● Infuse the PHP userland with ad-hoc functionality ● Require interaction with a low-level PHP engine API

Slide 4

Slide 4 text

Why even bother? ● Extensions are typically faster than their PHP equivalents ○ Primarily because they are written in C/C++ ● Extensions allow for infusion of performant ad-hoc solutions ○ Addition of features otherwise not present in PHP userland (ext-uv, ext-apcu) ○ Either unique projects or wrappers around other C/C++ packages ● Extension-building likely results in a better understanding of PHP internals ○ Engaging endeavor likely to test your patience and skill

Slide 5

Slide 5 text

Pump the brakes! You have to get familiar with PHP’s lifecycle

Slide 6

Slide 6 text

PHP Lifecycle 1. MINIT (Module Initialization) 2. RINIT (Request Initialization) 3. RSHUTDOWN (Request Shutdown) 4. MSHUTDOWN (Module shutdown) MINIT RINIT MSHUTDOWN RSHUTDOWN

Slide 7

Slide 7 text

Traditionally...

Slide 8

Slide 8 text

Anatomy of an extension ● tests -> *.phpt ○ for module test files ● config.m4/config.w32 ○ for platform-specific configuration options ● ext.cpp|.c/[name].cpp|.c ○ arbitrarily named extension file ● php_ext.h/php_[name].h ○ primary extension header file

Slide 9

Slide 9 text

php_trie ● Trie data structures for PHP ● Built in C++

Slide 10

Slide 10 text

So, tries huh?

Slide 11

Slide 11 text

What about tries? ● Potent tree structures for storing string data ● Persistent data structures ● Designed for fast traversal and string searches ● Empty root node with multiple child nodes ● Useful as dictionaries and associative maps ● Somewhat space inefficient

Slide 12

Slide 12 text

The first thing to do is set things up.

Slide 13

Slide 13 text

● Comments ● Configuration option definitions ● Build specifics Configuring the extension (for POSIX systems)

Slide 14

Slide 14 text

● Comments ● Configuration option definitions ● Build specifics Configuring the extension (for Windows systems)

Slide 15

Slide 15 text

Onto the primary extension header file...

Slide 16

Slide 16 text

Salient elements ● Extension info (name, version) ● PHP-engine header file inclusions ● Module definition ● Other discretionary constants

Slide 17

Slide 17 text

How about the primary extension file?

Slide 18

Slide 18 text

● PHP userland-bound artifacts ● PHP lifecycle handlers php_trie.cpp’s features

Slide 19

Slide 19 text

● Extension entry table ● Shared object loading routines php_trie.cpp’s features continued...

Slide 20

Slide 20 text

The next thing to do is implement the trie.

Slide 21

Slide 21 text

The scope of the implementation ● A single Trie class ● Public constructor ● Two additional methods - insert and search

Slide 22

Slide 22 text

● Linked list ● Stores string keys and values ● String values are appendable to the end of each final key node C++ trie object

Slide 23

Slide 23 text

● Creates a new trie entry ● Appends string to the end of a branch Insertion

Slide 24

Slide 24 text

● Performs trie traversal ● Outputs a matching value at the end of a branch search/lookup

Slide 25

Slide 25 text

Onto the PHP engine API side of things...

Slide 26

Slide 26 text

What to expect ● Macros, macros, and more macros ● Engine-specific functions ● Memory management ● PHP internals conventions

Slide 27

Slide 27 text

● Basis for the PHP userland object ● Contains C++ trie object PHP-C/C++ trie object

Slide 28

Slide 28 text

More PHP object-related stuff ● Object handlers ● Class registration ● The MINIT function

Slide 29

Slide 29 text

Things to be mindful of when writing functions ● PHP zvals ● Argument parsing ● Return values ● Memory management

Slide 30

Slide 30 text

● Zend value container ● PHP variables ● C union ● Has unique macros for multiple use-cases (ZVAL_P, Z_TYPE_P, Z_LVAL_P, etc...) zvals

Slide 31

Slide 31 text

● All manner of types (string, float, array, etc...) ● Arguments should be relevant to function Argument parsing

Slide 32

Slide 32 text

● PHP engine API return_value variable ● PHP engine API return macros ● Should translate to PHP userland types Return values

Slide 33

Slide 33 text

● Allocate something then free it ● Use PHP engine API helpers ● Guards against some nasty leaks and faults Memory management

Slide 34

Slide 34 text

● Create a trie ● Initializes the Trie object __construct

Slide 35

Slide 35 text

● Takes two arguments ● boolean to zend_bool return value conversion insert

Slide 36

Slide 36 text

● Takes one argument ● C++ string to C string conversion search

Slide 37

Slide 37 text

How about some tests?

Slide 38

Slide 38 text

The .phpt file ● De-facto engine test file format ● Sections vs succinct PHP method assertions (SKIPIF, EXPECT, FILE, etc...) ● Trigger tests by using the directive make test

Slide 39

Slide 39 text

All that’s left is to build and use the extension.

Slide 40

Slide 40 text

● Requires autoconf, make, gcc, and libtool ● Installs the extension in the PHP modules directory

Slide 41

Slide 41 text

Moving Forward... ● Take a look at the Internals book ● Contact someone knowledgeable ● Look at engine code ● Sharpen your C/C++ skills

Slide 42

Slide 42 text

Thanks.