summaryrefslogtreecommitdiff
path: root/documentation
diff options
context:
space:
mode:
Diffstat (limited to 'documentation')
-rw-r--r--documentation/constructors-and-destructors.html8
-rw-r--r--documentation/install.html37
-rw-r--r--documentation/magic-methods.html82
-rw-r--r--documentation/properties.html272
-rw-r--r--documentation/variables.html22
5 files changed, 387 insertions, 34 deletions
diff --git a/documentation/constructors-and-destructors.html b/documentation/constructors-and-destructors.html
index d7cc61b..399367a 100644
--- a/documentation/constructors-and-destructors.html
+++ b/documentation/constructors-and-destructors.html
@@ -135,10 +135,10 @@ extern "C" {
// description of the class so that PHP knows which methods are accessible
Php::Class<Counter> counter("Counter");
- counter.method("__construct", &Counter::__construct);
- counter.method("increment", &Counter::increment);
- counter.method("decrement", &Counter::decrement);
- counter.method("value", &Counter::value);
+ counter.method("__construct", &Counter::__construct);
+ counter.method("increment", &Counter::increment);
+ counter.method("decrement", &Counter::decrement);
+ counter.method("value", &Counter::value);
// add the class to the extension
myExtension.add(std::move(counter));
diff --git a/documentation/install.html b/documentation/install.html
index 7f7a2c3..d1d1cb0 100644
--- a/documentation/install.html
+++ b/documentation/install.html
@@ -5,17 +5,16 @@
system(s).
</p>
<p>
- Luckily, for most of us (those who use Linux environments), this will be
- a piece of cake. If you're on a different platform however, you are left on
- your own, because we (as in me, the PHP-CPP developer), only uses Linux
- systems. There is however no reason why this library should not also work on
- other platforms, because it only uses straight forward C++ code. Thus, if
- you are on a different platform and have managed to compile the library on
- it, please give us feedback so that we can update these installation
- instructions and include other platforms as well.
+ Luckily, for most of us (those who use Linux or Apple environments), this
+ will be a piece of cake. If you're on a different platform however, you are
+ left on your own, because we (as in me, the PHP-CPP developer), only uses
+ Linux systems. There is however no reason why this library should not also
+ work on other platforms, because it only uses straight forward C++ code.
+ Thus, if you are on a different platform and have managed to compile the
+ library on it, please give us feedback so that we can update these
+ installation instructions and include other platforms as well.
</p>
-
<h2 id="limitations">Limitations</h2>
<p>
At this moment, PHP-CPP only supports single-threaded PHP installations.
@@ -85,7 +84,20 @@
<pre><code>make</code></pre>
</p>
<p>
- The PHP-CPP library has now been built, and all that is left to do is
+ This will start the compiler and build the library.
+</p>
+
+<h2 id="osx">Compiling on OSX?</h2>
+<p>
+ If you compile the software on OSX, you may run into linking and "unresolved
+ symbol" errors. In that case you will have to make a change to the Makefile.
+ Somewhere in this Makefile there is an option "LINKER_FLAGS". This option
+ should be extended, and the extra flag "-undefined dynamic_lookup" should
+ be added to it.
+</p>
+
+<p>
+ After you ran 'make', and the PHP-CPP library was built, all that is left to do is
install it on your system. You can use the "make install" command for it.
This command should be executed as root, either by using "sudo", or by
logging on as root first.
@@ -94,6 +106,7 @@
<pre><code>sudo make install</code></pre>
</p>
<p>
- Congratulations! You are now the happy owner of a system with PHP-CPP installed
- and nothing can stop you from building your first fast native PHP extension.
+ That was it! After these steps you are now the happy owner of a system with
+ PHP-CPP installed and nothing can stop you from building your first fast
+ native PHP extension.
</p>
diff --git a/documentation/magic-methods.html b/documentation/magic-methods.html
index 8a1fbfa..6356d2a 100644
--- a/documentation/magic-methods.html
+++ b/documentation/magic-methods.html
@@ -10,13 +10,21 @@
in your class, and if they do, they will be compiled into your extension
and called when they are accessed from PHP.
</p>
+<h2 id="compile-time-detection">Compile time detection</h2>
<p>
- The signature of the methods is flexible. Most of the methods accept
- Php::Value objects and also return Php::Value objects, but if your own
- magic methods have a slightly different signature (they return an integer
- for example) it will be picked up by the compiler too because the Php::Value
- has many implicit constructors to convert other types into Php::Value
- objects.
+ Although you may have expected that the magic methods are virtual methods in
+ the Php::Base class that can be overridden, they are not. The methods are
+ detected by the C++ compiler at compile time - and are very normal methods
+ that just happen to have a certain name.
+</p>
+<p>
+ Because of the compile time detection, the signature of the methods is
+ somewhat flexible. The return values of many magic methods are assigned to
+ Php::Value objects, which means that as long as you make sure
+ that your magic method returns a type that is assignable to a Php::Value,
+ you can use it in your class. Your __toString() method may thus return a
+ char*, a std::string, Php::Value (and even an integer!), because all these
+ types can be assigned to a Php::Value.
</p>
<p>
The nice thing about magic methods implemented with PHP-CPP is that they
@@ -25,6 +33,68 @@
can not be called explicitly from PHP scripts - but they do get called
when a property is accessed.
</p>
+<h2 id="constructors">Constructors</h2>
+<p>
+ Normally, magic methods do not have
+ to be registered to make them work. When you add a magic method like
+ __toString() or __get() to your class, it will automatically be
+ called when an object is casted to a string or a property is accessed. There
+ is no need to enable the magic method explicitly in the get_module() startup
+ function.
+</p>
+<p>
+ The only exception to this rule is the __construct() method. This method
+ does have to be explicitly registered. There are a number of reasons for this.
+ For a start, the __construct() method does not have a fixed signature, and
+ by explicitly adding it to the extension, you can also specify what
+ parameters it accepts, and whether the __construct() method should be public,
+ private or protected (if you want to create classes that can not be
+ instantiated from PHP).
+</p>
+<p>
+ The other reason why you have to explicitly register the __construct() method,
+ is that, unlike other magic methods, the __construct method <i>must</i>
+ be visible from PHP. Inside constructors of derived classes, it often is
+ necessary to make a call to parent::__construct(). By registering the
+ __construct() method in the get_module() function you make the function
+ visible from PHP.
+</p>
+<p>
+ We have a special article about <a href="constructors-and-destructors">
+ constructors and destructors</a> with multiple examples how to register
+ the __construct() method.
+<p>
+<h2 id="clone-and-destruct">Clone and destruct</h2>
+<p>
+ The magic __clone() method is very similar to the __construct() method. It
+ also is a method that is called directly <i>after</i> an object is constructed.
+ The difference is that __clone() is called after an object is <i>copy
+ constructed</i> (or <i>cloned</i/> if you prefer the PHP idiom), while
+ __construct() is called right after the normal constructor.
+</p>
+<p>
+ The magic __destruct() method gets called right before the object gets
+ destructed (and right before the C++ destructor runs).
+</p>
+<p>
+ The __clone() and __destruct() methods are regular magic methods (unlike
+ __construct()) and you therefore do not have to register them to make them
+ active. If you add one of these two methods to your class, you will not have
+ to make any changes to the get_module() startup function. The PHP-CPP library
+ calls them automatically if they are available.
+</p>
+<p>
+ In normal circumstances you probably have no need for these methods.
+ The C++ copy constructor and the C++ destructor can be used too. The only
+ difference is that the magic methods are called on objects that are in a
+ fully initialized state, while the C++ copy constructor and C++ destructor
+ work on objects that are <i>being initialized</i>, or that are
+ <i>being destructed</i>.
+</p>
+<p>
+ The article about mentioned above about <a href="constructors-and-destructors">
+ constructors and destructors</a> has more details and examples.
+</p>
<h2 id="pseudo-properties">Pseudo properties</h2>
<p>
With the methods __get(), __set(), __unset() and __isset() you can define
diff --git a/documentation/properties.html b/documentation/properties.html
index bdbdfa7..f7f96c6 100644
--- a/documentation/properties.html
+++ b/documentation/properties.html
@@ -2,22 +2,274 @@
<p>
When you define a class completely in PHP, you can add properties (member
variables) to it. When you add member variables to a native C++ class however,
- you better use regular C++ member variables for that, instead of PHP variables.
+ you better use regular native member variables for that, instead of PHP variables.
Native variables have an immensely better performance than PHP variables,
and it would be insane to store integers or strings in Php::Value objects
if you can store them in int's and std::string objects as well.
</p>
+<h2 id="normal-members">Normal member variables</h2>
<p>
- To access these member variables you could create getX() and setX()
- methods, or alternatively implement __get() and __set() methods if you
- want to make your native member variables look like public or protected
- properties.
+ It is difficult to imagine that someone in the world would like to create
+ a native class, with regular non-typed public PHP properties on it. However,
+ if you insist, you can use the PHP-CPP library for this. Let's take an example
+ class in PHP, and see what it would look like in C++.
</p>
<p>
- I can not imagine that there is anyone in the world who would like to create
- a native class, with regular public PHP properties on it. But still, in this
- article we explain how you can do that.
+<pre class="language-php"><code>
+&lt;?php
+/**
+ * PHP example class
+ */
+class Example
+{
+ /**
+ * Define a public property
+ */
+ public $property1;
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ // initialize the property
+ $this->property1 = "xyz";
+ }
+
+ /**
+ * Example method
+ */
+ public function method()
+ {
+ // do something with the public property (like changing it)
+ $this->property = "abc";
+ }
+}
+
+// create an instance
+$example = new Example();
+
+// overwrite the public property
+$example->property1 = "new value";
+
+?&gt;
+</code></pre>
</p>
<p>
- ... this article is not finished yet
-</p> \ No newline at end of file
+ The above example creates a class with one public property. This property
+ can be accessed by the Example class, and because it is public also by
+ everyone else, as is shown in the example. If you like such classes, you can
+ write something similar with PHP-CPP.
+</p>
+<p>
+<pre class="language-cpp"><code>
+#include &lt;phpcpp.h&gt;
+
+/**
+ * C++ Example class
+ */
+class Example : public Php::Base
+{
+public:
+ /**
+ * c++ constructor
+ */
+ Example() {}
+
+ /**
+ * c++ destructor
+ */
+ virtual ~Example() {}
+
+ /**
+ * php "constructor"
+ * @param params
+ */
+ void __construct()
+ {
+ // get self reference as Php::Value object
+ Php::Value self(this);
+
+ // initialize a public property
+ self["property1"] = "xyz";
+ }
+
+ /**
+ * Example method
+ */
+ void method()
+ {
+ // get self reference as Php::Value object
+ Php::Value self(this);
+
+ // overwrite the property
+ self["property1"] = "abc";
+ }
+};
+
+/**
+ * Switch to C context so that the get_module() function can be
+ * called by C programs (which the Zend engine is)
+ */
+extern "C" {
+ /**
+ * Startup function for the extension
+ * @return void*
+ */
+ PHPCPP_EXPORT void *get_module() {
+ // create static 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;Example&gt; example("Example");
+
+ // register the methods
+ example.method("__construct", &amp;Example::__construct);
+ example.method("method", &amp;Example::method);
+
+ // the Example class has one public property
+ example.property("property1", "xyz", Php::Public);
+
+ // add the class to the extension
+ myExtension.add(std::move(example));
+
+ // return the extension
+ return myExtension;
+ }
+}
+</code></pre>
+</p>
+<p>
+ The example code shows how you initialize the properties inside
+ the get_module() function.
+</p>
+<p>
+ Instead of public properties, you can also define private or protected
+ properties, but even that is probably not what you want, as storing
+ data in native C++ variables is much faster.
+</p>
+<h2>Smart properties</h2>
+<p>
+ With the <a href="magic-methods">magic methods __get() and __set()</a> you
+ can make more advanced properties that are directly mapped to C++
+ variables, and that allow you to perform additional checks when a property
+ is overwritten, so that an object always remains in a valid state.
+</p>
+<p>
+ On top of that, with the PHP-CPP library you can also assign getter and
+ setter methods to properties. Every time a property is accessed, your getter
+ or setter method is automatically called.
+</p>
+<p>
+<pre class="language-cpp"><code>
+#include &lt;phpcpp.h&gt;
+
+/**
+ * C++ Example class
+ */
+class Example : public Php::Base
+{
+private:
+ /**
+ * Example property
+ * @var int
+ */
+ int _value = 0;
+
+
+public:
+ /**
+ * c++ constructor
+ */
+ Example() {}
+
+ /**
+ * c++ destructor
+ */
+ virtual ~Example() {}
+
+ /**
+ * Method to get access to the property
+ * @return Php::Value
+ */
+ Php::Value getValue() const
+ {
+ return _value;
+ }
+
+ /**
+ * Method to overwrite the property
+ * @param value
+ */
+ void setValue(const Php::Value &amp;value)
+ {
+ // overwrite property
+ _value = value;
+
+ // sanity check: the value should never exceed 100
+ if (_value > 100) _value = 100;
+ }
+
+ /**
+ * Method to retrieve the double property value
+ * @return Php::Value
+ */
+ Php::Value getDouble() const
+ {
+ return _value * 2;
+ }
+};
+
+/**
+ * Switch to C context so that the get_module() function can be
+ * called by C programs (which the Zend engine is)
+ */
+extern "C" {
+ /**
+ * Startup function for the extension
+ * @return void*
+ */
+ PHPCPP_EXPORT void *get_module() {
+ // create static 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;Example&gt; example("Example");
+
+ // register the "value" property, with the methods to get and set it
+ example.property("value", &amp;Example::getValue, &amp;Example::setValue);
+
+ // register a read-only "double" property, with a method to get it
+ example.property("double", &amp;Example::getDouble);
+
+ // add the class to the extension
+ myExtension.add(std::move(example));
+
+ // return the extension
+ return myExtension;
+ }
+}
+</code></pre>
+</p>
+<p>
+ The following PHP script uses this. It created an example object, sets the
+ value property to 500 (which is not allowed, values higher than 100 are
+ rounded to 100), and then it reads out the double value.
+</p>
+<p>
+<pre class="language-php"><code>
+&lt;?php
+// create object
+$object = new Example();
+
+// set the value
+$object->value = 500;
+
+// show the double value
+echo($object->double."\n");
+
+// update the double value
+// (this will trigger an error, this is a read-only property)
+$object->double = 300;
+?&gt;
+</code></pre>
diff --git a/documentation/variables.html b/documentation/variables.html
index 6b63598..b3f4330 100644
--- a/documentation/variables.html
+++ b/documentation/variables.html
@@ -286,7 +286,7 @@ std::cout &lt;&lt; array("Y-m-d H:i:s") &lt;&lt; std::endl;
<h2 id="global-variables">Global variables</h2>
<p>
To read or update global PHP variables, you can use the Php::GLOBALS
- variable. This variable works more or less the same as the $_GLOBALS
+ variable. This variable works more or less the same as the $GLOBALS
variable in a PHP script.
</p>
<p>
@@ -305,7 +305,25 @@ std::cout &lt;&lt; Php::GLOBALS["b"] &lt;&lt; std::endl;
</code></pre>
</p>
<p>
- Unlike PHP scripts, that handles only single pageviews, an extension is
+ Next to the $GLOBALS variable, PHP allows you to access variables using
+ the $_GET, $_POST, $_COOKIE, $_FILES, $_SERVER, $_REQUEST and $_ENV variables.
+ In your C++ extension you can do something similar with the global variables
+ Php::GET, Php::POST, Php::COOKIE, Php::FILES, Php::SERVER, Php::REQUEST and
+ Php::ENV. These are global, read-only, objects with an overloaded operator[]
+ method. You can thus access them as if it were associative arrays.
+</p>
+<p>
+<pre class="language-c++"><code>
+// retrieve the value of a request variable
+int age = Php::REQUEST["name"];
+
+// or retrieve the value of a server variable
+std::string referer = Php::SERVER["HTTP_REFERER"];
+</code></pre>
+</p>
+<h2 id="global-natives">Be careful with global C++ variables</h2>
+<p>
+ Unlike PHP scripts, that only handle single pageviews, an extension is
used to handle multiple pageviews after each other. This means that when
you use global C++ (!) variables in your extension, that these variables are
not set back to their initial value in between the pageviews. The