Why would you want to do such a thing?
Perhaps you enjoy programming in C (or want a break from coding in PHP), yet you still want your end result to be usable in your PHP codebase.
Or, perhaps you're doing it for performance reasons.
Perhaps curiosity, or perhaps all of the above.
When I went to look this up on my own, I noticed that most the articles detailing this process were quite old (aimed at PHP 4 and 5), and following them verbatim did not work for various reasons.
I hope to save you (the reader) some time, by being able to go step by step and type along to get you started.
To begin with, get a copy of the latest PHP 7 source code from here:
After the download ends (you'll have to choose a mirror) you can then decompress the archive (if you intend to create a PHP extension, I hope you know how to do this…).
You're then going to cd into the extension directory, 'ext', and run the following command:
./ext_skel --extname=hello
You should see some output similar to the following:
Creating directory hello Creating basic files: config.m4 config.w32 .gitignore hello.c php_hello.h CREDITS EXPERIMENTAL tests/001.phpt hello.php [done]. To use your new extension, you will have to execute the following steps: 1. $ cd .. 2. $ vi ext/hello/config.m4 3. $ ./buildconf 4. $ ./configure --[with|enable]-hello 5. $ make 6. $ ./sapi/cli/php -f ext/hello/hello.php 7. $ vi ext/hello/hello.c 8. $ make Repeat steps 3-6 until you are satisfied with ext/hello/config.m4 and step 6 confirms that your module is compiled into PHP. Then, start writing code and repeat the last two steps as often as necessary.
What do you think you should do next?
If you guessed follow the instructions presented, you're (mostly) right!
So, some of the steps the skeleton program told us to do are not 100% correct, and I found the most direct route to get to the point of the extension working was as follows:
First off, open this file as indicated in your editor of choice, and make the following updates (customize it later as you need).
Uncomment lines 16 and 18, so your file has an uncommented section that looks like this (including line breaks at those spots):
PHP_ARG_ENABLE(hello, whether to enable hello support, # Make sure that the comment is aligned: [ --enable-hello Enable hello support])
Then go down to line 53 and uncomment the ACDEFINE (for this very basic example, it will work without the wrapper check around it) so that it looks like this:
AC_DEFINE(HAVE_HELLOLIB,1,[ ])
Lastly, save and quit the file.
So, one thing that the instructions above mentioned were to run buildconf and configure up at the top level (as well as make).
That is going to build the entire PHP 7 distro from source.
I'm assuming most readers already have a PHP 7 distro set up that can load extension.so files, so this is a bit overkill for creating a simple Hello World extension.
So, ignore the advice given from the extskel command, and instead make sure you're in the ext/hello directory, and run the following:
phpize
This will set up the configure scripts directly in this directory, based on what was read from the config.m4 file.
Next up, run:
./configure --enable-hello
You should see it produced Makefiles.
Now, open up your hello.c file, and lets add another custom function (in addition to the one that confirms the extension built successfully).
Jump down to line 74 and add the following:
/* {{{ proto string hello_world(string arg) Say Hello World to everyone */ PHP_FUNCTION(hello_world) { RETURN_STRING("Hello world"); } /* }}} */
The weird comments have to do with code folding in emacs/vim and is recommended within the PHP extension files as a best practice (so I suggest leaving it there if I were you).
Now jump down to line 155 and update it to look like this (it's just adding one line actually):
const zend_function_entry hello_functions[] = { PHP_FE(confirm_hello_compiled, NULL) /* For testing, remove later. */ PHP_FE(hello_world, NULL) PHP_FE_END /* Must be the last line in hello_functions[] */ };
This registers our new 'helloworld' function.
Save and exit your hello.c file and type the standard:
make
At this point, you should now see a file in modules/hello.so if everything went as planned.
Now, copy or symlink this hello.so module into your system specific modules directory (I use Arch Linux, and it is located at /usr/lib/php/modules for me).
After this is done, if you type:
php -i | grep hello
You should see your module is loaded in the ini output.
There is a script in the ext/hello directory which will print out all your extension's defined functions, so give it a go with:
php hello.php
You should see some output that indicates a success.
You can also directly test your new call via:
php -r 'echo hello_world();'