search
HomeBackend DevelopmentPHP TutorialDeveloping PHP Extensions with C and PHP-CPP: Advanced

Develop PHP extensions with C and PHP-CPP: Advanced Topics and Best Practices

Key Points

  • Developing PHP extensions with C and PHP-CPP involves advanced topics such as returning "this" pointers, returning complex object pointers, exposing magic methods, linking member function calls, and exception throwing and handling in PHP. __toString
  • PHP-CPP library is ideal for projects that require software, data structures or algorithms for non-PHP projects in the future, or projects that require using tools or libraries not yet provided as PHP extensions. It also provides the performance advantages of C/C code while maintaining structured, object-oriented code for easy understanding and maintenance.
  • PHP-CPP library can be used for personal and commercial projects. However, while the library itself is free, it may take time and resources to learn how to use it effectively and maintain PHP extensions.
  • Common challenges in PHP extension development using C include the correct management of memory, handling of errors and exceptions, and the interface between PHP and C. These challenges can be overcome by gaining insight into PHP and C, using good programming practices, and leveraging the features and tools provided by PHP-CPP.
In my previous post, I introduced the PHP-CPP library that uses C (first and second posts) to create PHP extensions. In the latter post, I demonstrate the object-oriented aspect of writing PHP extensions using Complex class for plural operations.

Developing PHP Extensions with C   and PHP-CPP: Advanced

This introduction is not complete, because the main focus of the article is more on demonstrating the object-oriented capabilities of PHP-CPP than on the details of the object-oriented implementation.

In this article, we will further dive into the development of the Complex library, add more member functions, and address some advanced topics in writing object-oriented PHP extensions using PHP-CPP:

    Return this pointer;
  • Returns the Complex object pointer, i.e. Complex *;
  • Open
  • Magic method; __toString
  • Chain member function call;
  • Top the exception and handle it in PHP
The complete Complex library source code and test PHP scripts are located in this Github repository.

Let's get started.

Preparation

The entire process of preparing the environment is explained in the first article.

Return this pointer in C

As mentioned in the second article, we use member functions to perform various mathematical operations on complex numbers. In this demonstration, we will implement four such functions: add, sub, mul, and div. I will explain the first three first. The div function involves exception handling, which will be discussed later.

Let's take a look at the mul function (for multiplication). The add and sub functions are roughly the same.

Php::Value add(Php::Parameters &params) {
    Php::Value t = params[0];
    Complex *a = (Complex *) t.implementation();

    r += (double) a->getReal();
    i += (double) a->getImage();

    return this;
}
Note: In this article, I will not introduce some basic topics discussed before, such as modifying Makefile and ini files, registering member functions, classes and namespaces, etc. Please refer to the previous section for these contents.

Returning this pointer from C to PHP is simple. Inside this C function, this pointer (as Complex* type) can be returned to PHP as Php::Value type. The conversion does not lose any object information. It also does not require explicit type conversion.

Return Complex object pointer

Returning this usually means that the object itself has changed. But in some cases we might want to return a new object and leave the "current" object (call object) unchanged.

In our Complex class, we have a function like this that returns the conjugate number of a given complex number (a bi becomes a-bi).

Php::Value add(Php::Parameters &params) {
    Php::Value t = params[0];
    Complex *a = (Complex *) t.implementation();

    r += (double) a->getReal();
    i += (double) a->getImage();

    return this;
}

The key point here is that we have to use Php::Object to explicitly convert our Complex* object to Php::Object, so when the object is later parsed by the PHP script, the class information is properly ensured and kept Its accessibility.

The first parameter of this function is the class type, in this case trComplex. I'm using this name because I've wrapped this class ("Complex") into a separate namespace ("tr").

The second parameter is the object to be passed back.

Returning a new class instance is a bit trickier than just returning this pointer, but it is still manageable as long as you read the documentation and find the correct part. For more usage examples, you may want to read this section in the official PHP-CPP documentation.

Open __toString magic method

In our class, there is a __toString function that prints plural numbers in a more readable way, for example: 1 2i. In my previous post, this function is not exposed (or "registered" in PHP-CPP terminology), but it can still be called from inside PHP. However, in order for this function to be called on the Complex object after we apply some mathematical operations (e.g. "echo $a->add($b)->sub($c)"), we need to be compiled It is explicitly registered in the extension:

Php::Value conjugate() {
    Complex *t = new Complex();

    t->r = r;
    t->i = -i;

    return Php::Object("tr\Complex", t);
}

The issue we submitted in the PHP-CPP repository Issue #150 discusses in detail why we have to do this.

Chain member function call

One thing that must be implemented in this class is to be able to link member functions so that we can do the following calculation: $a->add($b)->sub($c). The result should still be able to call its member functions.

This is done by the above method, that is, returning this pointer to PHP. However, older PHP-CPP libraries have errors when dereferenced objects, and if the link method is called, a "segment fault" is created.

The issue was submitted (#151) and a commit containing the PHP-CPP source code patch was submitted. If you are using an older version of the PHP-CPP library to compile the PHP-CPP library and your own library, please update the PHP source code and recompile and reinstall the PHP-CPP library and your library.

As explained in the submission summary:

complex.method("__toString", &Complex::__toString);

I'm glad my own project work can help the libraries I use become better.

Exception throwing and handling in PHP

Two more functions in our Complex class may throw exceptions back to PHP for processing: div and phi. The former performs division operation, while the latter returns the angle of the complex number, as shown in its alternative representation, polar coordinate representation (r, θ).

If you pass a plural number as a parameter (or caller), but the part and imaginary parts are actually 0, both operations may fail. For these two operations, we need to perform exception handling. Remember that we are throwing exceptions in C code, and the PHP script will catch the exception and do the necessary processing:

Php::Value add(Php::Parameters &params) {
    Php::Value t = params[0];
    Complex *a = (Complex *) t.implementation();

    r += (double) a->getReal();
    i += (double) a->getImage();

    return this;
}

In PHP scripts, we catch this exception like this:

Php::Value conjugate() {
    Complex *t = new Complex();

    t->r = r;
    t->i = -i;

    return Php::Object("tr\Complex", t);
}

The above code snippet will display the following text line:

complex.method("__toString", &Complex::__toString);

It's very simple, right? The C exception constructed in our extension is passed back to PHP and is correctly caught. In addition, we can operate exceptions like we handle native PHP exceptions thrown by other PHP codes!

Test all functions

Finally, we can compile and install the complex.so extension for our PHP installation via make && sudo make install. If all goes well, we can verify the installation of the extension by issuing the following command in the terminal:

<code>修复问题#151,链式方法调用无法正常工作……
……因为每个对象的引用计数未正确更新,这导致即使对象已分配给不同的变量,该对象也会被销毁。</code>

The terminal should display a line that says "/etc/php5/cli/conf.d/complex.ini", we can make sure that our extension is installed and ready to be called by any PHP script.

Note: If we check the Makefile for this extension, we will see that we are installing this PHP extension into its CLI environment. If we want to install this extension so that Apache can load it, we change the following line:

Php::Value div(Php::Parameters &params) {
    Php::Value t = params[0];
    Complex *b = (Complex*) t.implementation();

    double t1 = b->mod() * b->mod();

    if (t1 == 0)
        throw Php::Exception("Division by zero");

    double tr = r * (double) (b->getReal()) + i * (double) (b->getImage());
    double ti = i * (double) (b->getReal()) - r * (double) (b->getImage());

    r = tr / t1;
    i = ti / t1;

    return this;
}

The test PHP script for this extension is as follows, with some notes:

$a=new tr\Complex(1,2);
$c=new tr\Complex(); //$c实际上是0+0i

try
{
    $res=$a->div($c);
}
catch(Exception $e)
{
    echo "Caught exception: ".$e->getMessage()."\n";
}
}

All test scripts should run correctly and the exception is caught correctly.

Conclusion

This summarizes my 3 article series on building this powerful library with C for PHP extensions. We cover the basics, object-oriented aspects, and some advanced topics in object-oriented programming. We also helped PHP-CPP improve.

What else can we do with PHP-CPP? I'll quote a few lines of email communication I received from Emiel Bruijntjes (co-author of PHP-CPP):

If you are working on a project and have one or more of the following requirements, the PHP-CPP library is ideal: – You are working on software/data structures/algorithms and you want to make sure that your software can also be used in non-PHP projects in the future. – You want to use a tool or library that is not yet available as a PHP extension. – You want better performance of your C/C code (compared to PHP), but you also want to build structured, object-oriented code for easy understanding and maintenance by other developers/colleagues.

The possibilities are huge: frameworks (such as Phalcon), template languages ​​(such as Smarty or Twig), and so on.

Please leave your comments and opinions and let us know what you have done with this library!

FAQs on Developing PHP Extensions with C

What are the benefits of using C to develop PHP extensions?

There are many benefits to developing PHP extensions using C. First, it allows you to take advantage of the power and flexibility of C in your PHP application. This can improve performance, especially in compute-intensive tasks. Second, it provides a way to reuse existing C code in a PHP environment, which can save a lot of development time and effort. Finally, it enables you to create custom PHP extensions that extend the functionality of PHP and provide features that are not available in the standard PHP library.

How to start using C for PHP extension development?

To start using C for PHP extension development, you need to have a basic understanding of PHP and C programming languages. You also need to install the PHP development environment and the C compiler. After installing these prerequisites, you can start writing PHP extensions in C. There are a lot of resources available online, including tutorials and sample code to guide you through this process.

What is PHP-CPP and how does it help PHP extension development?

PHP-CPP is a library for developing PHP extensions using C. It provides a set of C classes and methods, simplifying the process of writing PHP extensions. With PHP-CPP, you can write PHP extensions in a more natural and intuitive way, using C's familiar syntax and concepts. This can make the development process more efficient and reduce errors.

Can I use PHP-CPP for commercial projects?

Yes, PHP-CPP is open source software that can be used in personal and commercial projects. However, it is important to understand that while the library itself is free, you may need to invest time and resources in learning how to use it effectively and maintain your PHP extensions.

What are some common challenges for PHP extension development using C and how can I overcome them?

Some common challenges in PHP extension development using C include the correct management of memory, handling of errors and exceptions, and the interface between PHP and C. These challenges can be overcome by gaining insight into PHP and C, using good programming practices, and leveraging the features and tools provided by PHP-CPP.

How to debug PHP extensions written in C?

PHP extensions written in C can be debugged using standard C debugging tools. In addition, PHP-CPP provides some features that can aid debugging, such as exception handling and error reporting.

Can I use PHP-CPP with other C libraries?

Yes, PHP-CPP can be used with other C libraries. This allows you to take advantage of various C features in PHP extensions.

How to improve the performance of PHP extensions written in C?

You can improve the performance of PHP extensions by using efficient algorithms and data structures, minimizing memory usage, and optimizing C code. In addition, PHP-CPP provides some features that can help improve performance, such as direct access to PHP variables and functions.

Can I contribute code to the PHP-CPP project?

Yes, the PHP-CPP project is open source and the contribution of the community is welcome. You can contribute your code by reporting bugs, suggesting new features, or submitting patches.

Where can I find more resources on using C for PHP extension development?

There are many resources available online for learning to use C for PHP extension development. These resources include tutorials, sample code, documentation, and forums. In addition, the PHP-CPP website provides a large amount of information and resources on the use of the library.

The above is the detailed content of Developing PHP Extensions with C and PHP-CPP: Advanced. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
PHP vs. Python: Understanding the DifferencesPHP vs. Python: Understanding the DifferencesApr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP: Is It Dying or Simply Adapting?PHP: Is It Dying or Simply Adapting?Apr 11, 2025 am 12:13 AM

PHP is not dying, but constantly adapting and evolving. 1) PHP has undergone multiple version iterations since 1994 to adapt to new technology trends. 2) It is currently widely used in e-commerce, content management systems and other fields. 3) PHP8 introduces JIT compiler and other functions to improve performance and modernization. 4) Use OPcache and follow PSR-12 standards to optimize performance and code quality.

The Future of PHP: Adaptations and InnovationsThe Future of PHP: Adaptations and InnovationsApr 11, 2025 am 12:01 AM

The future of PHP will be achieved by adapting to new technology trends and introducing innovative features: 1) Adapting to cloud computing, containerization and microservice architectures, supporting Docker and Kubernetes; 2) introducing JIT compilers and enumeration types to improve performance and data processing efficiency; 3) Continuously optimize performance and promote best practices.

When would you use a trait versus an abstract class or interface in PHP?When would you use a trait versus an abstract class or interface in PHP?Apr 10, 2025 am 09:39 AM

In PHP, trait is suitable for situations where method reuse is required but not suitable for inheritance. 1) Trait allows multiplexing methods in classes to avoid multiple inheritance complexity. 2) When using trait, you need to pay attention to method conflicts, which can be resolved through the alternative and as keywords. 3) Overuse of trait should be avoided and its single responsibility should be maintained to optimize performance and improve code maintainability.

What is a Dependency Injection Container (DIC) and why use one in PHP?What is a Dependency Injection Container (DIC) and why use one in PHP?Apr 10, 2025 am 09:38 AM

Dependency Injection Container (DIC) is a tool that manages and provides object dependencies for use in PHP projects. The main benefits of DIC include: 1. Decoupling, making components independent, and the code is easy to maintain and test; 2. Flexibility, easy to replace or modify dependencies; 3. Testability, convenient for injecting mock objects for unit testing.

Explain the SPL SplFixedArray and its performance characteristics compared to regular PHP arrays.Explain the SPL SplFixedArray and its performance characteristics compared to regular PHP arrays.Apr 10, 2025 am 09:37 AM

SplFixedArray is a fixed-size array in PHP, suitable for scenarios where high performance and low memory usage are required. 1) It needs to specify the size when creating to avoid the overhead caused by dynamic adjustment. 2) Based on C language array, directly operates memory and fast access speed. 3) Suitable for large-scale data processing and memory-sensitive environments, but it needs to be used with caution because its size is fixed.

How does PHP handle file uploads securely?How does PHP handle file uploads securely?Apr 10, 2025 am 09:37 AM

PHP handles file uploads through the $\_FILES variable. The methods to ensure security include: 1. Check upload errors, 2. Verify file type and size, 3. Prevent file overwriting, 4. Move files to a permanent storage location.

What is the Null Coalescing Operator (??) and Null Coalescing Assignment Operator (??=)?What is the Null Coalescing Operator (??) and Null Coalescing Assignment Operator (??=)?Apr 10, 2025 am 09:33 AM

In JavaScript, you can use NullCoalescingOperator(??) and NullCoalescingAssignmentOperator(??=). 1.??Returns the first non-null or non-undefined operand. 2.??= Assign the variable to the value of the right operand, but only if the variable is null or undefined. These operators simplify code logic, improve readability and performance.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MantisBT

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.

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.