37

I know you can technically make PHP extension just by making a PHP file and using require_once.

But would it optimize the performance if you wrote an extension in C or C++.

If so, how would you make a "hello-world" for that?

Connor Pearson
  • 63,902
  • 28
  • 145
  • 142
Mark Lalor
  • 7,820
  • 18
  • 67
  • 106
  • 3
    Writing extensions in C or C++ for performance reasons is a losing game. You're trading a negligible gain in performance for a huge penalty in maintainability. PHP is fast enough for 99.999% of web-related use cases. Yes, some sites do this because they have absolutely absurd amounts of traffic. Those are outliers, they are not in any way representative of the average PHP site's traffic. – user229044 Sep 24 '18 at 12:57
  • 2
    The above comment that "writing PHP extensions in C for performance reasons is a losing game" is simply untrue. Everything in ext/standard (e.g. strpos(), substr(), fopen()) is written in C because doing the same things in userland would be painfully slow and/or impossible. C is a system language. PHP extensions link userland to the system in a performant, cross-platform manner. There are plenty of things currently done in PHP userland that should be done via extensions - the existence of PECL (pecl.php.net) is proof positive of this fact. – CubicleSoft Oct 23 '22 at 12:11
  • 1
    Since this post is still a highly ranked result for Google search but is inexplicably closed to new answers, anyone stumbling on this in 2022+ will need this comment. Go download the PHP source code, extract it. Locate `ext/standard`. Start opening .c files as you write your PHP userland software and read the code for a while until you are comfortable with how userland works with extensions. Visit pecl.php.net and download the source code to a few extensions that implement functions/classes the way you'd like to emulate for your extension and read the source code for those. – CubicleSoft Oct 23 '22 at 12:20
  • (continuing) Once you are comfortable with how PHP and PECL do things behind the scenes, then you are ready to start [writing your first PHP extension](https://www.zend.com/resources/writing-php-extensions). While you _can_ develop PHP extensions on Windows, Linux is both the natural environment for developing/testing language extensions and the most likely deployment environment. Porting an extension to Windows and multiple versions of PHP is a highly recommended step as you get closer to the end of the dev/test cycle. Especially if you plan to publish to PECL. – CubicleSoft Oct 23 '22 at 12:37
  • (continuing) The decision to write an extension should not be undertaken lightly. C can easily do things like accidentally introduce buffer overflows that can be exploited. That is dangerous given that PHP tends to run facing the Internet (great power = greater responsibility). However, the reasons to write an extension are varied and vast: Expose an existing C/C++ library to PHP userland (e.g. zlib, OpenSSL), make system calls (e.g. POSIX, Windows APIs), modify the core engine (e.g. XDebug), directly access low level hardware (e.g. OpenGL), faster performance (e.g. BCMath), and much more. – CubicleSoft Oct 23 '22 at 13:02

4 Answers4

61

I know you can technically make PHP extension just by making a PHP file and using require_once.

The base of this functionality is the include statement, which includes and evaluates the specified file. Extension isn't the right term, because you are just including another PHP script file. A PHP extensions provides additional functions to the language in form of a compiled module.

But would it optimize the performance, if you wrote an extension in C or C++.

Yes, it optimizes the performance. That's why PHP extensions like CPhalcon or YAF were written.

How to make a "Hello World" PHP Extension?

I will describe how you can build a "Hello World" PHP extension in five steps.

A Debian based OS is required, because we need to fetch some tools and dependencies with apt-get.

Step 1 - Setup Build Environment / Requirements

A PHP Extension is compiled C code. We need a shell (should already be installed), an editor (your choice), a compiler (here we'll use GCC), PHP itself and PHP development dependencies for the build.

sudo apt-get install build-essential php7.0 php7.0-dev

Step 2 - Config

We need to describe our extension and the files forming it in a basic configuration file:

File: config.m4

PHP_ARG_ENABLE(php_helloworld, Whether to enable the HelloWorldPHP extension, [ --enable-helloworld-php Enable HelloWorldPHP])

if test "$PHP_HELLOWORLD" != "no"; then
    PHP_NEW_EXTENSION(php_helloworld, php_helloworld.c, $ext_shared)
fi

As you can see, the NEW_EXTENSION contains a C file: php_helloworld.c.

Step 3 - Code

Let's create the C code for our extension.

Firstly, we create a header file:

php_helloworld.h

// we define Module constants
#define PHP_HELLOWORLD_EXTNAME "php_helloworld"
#define PHP_HELLOWORLD_VERSION "0.0.1"

// then we declare the function to be exported
PHP_FUNCTION(helloworld_php);

Secondly, we create the source file:

php_helloworld.c

// include the PHP API itself
#include <php.h>
// then include the header of your extension
#include "php_helloworld.h"

// register our function to the PHP API 
// so that PHP knows, which functions are in this module
zend_function_entry helloworld_php_functions[] = {
    PHP_FE(helloworld_php, NULL)
    {NULL, NULL, NULL}
};

// some pieces of information about our module
zend_module_entry helloworld_php_module_entry = {
    STANDARD_MODULE_HEADER,
    PHP_HELLOWORLD_EXTNAME,
    helloworld_php_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    PHP_HELLOWORLD_VERSION,
    STANDARD_MODULE_PROPERTIES
};

// use a macro to output additional C code, to make ext dynamically loadable
ZEND_GET_MODULE(helloworld_php)

// Finally, we implement our "Hello World" function
// this function will be made available to PHP
// and prints to PHP stdout using printf
PHP_FUNCTION(helloworld_php) {
    php_printf("Hello World! (from our extension)\n");
}

Step 4 - Build

Now, we are ready to build the extension.

First we prepare the build environment for a PHP extension:

phpize

Then we configure the build and enable our extension:

./configure --enable-php-helloworld

Finally, we can build it:

make
sudo make install

Step 5 - Test

To test our PHP extension, lets load the helloworld_php.so extension file and execute our function helloworld_php():

php -d extension=php_helloworld.so -r 'helloworld_php();'

Done :)


Building on Windows

If you try to build an Windows (YIKES!), then you need to adjust the steps a bit:

Step 2 - Config

File: config.w32

ARG_ENABLE("helloworld", "helloworld support", "yes");

if (PHP_HELLOWORLD == "yes") {
    EXTENSION("helloworld", "php_helloworld.c");
}

Step 4 - Build

Use nmake instead of make.


List of helpful resources:

Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
  • 1
    How do I write a `C++` extension? I've been searching all over the web and couldn't find anything but obsolete tutorials. Could you possibly extend your answer to include a C++ example or provide some good links to turorials or modern examples? – razz Mar 16 '16 at 16:07
  • 1
    Well, C and C++ are not the same. I would suggest to use a wrapper library like PHP-CPP, see http://www.php-cpp.com/documentation/your-first-extension for basic start. You may find a tutorial for this lib over here: http://www.sitepoint.com/developing-php-extensions-c-php-cpp-advanced/ – Jens A. Koch Mar 16 '16 at 17:49
  • `make` throws `php_helloworld.c:28:17: error: 'helloworld_php_module_entry' undeclared (first use in this function)` – Jeff Puckett Aug 01 '17 at 03:10
  • should be `zend_module_entry helloworld_php_module_entry` instead of `zend_module_entry hello_php_module_entry` – Jeff Puckett Aug 01 '17 at 03:23
  • also `php -d extension=php_helloworld.so -r 'helloworld_php();'` instead of `php -d extension=helloworld_php.so -r 'helloworld_php();'` – Jeff Puckett Aug 01 '17 at 03:24
  • This is the most appropriate answer – JSON Aug 27 '18 at 18:50
  • If you cannot find the php7.2-dev package, you need to add the ppa:ondrej/php repository: `sudo add-apt-repository ppa:ondrej/php -y && sudo apt-get update && sudo apt-get install php7.2-dev` – Stuart Welch Jan 12 '21 at 16:15
  • for apache2 php and ubuntu create an ini file with ```extension=php_helloworld.so``` and copy the file at ```dpkg -L libapache2-mod-php | grep mods-available``` and run ```phpenmod php_helloworld``` – Sam Jan 05 '23 at 07:38
34

Software written in C/C++ certainly does run faster than code in PHP. And you can write an extension in C/C++ and link it into PHP. The PHP manual covers this here: http://php.net/manual/en/internals2.php

The other answers give links to other tutorials for writing PHP extensions, and you can google for "PHP extension tutorial" to find more.

But whether this is the right thing to do in your app is another story. Most experts agree that PHP runs just fine, fast enough for 98% of applications. The instances where PHP isn't fast enough are not in general due to the language, but an inefficient application architecture that the programmer has created. That's a weakness that can't be remedied by rewriting parts of your app in C/C++.

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
8

Here's a tutorial on PHP extensions. Whether it will optimize the performance or not, it depends on what you are trying to wrap on your extension. But I would not write a PHP extension just for optimization purposes. I would write one if I have no choice. I.E. Wrapping a common C library to make it available directly in PHP...

Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
-11

i think (but no sure) you can do that by make an dll file and put it in ext folder which exist with php installation files.if my previous words is correct you can do that (dll) file in visual studio

khalid J-A
  • 574
  • 1
  • 7
  • 19