Commit | Line | Data |
---|---|---|
920dae64 AT |
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> |