summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-04-12 12:35:23 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-04-12 12:35:23 +0200
commit8ca556ab2a41a6c7245fada4628e4719cd99f8b3 (patch)
treeb3e87bce697ef21f568fd0880ea41d01420d6e68
parenta8f3d4c47b342ef1ce9c951239a1618a0912484c (diff)
Update documentation about persistent loading
-rw-r--r--documentation/dynamic-loading.html101
1 files changed, 101 insertions, 0 deletions
diff --git a/documentation/dynamic-loading.html b/documentation/dynamic-loading.html
index 12ae965..dbc7410 100644
--- a/documentation/dynamic-loading.html
+++ b/documentation/dynamic-loading.html
@@ -251,3 +251,104 @@ $object->methodFromMyExtension();
if you're the administrator of a shared hosting platform, you definitely
do not want to install it!
</p>
+<h2 id="persistent">Persistent extensions</h2>
+<p>
+ A dynamically loaded extension is automatically unloaded at the end of the
+ page view. If a subsequent pageview also dynamically loads the same extension,
+ it will start with a completely new and fresh environment. If you want to
+ write an extension that uses static data or static resources (think of a persistent
+ database connection, or a worker thread that processes tasks) this may not
+ always be the desired behavior. You want to keep the database connection active,
+ or the thread running, also after the extension is unloaded.
+</p>
+<p>
+ To overcome this, the Php::dl() function comes with a second boolean parameter
+ that you can use to specify whether you want to load the extension persistently,
+ or only for that specific pageview.
+</p>
+<p>
+ Notice that the only thing that persists is the data <i>in</i> an extension.
+ In subsequent pageviews you must also load the extension to activate these
+ functions and classes, even if you had already loaded the extension persistently
+ in an earlier call. But because the extension was already loaded before, the
+ static data (like the database connection or the thread) are preserved.
+</p>
+<p>
+ The dl_unrestricted() function that we used above can be modified to include
+ this persistent parameter:
+</p>
+<p>
+<pre class="language-c++"><code>
+/**
+ * Function to load every possible extension by pathname
+ *
+ * It takes two arguments: the filename of the PHP extension, and a boolean to
+ * specify whether the extension data should be kept in memory. It returns a
+ * boolean to indicate whether the extension was correctly loaded.
+ *
+ * This function goes further than the original PHP dl() fuction, because
+ * it does not check whether the passed in extension object is stored in the
+ * right directory, and because it allows persistent loading of extensions.
+ * Literally every possible extension, also local ones created by end users,
+ * can be loaded.
+ *
+ * @param params Vector of parameters
+ * @return boolean
+ */
+Php::Value dl_unrestricted(Php::Parameters &amp;params)
+{
+ // get extension name
+ std::string pathname = params[0];
+
+ // persistent setting
+ bool persistent = params.size() > 1 ? params[1].boolValue() : false;
+
+ // load the extension
+ return Php::dl(pathname, persistent);
+}
+
+/**
+ * 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() {
+ // create static instance of the extension object
+ static Php::Extension myExtension("load_extension", "1.0");
+
+ // the extension has one method
+ myExtension.add("dl_unrestricted", dl_unrestricted, {
+ Php::ByVal("pathname", Php::Type::String),
+ Php::ByVal("persistent", Php::Type::Bool, false)
+ });
+
+ // return the extension
+ return myExtension;
+ }
+}
+</code></pre>
+</p>
+<p>
+ And this extension allows us to dynamically load extensions, while preserving
+ persistent data <i>inside</i> the extension:
+</p>
+<p>
+<pre class="language-php"><code>
+&lt;?php
+// load the C++ extension stored in the same directory as this file, the
+// extension is persistently loaded, so it may use persistent data like
+// database connections and so on.
+if (!dl_unrestricted(__DIR__.'/MyExtension.so', true)) die("Extension could not be loaded");
+
+// from now on we can use classes and functions from the extension
+$object = new ClassFromMyExtension();
+$object->methodFromMyExtension();
+
+?&gt;
+</code></pre>
+</p>