summaryrefslogtreecommitdiff
path: root/documentation/functions.html
blob: 159052001a316573949f814afc7aadefdd807688 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<h1>Exporting native functions</h1>
<p>
    A PHP extension can of course only be useful if you can make functions and/or 
    classes that can be called from PHP scripts. For functions this is 
    astonishingly simple. As long as you have a native C++ function that has 
    one of the following signatures, you can call it almost directly from PHP:
</p>
<p>
<pre class="language-c++"><code>
void example1();
void example2(Php::Parameters &amp;params);
Php::Value example3();
Php::Value example4(Php::Parameters &amp;params);
</code></pre>
</p>
<p>
    These function signatures show you two important PHP-CPP classes, the
    Php::Value class and the Php::Parameters class. The Php::Value class is a
    powerful class that does the same as a regular PHP $variable: it can hold
    almost any variable (integers, floating pointer numbers, strings, but also
    regular and associative arrays and objects). The Php::Parameters class
    can be best compared with an array or a vector holding all the parameters
    that were passed to your function. We will come back to both classes in
    much more detail later on.
</p>
<p>
    To make a function callable from PHP, you must <i>add</i> the function
    to your extension object, and assign a name to it. This is the
    name by which the function becomes callable from within PHP scripts.
</p>
<p>
<pre class="language-c++"><code>
#include &lt;phpcpp.h&gt;
#include &lt;iostream&gt;

void myFunction()
{
    std::cout &lt;&lt; "example output" &lt;&lt; std::endl;
}

extern "C" {
    PHPCPP_EXPORT void *get_module() {
        static Php::Extension extension("my_extension", "1.0");
        extension.add("myFunction", myFunction);
        return extension;
    }
}
</code></pre>
</p>
<p>
    It is not difficult to imagine what the above code does. If you enable
    this extension, you can create PHP scripts in which you can call myFunction(),
    which will print "example output" to stdout.
</p>
<p>
    As we've said before, there are four types of functions that can be used. In
    this first example we showed the most simple one: a function that does not
    take any parameter, and that returns nothing. What if you
    want to return a value from your function?
</p>
<p>
<pre class="language-c++"><code>
#include &lt;phpcpp.h&gt;
#include &lt;stdlib.h&gt;

Php::Value myFunction()
{
    if (rand() % 2 == 0)
    {
        return "string";
    }
    else
    {
        return 123;
    }
}

extern "C" {
    PHPCPP_EXPORT void *get_module() {
        static Php::Extension extension("my_extension", "1.0");
        extension.add("myFunction", myFunction);
        return extension;
    }
}
</code></pre>
</p>
<p>
    Is that cool or not? In PHP it is perfectly legal to make functions that
    sometimes return a number, and sometimes return a string. This can not be
    done in C++, because a function must always return the same type of variable.
    But because the Php::Value class can be used to represent both numeric
    variables as well as strings (and arrays, and objects, but more on that 
    later) - we can now also create native C++ functions that sometimes return
    a string and sometimes a numeric value. You can test the function with a 
    simple PHP script.
</p>
<p>
<pre class="language-php"><code>
&lt;?php
    for ($i=0; $i&lt;10; $i++) echo(myFunction()."\n");
?&gt;
</code></pre>
</p>
<p>
    The only type of native function that is left is the one that accepts 
    parameters. Let's give an example of a function that takes a variable
    number of parameters, and sums up the integer value of each of the
    parameters:
</p>
<pre class="language-c++"><code>
#include &lt;phpcpp.h&gt;

Php::Value sum_everything(Php::Parameters &parameters)
{
    int result = 0;
    for (auto &param : parameters) result += param;
    return result;
}

extern "C" {
    PHPCPP_EXPORT void *get_module() {
        static Php::Extension extension("my_extension", "1.0");
        extension.add("sum_everything", sum_everything);
        return extension;
    }
}
</code></pre>
<p>
    The above example shows how to work with parameters. The Php::Parameters class
    is in reality nothing less than a std::vector filled with Php::Value objects -
    and you can thus iterate over it. In this example we use the new C++11 way of
    iterating, and the new-for-C++11 auto keyword to ask the compiler to find out
    what type of variables are stored in the parameters vector (it are Php::Value
    objects).
</p>
<p>
    And once again you can see how powerful this cute Php::Value class is. It can 
    for example be used on the right hand side of a += operator to be added to 
    an integer value, and the final integer result variable is automatically 
    converted back into a Php::Value object when the function returns - just as if 
    you are working with regular PHP $variables. But remember, this is C++ code and 
    therefore much, much faster!
</p>
<p>
    The sum_everything() function that we just made is now accessible from your
    PHP script. Let's run a test.
</p>
<p>
<pre class="language-php"><code>
&lt;?php
    echo(sum_everything(10,"100",20)."\n");
?&gt;
</code></pre>
</p>
<p>
    The output of the above script is, of course, 130. Do you want an even 
    funnier example? This outputs 130 too:
</p>
<p>
<pre class="language-php"><code>
&lt;?php
    class MyClass {
        public function __toString() {
            return 20;
        }
    }
    echo(sum_everything(10,"100",new MyClass())."\n");
?&gt;
</code></pre>
</p>