summaryrefslogtreecommitdiff
path: root/documentation
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-23 21:11:57 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-23 21:11:57 +0100
commit68441d448e377f9a61af5c29c793922fff0d9328 (patch)
tree6fc34379b4fc010751c4cd38ea0722f37f1cf085 /documentation
parentd8b25fe2e585634567483124a33c3b779d2516f5 (diff)
errors have a limited buffer, and discard any overflow data, replaced std::cout calls with Php::out calls in the documentation
Diffstat (limited to 'documentation')
-rw-r--r--documentation/calling-functions-and-methods.html6
-rw-r--r--documentation/functions.html2
-rw-r--r--documentation/output-and-errors.html103
-rw-r--r--documentation/variables.html18
4 files changed, 116 insertions, 13 deletions
diff --git a/documentation/calling-functions-and-methods.html b/documentation/calling-functions-and-methods.html
index d3bc3e2..00f166a 100644
--- a/documentation/calling-functions-and-methods.html
+++ b/documentation/calling-functions-and-methods.html
@@ -36,7 +36,7 @@ void example_function(Php::Parameters &amp;params)
for (auto &key : keys)
{
// output key
- std::cout &lt;&lt; "key: " &lt;&lt; key &lt;&lt; std::endl;
+ Php::out &lt;&lt; "key: " &lt;&lt; key &lt;&lt; std::endl;
}
// call a function from user space
@@ -46,7 +46,7 @@ void example_function(Php::Parameters &amp;params)
Php::Object time("DateTime", "now");
// call a method on the datetime object
- std::cout &lt;&lt; time.call("format", "Y-m-d H:i:s") &lt;&lt; std::endl;
+ 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];
@@ -60,7 +60,7 @@ void example_function(Php::Parameters &amp;params)
Php::Array time_format({time, "format"});
// call the method that is stored in the array
- std::cout &lt;&lt; time_format("Y-m-d H:i:s") &lt;&lt; std::endl;
+ Php::out &lt;&lt; time_format("Y-m-d H:i:s") &lt;&lt; std::endl;
}
/**
diff --git a/documentation/functions.html b/documentation/functions.html
index 58f2394..c8a521b 100644
--- a/documentation/functions.html
+++ b/documentation/functions.html
@@ -32,7 +32,7 @@ Php::Value example4(Php::Parameters &amp;params);</code></pre>
void myFunction()
{
- std::cout &lt;&lt; "example output" &lt;&lt; std::endl;
+ Php::out &lt;&lt; "example output" &lt;&lt; std::endl;
}
extern "C" {
diff --git a/documentation/output-and-errors.html b/documentation/output-and-errors.html
new file mode 100644
index 0000000..4697854
--- /dev/null
+++ b/documentation/output-and-errors.html
@@ -0,0 +1,103 @@
+<h1>Output and errors</h1>
+<p>
+ You can use regular C++ streams for IO. It is however not
+ a good idea to use the std::cout and std::cerr streams for output.
+</p>
+<p>
+ When PHP runs as a webserver module, stdout is redirected to the
+ terminal <i>from where the webserver process was originally started</i>,
+ while you probably want to generate output that ends up in the generated
+ (HTML) output. But even when PHP runs as a CLI script - and std::cout works -
+ you still should not write to stdout directly, because it will bypass all
+ output handlers that may have been set up by the PHP user space script.
+</p>
+<p>
+ The PHP-CPP library offers a Php::out stream that can be used instead. This
+ Php::out variable is an instance of the well known std::ostream class, and
+ utilizes all the output buffering set up in PHP. All output that you send to
+ it always ends up where you expect: on stdout for CLI scripts, and in the
+ generated code for webserver processes. It does essentially the same
+ as the echo() function in PHP scripts.
+</p>
+<p>
+ Php::out is a regular std::ostring object. This also has as consequence that
+ it uses a buffer that needs to be sync'ed to flush the output. This flush
+ happens automatically when you add 'std::endl' to the output, or when you
+ add 'std::sync' explicitly.
+</p>
+<p>
+<pre class="language-c++"><code>
+/**
+ * Example function that shows how to generate output
+ */
+void example()
+{
+ // the C++ equivalent of the echo() function
+ Php::out &lt;&lt; "example output" &lt;&lt; std::endl;
+
+ // generate output without a newline, and ensure that it is flushed
+ Php::out &lt;&lt; "example output" &lt;&lt; std::flush;
+
+ // or call the flush() method
+ Php::out &lt;&lt; "example output";
+ Php::out.flush();
+
+ // just like all PHP functions, the Php::echo() function can also be used
+ Php::echo("Example output\n");
+}
+</code></pre>
+</p>
+<h2 id="warnings-and-notices">Errors, warnings and notices</h2>
+<p>
+ When you want to trigger a PHP error (the C++ equivalent of the PHP
+ trigger_error()) function, you can use one of the Php::error, Php::notice,
+ Php::warning and Php::deprecated streams. These are also instances of the
+ std::ostream class.
+</p>
+<p>
+<p>
+<pre class="language-c++"><code>
+/**
+ * Example function that shows how to generate output
+ */
+void example()
+{
+ // generate a PHP notice
+ Php::notice &lt;&lt; "this is a notice" &lt;&lt; std::flush;
+
+ // generate a PHP warning
+ Php::warning &lt;&lt; "this is a warning" &lt;&lt; std::flush;
+
+ // inform the user that a call to a deprecated function was made
+ Php::deprecated &lt;&lt; "this method is deprecated" &lt;&lt; std::flush;
+
+ // generate a fatal error
+ Php::error &lt;&lt; "fatal error" &lt;&lt; std::flush;
+
+ // this code will no longer be called
+ Php::out &lt;&lt; "regular output" &lt;&lt; std::endl;
+}
+</code></pre>
+</p>
+<p>
+ In the above example you can see that we used std::flush and not std::endl.
+ The reason for this is that std::endl internally does two things: it
+ appends a newline, and it flushes the buffer. For errors, notices and
+ warnings we don't need the newline, but we still have to flush the
+ buffer to actually generate the output.
+</p>
+<p>
+ There is something very peculiar with the Php::error stream: when you flush
+ it, the PHP script ends with a fatal error <i>and your C++ algorithm
+ immediately exits!!</i> Under the hood, the PHP engine does a longjump to
+ a place deep inside the Zend engine. In the example function the
+ 'Php::out &lt;&lt; "regular output"; statement is therefore never executed.
+</p>
+<p>
+ This all is very unusual, and (according to us) in conflict with the general
+ rules of decent software engineering. An output-generating function should
+ not behave like throwing an exception. Code that looks like normal code,
+ should also behave like normal code, and not do unexpected things like
+ leaping out of the current call stack. We therefore advise not to use
+ Php::error - or use it with extreme care.
+</p>
diff --git a/documentation/variables.html b/documentation/variables.html
index 8c8b328..d577699 100644
--- a/documentation/variables.html
+++ b/documentation/variables.html
@@ -101,7 +101,7 @@ void myFunction(const Php::Value &amp;value)
void myFunction(Php::Value &amp;value)
{
value += 10;
- std::cout &lt;&lt; value &lt;&lt; std::endl;
+ Php::out &lt;&lt; value &lt;&lt; std::endl;
if (value == "some string")
{
@@ -311,8 +311,8 @@ Php::Value array;
array["x"] = 10;
array["y"] = 20;
-std::cout &lt;&lt; array["x"] &lt;&lt; std::endl;
-std::cout &lt;&lt; array["y"] &lt;&lt; std::endl;
+Php::out &lt;&lt; array["x"] &lt;&lt; std::endl;
+Php::out &lt;&lt; array["y"] &lt;&lt; std::endl;
</code></pre>
</p>
<p>
@@ -359,11 +359,11 @@ object["property2"] = "value2";
object = Php::Object("DateTime", "now");
// methods can be called with the call() method
-std::cout &lt;&lt; object.call("format", "Y-m-d H:i:s") &lt;&lt; std::endl;
+Php::out &lt;&lt; object.call("format", "Y-m-d H:i:s") &lt;&lt; std::endl;
// all these methods can be called on a Php::Value object too
Php::Value value = Php::Object("DateTime", "now");
-std::cout &lt;&lt; value.call("format", "Y-m-d H:i:s") &lt;&lt; std::endl;
+Php::out &lt;&lt; value.call("format", "Y-m-d H:i:s") &lt;&lt; std::endl;
</code></pre>
</p>
<h2 id="iterating">Iterating</h2>
@@ -385,7 +385,7 @@ void myFunction(const Php::Value &amp;value)
for (auto &amp;iter : value)
{
// output key and value
- std::cout &lt;&lt; iter.first &lt;&lt; ": " &lt;&lt; iter.second &lt;&lt; std::endl;
+ Php::out &lt;&lt; iter.first &lt;&lt; ": " &lt;&lt; iter.second &lt;&lt; std::endl;
}
}
</code></pre>
@@ -439,7 +439,7 @@ void myFunction(const Php::Value &amp;value)
Php::Value date = "date";
// "date" is a built-in PHP function and thus can it be called
-std::cout &lt;&lt; date("Y-m-d H:i:s") &lt;&lt; std::endl;
+Php::out &lt;&lt; date("Y-m-d H:i:s") &lt;&lt; std::endl;
// create a date-time object
Php::Object now = Php::Object("DateTime","now");
@@ -453,7 +453,7 @@ array[1] = "format";
// an array with two members can be called too, the first
// member is seen as the object, and the second as the
// name of the method
-std::cout &lt;&lt; array("Y-m-d H:i:s") &lt;&lt; std::endl;
+Php::out &lt;&lt; array("Y-m-d H:i:s") &lt;&lt; std::endl;
</code></pre>
</p>
<h2 id="global-variables">Global variables</h2>
@@ -474,7 +474,7 @@ Php::GLOBALS["b"] = Php::Array({1,2,3,4});
Php::GLOBALS["b"][4] = 5;
// and global variables can also be read
-std::cout &lt;&lt; Php::GLOBALS["b"] &lt;&lt; std::endl;
+Php::out &lt;&lt; Php::GLOBALS["b"] &lt;&lt; std::endl;
</code></pre>
</p>
<p>