summaryrefslogtreecommitdiff
path: root/documentation/functions.html
blob: c8a521b7eaa024af5e013a8c0d2336866b2b5220 (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
171
172
173
174
175
176
177
178
179
<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 four 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>
    The 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 value (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 your PHP scripts.
</p>
<p>
<pre class="language-c++"><code>#include &lt;phpcpp.h&gt;
#include &lt;iostream&gt;

void myFunction()
{
    Php::out &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 deploy
    this extension, you can create PHP scripts in which you can call myFunction(),
    that 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 parameters, 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 possible output of this script could for example be:
</p>
<p>
<pre>
123
123
string
123
123
string
string
string
string
</pre>
</p>
<p>
    We've mentioned that there are four types of native functions that can be
    added to the extension object. We've showed you two examples, but none of
    these example functions accepted any parameters. Let's therefore round up with a 
    final example, one that accepts parameters and also returns a result. 
    The following function takes a variable number of parameters, 
    and sums up the integer value of all 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>
    It looks so simple, doesn't it? 
    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. 
    We use the new C++11 way of doing this, and we use 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, of course).
</p>
<p>
    And you can again see how powerful the Php::Value class is. 
    It can 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. The "100" string variable
    that is passed to the function is automatically converted into an integer,
    which is exactly the same behavior of a PHP script.
</p>
<p>
    All parameter-accepting functions can be called with a variable number of
    parameters. It is therefore valid to call them from PHP with zero, one, two 
    or even ten thousand parameters. It is up to you, the extension programmer, to check 
    this, and to check whether the parameters that are passed to your
    function are of the right type.
</p>
<p>
    In most situations however, you want
    your functions to be called with a fixed number of parameters, or with
    parameters of a certain type. To achieve that, you will have to specify
    the parameter types when you add your function to the extension object.
    More on that in the <a href="parameters">next section</a>.
</p>