summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--documentation/magic-methods.html78
-rw-r--r--src/classbase.cpp11
2 files changed, 86 insertions, 3 deletions
diff --git a/documentation/magic-methods.html b/documentation/magic-methods.html
index 899f335..a3fa4de 100644
--- a/documentation/magic-methods.html
+++ b/documentation/magic-methods.html
@@ -192,3 +192,81 @@ unset($user->email);
?>
</code></pre>
</p>
+<h2>Magic method __call()</h2>
+<p>
+ C++ methods need to be registered explicitly in your extension get_module()
+ startup function to make them accessible. However, when you override the __call()
+ method, you can accept all possible method calls. It does not matter what
+ the name of the method is, when something that looks like a method is called
+ from PHP user space, it will trigger a call to your __call() method.
+</p>
+<p>
+<pre class="language-c++"><code>
+#include &lt;phpcpp.h&gt;
+
+/**
+ * A sample class, that accepts all thinkable method calls
+ */
+class MyClass : public Php::Base
+{
+public:
+ /**
+ * C++ constructor and C++ destructpr
+ */
+ MyClass() {}
+ virtual ~MyClass() {}
+
+ /**
+ * Override the __call() method to accept all 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
+ */
+ Php::Value __call(const char *name, Php::Parameters &amp;params)
+ {
+ return std::string("method: ")+name;
+ }
+};
+
+/**
+ * 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 following PHP script calls some method on this class.
+</p>
+<p>
+<pre code="language-php"><code>
+&lt;?php
+// initialize an object
+$object = new MyClass();
+echo($object->something()."\n");
+echo($object->myMethod()."\n");
+echo($object->whatever()."\n");
+?&gt;
+</code></pre>
+</p>
diff --git a/src/classbase.cpp b/src/classbase.cpp
index e6fb88f..2c8efef 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -103,13 +103,18 @@ static void call_method(INTERNAL_FUNCTION_PARAMETERS)
* @param method_len
* @return zend_function
*/
+#if PHP_VERSION_ID < 50399
zend_function *ClassBase::getMethod(zval **object_ptr, char *method_name, int method_len)
+#else
+zend_function *ClassBase::getMethod(zval **object_ptr, char *method_name, int method_len, const struct _zend_literal *key)
+#endif
{
// something strange about the Zend engine (once more). The structure with
// object-handlers has a get_method and call_method member. When a function is
- // called, the get_method function is called first, but the call_method function
- // will later never be called again -- this is typical
-
+ // called, the get_method function is called first, to retrieve information
+ // about the method (like the handler that should be called to execute it),
+ // after that, this returned handler is also called. The call_method property
+ // of the object_handlers structure however, never gets called. Typical.
// retrieve the class entry linked to this object
auto *entry = zend_get_class_entry(*object_ptr);