diff options
-rw-r--r-- | documentation/magic-methods.html | 78 | ||||
-rw-r--r-- | src/classbase.cpp | 11 |
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 <phpcpp.h> + +/** + * 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 &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<MyClass> 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> +<?php +// initialize an object +$object = new MyClass(); +echo($object->something()."\n"); +echo($object->myMethod()."\n"); +echo($object->whatever()."\n"); +?> +</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); |