From c9274ab3c422390998e628820afc6a27c12a1a57 Mon Sep 17 00:00:00 2001
From: Emiel Bruijntjes
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.
@@ -305,7 +305,25 @@ std::cout << Php::GLOBALS["b"] << std::endl;
- 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.
+
+Global variables
+
+// 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"];
+
+ 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
diff --git a/include/super.h b/include/super.h
new file mode 100644
index 0000000..73e3761
--- /dev/null
+++ b/include/super.h
@@ -0,0 +1,76 @@
+/**
+ * Super.h
+ *
+ * The Super class is used to implement one of the super variables $_POST,
+ * $_GET, $_SERVER, et cetera
+ *
+ * @copyright 2014 Copernica BV
+ * @author Emiel Bruijntjes
- 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 think that the magic methods are virtual methods that + are overridden from the Php::Base class, 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. +
++ 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.
The nice thing about magic methods implemented with PHP-CPP is that they @@ -25,6 +33,61 @@ can not be called explicitly from PHP scripts - but they do get called when a property is accessed.
++ We start with an exception to the rule. Normally, you do not have to register + magic methods 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. +
++ 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 exactly specify what + parameters it accepts, and whether the __construct() method should be + private or protected (if you want to create classes that can not be + instantiated from PHP). +
++ The other reason why you have to explicitly register the __construct() method, + is that, unlike other magic methods, the magic __construct method must + 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, which makes constructs like this possible. +
++ We have a special article about + constructors and destructors with multiple examples how to register + the __construct() method. +
+
+ The magic __clone() method is very similar to the __construct() method. It + is the first method to be called on a new object after it is copy + constructed. The __destruct() is the method that gets called right before + the object gets destructed (and the C++ destructor runs). +
++ The __clone() and __destruct() methods are regular magic methods. You do + not have to register them to make them active. The PHP-CPP library calls + them automatically if they are available. +
++ In normal circumstances you probably do not need these methods very often. + 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 being initialized, or that are + being destructed. +
++ The article about mentioned above + as more details and examples. +
With the methods __get(), __set(), __unset() and __isset() you can define
diff --git a/include/class.h b/include/class.h
index 31e29a8..008ff8a 100644
--- a/include/class.h
+++ b/include/class.h
@@ -305,13 +305,13 @@ private:
* Call the __destruct method
* @param object
*/
- virtual Value callDestruct(Base *base) const override
+ virtual void callDestruct(Base *base) const override
{
// cast to actual object
T *obj = (T *)base;
// pass on
- return obj->__destruct();
+ obj->__destruct();
}
/**
diff --git a/include/classbase.h b/include/classbase.h
index 24e8f5a..1979f94 100644
--- a/include/classbase.h
+++ b/include/classbase.h
@@ -152,7 +152,7 @@ protected:
/**
* Call the __destruct method
*/
- virtual Value callDestruct(Base *base) const { return nullptr; }
+ virtual void callDestruct(Base *base) const {}
/**
* Call the __call(), __invoke() or __callStatic() method
--
cgit v1.2.3
From 1f1a0fa9349d37e623ae763b48c7ea21681cd45b Mon Sep 17 00:00:00 2001
From: Emiel Bruijntjes
- Although you may think that the magic methods are virtual methods that - are overridden from the Php::Base class, they are not. The methods are + 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.
@@ -46,18 +46,18 @@ 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 exactly specify what - parameters it accepts, and whether the __construct() method should be + 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).The other reason why you have to explicitly register the __construct() method, - is that, unlike other magic methods, the magic __construct method must + is that, unlike other magic methods, the __construct method must 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, which makes constructs like this possible. + visible from PHP.
We have a special article about @@ -72,12 +72,12 @@ the object gets destructed (and the C++ destructor runs).
- The __clone() and __destruct() methods are regular magic methods. You do - not have to register them to make them active. The PHP-CPP library calls - them automatically if they are available. + The __clone() and __destruct() methods are regular magic methods and you + therefore do not have to register them to make them active. The PHP-CPP + library calls them automatically if they are available.
- In normal circumstances you probably do not need these methods very often. + In normal circumstances you probably have not 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 @@ -85,8 +85,8 @@ being destructed.
- The article about mentioned above - as more details and examples. + The article about mentioned above about + constructors and destructors has more details and examples.
diff --git a/include/class.h b/include/class.h
index 008ff8a..d867699 100644
--- a/include/class.h
+++ b/include/class.h
@@ -156,7 +156,27 @@ public:
void property(const char *name, const std::string &value, int flags = Public) { ClassBase::property(name, value, flags); }
void property(const char *name, bool value, int flags = Public) { ClassBase::property(name, value, flags); }
void property(const char *name, double value, int flags = Public) { ClassBase::property(name, value, flags); }
-
+
+ /**
+ * Properties as methods
+ *
+ * This is a smarter way for adding properties to a class. You can define
+ * a property and a method that gets called every time the property is
+ * set or unset.
+ *
+ * If you do not set a setter method, your property will be read-only.
+ *
+ * @param name Name of the property
+ * @param getter The getter method
+ * @param setter The setter method
+ */
+ void property(const char *name, Value (T::*getter)() ) { ClassBase::property(name, static_cast
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.
- 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 will look like in C++.
- 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.
+Normal member variables
+<?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";
+
+?>
+
- ... this article is not finished yet -
\ 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, but 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. + ++
+#include <phpcpp.h>
+
+/**
+ * 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<Example> example("Example");
+
+ // register the methods
+ example.method("__construct", &Example::__construct);
+ example.method("method", &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;
+ }
+}
+
+
++ The example code shows how you need to initialize the properties inside + the get_module() function. +
++ 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. +
++ With the magic methods __get() and __set() you + can make more advanced properties that are directly mapped to your C++ + code, and that allows you to perform additional checks when a property + is overwritten, so that an object always remains in a valid state. +
++ 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 will automatically be accessed. +
++
+#include <phpcpp.h>
+
+/**
+ * C++ Example class
+ */
+class Example : public Php::Base
+{
+private:
+ /**
+ * Example property 1
+ * @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 &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<Example> example("Example");
+
+ // register the "value" property, with the methods to get and set it
+ example.property("value", &Example::getValue, &Example::setValue);
+
+ // register a read-only "double" property, with a method to get it
+ example.property("double", &Example::getDouble);
+
+ // add the class to the extension
+ myExtension.add(std::move(example));
+
+ // return the extension
+ return myExtension;
+ }
+}
+
+
++ 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. +
++
+<?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;
+?>
+
diff --git a/include/class.h b/include/class.h
index d867699..23c39e1 100644
--- a/include/class.h
+++ b/include/class.h
@@ -170,12 +170,12 @@ public:
* @param getter The getter method
* @param setter The setter method
*/
- void property(const char *name, Value (T::*getter)() ) { ClassBase::property(name, static_cast
-<?php
+<?php
/**
* PHP example class
*/
@@ -57,7 +57,7 @@ $example->property1 = "new value";
The above example creates a class with one public property. This property
- can be accessed by the Example class, but because it is public, also by
+ 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.
@@ -140,7 +140,7 @@ extern "C" {
- The example code shows how you need to initialize the properties inside + The example code shows how you initialize the properties inside the get_module() function.
@@ -151,14 +151,14 @@ extern "C" {
With the magic methods __get() and __set() you - can make more advanced properties that are directly mapped to your C++ - code, and that allows you to perform additional checks when a property + 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.
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 will automatically be accessed. + or setter method will automatically be called.
@@ -171,7 +171,7 @@ class Example : public Php::Base
{
private:
/**
- * Example property 1
+ * Example property
* @var int
*/
int _value = 0;
@@ -258,7 +258,7 @@ extern "C" {
-<?php
+<?php
// create object
$object = new Example();
--
cgit v1.2.3
From 6c64773dc5edd4b56eabcfa76b66b53ab76ecdf6 Mon Sep 17 00:00:00 2001
From: Emiel Bruijntjes
Date: Fri, 14 Mar 2014 14:03:54 +0100
Subject: documentation typos
---
documentation/properties.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/documentation/properties.html b/documentation/properties.html
index 50b0df3..f7f96c6 100644
--- a/documentation/properties.html
+++ b/documentation/properties.html
@@ -158,7 +158,7 @@ extern "C" {
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 will automatically be called.
+ or setter method is automatically called.
--
cgit v1.2.3
From ab98c70a98e860f4cce0332d7164077cffa51b30 Mon Sep 17 00:00:00 2001
From: Emiel Bruijntjes
Date: Fri, 14 Mar 2014 15:02:40 +0100
Subject: Value::numericValue() now returns a int64_t, and no longer a long
---
include/callstatic.h | 64 ---------------------------------------------------
include/value.h | 12 +++++++---
src/arithmetic.h | 14 +++++------
src/classbase.cpp | 6 ++---
src/includes.h | 2 +-
src/longmember.h | 65 ----------------------------------------------------
src/numericmember.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/value.cpp | 4 ++--
8 files changed, 87 insertions(+), 145 deletions(-)
delete mode 100644 include/callstatic.h
delete mode 100644 src/longmember.h
create mode 100644 src/numericmember.h
diff --git a/include/callstatic.h b/include/callstatic.h
deleted file mode 100644
index 3979ef3..0000000
--- a/include/callstatic.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * CallStatic.h
- *
- * Class that performs a lot of C++11 magic to find out if the __callStatic()
- * method was implemented by the user, and if it was, calls it
- *
- */
-
-namespace Php {
-
-/**
- * SFINAE test to check if the __callStatic method is defined
- *
- * This type trait checks if the __callStatic method is defined in class T
- *
- * @see http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence
- */
-template
-class HasCallStatic
-{
- typedef char one;
- typedef long two;
-
- template static one test( decltype(&C::__callStatic) ) ;
- template static two test(...);
-
-public:
- static const bool value = sizeof(test(0)) == sizeof(char);
-};
-
-/**
- * Function that only exists if the class T has a __callStatic method
- * @param name Name of the function
- * @param params Parameters passed to the function
- * @return Value
- */
-template
-typename std::enable_if::value, Value >::type
-callStatic(const char *name, Parameters ¶ms)
-{
- // call the __callStatic() function
- return T::__callStatic(name, params);
-}
-
-/**
- * Function that only exists if the class T does not have a __callStatic method
- * @param name Name of the function
- * @param params Parameters passed to the function
- * @return Value
- */
-template
-typename std::enable_if::value >::type
-callStatic(const char *name, Parameters ¶ms)
-{
- std::cout << "has NO call static" << std::endl;
-
- return nullptr;
-}
-
-/**
- * End namespace
- */
-}
-
diff --git a/include/value.h b/include/value.h
index 9c48f1f..fce8750 100644
--- a/include/value.h
+++ b/include/value.h
@@ -381,9 +381,15 @@ public:
/**
* Retrieve the value as number
- * @return long
- */
- long numericValue() const;
+ *
+ * We force this to be a int64_t because we assume that most
+ * servers run 64 bits nowadays, and because we use int32_t, int64_t
+ * almost everywhere, instead of 'long' and on OSX neither of
+ * these intxx_t types is defined as 'long'...
+ *
+ * @return int64_t
+ */
+ int64_t numericValue() const;
/**
* Retrieve the value as boolean
diff --git a/src/arithmetic.h b/src/arithmetic.h
index ae690bc..21343d1 100644
--- a/src/arithmetic.h
+++ b/src/arithmetic.h
@@ -55,7 +55,7 @@ public:
if (_value->isFloat()) return Value(F()(_value->floatValue(), value));
// apply to natural numbers
- return Value(F()(_value->numericValue(), value));
+ return Value(F()(_value->numericValue(), value));
}
/**
@@ -69,7 +69,7 @@ public:
if (_value->isFloat()) return Value(F()(_value->floatValue(), value));
// apply to natural numbers
- return Value(F()(_value->numericValue(), value));
+ return Value(F()(_value->numericValue(), value));
}
/**
@@ -83,7 +83,7 @@ public:
if (_value->isFloat()) return Value(F()(_value->floatValue(), value));
// apply to natural numbers
- return Value(F()(_value->numericValue(), value));
+ return Value(F()(_value->numericValue(), value));
}
/**
@@ -97,7 +97,7 @@ public:
if (_value->isFloat()) return Value(F()(_value->floatValue(), value?1:0));
// apply to natural numbers
- return Value(F()(_value->numericValue(), value?1:0));
+ return Value(F()(_value->numericValue(), value?1:0));
}
/**
@@ -114,7 +114,7 @@ public:
if (_value->isFloat()) return Value(F()(_value->floatValue(), v));
// apply to natural numbers
- return Value(F()(_value->numericValue(), v));
+ return Value(F()(_value->numericValue(), v));
}
/**
@@ -174,7 +174,7 @@ public:
if (_value->isFloat()) return _value->operator=(F()(_value->floatValue(), value));
// do a numeric operation
- return _value->operator=(F()(_value->numericValue(), value));
+ return _value->operator=(F()(_value->numericValue(), value));
}
/**
@@ -188,7 +188,7 @@ public:
if (_value->isFloat()) return _value->operator=(F()(_value->floatValue(), value));
// do a numeric operation
- return _value->operator=(F()(_value->numericValue(), value));
+ return _value->operator=(F()(_value->numericValue(), value));
}
/**
diff --git a/src/classbase.cpp b/src/classbase.cpp
index 09850a7..ea24cfd 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -1595,7 +1595,7 @@ void ClassBase::property(const char *name, std::nullptr_t value, int flags)
void ClassBase::property(const char *name, int16_t value, int flags)
{
// add property
- _members.push_back(std::make_shared(name, value, flags));
+ _members.push_back(std::make_shared(name, value, flags));
}
/**
@@ -1607,7 +1607,7 @@ void ClassBase::property(const char *name, int16_t value, int flags)
void ClassBase::property(const char *name, int32_t value, int flags)
{
// add property
- _members.push_back(std::make_shared(name, value, flags));
+ _members.push_back(std::make_shared(name, value, flags));
}
/**
@@ -1619,7 +1619,7 @@ void ClassBase::property(const char *name, int32_t value, int flags)
void ClassBase::property(const char *name, int64_t value, int flags)
{
// add property
- _members.push_back(std::make_shared(name, value, flags));
+ _members.push_back(std::make_shared(name, value, flags));
}
/**
diff --git a/src/includes.h b/src/includes.h
index 721b29e..0c00df3 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -83,7 +83,7 @@
#include "method.h"
#include "member.h"
#include "nullmember.h"
-#include "longmember.h"
+#include "numericmember.h"
#include "boolmember.h"
#include "stringmember.h"
#include "floatmember.h"
diff --git a/src/longmember.h b/src/longmember.h
deleted file mode 100644
index 09d3d8a..0000000
--- a/src/longmember.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * LongMember.h
- *
- * Implementation for a property that is initially set to a long value
- *
- * @author Emiel Bruijntjes
- * @copyright 2013, 2014 Copernica BV
- */
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Class definition
- */
-class LongMember : public Member
-{
-private:
- /**
- * The value
- * @var long
- */
- long _value;
-
-public:
- /**
- * Constructor
- * @param name
- * @param value
- * @param flags
- */
- LongMember(const char *name, long value, int flags) : Member(name, flags), _value(value) {}
-
- /**
- * Destructor
- */
- virtual ~LongMember() {}
-
- /**
- * Declare class constant
- * @param entry Class entry
- */
- virtual void constant(struct _zend_class_entry *entry) override
- {
- zend_declare_class_constant_long(entry, _name.c_str(), _name.size(), _value);
- }
-
- /**
- * Virtual method to declare the property
- * @param entry Class entry
- */
- virtual void declare(struct _zend_class_entry *entry) override
- {
- // char* cast is necessary for php 5.3
- zend_declare_property_long(entry, (char *)_name.c_str(), _name.size(), _value, _flags);
- }
-};
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/numericmember.h b/src/numericmember.h
new file mode 100644
index 0000000..99889c6
--- /dev/null
+++ b/src/numericmember.h
@@ -0,0 +1,65 @@
+/**
+ * NumericMember.h
+ *
+ * Implementation for a property that is initially set to a numeric value
+ *
+ * @author Emiel Bruijntjes
+ * @copyright 2013, 2014 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class NumericMember : public Member
+{
+private:
+ /**
+ * The value
+ * @var long
+ */
+ long _value;
+
+public:
+ /**
+ * Constructor
+ * @param name
+ * @param value
+ * @param flags
+ */
+ NumericMember(const char *name, long value, int flags) : Member(name, flags), _value(value) {}
+
+ /**
+ * Destructor
+ */
+ virtual ~NumericMember() {}
+
+ /**
+ * Declare class constant
+ * @param entry Class entry
+ */
+ virtual void constant(struct _zend_class_entry *entry) override
+ {
+ zend_declare_class_constant_long(entry, _name.c_str(), _name.size(), _value);
+ }
+
+ /**
+ * Virtual method to declare the property
+ * @param entry Class entry
+ */
+ virtual void declare(struct _zend_class_entry *entry) override
+ {
+ // char* cast is necessary for php 5.3
+ zend_declare_property_long(entry, (char *)_name.c_str(), _name.size(), _value, _flags);
+ }
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/src/value.cpp b/src/value.cpp
index 29b6dcd..9af2d14 100644
--- a/src/value.cpp
+++ b/src/value.cpp
@@ -74,7 +74,7 @@ Value::Value(int32_t value)
}
/**
- * Constructor based on long value
+ * Constructor based on int64_t value
* @param value
*/
Value::Value(int64_t value)
@@ -1415,7 +1415,7 @@ Value Value::clone(Type type) const
* Retrieve the value as integer
* @return long
*/
-long Value::numericValue() const
+int64_t Value::numericValue() const
{
// already a long?
if (isNumeric()) return Z_LVAL_P(_val);
--
cgit v1.2.3
From 6bf3f222bbbd1adec7f85a954dc1aee146259894 Mon Sep 17 00:00:00 2001
From: Emiel Bruijntjes
Date: Fri, 14 Mar 2014 16:58:17 +0100
Subject: fixed magic method documentation, added comment in Makefile
---
Makefile | 5 ++++-
documentation/magic-methods.html | 25 ++++++++++++++++---------
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile
index 734590b..32fd0b0 100644
--- a/Makefile
+++ b/Makefile
@@ -80,8 +80,11 @@ COMPILER_FLAGS = -Wall -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext
# Just like the compiler, the linker can have flags too. The default flag
# is probably the only one you need.
#
+# Are you compiling on OSX? You may have to append the option "-undefined dynamic_lookup"
+# to the linker flags
+#
-LINKER_FLAGS = -shared
+LINKER_FLAGS = -shared `php-config --ldflags`
#
diff --git a/documentation/magic-methods.html b/documentation/magic-methods.html
index 9294a3e..6356d2a 100644
--- a/documentation/magic-methods.html
+++ b/documentation/magic-methods.html
@@ -35,8 +35,8 @@
Constructors
- We start with an exception to the rule. Normally, you do not have to register
- magic methods to make them work. When you add a magic method like
+ 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
@@ -67,17 +67,24 @@
Clone and destruct
The magic __clone() method is very similar to the __construct() method. It
- is the first method to be called on a new object after it is copy
- constructed. The __destruct() is the method that gets called right before
- the object gets destructed (and the C++ destructor runs).
+ also is a method that is called directly after an object is constructed.
+ The difference is that __clone() is called after an object is copy
+ constructed (or cloned if you prefer the PHP idiom), while
+ __construct() is called right after the normal constructor.
- The __clone() and __destruct() methods are regular magic methods and you
- therefore do not have to register them to make them active. The PHP-CPP
- library calls them automatically if they are available.
+ The magic __destruct() method gets called right before the object gets
+ destructed (and right before the C++ destructor runs).
- In normal circumstances you probably have not need for these methods.
+ 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.
+
+
+ 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
--
cgit v1.2.3
From cda98dc0dea7144941a46ff20598f3c095d7a6d0 Mon Sep 17 00:00:00 2001
From: Emiel Bruijntjes
Date: Fri, 14 Mar 2014 17:03:37 +0100
Subject: update documentation about installing on OSX
---
documentation/install.html | 37 +++++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)
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).
- 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.
-
Limitations
At this moment, PHP-CPP only supports single-threaded PHP installations.
@@ -85,7 +84,20 @@
make
- 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.
+
+
+Compiling on OSX?
+
+ 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.
+
+
+
+ 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 @@
sudo make install
- 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.
--
cgit v1.2.3