diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-23 21:11:57 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-23 21:11:57 +0100 |
commit | 68441d448e377f9a61af5c29c793922fff0d9328 (patch) | |
tree | 6fc34379b4fc010751c4cd38ea0722f37f1cf085 /documentation | |
parent | d8b25fe2e585634567483124a33c3b779d2516f5 (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.html | 6 | ||||
-rw-r--r-- | documentation/functions.html | 2 | ||||
-rw-r--r-- | documentation/output-and-errors.html | 103 | ||||
-rw-r--r-- | documentation/variables.html | 18 |
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 &params) for (auto &key : keys) { // output key - std::cout << "key: " << key << std::endl; + Php::out << "key: " << key << std::endl; } // call a function from user space @@ -46,7 +46,7 @@ void example_function(Php::Parameters &params) Php::Object time("DateTime", "now"); // call a method on the datetime object - std::cout << time.call("format", "Y-m-d H:i:s") << std::endl; + Php::out << time.call("format", "Y-m-d H:i:s") << std::endl; // second parameter is a callback function Php::Value callback = params[1]; @@ -60,7 +60,7 @@ void example_function(Php::Parameters &params) Php::Array time_format({time, "format"}); // call the method that is stored in the array - std::cout << time_format("Y-m-d H:i:s") << std::endl; + Php::out << time_format("Y-m-d H:i:s") << 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 &params);</code></pre> void myFunction() { - std::cout << "example output" << std::endl; + Php::out << "example output" << 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 << "example output" << std::endl; + + // generate output without a newline, and ensure that it is flushed + Php::out << "example output" << std::flush; + + // or call the flush() method + Php::out << "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 << "this is a notice" << std::flush; + + // generate a PHP warning + Php::warning << "this is a warning" << std::flush; + + // inform the user that a call to a deprecated function was made + Php::deprecated << "this method is deprecated" << std::flush; + + // generate a fatal error + Php::error << "fatal error" << std::flush; + + // this code will no longer be called + Php::out << "regular output" << 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 << "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 &value) void myFunction(Php::Value &value) { value += 10; - std::cout << value << std::endl; + Php::out << value << std::endl; if (value == "some string") { @@ -311,8 +311,8 @@ Php::Value array; array["x"] = 10; array["y"] = 20; -std::cout << array["x"] << std::endl; -std::cout << array["y"] << std::endl; +Php::out << array["x"] << std::endl; +Php::out << array["y"] << 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 << object.call("format", "Y-m-d H:i:s") << std::endl; +Php::out << object.call("format", "Y-m-d H:i:s") << std::endl; // all these methods can be called on a Php::Value object too Php::Value value = Php::Object("DateTime", "now"); -std::cout << value.call("format", "Y-m-d H:i:s") << std::endl; +Php::out << value.call("format", "Y-m-d H:i:s") << std::endl; </code></pre> </p> <h2 id="iterating">Iterating</h2> @@ -385,7 +385,7 @@ void myFunction(const Php::Value &value) for (auto &iter : value) { // output key and value - std::cout << iter.first << ": " << iter.second << std::endl; + Php::out << iter.first << ": " << iter.second << std::endl; } } </code></pre> @@ -439,7 +439,7 @@ void myFunction(const Php::Value &value) Php::Value date = "date"; // "date" is a built-in PHP function and thus can it be called -std::cout << date("Y-m-d H:i:s") << std::endl; +Php::out << date("Y-m-d H:i:s") << 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 << array("Y-m-d H:i:s") << std::endl; +Php::out << array("Y-m-d H:i:s") << 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 << Php::GLOBALS["b"] << std::endl; +Php::out << Php::GLOBALS["b"] << std::endl; </code></pre> </p> <p> |