summaryrefslogtreecommitdiff
path: root/documentation
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-03 14:14:49 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-03 14:14:49 +0200
commit6e2556ab445169cadb21d9ba16eb77d7350a79f7 (patch)
treecd7360bd946870f204af69b8ed057cb3c59663be /documentation
parent8ce7055ebfbd28f283e08eb822980a7f4641c0cd (diff)
update documentation about inheritance
Diffstat (limited to 'documentation')
-rw-r--r--documentation/classes-and-objects.html54
-rw-r--r--documentation/inheritance.html137
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&lt;YourClass&gt;, 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&lt;YourClass&gt; 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&lt;MyClass&gt; 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", &amp;MyClass::myMethod, {
+ Php::ByVal("value", Php::Type::String, true)
+ });
+
+ // create a third class
+ Php::Class&lt;DerivedClass&gt; 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>