summaryrefslogtreecommitdiff
path: root/documentation/calling-functions-and-methods.html
blob: 00f166a2976364291dd2bbcf3dede48934fb7396 (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
<h1>Calling PHP functions</h1>
<p>
    Let's get one thing clear first. Running native code is much faster than
    running PHP code. So, once your C++ function or your C++ method finally
    gets called, you normally cast the parameters to native variables, and 
    you start running your own fast algorithm. And you don't want to call 
    other PHP functions from that moment on.
</p>
<p>
    If, however, you would like to make a call to a PHP function - whether that
    is a function that is built-in in the Zend engine, that is defined in an
    extension, or even a function that comes from PHP user space - you can do
    so.
</p>
<p>
<pre class="language-c++"><code>#include &lt;phpcpp.h&gt;
#include &lt;iostream&gt;

/**
 *  Native function that is callable from PHP
 *
 *  This function gets two parameters: an associative array and a callback.
 *  It does not do anything meaningful, it is just a demonstration function.
 *
 *  @param  params      The parameters passed to the function
 */
void example_function(Php::Parameters &amp;params)
{
    // first parameter is an array
    Php::Value array = params[0];
    
    // call the PHP array_keys() function to get the parameter keys
    std::vector&lt;std::string&gt; keys = Php::array_keys(array);
    
    // loop through the keys
    for (auto &key : keys) 
    {
        // output key
        Php::out &lt;&lt; "key: " &lt;&lt; key &lt;&lt; std::endl;
    }
    
    // call a function from user space
    Php::Value data = Php::call("some_function", "some_parameter");
    
    // create an object (this will also call __construct())
    Php::Object time("DateTime", "now");
    
    // call a method on the datetime object
    Php::out &lt;&lt; time.call("format", "Y-m-d H:i:s") &lt;&lt; std::endl;
    
    // second parameter is a callback function
    Php::Value callback = params[1];
    
    // call the callback function
    callback("some","parameter");
    
    // in PHP it is possible to create an array with two parameters, the first
    // parameter being an object, and the second parameter should be the name
    // of the method, we can do that in PHP-CPP too
    Php::Array time_format({time, "format"});
    
    // call the method that is stored in the array
    Php::out &lt;&lt; time_format("Y-m-d H:i:s") &lt;&lt; std::endl;
}

/**
 *  Switch to C context, because the Zend engine expects get 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("example_function", example_function);
        
        // return the extension details
        return extension;
    }
}</code></pre>
</p>
<p>
    In above example you can see quite some different ways to call PHP 
    functions from C++. The first one is the call to Php::array_keys(). The
    PHP-CPP internally has a long list of all important PHP functions, and
    you can call these functions directly from your extension. Php::array_keys()
    is one of them.
</p>
<p>
    Many of the built-in function functions (like Php::array_keys()) return a
    Php::Value object. In the example however, you saw that we assigned the
    return value directly to a std::vector. This works because the Php::Value 
    object has an implicit casting operator to automatically transform the 
    object to a vector.
</p>
<p>
    Not every PHP function can of course be called like the built-in functions 
    can. User space functions, or functions from optional PHP extensions are not
    automatically forwarded by the PHP-CPP library. Such functions can still be
    called by using the Php::call() function. You must supply the name of the 
    function to call, and an optional list of arguments.
</p>
<p>
    The Php::Object class (which is derived from Php::Value) can be used to 
    create objects, and implicitly call the __construct() method. To call a 
    method on an object, you can use the Php::Value::call() method, which 
    is used in the example to call the PHP method DateTime::format().
</p>
<p>
    In PHP scripts you can create an array with two members: an object and 
    the name of a method. This array can then be used as if it was a regular
    function. You can do similar things in C++, as we showed in the example with the
    "time_format" variable.
</p>
<p>
    The following script runs the example.
</p>
<p>
<pre class="language-php"><code>
&lt;?php
    // define a user space function
    function some_function($param)
    {
        echo("userspace function called with $param\n");
    }

    // example input
    $input = array(
        'x' =>  10,
        'y' =>  20,
        'z' =>  30
    );
    
    example_function($input, function($param1, $param2) {
        echo("lambda function called with param $param1 $param2\n");
    });
?&gt;</code></pre>
</p>
<p>
    This above script will generate output similar to this:
<p>
<pre>
key: x
key: y
key: z
userspace function called with some_parameter
2014-03-08 13:55:54
lambda function called with param some parameter
2014-03-08 13:55:54
</pre>
</p>
<p>
    If you call a function or a method that does not exist, a Php::Exception
    will be thrown. If you do not catch this exception in your C++ code, it
    will bubble up and appear in PHP user space.
</p>