PHP7 Bindings Improvement
Summary
This project is to improve the already existing PHP7 bindings in SWIG to replace the existing object oriented approach. Current PHP7 bindings use flat method structure to bind C/C++ classes and functions and then a php wrapper around that to use object oriented approach. This project aims to replace that with a object oriented approach in the C/C++ wrapper itself using the Zend C Api, which wasn't well documented when the earlier PHP7 bindings was written.
The end goal from this project is to have a object oriented PHP7 bindings for Xapian.
SWIG
The Simplified Wrapper and Interface Generator (SWIG) is a tool used to extend native code written in C/C++ to scripting languages. The programmer writes an interface file which lists the set of classes and functions to be extended to the target interpreter/compiler. SWIG compiles this interface file to generate extensions/shared libraries that glue the native code to the target language.
Work done in this project
This project overhauls the existing PHP7 SWIG bindings to have a object oriented approach to them. The project entails the use of Zend C API to wrap the C/C++ source code to make it available to PHP user space. SWIG has an extensive test-suite to test the PHP Wrapper. So my work was to change the backend of the PHP7 bindings and completely pass the SWIG php test-suite.
To explain my project and the changes with an example.
The SWIG's current wrapper on a simple C/C++ class example (link above) generates the wrapper. The class methods are in a flat structure. Example - shape_area, circle_area, square_area. They are function "area" of class shape, circle, square respectively. With my changes, the SWIG wrapper for the same example generates the following wrapper. As you can see the above flat functions are now wrapped as PHP_ME(shape,area), PHP_ME(circle,area), PHP_ME(square,area). This is the class approach of wrapping C/C++ source code to make it available to the PHP userspace.
SWIG has extensive test-suite, around 512 test cases to check the correct functioning of the wrapper under different circumstances and wrap classes, constructors (also supports constructor overloading), director feature ,templates etc.
Currently, there are 5 tests failing out of 512 in the SWIG PHP test-suite. And will be touched upon in depth.
See Journal for a weekly timeline.
How to use SWIG php7 Wrapper
- Install SWIG or get the Github version.
- For Github version -> installation notes
- To test with an example
- Pre-defined Examples
- Examples/php/
- This folder contains the examples, just use make command once inside the specific folder to run the example.
- Examples/php/
- Custom Examples
- Write a example code (C/C++)
- Run the swig command to generate wrapper -> swig -php7 -c++ example.i
- .i is for swig interface files
- -c++ argument for C++ code
- Compile both the C/C++ and the generated wrapper (example_wrap.cxx)
- Link the shared object library of the code with the wrapper.
- Run a sample runme.php for testing the C/C++ code.
- For more details, refer -> Details
- Pre-defined Examples
Code
My Repository:
SWIG Branch: https://github.com/swig/swig/tree/gsoc2017-php7-classes-via-c-api
Work done during GSoC: commits up to August 28, 2017:
The code from my repository has been merged to the SWIG gsoc2017-php7-classes-via-c-api branch after review. This branch serves as a staging area, and it will be added to SWIG distribution after the module is thoroughly tested and documentation for users is added.
Work in Progress / Future Work
- Documentation
- 5 test cases
- director_basic
- director_detect
- director_pass_by_value
- Null pointer failures.
- evil_diamond_prop1
- This test case fails, as it is unable to get the parent classes variables in the magic setter/getter functions.
- global_scope_types
- ambiguous class_type in magic setter/getter functions
Challenging Parts
- The Zend C API isn't documented properly even now. Searching about this in Google results in near to nothing that can be used. There are a very few reliable sources to work with regarding Zend C API documentation. The original source code is by far the most helpful documentation out there. Theses are the following documentation that's available for future use.
- https://github.com/php/php-src/tree/master/Zend
- https://wiki.php.net/internals/engine/objects
- -> For Older Version of PHP (Use next link to map the old features/changes to version 7)
- https://wiki.php.net/phpng-upgrading
- http://www.phpinternalsbook.com/index.html
- https://wiki.php.net/internals/references
- http://jpauli.github.io/index.html
- Few questions on https://stackoverflow.com
- SWIG supports variety of features such as directors, typemaps etc. Binding those features with the object oriented structure is where the real challenge is. But I quite enjoyed it.
Future Work
- Fix work-arounds
- abstractness check -> GetFlag(n, "abstract") && Swig_directorclass(Swig_methodclass(n))
- Examples/test-suite/php/tests.php -> returns true for methods, classmethods, classes, functions.
- Replace flat method checks in test cases.
- Add more features
- Namespaces support
- Xapian Bindings
Closing Notes
- Thank you Olly, Jaylett, ayshtmr, samuelharden for the amazing opportunity to work with Xapian. Even though I worked on SWIG. It was an valuable experience for me. Thanks Olly, I had been warding off with my own new implementations of the solutions and you were patient enough to correct me. I had been stuck at places for days, frustrated. I would have been still stuck there, if it wasn't for you. Thank you.
- It has been a great joy to walk through the world of PHP Zend. In which Documentation is hard to comeby, but was a great experience nonetheless.
- Lastly, I would like to thank Google for this amazing opportunity at working with open-source projects.