In your dealings with PHP, you may come to consider writing a PHP extension yourself. There are several reasons I can think of that motivate me to do so:
- to extend PHP functionality for some very particular usage (mathematics, statistics, geometric, etc).
- to have a higher performance and efficiency compared to a pure PHP implementation
- to leverage the swiftness obtained from programming in another previously grasped language (for me, C ).
When it comes to choosing a tool to build PHP extensions, we see two different approaches:
- Use more pro-PHP semantics, like Zephir.
- Use more pro-C/C semantics, like PHP-CPP, which will be addressed in this article.
For me, the main drive to select the second approach is simple: I started my programming hobby with C/C , so I still feel more comfortable writing those lower level modules in C/C . PHP-CPP’s official site gives a few other reasons to do so.
Key Takeaways
- PHP-CPP is a library for developing PHP extensions that allows C developers to write PHP extensions without the complexities of working directly with the Zend API. It is written in C 11 and offers a collection of well-documented and user-friendly classes.
- PHP-CPP is evolving rapidly and it is recommended to use git to clone the repository for the latest updates. It supports single-threaded PHP installations and requires an upgrade to the g compiler to version 4.8.x or above for compatibility.
- PHP-CPP provides a skeleton extension project, which includes a main.cpp file, a MAKE file for compiling the extension, and an .ini file for extension loading. The skeleton project can be customized to suit individual needs and compiled and installed with the ‘make && sudo make install’ command.
- PHP-CPP supports four types of function signatures to be called from PHP and allows parameters to be passed by value in an array form. It also allows for function export/registration, specification of function parameter types, and the creation of object-oriented extensions.
Installation and configuration
PHP-CPP is evolving rapidly. At the time of this article’s writing, it is in version 0.9.1 (with 0.9.0 released about 2 days before). According to its documentation, “this is a feature-freeze release that prepares for the upcoming v1.0 version”, so we are confident we’ll see its 1.0 major release very soon.
It is thus recommended, at least during this interim period, to use git to clone the repository and get the latest update later via git pull.
NOTE: The PHP-CPP documentation on installation states that for the time being, it “only supports single-threaded PHP installations” because “internally the Zend engine uses a very odd system to ensure thread safety”. Future releases may support multi-threaded PHP installations but let’s just keep this in mind for now and stick to its current limitation. Luckily, “single-threaded PHP installations” should be the case for most of the PHP installations out there.
PHP-CPP is written in C 11. Thus, the older version of g installed in my Ubuntu 12.04 LTS does not support it. We need to upgrade our g compiler to version 4.8.x above. There is an article detailing the steps to do the upgrading. Please follow the instructions listed there.
Also, PHP-CPP compilation will use the php.h header file. This file is normally missing in an Ubuntu box, unless php-dev was installed. We can install PHP5 related development files by issuing this command:
<span>sudo apt-get install php5-dev</span>
After upgrading g and installing the necessary header files, we can issue the following command to compile and install the PHP-CPP library file (libphpcpp.so):
<span>make && sudo make install</span>
The compilation will be quite fast. After the installation, the libphpcpp.so file will be copied over to /usr/lib, and all PHP-CPP header files will be copied to /usr/include and /usr/include/phpcpp folders.
The installation of PHP-CPP lib is now complete. It is quite straightforward and we can now move on to the programming part.
Before we do that, we’ll discuss a few important concepts and terminologies used in PHP-CPP. The full documentation can be found on its official site, and everyone is encouraged to read through it BEFORE doing any real programming.
Skeleton (empty) extension project files
PHP-CPP provides a skeleton extension project, containing the following 3 files:
- main.cpp: the main cpp file containing a get_module function (will be discussed in more detail later)
- Makefile: the sample MAKE file to compile the extension
- yourextension.ini: contains just one line for extension loading
Makefile
If you are familiar with *nix development, you are familiar with this Makefile. Some slight changes shall be made to customize this file to fit our needs:
- Change NAME = yourextension to a more meaningful one, like NAME = skeleton.
- Change INI_DIR = /etc/php5/conf.d to match your system’s configuration. In my case, it is INI_DIR = /etc/php5/cli/conf.d. I modified the INI path to enable the extension for PHP’s cli environment first.
These are all the changes I have made. The rest of the Makefile can be kept as it is.
yourextension.ini
I renamed this file to skeleton.ini and changed the only line in that file like this:
<span>sudo apt-get install php5-dev</span>
main.cpp
In the empty project provided by PHP-CPP, this file contains only one function: get_module(), which is excerpted below:
<span>make && sudo make install</span>
For now, let’s just change this line to match the extension name we intend to create:
<span>extension=skeleton.so</span>
get_module() is called by PHP when the latter tries to load a required library. It is considered the entry point for a lib. It is declared using the extern "C" modifier to comply with PHP lib requirement for the get_module() function. It also uses a macro PHPCPP_EXPORT which makes sure that get_module() is publicly exported, and thus callable by PHP.
So far, we have made some changes to the empty project to suit our needs. We can now compile and install this project and install the extension:
<span><span>#include <phpcpp.h></phpcpp.h></span> </span> <span>/** </span><span> * tell the compiler that the get_module is a pure C function </span><span> */ </span><span>extern "C" { </span> <span>/** </span><span> * Function that is called by PHP right after the PHP process </span><span> * has started, and that returns an address of an internal PHP </span><span> * strucure with all the details and features of your extension </span><span> * </span><span> * @return void* a pointer to an address that is understood by PHP </span><span> */ </span> PHPCPP_EXPORT <span>void *get_module() </span> <span>{ </span> <span>// static(!) Php::Extension object that should stay in memory </span> <span>// for the entire duration of the process (that's why it's static) </span> <span>static Php::Extension extension("yourextension", "1.0"); </span> <span>// @todo add your own functions, classes, namespaces to the extension </span> <span>// return the extension </span> <span>return extension; </span> <span>} </span><span>} </span>
Next, we need to copy the required files into the appropriate folders:
<span>static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change the version number to 0.0.1</span>
We just need to make sure that the skeleton.so lib is copied to the right location of PHP extensions (in my Ubuntu setup, it should be /usr/lib/php5/20121212 as shown above).
We can then verify the extension is loaded in CLI by php -i | grep skeleton, and the terminal shall display something like this:
(Recall that the skeleton.ini is the file we modified above, which contains the extension=skeleton.so line.)
We have so far compiled and installed our first PHP extension using PHP-CPP. Of course, this extension does nothing yet. We will now create our first few functions to further understand the process of building PHP extensions.
“Hello, Taylor” function
The first function we create will be a slightly modified version of “Hello, World”. Let’s see the full code of main.cpp first:
<span>make && sudo make install</span>
According to the PHP-CPP documentation on “Register native functions“, it supports four types of function signatures to be called from PHP:
<span>cp -f skeleton.so /usr/lib/php5/20121212 </span><span>cp -f skeleton.ini /etc/php5/cli/conf.d</span>
In this case, I am using the second signature and the parameters are passed by value in an array form (PHP feature).
However, in helloWorld, we have specifically used C type std::string to grab the first parameter. We have also used C std lib to output a welcoming message.
In get_module() function, after declaring the extension variable, we add the function we would like to export (helloWorld()) and assign a name visible to the PHP script (helloWorld).
Now let’s compile and install the extension. If everything goes smoothly, the new skeleton.so file will be copied to the extension directory.
We can write a simple script to test the function just created:
<span><span>#include <phpcpp.h></phpcpp.h></span> </span><span><span>#include <iostream></iostream></span> </span> <span>void helloWorld (Php::Parameters ¶ms) </span><span>{ </span> std<span>::string name=params[0]; </span> std<span>::cout <span>} </span> <span>extern "C" { </span> PHPCPP_EXPORT <span>void *get_module() </span> <span>{ </span> <span>static Php::Extension extension("skeleton", "1.0"); </span> extension<span>.add("helloWorld", helloWorld); </span> <span>return extension; </span> <span>} </span><span>}</span></span>
Please take some time to look at the output:
We will come back to what we have observed here later.
Function parameters by reference
Next, we will see another function which passes parameters by reference, a swap() function. In this function, we will also try to specify the number of parameters and their type.
In main.cpp, we add one more function swap():
<span>sudo apt-get install php5-dev</span>
And also export the function by specifying the number of parameters and their type:
<span>make && sudo make install</span>
We explicitly say that:
- There will be two parameters (a and b);
- They should be passed by reference (instead of by value);
- They should be of type Numeric.
Let’s compile and install the updated extension again and write some code snippets to see how this new functions works:
<span>extension=skeleton.so</span>
swap($a) will fail. This is expected and unexpected. The expected part is that we need two parameters and only one is given. But, shouldn’t that error be captured by PHP when calling the function swap and prompting us something like Not enough parameters?
The first call (swap($a, $b)) shows the expected result: 20|10. The function swaps the two numbers passed in.
The second call is somehow unexpected: we have told PHP that we are to swap two numbers! But it just ignores the fact that the 2nd parameter passed is a string and does the swapping anyway!
Well, in a way, it is still expected. PHP does not really distinguish a number type and a string type. This behavior complies to the PHP standard. Also due to this behavior, we didn’t and can’t use C internal types for the temporary variable used in the function (temp) but used Php::Value as the variable type.
The third call will work. The first var_dump will show the DateTime object and the second will show the integer. This is somehow very much unexpected (at least to me). After all, an object is quite different from a number/string. But after considering that this “swap” behavior is also doable in PHP, it fits in with PHP’s oddities.
So, does it mean the “type” specification won’t have any impact? Not really. To further elaborate this, we create a third function:
<span><span>#include <phpcpp.h></phpcpp.h></span> </span> <span>/** </span><span> * tell the compiler that the get_module is a pure C function </span><span> */ </span><span>extern "C" { </span> <span>/** </span><span> * Function that is called by PHP right after the PHP process </span><span> * has started, and that returns an address of an internal PHP </span><span> * strucure with all the details and features of your extension </span><span> * </span><span> * @return void* a pointer to an address that is understood by PHP </span><span> */ </span> PHPCPP_EXPORT <span>void *get_module() </span> <span>{ </span> <span>// static(!) Php::Extension object that should stay in memory </span> <span>// for the entire duration of the process (that's why it's static) </span> <span>static Php::Extension extension("yourextension", "1.0"); </span> <span>// @todo add your own functions, classes, namespaces to the extension </span> <span>// return the extension </span> <span>return extension; </span> <span>} </span><span>} </span>
And we register this function like this:
<span>static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change the version number to 0.0.1</span>
The testing code will be like this:
<span>make && sudo make install</span>
The first call to swapObject() will work as we passed in the correct class type (sampleClass). The second will fail, displaying “PHP Catchable fatal error: Argument 1 passed to swapObject() must be an instance of sampleClass, instance of anotherClass given...“.
The above code segment illustrates one important aspect on type restriction: scalar types declaration is not really implemented. PHP and thus PHP-CPP only enforce object-type declaration. Also, the number of parameters is not really enforced on the PHP side.
Conclusion
In this article, we illustrated the steps to prepare PHP-CPP to work for our PHP environment. We also discussed some basic steps to create a PHP extension using PHP-CPP (and C semantics).
We covered the extension project files, function signatures, function export/registration, and the function parameter types.
In our next article, we will further elaborate a few key features in PHP-CPP and provide a real-world use case demonstrating the usage of C class and namespace implementations using PHP-CPP.
Frequently Asked Questions (FAQs) on PHP Extension Development
What is PHP-CPP and how does it differ from PHP?
PHP-CPP is a library for developing PHP extensions. It offers a collection of well-documented and user-friendly classes, allowing C developers to write PHP extensions without the complexities of working directly with the Zend API. Unlike PHP, which is an interpreted language, PHP-CPP allows you to write code in C , a compiled language. This can result in performance improvements, as compiled code generally runs faster than interpreted code.
How do I install PHP-CPP on my system?
To install PHP-CPP on your system, you need to clone the PHP-CPP repository from GitHub. After cloning, navigate to the directory and execute the ‘make’ command. Once the build process is complete, install the library using the ‘make install’ command. Remember, you need to have root privileges to install the library.
How do I create a basic PHP extension using PHP-CPP?
Creating a PHP extension using PHP-CPP involves several steps. First, you need to create a directory for your extension and navigate into it. Then, create a ‘Makefile’ and a C source file for your extension. The ‘Makefile’ will contain instructions for building your extension, while the C source file will contain the actual code for your extension. After writing your code, you can build your extension using the ‘make’ command.
How can I debug my PHP extension?
Debugging a PHP extension can be a bit tricky, as you’re dealing with a compiled language. However, you can use tools like GDB (GNU Debugger) to debug your extension. GDB allows you to set breakpoints, step through your code, and inspect variables, which can be very helpful when trying to track down bugs.
Can I use PHP-CPP to create extensions for PHP 7?
Yes, PHP-CPP is compatible with PHP 7. However, you need to make sure that you’re using the latest version of PHP-CPP, as earlier versions may not support PHP 7.
How can I handle exceptions in PHP-CPP?
PHP-CPP provides a class called Php::Exception, which you can use to throw exceptions from your C code. These exceptions can then be caught and handled in your PHP code, just like any other PHP exception.
Can I use PHP-CPP to create object-oriented extensions?
Yes, PHP-CPP supports object-oriented programming. You can define classes in your C code, and these classes can then be used in your PHP code. This allows you to write clean, modular code that’s easy to maintain.
How can I call PHP functions from my C code?
PHP-CPP provides a class called Php::Call, which you can use to call PHP functions from your C code. This allows you to leverage the power of PHP’s built-in functions in your extension.
Can I use PHP-CPP to create extensions that interact with databases?
Yes, you can use PHP-CPP to create extensions that interact with databases. However, you’ll need to use a C database library, as PHP-CPP does not provide any built-in database functionality.
How can I distribute my PHP extension?
Once you’ve built your PHP extension, you can distribute it by packaging it as a PECL package. PECL is a repository for PHP extensions, and it provides a standard way to distribute and install extensions.
The above is the detailed content of Getting Started with PHP Extension Development via PHP-CPP. For more information, please follow other related articles on the PHP Chinese website!

In PHP, you can use session_status() or session_id() to check whether the session has started. 1) Use the session_status() function. If PHP_SESSION_ACTIVE is returned, the session has been started. 2) Use the session_id() function, if a non-empty string is returned, the session has been started. Both methods can effectively check the session state, and choosing which method to use depends on the PHP version and personal preferences.

Sessionsarevitalinwebapplications,especiallyfore-commerceplatforms.Theymaintainuserdataacrossrequests,crucialforshoppingcarts,authentication,andpersonalization.InFlask,sessionscanbeimplementedusingsimplecodetomanageuserloginsanddatapersistence.

Managing concurrent session access in PHP can be done by the following methods: 1. Use the database to store session data, 2. Use Redis or Memcached, 3. Implement a session locking strategy. These methods help ensure data consistency and improve concurrency performance.

PHPsessionshaveseverallimitations:1)Storageconstraintscanleadtoperformanceissues;2)Securityvulnerabilitieslikesessionfixationattacksexist;3)Scalabilityischallengingduetoserver-specificstorage;4)Sessionexpirationmanagementcanbeproblematic;5)Datapersis

Load balancing affects session management, but can be resolved with session replication, session stickiness, and centralized session storage. 1. Session Replication Copy session data between servers. 2. Session stickiness directs user requests to the same server. 3. Centralized session storage uses independent servers such as Redis to store session data to ensure data sharing.

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

Alternatives to PHP sessions include Cookies, Token-based Authentication, Database-based Sessions, and Redis/Memcached. 1.Cookies manage sessions by storing data on the client, which is simple but low in security. 2.Token-based Authentication uses tokens to verify users, which is highly secure but requires additional logic. 3.Database-basedSessions stores data in the database, which has good scalability but may affect performance. 4. Redis/Memcached uses distributed cache to improve performance and scalability, but requires additional matching

Sessionhijacking refers to an attacker impersonating a user by obtaining the user's sessionID. Prevention methods include: 1) encrypting communication using HTTPS; 2) verifying the source of the sessionID; 3) using a secure sessionID generation algorithm; 4) regularly updating the sessionID.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 Linux new version
SublimeText3 Linux latest version

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

Zend Studio 13.0.1
Powerful PHP integrated development environment
