diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-04-03 14:14:49 +0200 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-04-03 14:14:49 +0200 |
commit | 6e2556ab445169cadb21d9ba16eb77d7350a79f7 (patch) | |
tree | cd7360bd946870f204af69b8ed057cb3c59663be /documentation | |
parent | 8ce7055ebfbd28f283e08eb822980a7f4641c0cd (diff) |
update documentation about inheritance
Diffstat (limited to 'documentation')
-rw-r--r-- | documentation/classes-and-objects.html | 54 | ||||
-rw-r--r-- | documentation/inheritance.html | 137 |
2 files changed, 137 insertions, 54 deletions
diff --git a/documentation/classes-and-objects.html b/documentation/classes-and-objects.html index e0087b6..fe1c9b5 100644 --- a/documentation/classes-and-objects.html +++ b/documentation/classes-and-objects.html @@ -567,60 +567,6 @@ extern "C" { To register abstract methods, you can simply use an alternative form of the Counter::method() method that does not take a pointer to a C++ method. </p> -<h2 id="interfaces">Interfaces</h2> -<p> - In C++ interfaces do not exist. C++ supports multiple inheritance, which is - more powerful than interfaces or traits. Interfaces and traits are basically - PHP workarounds to make up for not having multiple inheritance. So when - you're writing C++ code, you don't need interfaces or traits. -</p> -<p> - In case you want your extension to <i>define</i> an interface, so that the - interface can be implemented from PHP user space scripts, you can do that - almost in a similar way to how you would define an abstract class. The only - difference is that you will not use a Php::Class instance to define the - methods, but a Php::Interface instance. The interface does not have to be - linked to a real C++ class (it is an interface after all), so the - Php::Interface does not have to be passed the name of a C++ class. -</p> -<p> -<pre class="language-c++"><code> -/** - * Switch to C context to ensure that the get_module() function - * is callable by C programs (which the Zend engine is) - */ -extern "C" { - /** - * Startup function that is called by the Zend engine - * to retrieve all information about the extension - * @return void* - */ - PHPCPP_EXPORT void *get_module() { - // create static instance of the extension object - static Php::Extension myExtension("my_extension", "1.0"); - - // description of the interface so that PHP knows which methods - // are defined by it - Php::Interface interface("MyInterface"); - - // define an interface method - interface.method("myMethod", { - Php::ByVal("value", Php::Type::String, true) - }); - - // register other methods - ... - - // add the interface to the extension - // (or move it into the extension, which is faster) - myExtension.add(std::move(interface)); - - // return the extension - return myExtension; - } -} -</code></pre> -</p> <p> There is much more to say about classes and objects, in the next section we'll explain <a href="constructors-and-destructors">constructors and diff --git a/documentation/inheritance.html b/documentation/inheritance.html new file mode 100644 index 0000000..f4f027e --- /dev/null +++ b/documentation/inheritance.html @@ -0,0 +1,137 @@ +<h1>Inheritance</h1> +<p> + Both PHP and C++ are object oriented programming languages that support + class inheritance. There are some differences: C++ supports multiple + inheritance, while a PHP class can only have a single base class. + To make up for not having multiple inheritance, PHP supports interfaces + and traits. +</p> +<p> + The PHP-CPP library also allows you to define PHP interfaces and to create + hierarchies of PHP classes and PHP interfaces. +<p> +<h2 id="defining-interfaces">Defining interfaces</h2> +<p> + In case you want your extension to <i>define</i> an interface, so that the + interface can be implemented from PHP user space scripts, you can do that + almost in a similar way to how you would define a class. The only + difference is that you do not use Php::Class<YourClass>, but a + Php::Interface instance. +</p> +<p> +<pre class="language-c++"><code> +/** + * Switch to C context to ensure that the get_module() function + * is callable by C programs (which the Zend engine is) + */ +extern "C" { + /** + * Startup function that is called by the Zend engine + * to retrieve all information about the extension + * @return void* + */ + PHPCPP_EXPORT void *get_module() { + // create static instance of the extension object + static Php::Extension myExtension("my_extension", "1.0"); + + // description of the interface so that PHP knows which methods + // are defined by it + Php::Interface interface("MyInterface"); + + // define an interface method + interface.method("myMethod", { + Php::ByVal("value", Php::Type::String, true) + }); + + // register other methods + ... + + // add the interface to the extension + // (or move it into the extension, which is faster) + myExtension.add(std::move(interface)); + + // return the extension + return myExtension; + } +} +</code></pre> +</p> +<h2 id="deriving-and-implementing">Deriving and implementing</h2> +<p> + The PHP-CPP library tries to make working with PHP and C++ as transparent + as possible. C++ functions can be called from PHP userspace scripts, + and C++ classes can be made accessible from PHP. However, in the end PHP + and C++ are still different languages, and because C++ does not have the + same reflection features as PHP, you will have to explicit tell the PHP + engine which base classes and interfaces the class implements. +</p> +<p> + The Php::Class<YourClass> object has a method 'extends()' and a + method 'implements()' that can be used for specifying the base classes + and implemented interfaces. You need to pass in a class or interface that + you configured before. Let's look at an example. +</p> +<p> +<p> +<pre class="language-c++"><code> +/** + * Switch to C context to ensure that the get_module() function + * is callable by C programs (which the Zend engine is) + */ +extern "C" { + /** + * Startup function that is called by the Zend engine + * to retrieve all information about the extension + * @return void* + */ + PHPCPP_EXPORT void *get_module() { + // create static instance of the extension object + static Php::Extension myExtension("my_extension", "1.0"); + + // description of the interface so that PHP knows which methods + // are defined by it + Php::Interface myInterface("MyInterface"); + + // define an interface method + myInterface.method("myMethod", { + Php::ByVal("value", Php::Type::String, true) + }); + + // register our own class + Php::Class<MyClass> myClass("MyClass"); + + // from PHP user space scripts, it must look like the myClass implements + // the MyInterface interface + myClass.implements(myInterface); + + // the interface requires that the myMethod method is implemented + myClass.method("myMethod", &MyClass::myMethod, { + Php::ByVal("value", Php::Type::String, true) + }); + + // create a third class + Php::Class<DerivedClass> derivedClass("DerivedClass"); + + // in PHP scripts, it should look like DerivedClass has "MyClass" + // as its base + derivedClass.extends(myClass); + + // add the interface and the classes to the extension + myExtension.add(myInterface); + myExtension.add(myClass); + myExtension.add(derivedClass); + + // return the extension + return myExtension; + } +} +</code></pre> +</p> +<p> + Be aware that the PHP class hierarchy that you define inside the get_module() + function does not have to match the C++ class hierarchy. Your C++ class + "DerivedClass" does not at all have to have "MyClass" as its base, even + although in PHP scripts it would look like it has. For code maintainability + is it of course better to make the PHP signature more or less similar to the + C++ implementation. +<p> |