mirror of https://github.com/swig/swig
1014 lines
27 KiB
HTML
1014 lines
27 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<!-- Hand crafted HTML -->
|
|
<html>
|
|
<head>
|
|
<title>SWIG and PHP</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<H1><a name="Php"></a>28 SWIG and PHP</H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Php_nn1">Generating PHP Extensions</a>
|
|
<ul>
|
|
<li><a href="#Php_nn1_1">Building a loadable extension</a>
|
|
<li><a href="#Php_nn1_2">Building extensions into PHP</a>
|
|
<li><a href="#Php_nn1_3">Using PHP Extensions</a>
|
|
</ul>
|
|
<li><a href="#Php_nn2">Basic PHP interface</a>
|
|
<ul>
|
|
<li><a href="#Php_nn2_1">Constants</a>
|
|
<li><a href="#Php_nn2_2">Global Variables</a>
|
|
<li><a href="#Php_nn2_3">Functions</a>
|
|
<li><a href="#Php_nn2_4">Overloading</a>
|
|
<li><a href="#Php_nn2_5">Pointers and References</a>
|
|
<li><a href="#Php_nn2_6">Structures and C++ classes</a>
|
|
<ul>
|
|
<li><a href="#Php_nn2_6_1">Using <tt>-noproxy</tt></a>
|
|
<li><a href="#Php_nn2_6_2">Constructors and Destructors</a>
|
|
<li><a href="#Php_nn2_6_3">Static Member Variables</a>
|
|
<li><a href="#Php_nn2_6_4">Static Member Functions</a>
|
|
</ul>
|
|
<li><a href="#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
|
|
</ul>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
<b>Caution: This chapter (and module!) is still under construction</b>
|
|
</p>
|
|
|
|
<p>
|
|
In this chapter, we discuss SWIG's support of PHP. The PHP module
|
|
was extensively rewritten in release 1.3.26, and although it is
|
|
significantly more functional, it still does not implement all the
|
|
features available in some of the other languages.
|
|
</p>
|
|
|
|
<p>
|
|
The examples and test cases have been developed with PHP4. Release
|
|
1.3.30 added support for generating PHP5 class wrappers for C++
|
|
libraries.
|
|
</p>
|
|
|
|
<p>
|
|
In order to use this module, you will need to have a copy of the PHP4 or PHP5
|
|
include files to compile the SWIG generated files. If you installed
|
|
PHP from a binary package, you may need to install a "php-dev" or "php-devel"
|
|
package for these to be installed. You can find out where these files are
|
|
by running <tt>php-config --includes</tt>. To use the built PHP module you
|
|
will need either the php binary or the Apache php module. If you want to build
|
|
your extension into php directly, you will need the complete PHP source tree
|
|
available.
|
|
</p>
|
|
|
|
<H2><a name="Php_nn1"></a>28.1 Generating PHP Extensions</H2>
|
|
|
|
|
|
<p>
|
|
To build a PHP extension, run swig using the <tt>-php</tt> option as
|
|
follows:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
swig -php example.i
|
|
</pre></div>
|
|
|
|
<p>
|
|
This will produce 3 files example_wrap.c, php_example.h and
|
|
example.php. The first file, <tt>example_wrap.c</tt> contains all of
|
|
the C code needed to build a PHP extension. The second file,
|
|
<tt>php_example.h</tt> contains the header information needed if
|
|
you wish to statically link the extension into the php interpreter.
|
|
The third file,
|
|
<tt>example.php</tt> can be included by PHP scripts. It attempts to
|
|
dynamically load the extension and contains extra php code specified
|
|
in the interface file. If wrapping C++ code for PHP5, it will
|
|
also contain PHP5 class wrappers.
|
|
</p>
|
|
|
|
<p>
|
|
Swig can generate PHP extensions from C++ libraries as well when
|
|
given the <tt>-c++</tt> option. The support for C++ is discussed in
|
|
more detail in <a href="#Php_nn2_6">section 27.2.6</a>.
|
|
</p>
|
|
|
|
<p>
|
|
The usual (and recommended) way is to build the extension as a separate
|
|
dynamically loaded module. You can then specify that this be loaded
|
|
automatically in <tt>php.ini</tt> or load it explicitly for any script which
|
|
needs it.
|
|
</p>
|
|
|
|
<p>
|
|
It is also possible to rebuild PHP from source so that your module is
|
|
statically linked into the php executable/library. This is a lot more
|
|
work, and also requires a full rebuild of PHP to update your module,
|
|
and it doesn't play nicely with package system. We don't recommend
|
|
this approach, but if you really want to do this, the <tt>-phpfull</tt>
|
|
command line argument to swig may be of use - see below for details.
|
|
</p>
|
|
|
|
<H3><a name="Php_nn1_1"></a>28.1.1 Building a loadable extension</H3>
|
|
|
|
|
|
<p>
|
|
To build your module as a dynamically loadable extension, use compilation
|
|
commands like these (if you aren't using GCC, the commands will be different,
|
|
and there may be so variation between platforms - these commands should at
|
|
least work for Linux though):
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
gcc `php-config --includes` -fpic -c example_wrap.c
|
|
gcc -shared example_wrap.o -o example.so
|
|
</pre></div>
|
|
|
|
<p>
|
|
There is a deprecated <tt>-make</tt> command line argument to swig which will
|
|
generate an additional file <tt>makefile</tt> which can usually build the
|
|
extension (at least on some UNIX platforms), but the Makefile generated isn't
|
|
very flexible, and the commands required are trivial so it is simpler to just
|
|
add them to your Makefile or other build system directly. We recommend that
|
|
you don't use <tt>-make</tt> and it's likely to be removed at some point.
|
|
</p>
|
|
|
|
<H3><a name="Php_nn1_2"></a>28.1.2 Building extensions into PHP</H3>
|
|
|
|
|
|
<p>
|
|
Note that we don't recommend this approach - it's cleaner and simpler to
|
|
use dynamically loadable modules, which are supported by all modern OSes.
|
|
Support for this may be discontinued entirely in the future.
|
|
</p>
|
|
|
|
<p>
|
|
It is possible to rebuild PHP itself with your module statically linked
|
|
in. To do this, you can use the <tt>-phpfull</tt> command line option to
|
|
swig. Using this option will generate three additional files. The first
|
|
extra file, <tt>config.m4</tt> contains the m4 and shell code needed to
|
|
enable the extension as part of the PHP build process. The second
|
|
extra file, <tt>Makefile.in</tt> contains the information needed to
|
|
build the final Makefile after substitutions. The third and final
|
|
extra file, <tt>CREDITS</tt> should contain the credits for the
|
|
extension.
|
|
</p>
|
|
|
|
<p>
|
|
To build with phpize, after you have run swig you will need to run the
|
|
'phpize' command (installed as part of php) in the same
|
|
directory. This re-creates the php build environment in that
|
|
directory. It also creates a configure file which includes the shell
|
|
code from the config.m4 that was generated by SWIG, this configure
|
|
script will accept a command line argument to enable the extension to
|
|
be run (by default the command line argument is --enable-modulename,
|
|
however you can edit the config.m4 file before running phpize to
|
|
accept --with-modulename. You can also add extra tests in config.m4 to
|
|
check that a correct library version is installed or correct header
|
|
files are included, etc, but you must edit this file before running
|
|
phpize.) You can also get SWIG to generate simple extra tests for
|
|
libraries and header files for you.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
swig -php -phpfull
|
|
</pre></div>
|
|
|
|
<p>
|
|
If you depend on source files not generated by SWIG, before generating
|
|
the configure file, you may need to edit the <tt>Makefile.in</tt>
|
|
file. This contains the names of the source files to compile (just the
|
|
wrapper file by default) and any additional libraries needed to be
|
|
linked in. If there are extra C files to compile, you will need to add
|
|
them to the <tt>Makefile.in</tt>, or add the names of libraries if they are
|
|
needed. In simple cases SWIG is pretty good at generating a complete
|
|
<tt>Makefile.in</tt> and <tt>config.m4</tt> which need no further editing.
|
|
</p>
|
|
|
|
<p>
|
|
You then run the configure script with the command line argument needed
|
|
to enable the extension. Then run make, which builds the extension.
|
|
The extension object file will be left in the modules sub directory, you can
|
|
move it to wherever it is convenient to call from your php script.
|
|
</p>
|
|
|
|
<p>
|
|
When using <tt>-phpfull</tt>, swig also accepts the following
|
|
additional optional arguments:
|
|
</p>
|
|
<ul>
|
|
<li><tt>-withincs "<incs>"</tt> Adds include files to the config.m4 file.
|
|
<li><tt>-withlibs "<libs>"</tt> Links with the specified libraries.
|
|
<li><tt>-withc "<files>"</tt> Compiles and links the additional specified C files.
|
|
<li><tt>-withcxx "<files>"</tt> Compiles and links the additional specified C++ files.
|
|
</ul>
|
|
|
|
<p>
|
|
After running swig with the <tt>-phpfull</tt> switch, you will be left with a shockingly
|
|
similar set of files to the previous build process. However you will then need
|
|
to move these files to a subdirectory within the php source tree, this subdirectory you will need to create under the ext directory, with the name of the extension (e.g. <tt>mkdir php-4.0.6/ext/modulename</tt>).
|
|
</p>
|
|
|
|
<p>
|
|
After moving the files into this directory, you will need to run the 'buildall'
|
|
script in the php source directory. This rebuilds the configure script
|
|
and includes the extra command line arguments from the module you have added.
|
|
</p>
|
|
|
|
<p>
|
|
Before running the generated configure file, you may need to edit the <tt>
|
|
Makefile.in</tt>. This contains the names of the source files to compile (
|
|
just the wrapper file by default) and any additional libraries needed to
|
|
link in. If there are extra C files to compile you will need to add them
|
|
to the Makefile, or add the names of libraries if they are needed.
|
|
In most cases <tt>Makefile.in</tt> will be complete, especially if you
|
|
make use of <tt>-withlibs</tt> and <tt>-withincs</tt>
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
swig -php -phpfull -withlibs "xapian omquery" --withincs "om.h"
|
|
</pre></div>
|
|
|
|
<p>
|
|
Will include in the <tt>config.m4</tt> and <tt>Makefile.in</tt> search for
|
|
<tt>libxapian.a</tt> or <tt>libxapian.so</tt> and search for
|
|
<tt>libomquery.a</tt> or <tt>libomquery.so</tt> as well as a
|
|
search for <tt>om.h</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
You then need to run the configure command and pass the necessary command
|
|
line arguments to enable your module (by default this is --enable-modulename,
|
|
but this can be changed by editing the config.m4 file in the modules directory
|
|
before running the buildall script. In addition, extra tests can be added to
|
|
the config.m4 file to ensure the correct libraries and header files are
|
|
installed.)
|
|
</p>
|
|
|
|
<p>
|
|
Once configure has completed, you can run make to build php. If this all
|
|
compiles correctly, you should end up with a php executable/library
|
|
which contains your new module. You can test it with a php script which
|
|
does not have the 'dl' command as used above.
|
|
</p>
|
|
|
|
<H3><a name="Php_nn1_3"></a>28.1.3 Using PHP Extensions</H3>
|
|
|
|
|
|
<p>
|
|
To test the extension from a PHP script, you need to load it first. You
|
|
can load it for every script by adding this line the <tt>[PHP]</tt> section of
|
|
<tt>php.ini</tt>:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
extension=/path/to/modulename.so
|
|
</pre></div>
|
|
|
|
<p>
|
|
Alternatively, you can load it explicitly only for scripts which need it
|
|
by adding this line:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
dl("/path/to/modulename.so"); // Load the module
|
|
</pre></div>
|
|
|
|
<p>
|
|
to the start of each PHP file. SWIG also generates a php module, which
|
|
attempts to do the <tt>dl()</tt> call for you:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
include("example.php");
|
|
</pre></div>
|
|
|
|
<H2><a name="Php_nn2"></a>28.2 Basic PHP interface</H2>
|
|
|
|
|
|
<p>
|
|
It is important to understand that PHP uses a single global namespace
|
|
into which all symbols from extension modules are loaded. It is quite
|
|
possible for names of symbols in one extension module to clash with
|
|
other symbols unless care is taken to <tt>%rename</tt> them.
|
|
</p>
|
|
|
|
<H3><a name="Php_nn2_1"></a>28.2.1 Constants</H3>
|
|
|
|
|
|
<p>
|
|
These work in much the same way as in C/C++, constants can be defined
|
|
by using either the normal C pre-processor declarations, or the
|
|
<tt>%constant</tt> SWIG directive. These will then be available from
|
|
your PHP script as a PHP constant, (i.e. no dollar sign is needed to
|
|
access them.) For example, with a swig interface file like this,
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
|
|
#define PI 3.14159
|
|
|
|
%constant int E = 2.71828
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
you can access the constants in your php script like this,
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
include("example.php");
|
|
|
|
echo "PI = " . PI . "\n";
|
|
|
|
echo "E = " . E . "\n";
|
|
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
There are two peculiarities with using constants in PHP. The first is that
|
|
if you try to use an undeclared constant, it will evaluate to a string
|
|
set to the constant's name. For example,
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
|
|
#define EASY_TO_MISPELL 0
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
accessed incorrectly in PHP,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
include("example.php");
|
|
|
|
if(EASY_TO_MISPEL) {
|
|
....
|
|
} else {
|
|
....
|
|
}
|
|
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
will issue a warning about the undeclared constant, but will then
|
|
evaluate it and turn it into a string ('EASY_TO_MISPEL'), which
|
|
evaluates to true, rather than the value of the constant which would
|
|
be false. This is a feature!
|
|
</p>
|
|
|
|
<p>
|
|
The second 'feature' is that although constants are case sensitive (by
|
|
default), you cannot declare a constant twice with alternative
|
|
cases. E.g.,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
#define TEST Hello
|
|
#define Test World
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
accessed from PHP,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
include("example.php");
|
|
|
|
echo TEST, Test;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
will output "Hello Test" rather than "Hello World". This is because
|
|
internally, all constants are stored in a hash table by their lower
|
|
case name, so 'TEST' and 'Test' will map to the same hash element
|
|
('Test'). But, because we declared them case sensitive, the Zend
|
|
engine will test if the case matches with the case the constant was
|
|
declared with first.
|
|
</p>
|
|
|
|
<p>
|
|
So, in the example above, the TEST constant was declared first, and
|
|
will be stored under the hash element 'test'. The 'Test' constant will
|
|
also map to the same hash element 'test', but will not overwrite
|
|
it. When called from the script, the TEST constant will again be
|
|
mapped to the hash element 'test' so the constant will be
|
|
retrieved. The case will then be checked, and will match up, so the
|
|
value ('Hello') will be returned. When 'Test' is evaluated, it will
|
|
also map to the same hash element 'test'. The same constant will be
|
|
retrieved, this time though the case check will fail as 'Test' !=
|
|
'TEST'. So PHP will assume that Test is a undeclared constant, and as
|
|
explained above, will return it as a string set to the constant name
|
|
('Test'). Hence the script above will print 'Hello Test'. If they were
|
|
declared non-case sensitive, the output would be 'Hello Hello', as
|
|
both point to the same value, without the case test taking place. (
|
|
Apologies, this paragraph needs rewriting to make some sense. )
|
|
</p>
|
|
|
|
<H3><a name="Php_nn2_2"></a>28.2.2 Global Variables</H3>
|
|
|
|
|
|
<p>
|
|
Because PHP does not provide a mechanism to intercept access and
|
|
assignment of global variables, global variables are supported through
|
|
the use of automatically generated accessor functions.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example;
|
|
|
|
%inline %{
|
|
double seki = 2;
|
|
void print_seki() {
|
|
zend_printf("seki is now %f\n",seki);
|
|
}
|
|
%}
|
|
</pre></div>
|
|
|
|
<p>
|
|
is accessed as follows:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
include("example.php");
|
|
print seki_get();
|
|
seki_set( seki_get() * 2); # The C variable is now 4.
|
|
print seki_get();
|
|
</pre></div>
|
|
|
|
<p>
|
|
SWIG supports global variables of all C datatypes including pointers
|
|
and complex objects. Additional types can be supported by using the
|
|
<tt>varinit</tt> typemap.
|
|
</p>
|
|
|
|
<p>
|
|
SWIG honors the <tt>%immutable</tt> modifier by not generating code
|
|
for the <tt>_set</tt> method. This provides read-only access to the
|
|
variable from the php script. Attempting to access the <tt>_set</tt>
|
|
method will result in a php fatal error because the function is
|
|
undefined.
|
|
</p>
|
|
|
|
<p>
|
|
At this time SWIG does not support custom accessor methods.
|
|
</p>
|
|
|
|
<H3><a name="Php_nn2_3"></a>28.2.3 Functions</H3>
|
|
|
|
|
|
<p>
|
|
C functions are converted into PHP functions. Default/optional arguments are
|
|
also allowed. An interface file like this :
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
int foo(int a);
|
|
double bar(double, double b = 3.0);
|
|
...
|
|
</pre></div>
|
|
|
|
<p>
|
|
Will be accessed in PHP like this :
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
include("example.php");
|
|
$a = foo(2);
|
|
$b = bar(3.5, -1.5);
|
|
$c = bar(3.5); # Use default argument for 2nd parameter
|
|
|
|
</pre></div>
|
|
|
|
<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
|
|
<p>
|
|
Because PHP is a dynamically typed language, the default typemaps
|
|
used for simple types will attempt to coerce the arguments into the appropriate type. That is the following invocations are equivalent:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$a = foo(2);
|
|
$a = foo("2");
|
|
$a = foo(2.0);
|
|
</pre></div>
|
|
|
|
<p>
|
|
Functions are invoked using pass by value semantics like all of PHP.
|
|
This means the conversion which automatically takes place when
|
|
invoking a swig wrapped method does not change the native type of the
|
|
argument variable.
|
|
</p>
|
|
<div class="code"><pre>
|
|
$s = "2 A string representing two";
|
|
$a = foo($s); # invokes 'foo(2)';
|
|
print $s; # The value of $s was not changed.
|
|
</pre></div>
|
|
-->
|
|
|
|
|
|
<H3><a name="Php_nn2_4"></a>28.2.4 Overloading</H3>
|
|
|
|
|
|
<p>
|
|
Although PHP does not support overloading functions natively, swig
|
|
will generate dispatch functions which will use <tt>%typecheck</tt>
|
|
typemaps to allow overloading. This dispatch function's operation and
|
|
precedence is described in <a
|
|
href="TypemapsSWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping
|
|
Overloaded Functions and Methods</a>.
|
|
</p>
|
|
|
|
<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
|
|
<p>
|
|
Because PHP4 is a dynamically typed language, simple values can be
|
|
silently converted from one type to another. For example, integers,
|
|
doubles and strings silently convert to each other depending on
|
|
context. This situation make overloading slightly problematic because
|
|
given the following function:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
void doit( int i );
|
|
void doit( double i );
|
|
</pre></div>
|
|
|
|
<p>
|
|
it is questionable which to invoke when <tt>doit("2");</tt> is used in
|
|
PHP. The string <tt>"2"</tt> simultaneously represents the integer
|
|
<tt>2</tt> and the double <tt>2.0</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
In order to provide the most natural experience to PHP programmers,
|
|
the default <tt>%typecheck</tt> implemented in <tt>php4.swg</tt>
|
|
allows any simple type (integer, double, string) in PHP to be used for
|
|
any simple C type (int, double, char *). The function selected then
|
|
depends only on the argument type precedence defined by SWIG.
|
|
</p>
|
|
|
|
<p>
|
|
It should be noted that <tt>SWIGTYPE</tt> references and pointers will
|
|
not be silently converted. So these two functions:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
void doit( const Vector & );
|
|
void doit( int i );
|
|
</pre></div>
|
|
|
|
<p>
|
|
Cause less confusion and <tt>doit("2");</tt> will invoke the function
|
|
taking the integer argument.
|
|
</p>
|
|
-->
|
|
|
|
<H3><a name="Php_nn2_5"></a>28.2.5 Pointers and References</H3>
|
|
|
|
|
|
<p>
|
|
Pointers to C/C++ objects are represented
|
|
as PHP resources, rather like MySQL connection handles.
|
|
</p>
|
|
|
|
<p>
|
|
There are multiple ways to wrap pointers to simple types. Given the
|
|
following C method:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
void add( int *in1, int *in2, int *result);
|
|
</pre></div>
|
|
|
|
<p>
|
|
One can include <b>cpointer.i</b> to generate PHP wrappers to <tt>int
|
|
*</tt>.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
%include cpointer.i
|
|
%pointer_functions(int,intp)
|
|
|
|
void add( int *in1, int *in2, int *result);
|
|
</pre></div>
|
|
|
|
<p>
|
|
This will result in the following usage in PHP:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
<?php
|
|
|
|
include("example.php");
|
|
|
|
$in1=copy_intp(3);
|
|
$in2=copy_intp(5);
|
|
$result=new_intp();
|
|
|
|
add( $in1, $in2, $result );
|
|
|
|
echo "The sum " . intp_value($in1) . " + " . intp_value($in2) . " = " . intp_value( $result) . "\n";
|
|
?>
|
|
</pre></div>
|
|
|
|
<p>
|
|
An alternative would be to use the include <b>typemaps.i</b> which
|
|
defines named typemaps for INPUT, OUTPUT and INOUT variables. One
|
|
needs to either <tt>%apply</tt> the appropriate typemap or adjust the
|
|
parameter names as appropriate.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
%include typemaps.i
|
|
|
|
void add( int *INPUT, int *INPUT, int *OUTPUT);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
This will result in the following usage in PHP:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
<?php
|
|
|
|
include("example.php");
|
|
|
|
$in1 = 3;
|
|
$in2 = 5;
|
|
$result= add($in1,$in2); # Note using variables for the input is unnecessary.
|
|
|
|
echo "The sum $in1 + $in2 = $result\n";
|
|
?>
|
|
</pre></div>
|
|
|
|
<p>
|
|
Because PHP has a native concept of reference, it may seem more natural
|
|
to the PHP developer to use references to pass pointers. To enable
|
|
this, one needs to include <b>phppointers.i</b> which defines the
|
|
named typemap REFERENCE.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
%include phppointers.i
|
|
|
|
void add( int *REF, int *REF, int *REF);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
This will result in the following usage in PHP:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
<?php
|
|
|
|
include("example.php");
|
|
|
|
$in1 = 3;
|
|
$in2 = 5;
|
|
$result = 0;
|
|
add(&$in1,&$in2,&$result);
|
|
|
|
echo "The sum $in1 + $in2 = $result\n";
|
|
?>
|
|
</pre></div>
|
|
|
|
<p>
|
|
It is important to note that a php variable which is NULL when passed
|
|
by reference would end up passing a NULL pointer into the function.
|
|
In PHP, an unassigned variable (i.e. where the first reference to the
|
|
variable is not an assignment) is
|
|
NULL. In the above example, if any of the three variables had not
|
|
been assigned, a NULL pointer would have been passed into
|
|
<tt>add</tt>. Depending on the implementation of the function, this
|
|
may or may not be a good thing.
|
|
</p>
|
|
|
|
<p>
|
|
We chose to allow passing NULL pointers into functions because that is
|
|
sometimes required in C libraries. A NULL pointer can be created in
|
|
PHP in a number of ways: by using <tt>unset</tt> on an existing
|
|
variable, or assigning <tt>NULL</tt> to a variable.
|
|
</p>
|
|
|
|
<H3><a name="Php_nn2_6"></a>28.2.6 Structures and C++ classes</H3>
|
|
|
|
|
|
<p>
|
|
SWIG defaults to wrapping C++ structs and classes with PHP classes. This
|
|
requires SWIG to generate different code for PHP4 and PHP5, so you must
|
|
specify which you want using <tt>-php4</tt> or <tt>-php5</tt> (currently
|
|
<tt>-php</tt> generates PHP4 class wrappers for compatibility with
|
|
SWIG 1.3.29 and earlier, but this may change in the future).
|
|
</p>
|
|
|
|
<p>
|
|
PHP4 classes are implemented entirely using the Zend C API so
|
|
no additional php code is generated. For PHP5, a PHP wrapper
|
|
class is generated which calls a set of flat functions wrapping the C++ class.
|
|
In many cases the PHP4 and PHP5 wrappers will behave the same way,
|
|
but the PHP5 ones make use of better PHP5's better OO functionality
|
|
where appropriate.
|
|
</p>
|
|
|
|
<p>
|
|
This interface file
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module vector
|
|
|
|
class Vector {
|
|
public:
|
|
double x,y,z;
|
|
Vector();
|
|
~Vector();
|
|
double magnitude();
|
|
};
|
|
|
|
struct Complex {
|
|
double re, im;
|
|
};
|
|
</pre></div>
|
|
|
|
<p>
|
|
Would be used in the following way from either PHP4 or PHP5:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
<?php
|
|
require "vector.php";
|
|
|
|
$v = new Vector();
|
|
$v->x = 3;
|
|
$v->y = 4;
|
|
$v->z = 5;
|
|
|
|
echo "Magnitude of ($v->x,$v->y,$v->z) = " . $v->magnitude() . "\n";
|
|
|
|
$v = NULL; # destructor called.
|
|
|
|
$c = new Complex();
|
|
|
|
$c->re = 0;
|
|
$c->im = 0;
|
|
|
|
# $c destructor called when $c goes out of scope.
|
|
?>
|
|
</pre></div>
|
|
|
|
<p>
|
|
Member variables and methods are accessed using the <tt>-></tt> operator.
|
|
</p>
|
|
|
|
<H4><a name="Php_nn2_6_1"></a>28.2.6.1 Using <tt>-noproxy</tt></H4>
|
|
|
|
|
|
<p>
|
|
The <tt>-noproxy</tt> option flattens the object structure and
|
|
generates collections of named functions (these are the functions
|
|
which the PHP5 class wrappers call). The above example results
|
|
in the following PHP functions:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
new_Vector();
|
|
Vector_x_set($obj,$d);
|
|
Vector_x_get($obj);
|
|
Vector_y_set($obj,$d);
|
|
Vector_y_get($obj);
|
|
Vector_z_set($obj,$d);
|
|
Vector_z_get($obj);
|
|
Vector_magnitude($obj);
|
|
new_Complex();
|
|
Complex_re_set($obj,$d);
|
|
Complex_re_get($obj);
|
|
Complex_im_set($obj,$d);
|
|
Complex_im_get($obj);
|
|
</pre></div>
|
|
|
|
<H4><a name="Php_nn2_6_2"></a>28.2.6.2 Constructors and Destructors</H4>
|
|
|
|
|
|
<p>
|
|
The constructor is called when <tt>new Object()</tt> (or
|
|
<tt>new_Object()</tt> if using <tt>-noproxy</tt>) is used to create an
|
|
instance of the object. If multiple constructors are defined for an
|
|
object, function overloading will be used to determine which
|
|
constructor to execute.
|
|
</p>
|
|
|
|
<p>
|
|
Because PHP uses reference counting to manage resources, simple
|
|
assignment of one variable to another such as:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ref = $v;
|
|
</pre></div>
|
|
|
|
<p>
|
|
causes the symbol <tt>$ref</tt> to refer to the same underlying object
|
|
as <tt>$v</tt>. This does not result in a call to the C++ copy
|
|
constructor or copy assignment operator.
|
|
</p>
|
|
|
|
<p>
|
|
One can force execution of the copy constructor by using:
|
|
</p>
|
|
<div class="code"><pre>
|
|
$o_copy = new Object($o);
|
|
</pre></div>
|
|
|
|
<p>
|
|
Destructors are automatically called when all variables referencing
|
|
the instance are reassigned or go out of scope. The destructor is not
|
|
available to be called manually. To force a destructor to be called
|
|
the programmer can either reassign the variable or call
|
|
<tt>unset($v)</tt>
|
|
</p>
|
|
|
|
<H4><a name="Php_nn2_6_3"></a>28.2.6.3 Static Member Variables</H4>
|
|
|
|
|
|
<p>
|
|
Static member variables are not supported in PHP4, and it does not
|
|
appear to be possible to intercept accesses to static member variables
|
|
in PHP5. Therefore, static member variables are
|
|
wrapped using a class function with the same name, which
|
|
returns the current value of the class variable. For example
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
|
|
class Ko {
|
|
static int threats;
|
|
};
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
would be accessed in PHP as,
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
include("example.php");
|
|
|
|
echo "There has now been " . Ko::threats() . " threats\n";
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
To set the static member variable, pass the value as the argument to the class
|
|
function, e.g.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
|
|
Ko::threats(10);
|
|
|
|
echo "There has now been " . Ko::threats() . " threats\n";
|
|
|
|
</pre></div>
|
|
<H4><a name="Php_nn2_6_4"></a>28.2.6.4 Static Member Functions</H4>
|
|
|
|
|
|
<p>
|
|
Static member functions are supported in PHP using the
|
|
<tt>class::function()</tt> syntax. For example
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
class Ko {
|
|
static void threats();
|
|
};
|
|
</pre></div>
|
|
|
|
would be executed in PHP as,
|
|
<div class="code"><pre>
|
|
include("example.php");
|
|
Ko::threats();
|
|
</pre></div>
|
|
|
|
|
|
<H3><a name="Php_nn2_7"></a>28.2.7 PHP Pragmas, Startup and Shutdown code</H3>
|
|
|
|
|
|
<p>
|
|
Note: Currently pragmas for PHP need to be specified using
|
|
<tt>%pragma(php4)</tt> but also apply for PHP5! This is just a historical
|
|
oddity because SWIG's PHP support predates PHP5.
|
|
</p>
|
|
|
|
<p>
|
|
To place PHP code in the generated "example.php" file one can use the
|
|
<b>code</b> pragma. The code is inserted after loading the shared
|
|
object.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
%pragma(php4) code="
|
|
# This code is inserted into example.php
|
|
echo \"example.php execution\\n\";
|
|
"
|
|
</pre></div>
|
|
|
|
<p>
|
|
Results in the following in "example.php"
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
# This code is inserted into example.php
|
|
echo "example.php execution\n";
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <b>include</b> pragma is a short cut to add include statements to
|
|
the example.php file.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
%pragma(php4) code="
|
|
include \"include.php\";
|
|
"
|
|
%pragma(php) include="include.php" // equivalent.
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <b>phpinfo</b> pragma inserts code in the
|
|
<tt>PHP_MINFO_FUNCTION</tt> which is called from PHP's
|
|
phpinfo() function.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example;
|
|
%pragma(php4) phpinfo="
|
|
zend_printf("An example of PHP support through SWIG\n");
|
|
php_info_print_table_start();
|
|
php_info_print_table_header(2, \"Directive\", \"Value\");
|
|
php_info_print_table_row(2, \"Example support\", \"enabled\");
|
|
php_info_print_table_end();
|
|
"
|
|
</pre></div>
|
|
|
|
<p>
|
|
To insert code into the <tt>PHP_MINIT_FUNCTION</tt>, one can use
|
|
either <tt>%init</tt> or <tt>%minit</tt>.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example;
|
|
%init {
|
|
zend_printf("Inserted into PHP_MINIT_FUNCTION\n");
|
|
}
|
|
%minit {
|
|
zend_printf("Inserted into PHP_MINIT_FUNCTION\n");
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
To insert code into the <tt>PHP_MSHUTDOWN_FUNCTION</tt>, one can use
|
|
either <tt>%init</tt> or <tt>%minit</tt>.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example;
|
|
%mshutdown {
|
|
zend_printf("Inserted into PHP_MSHUTDOWN_FUNCTION\n");
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <tt>%rinit</tt> and <tt>%rshutdown</tt> statements insert code
|
|
into the request init and shutdown code respectively.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|