summaryrefslogtreecommitdiff
path: root/documentation
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-01-16 13:40:49 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-01-16 13:40:49 +0100
commit9390addb0798598d7b333dcc86487caf0117a231 (patch)
tree46f6eecefcad4ecade3fa09debca7304c1ed14bb /documentation
parentd87b3ca8f1dbcb395f2dfd6540483da7a0e5e15c (diff)
added documentation about lambda functions
Diffstat (limited to 'documentation')
-rw-r--r--documentation/lambda-functions.html208
1 files changed, 208 insertions, 0 deletions
diff --git a/documentation/lambda-functions.html b/documentation/lambda-functions.html
new file mode 100644
index 0000000..19b7775
--- /dev/null
+++ b/documentation/lambda-functions.html
@@ -0,0 +1,208 @@
+<h1>Lambda functions</h1>
+<p>
+ C++ and PHP both support lambda functions or anonumous functions (in
+ the C++ world the word 'lambda' is most used, PHP people speak about
+ 'anonymous functions'). With PHP-CPP you can pass these functions
+ from one language to the other. It is possible to call an anonymous
+ PHP function from your C++ code, and the other way around, to call a C++
+ lambda from a PHP script.
+</p>
+<h2>Calling anonymous PHP functions from C++</h2>
+<p>
+ Let's start with a very simple example in PHP. In PHP you can create
+ anonymous functions, and assign them to a variable (or pass them
+ directly to a function).
+</p>
+<p>
+<pre class="language-php"><code>&lt;php
+// anonymous PHP function stored in the variable $f
+$f = function($a, $b) {
+
+ // return the sum of the parameters
+ return $a + $b;
+}
+
+// pass the function to another function
+other_function($f);
+
+// or pass an anonymous function without assigning it to a variable
+other_function(function() {
+
+ // return the product of the parameters
+ return $a * $b;
+});
+
+?&gt;
+</code></pre>
+</p>
+<p>
+ The code above should be familiar to most PHP programmers. The
+ 'other_function' can of course be implemented in PHP user space,
+ but to demonstrate how to do this with PHP-CPP we are going to
+ build it with C++. Just like all the other functions that you've
+ seen in the earlier examples, such a C++ function function receives
+ a vector of Php::Value objects as its parameters.
+</p>
+<p>
+<pre class="language-c++"><code>#include &lt;phpcpp.h&gt;
+/**
+ * Native function that is callable from PHP
+ *
+ * This function gets one parameter that holds a callable anonynous
+ * PHP function.
+ *
+ * @param params The parameters passed to the function
+ */
+void other_function(Php::Parameters &amp;params)
+{
+ // first parameter is an anonymous function
+ Php::Value func = params[0];
+
+ // the Php::Value class has implemented the operator (), which allows
+ // us to use the object just as if it is a real function.
+ Php::Value result = func(3, 4);
+
+ // @todo do something with the result
+}
+
+/**
+ * Switch to C context, because the Zend engine expects the get_module()
+ * to have a C style function signature
+ */
+extern "C" {
+ /**
+ * Startup function that is automatically called by the Zend engine
+ * when PHP starts, and that should return the extension details
+ * @return void*
+ */
+ PHPCPP_EXPORT void *get_module()
+ {
+ // the extension object
+ static Php::Extension extension("my_extension", "1.0");
+
+ // add the example function so that it can be called from PHP scripts
+ extension.add("other_function", other_function);
+
+ // return the extension details
+ return extension;
+ }
+}</code></pre>
+</p>
+<p>
+ It is that simple. But the other way around is possible too. Imagine
+ we have a function in PHP user space code that accepts a function
+ as it's parameter:
+</p>
+<p>
+<pre class="language-php"><code>&lt;php
+// function that iterates over an array, and calls a function on every
+// element in that array, it returns a new array with every item
+// replaced by the result of the callback
+function my_iterate($array, $callback) {
+
+ // initial result variable
+ $result = array();
+
+ // loop through the array
+ foreach ($array as $index => $item) {
+
+ // call the callback on the item
+ $result[$index] = $callback($item);
+ }
+
+ // done
+ return $result;
+}
+&lt;?&gt;
+</code></pre>
+</p>
+<p>
+ Imagine that we want to call this PHP function from your C++ code,
+ using a C++ lambda function as a callback. This is possible, and easy:
+</p>
+<p>
+<pre class="language-c++"><code>#include &lt;phpcpp.h&gt;
+/**
+ * Native function that is callable from PHP
+ */
+void run_test()
+{
+ // create the anonymous function
+ Php::Function multiply_by_two([](Php::Parameters &amp;params) -> Php::Value) {
+
+ // make sure the function was really called with one parameter
+ if (params.size() == 0) return nullptr;
+
+ // one parameter is passed to the function
+ Php::Value param = params[0];
+
+ // multiple the parameter by two
+ return params * 2;
+ });
+
+ // the function now is callable
+ Php::Value four = multiply_by_two(2);
+
+ // a Php::Function object is a derived Php::Value, and can be used
+ // as a normal Php::Value object - it just happen to store a callback,
+ // it can also be stored in a Php::Value object, without losing
+ // anything
+ Php::Value value = multiply_by_two;
+
+ // the value object now also holds a function
+ Php::Value six = value(3);
+
+ // create an array
+ Php::Value array;
+ array[0] = 1;
+ array[1] = 2;
+ array[2] = 3;
+ array[3] = 4;
+
+ // call the user-space function
+ Php::Value result = Php::call("my_iterate", array, multiply_by_two);
+
+ // @todo do something with the result variable (which now holds
+ // an array with values 2, 4, 6 and 8).
+}
+
+/**
+ * Switch to C context, because the Zend engine expects the get_module()
+ * to have a C style function signature
+ */
+extern "C" {
+ /**
+ * Startup function that is automatically called by the Zend engine
+ * when PHP starts, and that should return the extension details
+ * @return void*
+ */
+ PHPCPP_EXPORT void *get_module()
+ {
+ // the extension object
+ static Php::Extension extension("my_extension", "1.0");
+
+ // add the example function so that it can be called from PHP scripts
+ extension.add("run_test", run_test);
+
+ // return the extension details
+ return extension;
+ }
+}</code></pre>
+</p>
+<p>
+ In the example we assigned a C++ lambda function to a Php::Function
+ object. The Php::Function class is derived from the Php::Value class.
+ The only difference between a Php::Value and a Php::Function is
+ that the constructor of Php::Function accepts a function as its
+ parameter. Despite that difference, both classes are completely
+ identical. In fact, we would have preferred to make it possible to
+ assign C++ functions directly to Php::Value objects, but that was
+ impossible because of calling ambiguities.
+</p>
+<p>
+ The Php::Function class can be used as if it is a normal Php::Value
+ object: you can assign it to other Php::Value objects, and you
+ can use it as a parameter when you call user space PHP functions.
+ In the above example we do exactly that: we call the user space
+ my_iterate() function with our own 'multiply_by_two' C++ function.
+</p>