From 5d5892dbbf42deb4eb4c6e9b85befb0d7a59f1f3 Mon Sep 17 00:00:00 2001
From: Emiel Bruijntjes
-
-
-
-
-
- What do we see here? We've added four function declarations ("example1",
- "example2", "example3" and "example4") to the source code of our extension.
- The reason why we've only declared the functions, and not fully implemented
- them is to keep the example code relatively small. We assume that the
- four example functions are implemented in a different file. In a real world
- example you could just as well remove the "extern" keyword and implement the
- four functions in the same source file as the get_module() call.
-
- The four functions all have a different signature: Some return a value, while
- others do not return anything. And some take parameters, while others do not.
- Despite the different signature of the functions, they can all be made
- available in PHP by adding them to the extension object, by simply calling
- the myExtension.add() method. This method takes two parameters: the name by
- which the function should be accessible in PHP, and the actual native
- function.
-
- In the example above we've used different names for the native functions
- ("example1" up to "example4") as for the PHP functions ("native1" to
- "native4"). This is legal - you do not have to use the same names for your
- native functions as for your PHP functions. The following PHP script can be
- used to call the four native functions:
+ The above example shows how to work with parameters. The Php::Parameters class
+ is in reality nothing less than a std::vector filled with Php::Value objects -
+ and you can thus iterate over it. In this example we use the new C++11 way of
+ iterating, and the new-for-C++11 auto keyword to ask the compiler to find out
+ what type of variables are stored in the parameters vector (it are Php::Value
+ objects).
-
- It is not possible to export every thinkable C/C++ function to the
- PHP extension. Only functions that have one of the four supported signatures
- can be exported: functions that return
- void or a Php::Value object, and that either accept a Php::Parameters object
- or no parameters at all, can be added to the extension object and can thus
- be exported to PHP.
+ The sum_everything() function that we just made is now accessible from your
+ PHP script. Let's run a test.
- PHP has a mechanism to enforce function parameters types, and to accept
- parameters either by reference or by value. In the examples above, we have
- not yet used that mechanism yes: it is up to the function implementations
- themselves to inspect the 'Parameters' object, and check if the
- variables are of the right type.
+
+ And once again you can see how powerful this cute Php::Value class is. It can
+ for example be used on the right hand side of a += operator to be added to
+ an integer value, and the final integer result variable is automatically
+ converted back into a Php::Value object when the function returns - just as if
+ you are working with regular PHP $variables. But remember, this is C++ code and
+ therefore much, much faster!
- <?php
- native1();
- native2("a","b");
- $x = native3();
- $y = native4(1,2);
- ?>
-
Parameter types
+<?php
+ echo(sum_everything(10,"100",20)."\n");
+?>
+
- However, the 'Extension::add()' method takes a third optional parameter that - you can use to specify the number of parameters that are supported, whether - the parameters are passed by reference or by value, and what the type of - the parameters is: + The output of the above script is, of course, 130. Do you want an even + funnier example? This outputs 130 too:
-
--#include <phpcpp.h> - -extern void example(Php::Parameters ¶ms); - -extern "C" { - PHPCPP_EXPORT void *get_module() { - static Php::Extension myExtension("my_extension", "1.0"); - myExtension.add("example", example, { - Php::ByVal("a", Php::Type::Numeric), - Php::ByVal("b", "ExampleClass"), - Php::ByRef("c", "OtherClass") - }); - return myExtension.module(); +
- -+<?php + class MyClass { + public function __toString() { + return 20; + } } -} -
- Above you see that we passed in additional information when we registered the - "example" function. We tell our extension that our function accepts three parameters: - the first parameter must be a regular number, while the other ones are object - instances of type "ExampleClass" and "OtherClass". In the end, your native C++ - "example" function will still be called with a Php::Parameters instance, but - the moment it gets called, you can be sure that the Php::Parameters object - will be filled with three members, and that two of them are objects of the - appropriate type, and that the third one is also passed by reference. -
-Working with variables
-- Variables in PHP are non-typed. A variable can thus hold any possible type: - an integer, string, a floating point number, and even an object or an array. - C++ on the other hand is a typed language. In C++ an integer variable always - has a numeric value, and a string variable always hold a string value. -
-- When you mix native code and PHP code, you will need to convert the non-typed - PHP variables into native variables, and the other way round: convert native - variables back into non-typed PHP variables. The PHP-CPP library offers the - "Value" class that makes this a very simple task. + echo(sum_everything(10,"100",new MyClass())."\n"); +?> +
- \ No newline at end of file diff --git a/documentation/parameters.html b/documentation/parameters.html new file mode 100644 index 0000000..464d855 --- /dev/null +++ b/documentation/parameters.html @@ -0,0 +1,58 @@ +
+ PHP has a mechanism to enforce function parameters types, and to accept + parameters either by reference or by value. In the examples above, we have + not yet used that mechanism yes: it is up to the function implementations + themselves to inspect the 'Parameters' object, and check if the + variables are of the right type. +
++ However, the 'Extension::add()' method takes a third optional parameter that + you can use to specify the number of parameters that are supported, whether + the parameters are passed by reference or by value, and what the type of + the parameters is: +
++
+#include <phpcpp.h>
+
+extern void example(Php::Parameters ¶ms);
+
+extern "C" {
+ PHPCPP_EXPORT void *get_module() {
+ static Php::Extension myExtension("my_extension", "1.0");
+ myExtension.add("example", example, {
+ Php::ByVal("a", Php::Type::Numeric),
+ Php::ByVal("b", "ExampleClass"),
+ Php::ByRef("c", "OtherClass")
+ });
+ return myExtension.module();
+ }
+}
+
+
++ Above you see that we passed in additional information when we registered the + "example" function. We tell our extension that our function accepts three parameters: + the first parameter must be a regular number, while the other ones are object + instances of type "ExampleClass" and "OtherClass". In the end, your native C++ + "example" function will still be called with a Php::Parameters instance, but + the moment it gets called, you can be sure that the Php::Parameters object + will be filled with three members, and that two of them are objects of the + appropriate type, and that the third one is also passed by reference. +
++ Variables in PHP are non-typed. A variable can thus hold any possible type: + an integer, string, a floating point number, and even an object or an array. + C++ on the other hand is a typed language. In C++ an integer variable always + has a numeric value, and a string variable always hold a string value. +
++ When you mix native code and PHP code, you will need to convert the non-typed + PHP variables into native variables, and the other way round: convert native + variables back into non-typed PHP variables. The PHP-CPP library offers the + "Value" class that makes this a very simple task. +
+
+
\ No newline at end of file
diff --git a/include/value.h b/include/value.h
index d0079dc..b732616 100644
--- a/include/value.h
+++ b/include/value.h
@@ -683,6 +683,24 @@ protected:
*/
std::ostream &operator<<(std::ostream &stream, const Value &value);
+/**
+ * Custom +=, -=, *=, /=, &= operators, to update integral types with a Php::Value
+ *
+ * This code looks complicated, it ensures that the operators are only
+ * overloaded for integral types (int, bool, etc) - and not for complex types
+ * (arrays, objects, etc)
+ */
+template