| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| 2 | <!-- Hand crafted HTML --> |
| 3 | <html> |
| 4 | <head> |
| 5 | <title>SWIG and PHP4</title> |
| 6 | <link rel="stylesheet" type="text/css" href="style.css"> |
| 7 | </head> |
| 8 | |
| 9 | <body bgcolor="#ffffff"> |
| 10 | <H1><a name="Php"></a>24 SWIG and PHP4</H1> |
| 11 | <!-- INDEX --> |
| 12 | <div class="sectiontoc"> |
| 13 | <ul> |
| 14 | <li><a href="#Php_nn1">Generating PHP4 Extensions</a> |
| 15 | <ul> |
| 16 | <li><a href="#Php_nn1_1">Building a loadable extension</a> |
| 17 | <li><a href="#Php_nn1_2">Building extensions into PHP</a> |
| 18 | <li><a href="#Php_nn1_3">Using PHP4 Extensions</a> |
| 19 | </ul> |
| 20 | <li><a href="#Php_nn2">Basic PHP4 interface</a> |
| 21 | <ul> |
| 22 | <li><a href="#Php_nn2_1">Constants</a> |
| 23 | <li><a href="#Php_nn2_2">Global Variables</a> |
| 24 | <li><a href="#Php_nn2_3">Functions</a> |
| 25 | <li><a href="#Php_nn2_4">Overloading</a> |
| 26 | <li><a href="#Php_nn2_5">Pointers and References</a> |
| 27 | <li><a href="#Php_nn2_6">Structures and C++ classes</a> |
| 28 | <ul> |
| 29 | <li><a href="#Php_nn2_6_1">Using <tt>-noproxy</tt></a> |
| 30 | <li><a href="#Php_nn2_6_2">Constructors and Destructors</a> |
| 31 | <li><a href="#Php_nn2_6_3">Static Member Variables</a> |
| 32 | <li><a href="#Php_nn2_6_4">Static Member Functions</a> |
| 33 | </ul> |
| 34 | <li><a href="#Php_nn2_7">PHP4 Pragmas, Startup and Shutdown code</a> |
| 35 | </ul> |
| 36 | </ul> |
| 37 | </div> |
| 38 | <!-- INDEX --> |
| 39 | |
| 40 | |
| 41 | |
| 42 | <p> |
| 43 | <b>Caution: This chapter (and module!) is still under construction</b> |
| 44 | </p> |
| 45 | |
| 46 | <p> |
| 47 | In this chapter, we discuss SWIG's support of PHP4. The PHP4 module |
| 48 | has been extensively rewritten in release 1.3.26. Although it is |
| 49 | significantly more functional, it still does not implement all the |
| 50 | features available in other languages. |
| 51 | </p> |
| 52 | |
| 53 | <p> |
| 54 | The examples and test cases have been developed with PHP4. |
| 55 | Support for PHP5 at this time is limited to wrapping C libraries or |
| 56 | C++ libraries while using the <tt>-noproxy</tt> flag. This deficiency |
| 57 | will be fixed in a subsequent release of SWIG. |
| 58 | </p> |
| 59 | |
| 60 | <p> |
| 61 | In order to use this module, you will need to have a copy of the PHP 4.0 (or |
| 62 | above) include files to compile the SWIG generated files. You can find these |
| 63 | files by running <tt>'php-config --includes'</tt>. To test the modules you will |
| 64 | need either the php binary or the Apache php module. If you want to build your |
| 65 | extension into php directly (without having the overhead of loading it into |
| 66 | each script), you will need the complete PHP source tree available. |
| 67 | </p> |
| 68 | |
| 69 | <H2><a name="Php_nn1"></a>24.1 Generating PHP4 Extensions</H2> |
| 70 | |
| 71 | |
| 72 | <p> |
| 73 | To build a PHP4 extension, run swig using the <tt>-php4</tt> option as |
| 74 | follows : |
| 75 | </p> |
| 76 | |
| 77 | <div class="code"><pre> |
| 78 | swig -php4 example.i |
| 79 | </pre></div> |
| 80 | |
| 81 | <p> |
| 82 | This will produce 3 files example_wrap.c, php_example.h and |
| 83 | example.php. The first file, <tt>example_wrap.c</tt> contains all of |
| 84 | the C code needed to build a PHP4 extension. The second file, |
| 85 | <tt>php_example.h</tt> contains the header information needed to |
| 86 | statically link the extension into PHP. The third file, |
| 87 | <tt>example.php</tt> can be included by php scripts. It attempts to |
| 88 | dynamically load the extension and contains extra php code specified |
| 89 | in the interface file. |
| 90 | </p> |
| 91 | |
| 92 | <p> |
| 93 | Swig can generate PHP4 extensions from C++ libraries as well when |
| 94 | given the <tt>-c++</tt> option. The support for C++ is discussed in |
| 95 | more detail in <a href="#Php_nn2_6">section 24.2.6</a>. |
| 96 | </p> |
| 97 | |
| 98 | <p> |
| 99 | To finish building the extension, you have two choices. You can either build |
| 100 | the extension as a separate shared object file which will then have to be explicitly |
| 101 | loaded by each script. Or you can rebuild the entire php source tree and build |
| 102 | the extension into the php executable/library so it will be available in every |
| 103 | script. The first choice is the default, however it can be changed by passing |
| 104 | the '-phpfull' command line switch to select the second build method. |
| 105 | </p> |
| 106 | |
| 107 | <H3><a name="Php_nn1_1"></a>24.1.1 Building a loadable extension</H3> |
| 108 | |
| 109 | |
| 110 | <p> |
| 111 | There are two methods to build the extension as a dynamically loaded |
| 112 | module: using standard compilation utilities (make, gcc), or using |
| 113 | PHP4's <em>phpize</em> utility. |
| 114 | </p> |
| 115 | |
| 116 | <p> |
| 117 | To build manually, use a compile string similar to this (different for each |
| 118 | OS): |
| 119 | </p> |
| 120 | <div class="code"><pre> |
| 121 | cc -I.. $(PHPINC) -fpic -c example_wrap.c |
| 122 | cc -shared example_wrap.o -o libexample.so |
| 123 | </pre></div> |
| 124 | |
| 125 | <p> |
| 126 | The <tt>-make</tt> command line argument to swig will generate an |
| 127 | additional file Makefile. This Makefile can usually build the |
| 128 | extension itself (on unix platforms). |
| 129 | </p> |
| 130 | |
| 131 | <p> |
| 132 | If you want to build your extension using the <tt>phpize</tt> |
| 133 | utility, or if you want to build your module into PHP directly, you |
| 134 | can specify the <tt>-phpfull</tt> command line argument to swig. |
| 135 | </p> |
| 136 | |
| 137 | <p> |
| 138 | The <tt>-phpfull</tt> will generate three additional files. The first |
| 139 | extra file, <tt>config.m4</tt> contains the shell code needed to |
| 140 | enable the extension as part of the PHP4 build process. The second |
| 141 | extra file, <tt>Makefile.in</tt> contains the information needed to |
| 142 | build the final Makefile after substitutions. The third and final |
| 143 | extra file, <tt>CREDITS</tt> should contain the credits for the |
| 144 | extension. |
| 145 | </p> |
| 146 | |
| 147 | <p> |
| 148 | To build with phpize, after you have run swig you will need to run the |
| 149 | 'phpize' command (installed as part of php) in the same |
| 150 | directory. This re-creates the php build environment in that |
| 151 | directory. It also creates a configure file which includes the shell |
| 152 | code from the config.m4 that was generated by SWIG, this configure |
| 153 | script will accept a command line argument to enable the extension to |
| 154 | be run ( by default the command line argument is --enable-modulename, |
| 155 | however you can edit the config.m4 file before running phpize to |
| 156 | accept --with-modulename. You can also add extra tests in config.m4 to |
| 157 | check that a correct library version is installed or correct header |
| 158 | files are included, etc, but you must edit this file before running |
| 159 | phpize. ) If you like SWIG can generate simple extra tests for |
| 160 | libraries and header files for you. |
| 161 | </p> |
| 162 | |
| 163 | <div class="code"><pre> |
| 164 | swig -php4 -phpfull |
| 165 | </pre></div> |
| 166 | |
| 167 | <p> |
| 168 | If you depend on source files not generated by SWIG, before generating |
| 169 | the configure file, you may need to edit the <tt>Makefile.in</tt> |
| 170 | file. This contains the names of the source files to compile (just the |
| 171 | wrapper file by default) and any additional libraries needed to be |
| 172 | linked in. If there are extra C files to compile, you will need to add |
| 173 | them to the Makefile.in, or add the names of libraries if they are |
| 174 | needed. In simple cases SWIG is pretty good at generating a complete |
| 175 | Makefile.in and config.m4 which need no further editing. |
| 176 | </p> |
| 177 | |
| 178 | <p> |
| 179 | You then run the configure script with the command line argument needed |
| 180 | to enable the extension. Then run make, which builds the extension. |
| 181 | The extension object file will be left in the modules sub directory, you can |
| 182 | move it to wherever it is convenient to call from your php script. |
| 183 | </p> |
| 184 | |
| 185 | <p> |
| 186 | Both the <tt>-make</tt> and <tt>-phpfull</tt> arguments accept |
| 187 | additional optional arguments: |
| 188 | </p> |
| 189 | <ul> |
| 190 | <li><tt>-withincs "<files>"</tt> Adds include files to the config.m4 file. |
| 191 | <li><tt>-withlibs "<files>"</tt> Links the libraries into the shared object. |
| 192 | <li><tt>-withc "<files>"</tt> Compiles and links the named C files into the shared object. |
| 193 | <li><tt>-withcxx "<files>"</tt> Compiles and links the named C++ files into the shared object, |
| 194 | <li><tt>-dlname "<name>"</tt> Changes the name of the generated shared object. |
| 195 | </ul> |
| 196 | |
| 197 | <H3><a name="Php_nn1_2"></a>24.1.2 Building extensions into PHP</H3> |
| 198 | |
| 199 | |
| 200 | <p> |
| 201 | This method, selected with the <tt>-phpfull</tt> command line switch, involves |
| 202 | rebuilding the entire php source tree. Whilst more complicated to build, |
| 203 | it does mean that the extension is then available without having to load it |
| 204 | in each script. |
| 205 | </p> |
| 206 | |
| 207 | <p> |
| 208 | After running swig with the -phpfull switch, you will be left with a shockingly |
| 209 | similar set of files to the previous build process. However you will then need |
| 210 | 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 mkdir php-4.0.6/ext/modulename .) |
| 211 | </p> |
| 212 | |
| 213 | <p> |
| 214 | After moving the files into this directory, you will need to run the 'buildall' |
| 215 | script in the php source directory. This rebuilds the configure script |
| 216 | and includes the extra command line arguments from the module you have added. |
| 217 | </p> |
| 218 | |
| 219 | <p> |
| 220 | Before running the generated configure file, you may need to edit the <tt> |
| 221 | Makefile.in</tt>. This contains the names of the source files to compile ( |
| 222 | just the wrapper file by default) and any additional libraries needed to |
| 223 | link in. If there are extra C files to compile you will need to add them |
| 224 | to the Makefile, or add the names of libraries if they are needed. |
| 225 | In most cases <tt>Makefile.in</tt> will be complete, especially if you |
| 226 | make use of <tt>-withlibs</tt> and <tt>-withincs</tt> |
| 227 | </p> |
| 228 | |
| 229 | <div class="code"><pre> |
| 230 | swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h" |
| 231 | </pre></div> |
| 232 | |
| 233 | <p> |
| 234 | Will include in the config.m4 and Makefile.in search for libxapian.a or |
| 235 | libxapian.so and search for libomquery.a or libomquery.so as well as a |
| 236 | search for om.h |
| 237 | </p> |
| 238 | |
| 239 | <p> |
| 240 | You then need to run the configure command and pass the necessary command |
| 241 | line arguments to enable your module ( by default this is --enable-modulename, |
| 242 | but this can be changed by editing the config.m4 file in the modules directory |
| 243 | before running the buildall script. In addition, extra tests can be added to |
| 244 | the config.m4 file to ensure the correct libraries and header files are |
| 245 | installed.) |
| 246 | </p> |
| 247 | |
| 248 | <p> |
| 249 | Once configure has completed, you can run make to build php. If this all |
| 250 | compiles correctly, you should end up with a php executable/library |
| 251 | which contains your new module. You can test it with a php script which |
| 252 | does not have the 'dl' command as used above. |
| 253 | </p> |
| 254 | |
| 255 | <H3><a name="Php_nn1_3"></a>24.1.3 Using PHP4 Extensions</H3> |
| 256 | |
| 257 | |
| 258 | <p> |
| 259 | To test the extension from a PHP script, you need to load it first. You do |
| 260 | this by putting the line, |
| 261 | </p> |
| 262 | |
| 263 | <div class="code"><pre> |
| 264 | dl("/path/to/modulename.so"); // Load the module |
| 265 | </pre></div> |
| 266 | |
| 267 | <p> |
| 268 | at the start of each PHP file. SWIG also generates a php module, which |
| 269 | attempts to do the <tt>dl()</tt> call for you: |
| 270 | </p> |
| 271 | |
| 272 | <div class="code"><pre> |
| 273 | include("example.php"); |
| 274 | </pre></div> |
| 275 | |
| 276 | |
| 277 | |
| 278 | <H2><a name="Php_nn2"></a>24.2 Basic PHP4 interface</H2> |
| 279 | |
| 280 | |
| 281 | <p> |
| 282 | It is important to understand that PHP uses a single global namespace |
| 283 | into which all symbols from extension modules are loaded. It is quite |
| 284 | possible for names of symbols in one extension module to clash with |
| 285 | other symbols unless care is taken to <tt>%rename</tt> them. |
| 286 | </p> |
| 287 | |
| 288 | <H3><a name="Php_nn2_1"></a>24.2.1 Constants</H3> |
| 289 | |
| 290 | |
| 291 | <p> |
| 292 | These work in much the same way as in C/C++, constants can be defined |
| 293 | by using either the normal C pre-processor declarations, or the |
| 294 | <tt>%constant</tt> SWIG directive. These will then be available from |
| 295 | your PHP script as a PHP constant, (i.e. no dollar sign is needed to |
| 296 | access them. ) For example, with a swig file like this, |
| 297 | </p> |
| 298 | |
| 299 | <div class="code"><pre> |
| 300 | %module example |
| 301 | |
| 302 | #define PI 3.14159 |
| 303 | |
| 304 | %constant int E = 2.71828 |
| 305 | </pre> |
| 306 | </div> |
| 307 | |
| 308 | <p> |
| 309 | you can access the constants in your php script like this, |
| 310 | </p> |
| 311 | |
| 312 | <div class="code"><pre> |
| 313 | include("example.php"); |
| 314 | |
| 315 | echo "PI = " . PI . "\n"; |
| 316 | |
| 317 | echo "E = " . E . "\n"; |
| 318 | |
| 319 | </pre> |
| 320 | </div> |
| 321 | |
| 322 | <p> |
| 323 | There are two peculiarities with using constants in PHP4. The first is that |
| 324 | if you try to use an undeclared constant, it will evaluate to a string |
| 325 | set to the constant's name. For example, |
| 326 | </p> |
| 327 | |
| 328 | <div class="code"><pre> |
| 329 | %module example |
| 330 | |
| 331 | #define EASY_TO_MISPELL 0 |
| 332 | </pre> |
| 333 | </div> |
| 334 | |
| 335 | <p> |
| 336 | accessed incorrectly in PHP, |
| 337 | </p> |
| 338 | |
| 339 | <div class="code"> |
| 340 | <pre> |
| 341 | include("example.php"); |
| 342 | |
| 343 | if(EASY_TO_MISPEL) { |
| 344 | .... |
| 345 | } else { |
| 346 | .... |
| 347 | } |
| 348 | |
| 349 | </pre> |
| 350 | </div> |
| 351 | |
| 352 | <p> |
| 353 | will issue a warning about the undeclared constant, but will then |
| 354 | evaluate it and turn it into a string ('EASY_TO_MISPEL'), which |
| 355 | evaluates to true, rather than the value of the constant which would |
| 356 | be false. This is a feature. |
| 357 | </p> |
| 358 | |
| 359 | <p> |
| 360 | The second 'feature' is that although constants are case sensitive (by |
| 361 | default), you cannot declare a constant twice with alternative |
| 362 | cases. E.g., |
| 363 | </p> |
| 364 | |
| 365 | <div class="code"> |
| 366 | <pre> |
| 367 | %module example |
| 368 | |
| 369 | #define TEST Hello |
| 370 | #define Test World |
| 371 | </pre> |
| 372 | </div> |
| 373 | |
| 374 | <p> |
| 375 | accessed from PHP, |
| 376 | </p> |
| 377 | |
| 378 | <div class="code"> |
| 379 | <pre> |
| 380 | include("example.php"); |
| 381 | |
| 382 | echo TEST, Test; |
| 383 | </pre> |
| 384 | </div> |
| 385 | |
| 386 | <p> |
| 387 | will output "Hello Test" rather than "Hello World". This is because |
| 388 | internally, all constants are stored in a hash table by their lower |
| 389 | case name, so 'TEST' and 'Test' will map to the same hash element |
| 390 | ('Test'). But, because we declared them case sensitive, the Zend |
| 391 | engine will test if the case matches with the case the constant was |
| 392 | declared with first. |
| 393 | </p> |
| 394 | |
| 395 | <p> |
| 396 | So, in the example above, the TEST constant was declared first, and |
| 397 | will be stored under the hash element 'test'. The 'Test' constant will |
| 398 | also map to the same hash element 'test', but will not overwrite |
| 399 | it. When called from the script, the TEST constant will again be |
| 400 | mapped to the hash element 'test' so the constant will be |
| 401 | retrieved. The case will then be checked, and will match up, so the |
| 402 | value ('Hello') will be returned. When 'Test' is evaluated, it will |
| 403 | also map to the same hash element 'test'. The same constant will be |
| 404 | retrieved, this time though the case check will fail as 'Test' != |
| 405 | 'TEST'. So PHP will assume that Test is a undeclared constant, and as |
| 406 | explained above, will return it as a string set to the constant name |
| 407 | ('Test'). Hence the script above will print 'Hello Test'. If they were |
| 408 | declared non-case sensitive, the output would be 'Hello Hello', as |
| 409 | both point to the same value, without the case test taking place. ( |
| 410 | Apologies, this paragraph needs rewriting to make some sense. ) |
| 411 | </p> |
| 412 | |
| 413 | <H3><a name="Php_nn2_2"></a>24.2.2 Global Variables</H3> |
| 414 | |
| 415 | |
| 416 | <p> |
| 417 | Because PHP4 does not provide a mechanism to intercept access and |
| 418 | assignment of global variables, global variables are supported through |
| 419 | the use of automatically generated accessor functions. |
| 420 | </p> |
| 421 | |
| 422 | <div class="code"><pre> |
| 423 | %module example; |
| 424 | |
| 425 | %inline %{ |
| 426 | double seki = 2; |
| 427 | void print_seki() { |
| 428 | zend_printf("seki is now %f\n",seki); |
| 429 | } |
| 430 | %} |
| 431 | </pre></div> |
| 432 | |
| 433 | <p> |
| 434 | is accessed as follows: |
| 435 | </p> |
| 436 | |
| 437 | <div class="code"><pre> |
| 438 | include("example.php"); |
| 439 | print seki_get(); |
| 440 | seki_set( seki_get() * 2); # The C variable is now 4. |
| 441 | print seki_get(); |
| 442 | </pre></div> |
| 443 | |
| 444 | <p> |
| 445 | SWIG supports global variables of all C datatypes including pointers |
| 446 | and complex objects. Additional types can be supported by using the |
| 447 | <tt>varinit</tt> typemap. |
| 448 | </p> |
| 449 | |
| 450 | <p> |
| 451 | SWIG honors the <tt>%immutable</tt> modifier by not generating code |
| 452 | for the <tt>_set</tt> method. This provides read-only access to the |
| 453 | variable from the php script. Attempting to access the <tt>_set</tt> |
| 454 | method will result in a php fatal error because the function is |
| 455 | undefined. |
| 456 | </p> |
| 457 | |
| 458 | <p> |
| 459 | At this time SWIG does not support custom accessor methods. |
| 460 | </p> |
| 461 | |
| 462 | <H3><a name="Php_nn2_3"></a>24.2.3 Functions</H3> |
| 463 | |
| 464 | |
| 465 | <p> |
| 466 | C functions are converted into PHP functions. Default/optional arguments are |
| 467 | also allowed. An interface file like this : |
| 468 | </p> |
| 469 | |
| 470 | <div class="code"><pre> |
| 471 | %module example |
| 472 | int foo(int a); |
| 473 | double bar(double, double b = 3.0); |
| 474 | ... |
| 475 | </pre></div> |
| 476 | |
| 477 | <p> |
| 478 | Will be accessed in PHP like this : |
| 479 | </p> |
| 480 | |
| 481 | <div class="code"><pre> |
| 482 | include("example.php"); |
| 483 | $a = foo(2); |
| 484 | $b = bar(3.5, -1.5); |
| 485 | $c = bar(3.5); # Use default argument for 2nd parameter |
| 486 | |
| 487 | </pre></div> |
| 488 | |
| 489 | <p> |
| 490 | Because PHP4 is a dynamically typed language, the default typemaps |
| 491 | used for simple types will attempt to coerce the arguments into the appropriate type. That is the following invocations are equivalent: |
| 492 | </p> |
| 493 | |
| 494 | <div class="code"><pre> |
| 495 | $a = foo(2); |
| 496 | $a = foo("2"); |
| 497 | $a = foo(2.0); |
| 498 | </pre></div> |
| 499 | |
| 500 | <p> |
| 501 | Functions are invoked using pass by value semantics like all of PHP. |
| 502 | This means the conversion which automatically takes place when |
| 503 | invoking a swig wrapped method does not change the native type of the |
| 504 | argument variable. |
| 505 | </p> |
| 506 | <div class="code"><pre> |
| 507 | $s = "2 A string representing two"; |
| 508 | $a = foo($s); # invokes 'foo(2)'; |
| 509 | print $s; # The value of $s was not changed. |
| 510 | </pre></div> |
| 511 | |
| 512 | |
| 513 | <H3><a name="Php_nn2_4"></a>24.2.4 Overloading</H3> |
| 514 | |
| 515 | |
| 516 | <p> |
| 517 | Although PHP4 does not support overloading functions natively, swig |
| 518 | will generate dispatch functions which will use <tt>%typecheck</tt> |
| 519 | typemaps to allow overloading. This dispatch function's operation and |
| 520 | precedence is described in <a |
| 521 | href="TypemapsSWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping |
| 522 | Overloaded Functions and Methods</a>. |
| 523 | </p> |
| 524 | |
| 525 | <p> |
| 526 | Because PHP4 is a dynamically typed language, simple values can be |
| 527 | silently converted from one type to another. For example, integers, |
| 528 | doubles and strings silently convert to each other depending on |
| 529 | context. This situation make overloading slightly problematic because |
| 530 | given the following function: |
| 531 | </p> |
| 532 | |
| 533 | <div class="code"><pre> |
| 534 | void doit( int i ); |
| 535 | void doit( double i ); |
| 536 | </pre></div> |
| 537 | |
| 538 | <p> |
| 539 | it is questionable which to invoke when <tt>doit("2");</tt> is used in |
| 540 | PHP. The string <tt>"2"</tt> simultaneously represents the integer |
| 541 | <tt>2</tt> and the double <tt>2.0</tt>. |
| 542 | </p> |
| 543 | |
| 544 | <p> |
| 545 | In order to provide the most natural experience to PHP programmers, |
| 546 | the default <tt>%typecheck</tt> implemented in <tt>php4.swg</tt> |
| 547 | allows any simple type (integer, double, string) in PHP to be used for |
| 548 | any simple C type (int, double, char *). The function selected then |
| 549 | depends only on the argument type precedence defined by SWIG. |
| 550 | </p> |
| 551 | |
| 552 | <p> |
| 553 | It should be noted that <tt>SWIGTYPE</tt> references and pointers will |
| 554 | not be silently converted. So these two functions: |
| 555 | </p> |
| 556 | |
| 557 | <div class="code"><pre> |
| 558 | void doit( const Vector & ); |
| 559 | void doit( int i ); |
| 560 | </pre></div> |
| 561 | |
| 562 | <p> |
| 563 | Cause less confusion and <tt>doit("2");</tt> will invoke the function |
| 564 | taking the integer argument. |
| 565 | </p> |
| 566 | |
| 567 | <H3><a name="Php_nn2_5"></a>24.2.5 Pointers and References</H3> |
| 568 | |
| 569 | |
| 570 | <p> |
| 571 | Pointers to C/C++ objects are <b>no longer</b> represented as character |
| 572 | strings such as: <tt>_523d3f4_Circle_p</tt>, instead they are represented |
| 573 | as PHP resources, rather like MySQL connection handles. |
| 574 | </p> |
| 575 | |
| 576 | <p> |
| 577 | There are multiple ways to wrap pointers to simple types. Given the |
| 578 | following C method: |
| 579 | </p> |
| 580 | |
| 581 | <div class="code"><pre> |
| 582 | void add( int *in1, int *in2, int *result); |
| 583 | </pre></div> |
| 584 | |
| 585 | <p> |
| 586 | One can include <b>cpointer.i</b> to generate PHP wrappers to <tt>int |
| 587 | *</tt>. |
| 588 | </p> |
| 589 | |
| 590 | <div class="code"><pre> |
| 591 | %module example |
| 592 | %include cpointer.i |
| 593 | %pointer_functions(int,intp) |
| 594 | |
| 595 | void add( int *in1, int *in2, int *result); |
| 596 | </pre></div> |
| 597 | |
| 598 | <p> |
| 599 | This will result in the following usage in PHP: |
| 600 | </p> |
| 601 | |
| 602 | <div class="code"><pre> |
| 603 | <?php |
| 604 | |
| 605 | include("example.php"); |
| 606 | |
| 607 | $in1=copy_intp(3); |
| 608 | $in2=copy_intp(5); |
| 609 | $result=new_intp(); |
| 610 | |
| 611 | add( $in1, $in2, $result ); |
| 612 | |
| 613 | echo "The sum " . intp_value($in1) . " + " . intp_value($in2) . " = " . intp_value( $result) . "\n"; |
| 614 | ?> |
| 615 | </pre></div> |
| 616 | |
| 617 | <p> |
| 618 | An alternative would be to use the include <b>typemaps.i</b> which |
| 619 | defines named typemaps for INPUT, OUTPUT and INOUT variables. One |
| 620 | needs to either <tt>%apply</tt> the appropriate typemap or adjust the |
| 621 | parameter names as appropriate. |
| 622 | </p> |
| 623 | |
| 624 | <div class="code"><pre> |
| 625 | %module example |
| 626 | %include typemaps.i |
| 627 | |
| 628 | void add( int *INPUT, int *INPUT, int *OUTPUT); |
| 629 | |
| 630 | </pre></div> |
| 631 | |
| 632 | <p> |
| 633 | This will result in the following usage in PHP: |
| 634 | </p> |
| 635 | |
| 636 | <div class="code"><pre> |
| 637 | <?php |
| 638 | |
| 639 | include("example.php"); |
| 640 | |
| 641 | $in1 = 3; |
| 642 | $in2 = 5; |
| 643 | $result= add($in1,$in2); # Note using variables for the input is unnecessary. |
| 644 | |
| 645 | echo "The sum $in1 + $in2 = $result\n"; |
| 646 | ?> |
| 647 | </pre></div> |
| 648 | |
| 649 | <p> |
| 650 | Because PHP has a native concept of reference, it may seem more natural |
| 651 | to the PHP developer to use references to pass pointers. To enable |
| 652 | this, one needs to include <b>phppointers.i</b> which defines the |
| 653 | named typemap REFERENCE. |
| 654 | </p> |
| 655 | |
| 656 | <div class="code"><pre> |
| 657 | %module example |
| 658 | %include phppointers.i |
| 659 | |
| 660 | void add( int *REF, int *REF, int *REF); |
| 661 | |
| 662 | </pre></div> |
| 663 | |
| 664 | <p> |
| 665 | This will result in the following usage in PHP: |
| 666 | </p> |
| 667 | |
| 668 | <div class="code"><pre> |
| 669 | <?php |
| 670 | |
| 671 | include("example.php"); |
| 672 | |
| 673 | $in1 = 3; |
| 674 | $in2 = 5; |
| 675 | $result = 0; |
| 676 | add(&$in1,&$in2,&$result); |
| 677 | |
| 678 | echo "The sum $in1 + $in2 = $result\n"; |
| 679 | ?> |
| 680 | </pre></div> |
| 681 | |
| 682 | <p> |
| 683 | It is important to note that a php variable which is NULL when passed |
| 684 | by reference would end up passing a NULL pointer into the function. |
| 685 | In PHP, an unassigned variable (ie first reference is not assigned) is |
| 686 | NULL. In the above example, if any of the three variables had not |
| 687 | been assigned, a NULL pointer would have been passed into |
| 688 | <tt>add</tt>. Depending on the implementation of the function, this |
| 689 | may or may not be a good thing. |
| 690 | </p> |
| 691 | |
| 692 | <p> |
| 693 | We chose to allow passing NULL pointers into functions because that is |
| 694 | sometimes required in C libraries. A NULL pointer can be created in |
| 695 | PHP in a number of ways: by using <tt>unset</tt> on an existing |
| 696 | variable, or assigning <tt>NULL</tt> to a variable. |
| 697 | </p> |
| 698 | |
| 699 | <H3><a name="Php_nn2_6"></a>24.2.6 Structures and C++ classes</H3> |
| 700 | |
| 701 | |
| 702 | <p> |
| 703 | By default, SWIG represents structs and C++ classes using a PHP4 |
| 704 | class. The PHP4 class is implemented entirely using the Zend C API so |
| 705 | no additional php code is generated. |
| 706 | </p> |
| 707 | |
| 708 | <p> |
| 709 | This interface file |
| 710 | </p> |
| 711 | |
| 712 | <div class="code"><pre> |
| 713 | %module vector |
| 714 | |
| 715 | class Vector { |
| 716 | public: |
| 717 | double x,y,z; |
| 718 | Vector(); |
| 719 | ~Vector(); |
| 720 | double magnitude(); |
| 721 | }; |
| 722 | |
| 723 | struct Complex { |
| 724 | double re, im; |
| 725 | }; |
| 726 | </pre></div> |
| 727 | |
| 728 | <p> |
| 729 | Would be used in the following way: |
| 730 | </p> |
| 731 | |
| 732 | <div class="code"><pre> |
| 733 | <?php |
| 734 | require "vector.php"; |
| 735 | |
| 736 | $v = new Vector(); |
| 737 | $v->x = 3; |
| 738 | $v->y = 4; |
| 739 | $v->z = 5; |
| 740 | |
| 741 | echo "Magnitude of ($v->x,$v->y,$v->z) = " . $v->magnitude() . "\n"; |
| 742 | |
| 743 | $v = NULL; # destructor called. |
| 744 | |
| 745 | $c = new Complex(); |
| 746 | |
| 747 | $c->re = 0; |
| 748 | $c->im = 0; |
| 749 | |
| 750 | # $c destructor called when $c goes out of scope. |
| 751 | ?> |
| 752 | </pre></div> |
| 753 | |
| 754 | <p> |
| 755 | Member variables and methods are accessed using the <tt>-></tt> operator. |
| 756 | </p> |
| 757 | |
| 758 | <H4><a name="Php_nn2_6_1"></a>24.2.6.1 Using <tt>-noproxy</tt></H4> |
| 759 | |
| 760 | |
| 761 | <p> |
| 762 | The <tt>-noproxy</tt> option flattens the object structure and |
| 763 | generates collections of named functions. The above example results |
| 764 | in the following PHP functions: |
| 765 | </p> |
| 766 | |
| 767 | <div class="code"><pre> |
| 768 | new_Vector(); |
| 769 | Vector_x_set($obj,$d); |
| 770 | Vector_x_get($obj); |
| 771 | Vector_y_set($obj,$d); |
| 772 | Vector_y_get($obj); |
| 773 | Vector_z_set($obj,$d); |
| 774 | Vector_z_get($obj); |
| 775 | Vector_magnitude($obj); |
| 776 | new_Complex(); |
| 777 | Complex_re_set($obj,$d); |
| 778 | Complex_re_get($obj); |
| 779 | Complex_im_set($obj,$d); |
| 780 | Complex_im_get($obj); |
| 781 | </pre></div> |
| 782 | |
| 783 | <H4><a name="Php_nn2_6_2"></a>24.2.6.2 Constructors and Destructors</H4> |
| 784 | |
| 785 | |
| 786 | <p> |
| 787 | The constructor is called when <tt>new Object()</tt> (or |
| 788 | <tt>new_Object()</tt> if using <tt>-noproxy</tt>) is used to create an |
| 789 | instance of the object. If multiple constructors are defined for an |
| 790 | object, function overloading will be used to determine which |
| 791 | constructor to execute. |
| 792 | </p> |
| 793 | |
| 794 | <p> |
| 795 | Because PHP4 uses reference counting to manage resources, simple |
| 796 | assignment of one variable to another such as: |
| 797 | </p> |
| 798 | |
| 799 | <div class="code"><pre> |
| 800 | $ref = $v; |
| 801 | </pre></div> |
| 802 | |
| 803 | <p> |
| 804 | causes the symbol <tt>$ref</tt> to refer to the same underlying object |
| 805 | as <tt>$v</tt>. This does not result in a call to the C++ copy |
| 806 | constructor or copy assignment operator. |
| 807 | </p> |
| 808 | |
| 809 | <p> |
| 810 | One can force execution of the copy constructor by using: |
| 811 | </p> |
| 812 | <div class="code"><pre> |
| 813 | $o_copy = new Object($o); |
| 814 | </pre></div> |
| 815 | |
| 816 | <p> |
| 817 | Destructors are automatically called when all variables referencing |
| 818 | the instance are reassigned or go out of scope. The destructor is not |
| 819 | available to be called manually. To force a destructor to be called |
| 820 | the programmer can either reassign the variable or call |
| 821 | <tt>unset($v)</tt> |
| 822 | </p> |
| 823 | |
| 824 | <H4><a name="Php_nn2_6_3"></a>24.2.6.3 Static Member Variables</H4> |
| 825 | |
| 826 | |
| 827 | <p> |
| 828 | Class variables are not supported in PHP. Static member variables are |
| 829 | therefore accessed using a class function with the same name, which |
| 830 | returns the current value of the class variable. For example |
| 831 | </p> |
| 832 | |
| 833 | <div class="code"><pre> |
| 834 | %module example |
| 835 | |
| 836 | class Ko { |
| 837 | static int threats; |
| 838 | }; |
| 839 | |
| 840 | </pre></div> |
| 841 | |
| 842 | <p> |
| 843 | would be accessed in PHP as, |
| 844 | </p> |
| 845 | |
| 846 | <div class="code"><pre> |
| 847 | include("example.php"); |
| 848 | |
| 849 | echo "There has now been " . Ko::threats() . " threats\n"; |
| 850 | |
| 851 | </pre></div> |
| 852 | |
| 853 | <p> |
| 854 | To set the static member variable, pass the value as the argument to the class function, e.g. |
| 855 | </p> |
| 856 | |
| 857 | <div class="code"><pre> |
| 858 | |
| 859 | Ko::threats(10); |
| 860 | |
| 861 | echo "There has now been " . Ko::threats() . " threats\n"; |
| 862 | |
| 863 | </pre></div> |
| 864 | <H4><a name="Php_nn2_6_4"></a>24.2.6.4 Static Member Functions</H4> |
| 865 | |
| 866 | |
| 867 | <p> |
| 868 | Class functions are supported in PHP using the |
| 869 | <tt>class::function()</tt> syntax. For example |
| 870 | </p> |
| 871 | |
| 872 | <div class="code"><pre> |
| 873 | %module example |
| 874 | class Ko { |
| 875 | static void threats(); |
| 876 | }; |
| 877 | </pre></div> |
| 878 | |
| 879 | would be executed in PHP as, |
| 880 | <div class="code"><pre> |
| 881 | include("example.php"); |
| 882 | Ko::threats(); |
| 883 | </pre></div> |
| 884 | |
| 885 | |
| 886 | <H3><a name="Php_nn2_7"></a>24.2.7 PHP4 Pragmas, Startup and Shutdown code</H3> |
| 887 | |
| 888 | |
| 889 | <p> |
| 890 | To place PHP code in the generated "example.php" file one can use the |
| 891 | <b>code</b> pragma. The code is inserted after loading the shared |
| 892 | object. |
| 893 | </p> |
| 894 | |
| 895 | <div class="code"><pre> |
| 896 | %module example |
| 897 | %pragma(php4) code=" |
| 898 | # This code is inserted into example.php |
| 899 | echo \"example.php execution\\n\"; |
| 900 | " |
| 901 | </pre></div> |
| 902 | |
| 903 | <p> |
| 904 | Results in the following in "example.php" |
| 905 | </p> |
| 906 | |
| 907 | <div class="code"><pre> |
| 908 | # This code is inserted into example.php |
| 909 | echo "example.php execution\n"; |
| 910 | </pre></div> |
| 911 | |
| 912 | <p> |
| 913 | The <b>include</b> pragma is a short cut to add include statements to |
| 914 | the example.php file. |
| 915 | </p> |
| 916 | |
| 917 | <div class="code"><pre> |
| 918 | %module example |
| 919 | %pragma(php4) code=" |
| 920 | include \"include.php\"; |
| 921 | " |
| 922 | %pragma(php) include="include.php" // equivalent. |
| 923 | </pre></div> |
| 924 | |
| 925 | <p> |
| 926 | The <b>phpinfo</b> pragma inserts code in the |
| 927 | <tt>PHP_MINFO_FUNCTION</tt> which is called from PHP's |
| 928 | phpinfo() function. |
| 929 | </p> |
| 930 | |
| 931 | <div class="code"><pre> |
| 932 | %module example; |
| 933 | %pragma(php4) phpinfo=" |
| 934 | zend_printf("An example of PHP support through SWIG\n"); |
| 935 | php_info_print_table_start(); |
| 936 | php_info_print_table_header(2, \"Directive\", \"Value\"); |
| 937 | php_info_print_table_row(2, \"Example support\", \"enabled\"); |
| 938 | php_info_print_table_end(); |
| 939 | " |
| 940 | </pre></div> |
| 941 | |
| 942 | <p> |
| 943 | To insert code into the <tt>PHP_MINIT_FUNCTION</tt>, one can use |
| 944 | either <tt>%init</tt> or <tt>%minit</tt>. |
| 945 | </p> |
| 946 | |
| 947 | <div class="code"><pre> |
| 948 | %module example; |
| 949 | %init { |
| 950 | zend_printf("Inserted into PHP_MINIT_FUNCTION\n"); |
| 951 | } |
| 952 | %minit { |
| 953 | zend_printf("Inserted into PHP_MINIT_FUNCTION\n"); |
| 954 | } |
| 955 | </pre></div> |
| 956 | |
| 957 | <p> |
| 958 | To insert code into the <tt>PHP_MSHUTDOWN_FUNCTION</tt>, one can use |
| 959 | either <tt>%init</tt> or <tt>%minit</tt>. |
| 960 | </p> |
| 961 | |
| 962 | <div class="code"><pre> |
| 963 | %module example; |
| 964 | %mshutdown { |
| 965 | zend_printf("Inserted into PHP_MSHUTDOWN_FUNCTION\n"); |
| 966 | } |
| 967 | </pre></div> |
| 968 | |
| 969 | <p> |
| 970 | The <tt>%rinit</tt> and <tt>%rshutdown</tt> statements insert code |
| 971 | into the request init and shutdown code respectively. |
| 972 | </p> |
| 973 | |
| 974 | </body> |
| 975 | </html> |