diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-05 12:13:54 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-05 12:13:54 +0100 |
commit | 902d86acbe01b0368771eb57873e09f2cfcd8184 (patch) | |
tree | 915525263b9c6ecf7aebaffcd46e5a82f735f37d /documentation/tutorial.html | |
parent | ed200cc18fb5fea88b8e9e2ff730af6cf1d50663 (diff) |
default empty extension added, optimized Makefile
Diffstat (limited to 'documentation/tutorial.html')
-rw-r--r-- | documentation/tutorial.html | 250 |
1 files changed, 0 insertions, 250 deletions
diff --git a/documentation/tutorial.html b/documentation/tutorial.html deleted file mode 100644 index ff2bbbc..0000000 --- a/documentation/tutorial.html +++ /dev/null @@ -1,250 +0,0 @@ -<div style="width: 1024px; font-family: verdana; font-size: 10pt; line-height: 16pt;"> - - -<h1>A PHP-CPP tutorial</h1> -<p> - Building PHP extensions with the PHP-CPP library is not at all difficult - - in this tutorial we will give you step by step instructions to build - your own extensions. However, before we start the actual programming, we will - first explain how PHP interacts with its extensions - how extension libraries - are loaded and how PHP knows which functions, constants and classes are - defined by the extensions. -</p> -<h2>How does PHP load its extensions?</h2> -<p> - You probably already know that native PHP extensions are compiled into *.so - files on unix-like systems, and *.dll files in Windows environments, and that - the global php.ini file holds a list of all extensions available on your system. - This means that if you're building your own extension, you are also going to - create such a *.so or *.dll file and you will need to update the PHP - configuration so that your own extension is loaded by PHP. -</p> -<h3>Where to find your PHP configuration files?</h3> -<p> - If for one reason or another you can not find the PHP configuration file(s) - on your system, you can run the following command from the command line: -</p> -<p> - <code><pre> - php --ini - </pre></code> -</p> -<p> - This will output a list of all configuration files that are loaded by PHP. - Extensions are enabled by adding "extension=name.so" lines to the - configuration file - where 'name' should of course be replaced by the name of - your extension. A default PHP installation already comes with many default - extensions, so in the configuration file(s) on your system you will certainly - find a number of these "extension=name.so" lines. -</p> -<p> - The extension lines either take an absolute path ("extension=/path/to/extension.so") - or a relative path ("extension=extension.so"). If you'd like to use relative - paths, you must make sure that you've copied your extension *.so file to the - default extension directory, so that PHP can find it. To find out this default - extension directory, use the following command line instruction: -</p> -<p> - <code><pre> - php -i|grep extension_dir - </pre></code> -</p> -<h2>The get_module() startup function</h2> -<p> - Before we explain how you can create your own extension however, we first explain - what PHP does to load an extension. When PHP starts, it loads the *.ini configuration - file(s) that we just described and for each "extension=name.so" line in these - files, it opens the appropriate library, and calls the "get_module()" - function from it. Each extension library (your extension too) must therefore - define and implement this "get_module()" C function. The function is called by - PHP right after the library is loaded (and thus way before pageviews are handled), - and it should return a memory address that points to a structure that holds information - about all functions, classes, variables and constants that are made available - by the extension. -</p> -<p> - The structure that the get_module() returns is defined in the header files of - the Zend engine, but it is a pretty complicated structure without good documentation. - Luckily, the PHP-CPP library makes life easier for you, and offers an Extension - class that can be used instead. -</p> -<p> - <code><pre> - #include <phpcpp.h> - - extern "C" { - PHPCPP_EXPORT void *get_module() { - static Php::Extension myExtension("my_extension", "1.0"); - return myExtension.module(); - } - } - </pre></code> -</p> -<p> - In the example above you see a very straightforward implementation of the - get_module() function. Every PHP extension that uses the PHP-CPP library - implements this function in a more or less similar way as the extension - starting point. A number of elements require special attention. For a - start, the only header file that you see is the phpcpp.h header - file. If you're using the PHP-CPP library to build your own extensions, - you do not have to include the complicated, unstructured, and mostly undocumented - header files of the Zend engine - all you need is the single header file of - the PHP-CPP library. If you insist, you are of course free to also include the header - files of the core PHP engine - but you do not have to. -</p> -<p> - The next thing that you'll notice it that we placed the get_module() function - inside an 'extern "C"' code block. As the name of the library already gives away, - PHP-CPP is a C++ library. However, PHP expects your library, and especially your - get_module() function, to be implemented in C and not in C++. That's why we've - wrapped the get_module() function in an 'extern "C"' block. This will instruct - the C++ compiler that the get_module() is a regular C function, and - no C++ name mangling should be applied to it. -</p> -<p> - The PHP-CPP library defines a "PHPCPP_EXPORT" macro that should be placed - in front of the get_module() function. This macro makes sure that the get_module() - function is publicly exported, and thus callable by PHP. The macro has a different - implementation based on the compiler and operating system. -</p> -<p> - Inside the get_module() function the Extension object is instantiated, and the - Extension::module() method is called. It is crucial that you make a <i>static</i> - instance of this Extension class, because the object must exist for the entire - lifetime of the PHP process, and not only for the duration of the get_module() - call. The constructor takes two arguments: the name of your extension and - its version number. The Extension::module() method returns the memory address - that PHP needs to initialize the library. -</p> -<p> - Note that the example above does not yet export any native functions or - native classes to PHP - it only creates the extension. -</p> -<h2>Exporting native functions</h2> -<p> - An extension can of course only be useful if you define functions and/or - classes that can be accessed from PHP scripts. For functions you can do this - by adding your native function implementations to the Extension object: -</p> -<p> - <code><pre> - #include <phpcpp.h> - - extern void example1(); - extern void example2(Php::Parameters &params); - extern Php::Value example3(); - extern Php::Value example4(Php::Parameters &params); - - extern "C" { - PHPCPP_EXPORT void *get_module() { - static Php::Extension myExtension("my_extension", "1.0"); - myExtension.add("native1", example1); - myExtension.add("native2", example2); - myExtension.add("native3", example3); - myExtension.add("native4", example4); - return myExtension.module(); - } - } - </pre></code> -</p> -<p> - What do we see here? We've added four function declarations ("example1", - "example2", "example3" and "example4") to the source code of our extension. - The reason why we've only declared the functions, and not fully implemented - them is to keep the example code relatively small. We assume that the - four example functions are implemented in a different file. In a real world - example you could just as well remove the "extern" keyword and implement the - four functions in the same source file as the get_module() call. -</p> -<p> - The four functions all have a different signature: Some return a value, while - others do not return anything. And some take parameters, while others do not. - Despite the different signature of the functions, they can all be made - available in PHP by adding them to the extension object, by simply calling - the myExtension.add() method. This method takes two parameters: the name by - which the function should be accessible in PHP, and the actual native - function. -</p> -<p> - In the example above we've used different names for the native functions - ("example1" up to "example4") as for the PHP functions ("native1" to - "native4"). This is legal - you do not have to use the same names for your - native functions as for your PHP functions. The following PHP script can be - used to call the four native functions: -</p> -<p> - <code><pre> - <?php - native1(); - native2("a","b"); - $x = native3(); - $y = native4(1,2); - ?> - </pre></code> -</p> -<p> - It is not possible to export every thinkable C/C++ function to the - PHP extension. Only functions that have one of the four supported signatures - can be exported: functions that return - void or a Php::Value object, and that either accept a Php::Parameters object - or no parameters at all, can be added to the extension object and can thus - be exported to PHP. -</p> -<h2>Parameter types</h2> -<p> - PHP has a mechanism to enforce function parameters types, and to accept - parameters either by reference or by value. In the examples above, we have - not yet used that mechanism yes: it is up to the function implementations - themselves to inspect the 'Parameters' object, and check if the - variables are of the right type. -</p> -<p> - However, the 'Extension::add()' method takes a third optional parameter that - you can use to specify the number of parameters that are supported, whether - the parameters are passed by reference or by value, and what the type of - the parameters is: -</p> -<p> - <code><pre> - #include <phpcpp.h> - - extern void example(Php::Parameters &params); - - extern "C" { - PHPCPP_EXPORT void *get_module() { - static Php::Extension myExtension("my_extension", "1.0"); - myExtension.add("example", example, { - Php::ByVal("a", Php::Type::Numeric), - Php::ByVal("b", "ExampleClass"), - Php::ByRef("c", "OtherClass") - }); - return myExtension.module(); - } - } - </pre></code> -</p> -<p> - Above you see that we passed in additional information when we registered the - "example" function. We tell our extension that our function accepts three parameters: - the first parameter must be a regular number, while the other ones are object - instances of type "ExampleClass" and "OtherClass". In the end, your native C++ - "example" function will still be called with a Php::Parameters instance, but - the moment it gets called, you can be sure that the Php::Parameters object - will be filled with three members, and that two of them are objects of the - appropriate type, and that the third one is also passed by reference. -</p> -<h2>Working with variables</h2> -<p> - Variables in PHP are non-typed. A variable can thus hold any possible type: - an integer, string, a floating point number, and even an object or an array. - C++ on the other hand is a typed language. In C++ an integer variable always - has a numeric value, and a string variable always hold a string value. -</p> -<p> - When you mix native code and PHP code, you will need to convert the non-typed - PHP variables into native variables, and the other way round: convert native - variables back into non-typed PHP variables. The PHP-CPP library offers the - "Value" class that makes this a very simple task. -</p> -<p> -
\ No newline at end of file |