I have a performance intensive routine that is written in PHP that I'd like to port to C++ for a performance increase. Is there any way to write a plugin or extension or something using C++ and interface with it from PHP? WITHOUT manually editing the actual PHP source?
As Remus says, you can extend PHP with C/C++ using the Zend API. The linked tutorial by Sara Golemon is a good start, and the book Extending and Embedding PHP by the same author covers the subject in much more detail.
However, it's worth noting that both of these (and pretty much everything else I found online) focus on C and don't really cover some tweaks you need to get C++ extensions working.
In the config.m4 file you need to explicitly link to the C++ standard library:
PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(stdc++, 1, PHP5CPP_SHARED_LIBADD)
Any C++ library compile checks in the config.m4 file will also require linking the C++ lib:
PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,,
[
AC_MSG_ERROR([lib $LIBNAME not found.])
],[
-lstdc++ -ldl
])
EDIT - and here's how to specify g++:
Last, and not least, in order to choose the C++ rather than C compiler/linker when building the extension, the 6th parameter to PHP_NEW_EXTENSION() should be "yes". ie:
PHP_NEW_EXTENSION(your_extension,
your_extension.cpp,
$ext_shared,
,
"-Wall -Werror -Wno-error=write-strings -Wno-sign-compare",
"yes")
From the PHP build system manual, the parameters are:
The name of the extension
List of all source files which are part of the extension.
(optional) $ext_shared, a value which was determined by configure when PHP_ARG_WITH() was called for
(optional) "SAPI class", only useful for extensions which require the CGI or CLI SAPIs specifically. It should be left empty in all other cases.
(optional) A list of flags to be added to CFLAGS while building the extension.
(optional) A boolean value which, if "yes", will force the entire extension to be built using $CXX instead of $CC.
I couldn't work out how to get the configure script to set g++ as the compiler/linker instead of gcc, so ended up hacking the Makefile with a sed command to do a search replace in my bash build script:
phpize
./configure --with-myextension
if [ "$?" == 0 ]; then
# Ugly hack to force use of g++ instead of gcc
# (otherwise we'll get linking errors at runtime)
sed -i 's/gcc/g++/g' Makefile
make clean
make
fi
Presumably there's an automake command that would make this hack unnecessary.
I've written a PHP plugin in C++ with the help of SWIG. It's doable, but it may take a while to get used to the SWIG-compilation cycle. You can start with the SWIG docs for PHP.
Update
As #therefromhere has mentioned, I greatly recommend that you get the book Extending and Embedding PHP. There is almost no documentation to be found online (at least there wasn't in late 2008, early 2009 when I did my PHP plugin). I had to rely on the book for everything. Although sometimes Google Code Search is helpful for finding sample code.
PHP itself a collection of loosely related libraries. See http://devzone.zend.com/article/1021 for a tutorial how to write your own.
Related
When I generate my ctags file, it seems to be parsing content inside comments too. For instance, using Vim's plugin Tagbar, I can see in the list of functions non-existent functions such as:
is
in
just
What is happening here is that ctags is going into comments and finding things like:
"This function is...", thinking that "is" is a function, it is then adding an entry for it in the tags file.
I am wondering if there is an easy way to tell ctags not to parse contents inside comments.
I have found that apparently there was a fix for this to be released after 5.8.0 but I am not sure whether this has already been released or not, my ctags version is 5.8.0.
This is related to a PHP project but I guess it would be nice if the answer can cover a solution that would work for any programming language (if such a thing is possible).
Example:
The following comment to a function generates the tag "is" and lists it as a function:
/**
* This function is run to set certain preferences
*/
There's a bug in ctags 5.8. Fortunately, one day after it was released, jafl committed revision 729 to fix the problem. Unfortunately, there has not been a release since then.
Fortunately, the project has been forked as "Universal Ctags." Here's how to install that from source.
# Get rid of 5.8.
sudo apt-get remove exuberant-ctags
# autoconf is needed to assemble the configure files
sudo apt-get install autoconf autoconf-doc
git clone https://github.com/universal-ctags/ctags.git universal-ctags
cd universal-ctags
./autogen.sh
./configure
make
sudo make install
Exuberant Ctags has a large variety of languages already built into it. Each of these has a custom parser tailored to that language. Of course, it doesn't make sense to include comments / commented-out sections of code in the tags file. If that happens, it is a bug in the language's parser and must be fixed in the ctags code.
Note that Exuberant Ctags also supports extension to new languages via regular expressions. With these, it can be very difficult / slow / impossible to exclude comments (as there may be a large preceding context to consider, and the language syntax may not be fully representable as regexp), and you would have to live with this, or apply workarounds like preprocessing the comments out of the sources before processing them.
I am trying to build an extension for PHP. After following Sara Golemon's book I have a basic extension which I can compile as a shared module and, in addition, I can compile it statically along PHP itself.
Now I want to modify the PHP interpreter in order to intercept particular internal function invocations and communicate these calls to my extension. I want to do this only when my extension is statically compiled with PHP---the interpreter build process should otherwise generate an unmodified PHP binary. My understanding is that I should use the C preprocessor. However, to achieve my goal I need a preprocessor flag that will only be raised when PHP is configured to compile with my extension (i.e. ./configure --enable-myextension). Unfortunately, I cannot find such a flag nor one seems to be set by the configure script.
I should say here that I have tried setting preprossessor flags within my extension's code but this will not work. My extension is first touched late in the build process (i.e. roughly after the core of the interpreter) and the flags I set there are not active when the bulk of interpreter code is being compiled.
Any thoughts? Do the above sound reasonable?
My understanding is that I should use the C preprocessor.
Nope, you don't need that.
I need a preprocessor flag that will only be raised when PHP is configured to compile with my extension
Why would you want that? It would basically limit the functionality of your extension artificially, although it's possible to hook function calls no matter how your extension is compiled.
Do the above sound reasonable?
In my opinion, it's not reasonable. Please have a look at how AOP hooks function calls: https://github.com/AOP-PHP/AOP
If you need to hook more than just function calls, you need to reach down at the lowest level, the opcodes, by using zend_set_user_opcode_handler(). Please use lxr.php.net or similar tools (fgrep, etc) to find out where and how such handlers are used. I know laruence was working hard on an interesting extension last year here: http://svn.php.net/viewvc/pecl/taint/trunk/taint.c?view=markup so I would take that as the most "up to date" way of doing things as a reference, if anything has changed in the meanwhile.
I own a high traffic website that does business in the USA and Canada. We have lots of servers but I want to make sure it's 100% available with no latency whatsoever.
I've learned about creating custom extensions (I know a little C) and I want to create custom validation/files (since php extensions runs faster).
I don't want to ask for all new extensions from you guys but I want to know the general idea on how to build it (I am using CentOS).
Example:
One section of our site is the shipping tracking and this require a postal code.
For the USA I have:
function check_usa_postal_code($pc) {
return is_numeric($pc);
}
But for Canada, I would like to build in PHP a custom function like:
check_canada_postal_code($pc)
This function should return 1 or 0.
Thanks
I recommend to read this article:
Extension Writing Part I: Introduction to PHP and Zend
and here's how to compile:
UNIX: Compiling PHP Extensions
Build PHP extensions with SWIG
(I recommend SWIG like mario said)
Read more on Canadian zip codes at Postal codes in Canada since not all letters are being used.
Rather than try and build an extension in C you should consider compiling your source code using HipHop instead. This will be much simpiler and run your code pretty fast.
You should also consider using Zephir. Its syntax is very similar to PHP. It is specially designed to create PHP extensions and compiles into an extension.
There are even several converters from regular PHP to Zephir. They do not take into account all the peculiarities, so some minor code changes will be needed before compiling. I use sandrokeil/php-to-zephir.
I need to install cURL. PHP's official website writes:
To use PHP's cURL support you must also compile PHP --with-curl[=DIR] where DIR is the location of the directory containing the lib and include directories.
But I've seen people doing it like that:
<?php
// some text...
--with-curl
// some text...
?>
Which one should I choose?
Writing --with-curl arbitrarily in the middle of your code does nothing except potentially cause syntax errors.
The code that you show does not make any sense, is not valid PHP code and the PHP interpreter will throw an error. If you want to use curl you have to install it.
The second option isn't valid, as others have mentioned. The only way to add modules (in this case, the one that adds curl support) is to compile PHP with those modules active. That is what --with-php does - tells PHP to compile with curl.
Now, the source code for some packages do allow you to add that to one of the compiling config files, and it often takes the same form as the command line switch. I'm not sure if PHP has that option (never needed to compile it by hand), but if it does, it's not going to be in a PHP file.
If you run a version of Linux, you also have the option of installing php-curl/php5-curl from your distribution's repository. Doing it that way saves the headache of compiling it yourself and remembering what you need to turn on and off, and handles dependency needs.
Ultimately, though, how you go about installing it or adding modules depends on your platform, skill level, and overall needs and comfort level.
The standard way of writing PHP extensions is to use autoconf/automake alongside a script called phpize, which seems to generate your autoconf configuration based on a template that's specific to your PHP environment. This let's it build the PHP extension for the right version of PHP, etc.
autoconf and the m4 language that is used to configure it is arcane, and people have written alternatives, such as scons. I want to be able to use one of these when building a PHP extension.
In principle, you should be able to use scons or similar tools to build PHP extensions. However, I can't see how you would replace the phpize step.
Has anyone had any success in building PHP extensions with scons, or another more modern build tool?
The path of least resistance would be to have SCons run autoconf, phpize and whatever else is needed for your PHP extension. You may be able to extract the compiler configuration out of there and let SCons do the actual building, or you can simply have SCons run "make".
Declaring shell command targets from SCons is easy, but getting dependencies right is always tricky.
Basically you will have to let SCons know of any intermediate file produced by these external tools. This way it can not only properly clean them, but it can also cache the whole series of steps based on the content signature of each intermediate result (MD5 checksum).
Proper caching will significantly reduce the number of times these external tools will actually need to be invoked as the code base changes.
While I don't think somebody has written a specific solution for PHP, there are lots of custom builders on the SCons wiki that do similar things.
phpize(1) is just a shell script, so i guess you could modify it to work with scons...