summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Examples/EmptyExtension/Makefile135
-rw-r--r--Examples/EmptyExtension/main.cpp26
-rw-r--r--Examples/EmptyExtension/yourextension.ini1
-rw-r--r--documentation/compile-extensions.html170
-rw-r--r--documentation/loading-extensions.html (renamed from documentation/tutorial.html)96
5 files changed, 398 insertions, 30 deletions
diff --git a/Examples/EmptyExtension/Makefile b/Examples/EmptyExtension/Makefile
new file mode 100644
index 0000000..76d161d
--- /dev/null
+++ b/Examples/EmptyExtension/Makefile
@@ -0,0 +1,135 @@
+#
+# Makefile template
+#
+# This is an example Makefile that can be used by anyone who is building
+# his or her own PHP extensions using the PHP-CPP library.
+#
+# In the top part of this file we have included variables that can be
+# altered to fit your configuration, near the bottom the instructions and
+# dependencies for the compiler are defined. The deeper you get into this
+# file, the less likely it is that you will have to change anything in it.
+#
+
+#
+# Name of your extension
+#
+# This is the name of your extension. Based on this extension name, the
+# name of the library file (name.so) and the name of the config file (name.ini)
+# are automatically generated
+#
+
+NAME = yourextension
+
+
+#
+# Php.ini directories
+#
+# In the past, PHP used a single php.ini configuration file. Today, most
+# PHP installations use a conf.d directory that holds a set of config files,
+# one for each extension. Use this variable to specify this directory.
+#
+
+INI_DIR = /etc/php5/conf.d
+
+
+#
+# The extension dirs
+#
+# This is normally a directory like /usr/lib/php5/20121221 (based on the
+# PHP version that you use. We make use of the command line 'php-config'
+# instruction to find out what the extension directory is, you can override
+# this with a different fixed directory
+#
+
+EXTENSION_DIR = $(shell php-config --extension-dir)
+
+
+#
+# The name of the extension and the name of the .ini file
+#
+# These two variables are based on the name of the extension. We simply add
+# a certain extension to them (.so or .ini)
+#
+
+EXTENSION = ${NAME}.so
+INI = ${NAME}.ini
+
+
+#
+# Compiler
+#
+# By default, the GNU C++ compiler is used. If you want to use a different
+# compiler, you can change that here. You can change this for both the
+# compiler (the program that turns the c++ files into object files) and for
+# the linker (the program that links all object files into the single .so
+# library file. By default, g++ (the GNU C++ compiler) is used for both.
+#
+
+COMPILER = g++
+LINKER = g++
+
+
+#
+# Compiler and linker flags
+#
+# This variable holds the flags that are passed to the compiler. By default,
+# we include the -O2 flag. This flag tells the compiler to optimize the code,
+# but it makes debugging more difficult. So if you're debugging your application,
+# you probably want to remove this -O2 flag. At the same time, you can then
+# add the -g flag to instruct the compiler to include debug information in
+# the library (but this will make the final libphpcpp.so file much bigger, so
+# you want to leave that flag out on production servers).
+#
+# If your extension depends on other libraries (and it does at least depend on
+# one: the PHP-CPP library), you should update the LINKER_DEPENDENCIES variable
+# with a list of all flags that should be passed to the linker.
+#
+
+COMPILER_FLAGS = -Wall -c -O2 -std=c++11 -fpic -o
+LINKER_FLAGS = -shared
+LINKER_DEPENDENCIES = -lphpcpp
+
+
+#
+# Command to remove files, copy files and create directories.
+#
+# I've never encountered a *nix environment in which these commands do not work.
+# So you can probably leave this as it is
+#
+
+RM = rm -f
+CP = cp -f
+MKDIR = mkdir -p
+
+
+#
+# All source files are simply all *.cpp files found in the current directory
+#
+# A builtin Makefile macro is used to scan the current directory and find
+# all source files. The object files are all compiled versions of the source
+# file, with the .cpp extension being replaced by .o.
+#
+
+SOURCES = $(wildcard *.cpp)
+OBJECTS = $(SOURCES:%.cpp=%.o)
+
+
+#
+# From here the build instructions start
+#
+
+all: ${OBJECTS} ${EXTENSION}
+
+${EXTENSION}: ${OBJECTS}
+ ${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS} ${LINKER_DEPENDENCIES}
+
+${OBJECTS}:
+ ${COMPILER} ${COMPILER_FLAGS} $@ ${@:%.o=%.cpp}
+
+install:
+ ${CP} ${EXTENSION} ${EXTENSION_DIR}
+ ${CP} ${INI} ${INI_DIR}
+
+clean:
+ ${RM} ${EXTENSION} ${OBJECTS}
+
diff --git a/Examples/EmptyExtension/main.cpp b/Examples/EmptyExtension/main.cpp
new file mode 100644
index 0000000..22aba90
--- /dev/null
+++ b/Examples/EmptyExtension/main.cpp
@@ -0,0 +1,26 @@
+#include <phpcpp.h>
+
+/**
+ * tell the compiler that the get_module is a pure C function
+ */
+extern "C" {
+
+ /**
+ * Function that is called by PHP right after the PHP process
+ * has started, and that returns an address of an internal PHP
+ * strucure with all the details and features of your extension
+ *
+ * @return void* a pointer to an address that is understood by PHP
+ */
+ PHPCPP_EXPORT void *get_module()
+ {
+ // static(!) Php::Extension object that should stay in memory
+ // for the entire duration of the process (that's why it's static)
+ static Php::Extension myExtension("my_extension", "1.0");
+
+ // @todo add your own functions, classes, namespaces to the extension
+
+ // return the extension
+ return myExtension;
+ }
+}
diff --git a/Examples/EmptyExtension/yourextension.ini b/Examples/EmptyExtension/yourextension.ini
new file mode 100644
index 0000000..c473420
--- /dev/null
+++ b/Examples/EmptyExtension/yourextension.ini
@@ -0,0 +1 @@
+extension=yourextension.so
diff --git a/documentation/compile-extensions.html b/documentation/compile-extensions.html
new file mode 100644
index 0000000..3e6396d
--- /dev/null
+++ b/documentation/compile-extensions.html
@@ -0,0 +1,170 @@
+<div style="width: 1024px; font-family: verdana; font-size: 10pt; line-height: 16pt;">
+
+
+<h1>Compile your own extensions</h1>
+<p>
+ When you build your own PHP-CPP extensions, you also have to compile and
+ deploy them. A normal PHP script only has to be placed on a web server to be
+ deployed, but it takes a little more effort to deploy an extension.
+</p>
+<p>
+ To help your users, customers, and/or operations department with deploying
+ your native extensions, you best create a Makefile with settings and
+ instructions for the compiler. All that is then left for someone to install
+ your extension, is run "make" and "make install". And because it is PHP-CPP's
+ objective to make life easy, we give you already an example Makefile that
+ works on most Linux platforms.
+</p>
+<p>
+ <code><pre>
+ #
+ # Makefile template
+ #
+ # This is an example Makefile that can be used by anyone who is building
+ # his or her own PHP extensions using the PHP-CPP library.
+ #
+ # In the top part of this file we have included variables that can be
+ # altered to fit your configuration, near the bottom the instructions and
+ # dependencies for the compiler are defined. The deeper you get into this
+ # file, the less likely it is that you will have to change anything in it.
+ #
+
+ #
+ # Name of your extension
+ #
+ # This is the name of your extension. Based on this extension name, the
+ # name of the library file (name.so) and the name of the config file (name.ini)
+ # are automatically generated
+ #
+
+ NAME = yourextension
+
+
+ #
+ # Php.ini directories
+ #
+ # In the past, PHP used a single php.ini configuration file. Today, most
+ # PHP installations use a conf.d directory that holds a set of config files,
+ # one for each extension. Use this variable to specify this directory.
+ #
+
+ INI_DIR = /etc/php5/conf.d
+
+
+ #
+ # The extension dirs
+ #
+ # This is normally a directory like /usr/lib/php5/20121221 (based on the
+ # PHP version that you use. We make use of the command line 'php-config'
+ # instruction to find out what the extension directory is, you can override
+ # this with a different fixed directory
+ #
+
+ EXTENSION_DIR = $(shell php-config --extension-dir)
+
+
+ #
+ # The name of the extension and the name of the .ini file
+ #
+ # These two variables are based on the name of the extension. We simply add
+ # a certain extension to them (.so or .ini)
+ #
+
+ EXTENSION = ${NAME}.so
+ INI = ${NAME}.ini
+
+
+ #
+ # Compiler
+ #
+ # By default, the GNU C++ compiler is used. If you want to use a different
+ # compiler, you can change that here. You can change this for both the
+ # compiler (the program that turns the c++ files into object files) and for
+ # the linker (the program that links all object files into the single .so
+ # library file. By default, g++ (the GNU C++ compiler) is used for both.
+ #
+
+ COMPILER = g++
+ LINKER = g++
+
+
+ #
+ # Compiler and linker flags
+ #
+ # This variable holds the flags that are passed to the compiler. By default,
+ # we include the -O2 flag. This flag tells the compiler to optimize the code,
+ # but it makes debugging more difficult. So if you're debugging your application,
+ # you probably want to remove this -O2 flag. At the same time, you can then
+ # add the -g flag to instruct the compiler to include debug information in
+ # the library (but this will make the final libphpcpp.so file much bigger, so
+ # you want to leave that flag out on production servers).
+ #
+ # If your extension depends on other libraries (and it does at least depend on
+ # one: the PHP-CPP library), you should update the LINKER_DEPENDENCIES variable
+ # with a list of all flags that should be passed to the linker.
+ #
+
+ COMPILER_FLAGS = -Wall -c -O2 -std=c++11 -fpic -o
+ LINKER_FLAGS = -shared
+ LINKER_DEPENDENCIES = -lphpcpp
+
+
+ #
+ # Command to remove files, copy files and create directories.
+ #
+ # I've never encountered a *nix environment in which these commands do not work.
+ # So you can probably leave this as it is
+ #
+
+ RM = rm -f
+ CP = cp -f
+ MKDIR = mkdir -p
+
+
+ #
+ # All source files are simply all *.cpp files found in the current directory
+ #
+ # A builtin Makefile macro is used to scan the current directory and find
+ # all source files. The object files are all compiled versions of the source
+ # file, with the .cpp extension being replaced by .o.
+ #
+
+ SOURCES = $(wildcard *.cpp)
+ OBJECTS = $(SOURCES:%.cpp=%.o)
+
+
+ #
+ # From here the build instructions start
+ #
+
+ all: ${OBJECTS} ${EXTENSION}
+
+ ${EXTENSION}: ${OBJECTS}
+ ${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS} ${LINKER_DEPENDENCIES}
+
+ ${OBJECTS}:
+ ${COMPILER} ${COMPILER_FLAGS} $@ ${@:%.o=%.cpp}
+
+ install:
+ ${CP} ${EXTENSION} ${EXTENSION_DIR}
+ ${CP} ${INI} ${INI_DIR}
+
+ clean:
+ ${RM} ${EXTENSION} ${OBJECTS}
+
+ </pre></code>
+</p>
+<p>
+ But your extension should not only have a Makefile, but also an initial
+ yourextension.ini file. This file is much simpler that the Makefile:
+</p>
+<p>
+ <code><pre>
+ extension=yourextension.so
+ </pre></code>
+</p>
+<p>
+ You can download both the Makefile and the ini file from our empty extension
+ template, so that you can start making your application right away.
+</p>
+
diff --git a/documentation/tutorial.html b/documentation/loading-extensions.html
index ff2bbbc..2556efd 100644
--- a/documentation/tutorial.html
+++ b/documentation/loading-extensions.html
@@ -1,23 +1,14 @@
<div style="width: 1024px; font-family: verdana; font-size: 10pt; line-height: 16pt;">
-<h1>A PHP-CPP tutorial</h1>
-<p>
- Building PHP extensions with the PHP-CPP library is not at all difficult -
- in this tutorial we will give you step by step instructions to build
- your own extensions. However, before we start the actual programming, we will
- first explain how PHP interacts with its extensions - how extension libraries
- are loaded and how PHP knows which functions, constants and classes are
- defined by the extensions.
-</p>
-<h2>How does PHP load its extensions?</h2>
+<h1>How does PHP load its extensions?</h1>
<p>
You probably already know that native PHP extensions are compiled into *.so
files on unix-like systems, and *.dll files in Windows environments, and that
the global php.ini file holds a list of all extensions available on your system.
This means that if you're building your own extension, you are also going to
- create such a *.so or *.dll file and you will need to update the PHP
- configuration so that your own extension is loaded by PHP.
+ create such a *.so or *.dll file and you have to update the PHP
+ configuration file so that your own extension is loaded by PHP.
</p>
<h3>Where to find your PHP configuration files?</h3>
<p>
@@ -49,9 +40,14 @@
php -i|grep extension_dir
</pre></code>
</p>
+<p>
+ The extension dir often has the form /usr/lib/php5/20121212 - or a different
+ date string depending on the PHP version you use.
+</p>
+
<h2>The get_module() startup function</h2>
<p>
- Before we explain how you can create your own extension however, we first explain
+ Before we explain how you can create your own extension, we first explain
what PHP does to load an extension. When PHP starts, it loads the *.ini configuration
file(s) that we just described and for each "extension=name.so" line in these
files, it opens the appropriate library, and calls the "get_module()"
@@ -72,10 +68,28 @@
<code><pre>
#include &lt;phpcpp.h&gt;
+ /**
+ * tell the compiler that the get_module is a pure C function
+ */
extern "C" {
- PHPCPP_EXPORT void *get_module() {
+
+ /**
+ * Function that is called by PHP right after the PHP process
+ * has started, and that returns an address of an internal PHP
+ * strucure with all the details and features of your extension
+ *
+ * @return void* a pointer to an address that is understood by PHP
+ */
+ PHPCPP_EXPORT void *get_module()
+ {
+ // static(!) Php::Extension object that should stay in memory
+ // for the entire duration of the process (that's why it's static)
static Php::Extension myExtension("my_extension", "1.0");
- return myExtension.module();
+
+ // @todo add your own functions, classes, namespaces to the extension
+
+ // return the extension
+ return myExtension;
}
}
</pre></code>
@@ -83,14 +97,16 @@
<p>
In the example above you see a very straightforward implementation of the
get_module() function. Every PHP extension that uses the PHP-CPP library
- implements this function in a more or less similar way as the extension
- starting point. A number of elements require special attention. For a
- start, the only header file that you see is the phpcpp.h header
+ implements this function in a more or less similar way, and it is the
+ starting point of each extension. A number of elements require special attention.
+ For a start, the only header file that you see is the phpcpp.h header
file. If you're using the PHP-CPP library to build your own extensions,
you do not have to include the complicated, unstructured, and mostly undocumented
- header files of the Zend engine - all you need is the single header file of
- the PHP-CPP library. If you insist, you are of course free to also include the header
- files of the core PHP engine - but you do not have to.
+ header files of the Zend engine - all you need is this single phpcpp.h header
+ file of the PHP-CPP library. If you insist, you are of course free to also
+ include the header files of the core PHP engine - but you do not have to.
+ PHP-CPP takes care of dealing with the internals of the PHP engine, and offers
+ you a simple to use API.
</p>
<p>
The next thing that you'll notice it that we placed the get_module() function
@@ -98,8 +114,8 @@
PHP-CPP is a C++ library. However, PHP expects your library, and especially your
get_module() function, to be implemented in C and not in C++. That's why we've
wrapped the get_module() function in an 'extern "C"' block. This will instruct
- the C++ compiler that the get_module() is a regular C function, and
- no C++ name mangling should be applied to it.
+ the C++ compiler that the get_module() is a regular C function, and that it
+ should not apply any C++ name mangling to it.
</p>
<p>
The PHP-CPP library defines a "PHPCPP_EXPORT" macro that should be placed
@@ -108,18 +124,38 @@
implementation based on the compiler and operating system.
</p>
<p>
- Inside the get_module() function the Extension object is instantiated, and the
- Extension::module() method is called. It is crucial that you make a <i>static</i>
- instance of this Extension class, because the object must exist for the entire
- lifetime of the PHP process, and not only for the duration of the get_module()
+ This, by the way, is also the only macro that PHP-CPP offers. PHP-CPP intends to
+ be a very straightforward C++ library, without using magic or tricks from
+ pre-processors. What you see is what you get: If something looks like a
+ function, you can be sure that it actually IS a function, and when something
+ looks like a variable, you can be sure that it also IS a variable.
+</p>
+<p>
+ Let's move on. Inside the get_module() function the Php::Extension object is
+ instantiated, and it is returned. It is crucial that you make a <i>static</i>
+ instance of this Php::Extension class, because the object must exist for the
+ entire lifetime of the PHP process, and not only for the duration of the get_module()
call. The constructor takes two arguments: the name of your extension and
- its version number. The Extension::module() method returns the memory address
- that PHP needs to initialize the library.
+ its version number.
+</p>
+<p>
+ The final step in the get_module() function is that the extension object
+ is returned. This may seem strange at first, because the get_module() function
+ is supposed to return a pointer-to-void, and not a full Php::Extension object.
+ Why does the compiler not complain about this? Well, the Php::Extension class
+ has a cast-to-void-pointer-operator. So although it seems that you're returning
+ the full extension object, in reality you only return a memory address that
+ points to a data structure that is understood by the core PHP engine and that
+ holds all the details of your extension.
</p>
<p>
Note that the example above does not yet export any native functions or
- native classes to PHP - it only creates the extension.
+ native classes to PHP - it only creates the extension. That is going to be
+ the next step.
</p>
+
+
+
<h2>Exporting native functions</h2>
<p>
An extension can of course only be useful if you define functions and/or