summaryrefslogtreecommitdiff
path: root/documentation
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-13 16:18:56 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-13 16:18:56 +0100
commit40287b042fc252dbf348ae386cf3c9e3cab95d63 (patch)
tree88d737321ad81d0c643e91c81d5805a273024152 /documentation
parent1a8c587f3a67db2e5c38cc525b29800e86f27936 (diff)
update documentation, fixed __compare() method
Diffstat (limited to 'documentation')
-rw-r--r--documentation/magic-methods.html135
-rw-r--r--documentation/special-features.html (renamed from documentation/comparing-objects.html)163
2 files changed, 210 insertions, 88 deletions
diff --git a/documentation/magic-methods.html b/documentation/magic-methods.html
index ed7dd3b..8a1fbfa 100644
--- a/documentation/magic-methods.html
+++ b/documentation/magic-methods.html
@@ -5,10 +5,18 @@
names like __set(), __isset(), __call(), etcetera.
</p>
<p>
- The PHP-CPP library also has support for these magic methods. The methods
- are already defined in the Php::Base class (which is the base class for
- all classes that are written using the PHP-CPP library), and can be
- overridden in your derived class.
+ The PHP-CPP library also has support for these magic methods. Using some
+ C++ compiler tricks, the C++ compiler detects whether the methods exist
+ in your class, and if they do, they will be compiled into your extension
+ and called when they are accessed from PHP.
+</p>
+<p>
+ The signature of the methods is flexible. Most of the methods accept
+ Php::Value objects and also return Php::Value objects, but if your own
+ magic methods have a slightly different signature (they return an integer
+ for example) it will be picked up by the compiler too because the Php::Value
+ has many implicit constructors to convert other types into Php::Value
+ objects.
</p>
<p>
The nice thing about magic methods implemented with PHP-CPP is that they
@@ -61,7 +69,7 @@ public:
* @param name Name of the property
* @return Value Property value
*/
- virtual Php::Value __get(const Php::Value &amp;name) override
+ Php::Value __get(const Php::Value &amp;name)
{
// check if the property name is supported
if (name == "name") return _name;
@@ -76,7 +84,7 @@ public:
* @param name Name of the property
* @param value New property value
*/
- virtual void __set(const Php::Value &amp;name, const Php::Value &amp;value) override
+ void __set(const Php::Value &amp;name, const Php::Value &amp;value)
{
// check the property name
if (name == "name")
@@ -115,7 +123,7 @@ public:
* @param name Name of the property
* @return bool
*/
- virtual bool __isset(const Php::Value &amp;name) override
+ bool __isset(const Php::Value &amp;name)
{
// true for name and email address
if (name == "name" || name == "email") return true;
@@ -128,7 +136,7 @@ public:
* Remove a property
* @param name Name of the property to remove
*/
- virtual void __unset(const Php::Value &amp;name) override
+ void __unset(const Php::Value &amp;name)
{
// name and email can not be unset
if (name == "name" || name == "email")
@@ -192,7 +200,7 @@ unset($user->email);
?&gt;
</code></pre>
</p>
-<h2 id="call-and-invoke">Magic methods __call() and __invoke()</h2>
+<h2 id="call-and-invoke">Magic methods __call(), __callStatic() and __invoke()</h2>
<p>
C++ methods need to be registered explicitly in your extension get_module()
startup function to be accessible from PHP user space. However, when you override the __call()
@@ -204,9 +212,14 @@ unset($user->email);
__call() method in the C++ class.
</p>
<p>
- Next to the magic __call() function, the PHP-CPP library also supports the
- __invoke() method. This is a method that gets called when an object instance
- is used <i>as if</i> it was a function. This can be compared with overloading
+ The __callStatic() method is similar to the __call() method, but works for
+ static methods. A static call to YourClass::someMethod() can be automatically
+ passed on to the __callStatic() method of your C++ class.
+</p>
+<p>
+ Next to the magic __call() and __callStatic functions, the PHP-CPP library also
+ supports the __invoke() method. This is a method that gets called when an object
+ instance is used <i>as if</i> it was a function. This can be compared with overloading
the operator () in a C++ class. By implementing the __invoke() method, scripts
from PHP user space can create an object, and then use it as a function.
</p>
@@ -242,10 +255,32 @@ public:
* @param params Parameters that were passed to the method
* @return Value The return value
*/
- virtual Php::Value __call(const char *name, Php::Parameters &amp;params) override
+ Php::Value __call(const char *name, Php::Parameters &amp;params)
+ {
+ // the return value
+ std::string retval = std::string("__call ") + name;
+
+ // loop through the parameters
+ for (auto &amp;param : params)
+ {
+ // append parameter string value to return value
+ retval += " " + param.stringValue();
+ }
+
+ // done
+ return retval;
+ }
+
+ /**
+ * Overriden __callStatic() method to accept all static method calls
+ * @param name Name of the method that is called
+ * @param params Parameters that were passed to the method
+ * @return Value The return value
+ */
+ static Php::Value __callStatic(const char *name, Php::Parameters &amp;params)
{
// the return value
- std::string retval = name;
+ std::string retval = std::string("__callStatic ") + name;
// loop through the parameters
for (auto &amp;param : params)
@@ -263,7 +298,7 @@ public:
* @param params Parameters that were passed to the method
* @return Value The return value
*/
- virtual Php::Value __invoke(Php::Parameters &amp;params) override
+ Php::Value __invoke(Php::Parameters &amp;params)
{
// the return value
std::string retval = "invoke";
@@ -326,6 +361,11 @@ echo($object->something()."\n");
echo($object->myMethod(1,2,3,4)."\n");
echo($object->whatever("a","b")."\n");
+// call some pseudo-methods in a static context
+echo(MyClass::something()."\n");
+echo(MyClass::myMethod(5,6,7)."\n");
+echo(MyClass::whatever("x","y")."\n");
+
// call the object as if it was a function
echo($object("parameter","passed","to","invoke")."\n");
?&gt;
@@ -338,31 +378,20 @@ echo($object("parameter","passed","to","invoke")."\n");
<p>
<pre>
regular
-something
-myMethod 1 2 3 4
-whatever a b
+__call something
+__call myMethod 1 2 3 4
+__call whatever a b
+__callStatic something
+__callStatic myMethod 5 6 7
+__callStatic whatever x y
invoke parameter passed to invoke
</pre>
</p>
-<h2 id="casting">Casting methods (__toString and more)</h2>
+<h2 id="casting">Casting to a string</h2>
<p>
In PHP you can add a __toString() method to a class. This method is automatically
called when an object is casted to a string, or when an object is used in a string
- context. PHP-CPP supports this __toString() method too. But there are more casting
- methods offered by PHP-CPP.
-</p>
-<p>
- Internally, the Zend engine has special casting routines to cast objects
- to integers, to booleans and to floating point values. For one reason or another,
- a PHP script can only implement the __toString() method,
- while all other casting operations are kept away from it. The
- PHP-CPP library solves this limitation, and allows one to implement the
- other casting functions as well.
-</p>
-<p>
- One of the design goals of the PHP-CPP library is to stay as close to PHP as
- possible. For that reason the casting functions have been given names that match
- the __toString() method: __toInteger(), __toFloat(), and __toBool().
+ context. PHP-CPP supports this __toString() method too.
</p>
<p>
<pre class="language-c++"><code>
@@ -384,37 +413,10 @@ public:
* Cast to a string
* @return Value
*/
- virtual Php::Value __toString() override
+ Php::Value __toString()
{
return "abcd";
}
-
- /**
- * Cast to a integer
- * @return long
- */
- virtual long __toInteger() override
- {
- return 1234;
- }
-
- /**
- * Cast to a floating point number
- * @return double
- */
- virtual double __toFloat() override
- {
- return 88.88;
- }
-
- /**
- * Cast to a boolean
- * @return bool
- */
- virtual bool __toBool() override
- {
- return true;
- }
};
/**
@@ -445,3 +447,12 @@ extern "C" {
}
</code></pre>
</p>
+<p>
+ Next to the magic methods described here, and that you probably already know
+ from writing PHP scripts, the PHP-CPP library also introduces a number of
+ additional magic methods. These include extra casting methods, and a method
+ to compare objects.
+</p>
+<p>
+ You can read more about these additional features in the <a href="special-features">next section</a>.
+</p>
diff --git a/documentation/comparing-objects.html b/documentation/special-features.html
index ad8b07f..1569e5f 100644
--- a/documentation/comparing-objects.html
+++ b/documentation/special-features.html
@@ -1,4 +1,4 @@
-<h1>Comparing objects</h1>
+<h1>Special features</h1>
<p>
One of the questions we had to ask ourselves when we developed the PHP-CPP
library was whether we should follow PHP conventions or follow C++
@@ -25,20 +25,138 @@
as well follow PHP completely in this.
</p>
<p>
- Besides the magic methods and functions, the Zend engine has additional
- features that are not exposed via magic methods, and that only are accessible
- for extension programmers. We have already mentioned that PHP-CPP allows you
- to implement the __toInteger(), __toFloat() and __toBool() methods (next to
- the __toString() that can be implemented in PHP scripts too). Another thing
- that is not available in PHP but that can be used by extensions is the
- possibility to install a custom object comparison procedure.
+ Besides the magic methods and interfaces that are also available in PHP
+ user space, the Zend engine has additional features that are not exposed via
+ magic methods, and that only are accessible for extension programmers. These
+ features available for extensions built with PHP-CPP.
</p>
+<h2 id="casting-functions">Extra casting functions</h2>
+<p>
+ Internally, the Zend engine has special casting routines to cast objects
+ to integers, to booleans and to floating point values. For one reason or another,
+ a PHP script can only implement the __toString() method, while all other casting
+ operations are kept away from it. The PHP-CPP library solves this limitation,
+ and allows one to implement the other casting functions as well.
+</p>
+<p>
+ One of the design goals of the PHP-CPP library is to stay as close to PHP as
+ possible. For that reason the casting functions have been given names that match
+ the __toString() method: __toInteger(), __toFloat(), and __toBool().
+</p>
+<p>
+<pre class="language-c++"><code>
+#include &lt;phpcpp.h&gt;
+
+/**
+ * A sample class, with methods to cast objects to scalars
+ */
+class MyClass : public Php::Base
+{
+public:
+ /**
+ * C++ constructor and C++ destructpr
+ */
+ MyClass() {}
+ virtual ~MyClass() {}
+
+ /**
+ * Cast to a string
+ *
+ * Note that now we use const char* as return value, and not Php::Value.
+ * The __toString function is detected at compile time, and it does
+ * not have a fixed signature. You can return any value that can be picked
+ * up by a Php::Value object.
+ *
+ * @return const char *
+ */
+ const char *__toString()
+ {
+ return "abcd";
+ }
+
+ /**
+ * Cast to a integer
+ * @return long
+ */
+ long __toInteger()
+ {
+ return 1234;
+ }
+
+ /**
+ * Cast to a floating point number
+ * @return double
+ */
+ double __toFloat()
+ {
+ return 88.88;
+ }
+
+ /**
+ * Cast to a boolean
+ * @return bool
+ */
+ bool __toBool()
+ {
+ return true;
+ }
+};
+
+/**
+ * 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() {
+
+ // extension object
+ static Php::Extension myExtension("my_extension", "1.0");
+
+ // description of the class so that PHP knows
+ // which methods are accessible
+ Php::Class&lt;MyClass&gt; myClass("MyClass");
+
+ // add the class to the extension
+ myExtension.add(std::move(myClass));
+
+ // return the extension
+ return myExtension;
+ }
+}
+</code></pre>
+</p>
+<p>
+ The casting methods are automatically called when an object is casted
+ to a scalar type, or when it is used in a scalar context. The following
+ example demonstrates this.
+</p>
+<p>
+<pre class="language-php"><code>
+&lt;?php
+// initialize an object
+$object = new MyClass();
+
+// cast it
+echo((string)$object."\n");
+echo((int)$object."\n");
+echo((bool)$object."\n");
+echo((float)$object."\n");
+
+?&gt;
+</code></pre>
+</p>
+<h2 id="object-comparison">Comparing objects</h2>
<p>
If you compare two objects in PHP with comparison operators like &lt; ==, !=
&gt; (and the obvious others), the Zend engine runs an object comparison function.
The PHP-CPP library interupts this method, and passes the comparison method
- to the &lt; operator of your class. In other words, if you want to install
- a custom comparison operator, you can do so by implementing operator&lt;.
+ to the __compare method of your class. In other words, if you want to install
+ a custom comparison operator, you can do so by implementing __compare().
</p>
<p>
<pre class="language-c++"><code>
@@ -72,21 +190,21 @@ public:
/**
* Cast the object to a string
- * @return Php::Value
+ * @return std::string
*/
- virtual Php::Value __toString() override
+ std::string Php::Value __toString()
{
return std::to_string(_value);
}
/**
- * Comparison operator to compare the object
+ * Compare with a different object
* @param that
- * @return bool
+ * @return int
*/
- bool operator&lt;(const MyClass &amp;that) const
+ int __compare(const MyClass &amp;that) const
{
- return _value &lt; that._value;
+ return _value - that._value;
}
};
@@ -120,7 +238,9 @@ extern "C" {
</p>
<p>
The comparison function is automatically called when you try to compare
- objects in PHP scripts.
+ objects in PHP scripts. It should return 0 when the two objects are identical,
+ a value less than zero when the 'this' object is smaller, and higher than
+ zero when 'this' is bigger.
</p>
<p>
<pre class="language-php"><code>
@@ -161,12 +281,3 @@ else
1699622247 is not equal to 627198306
</pre>
</p>
-<p>
- We have thought about implementing the comparison method as a
- magic method (for example __compare()), or as a magic interface (for example
- Php::Comparable). In the end we have decided to go for the operator&lt;
- approach. It better fits the C++ language, and the big advantage is that your
- objects can also be used in many C++ STL algorithms, because these algorithms
- also rely on operator&lt;.
-</p>
-