| <!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> |