diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2015-01-25 20:41:13 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2015-01-25 20:41:13 +0100 |
commit | b2758c687ab8c36ef7a48787b4d590255e69cbc0 (patch) | |
tree | 7b5133ef683103ccd8a9cfef53413b1a8b9f5f76 | |
parent | 110f379c083a9e061d2337efabb86f12ce0fa750 (diff) |
added Php::define() function to create constants at run time
-rw-r--r-- | include/call.h | 3 | ||||
-rw-r--r-- | include/value.h | 2 | ||||
-rw-r--r-- | zend/constantfuncs.cpp | 71 |
3 files changed, 76 insertions, 0 deletions
diff --git a/include/call.h b/include/call.h index 950cc3e..d807190 100644 --- a/include/call.h +++ b/include/call.h @@ -21,6 +21,9 @@ inline bool class_exists(const std::string &classname, bool autoload = true) { extern Value constant(const char *constant); extern Value constant(const char *constant, size_t size); extern Value constant(const std::string &constant); +extern bool define(const char *name, size_t size, const Value &value); +extern bool define(const char *name, const Value &value); +extern bool define(const std::string &name, const Value &value); extern bool defined(const char *constant); extern bool defined(const char *constant, size_t size); extern bool defined(const std::string &constant); diff --git a/include/value.h b/include/value.h index dbd3788..b962415 100644 --- a/include/value.h +++ b/include/value.h @@ -378,6 +378,7 @@ public: bool isFloat() const { return type() == Type::Float; } bool isObject() const { return type() == Type::Object; } bool isArray() const { return type() == Type::Array; } + bool isScalar() const { return isNull() || isNumeric() || isBool() || isString() || isFloat(); } bool isCallable() const; /** @@ -1161,6 +1162,7 @@ protected: * Functions that need access to the privates */ friend Value constant(const char *name, size_t size); + friend bool define(const char *name, size_t size, const Value &value); /** * The Globals and Member classes can access the zval directly diff --git a/zend/constantfuncs.cpp b/zend/constantfuncs.cpp index c350f91..40ea20e 100644 --- a/zend/constantfuncs.cpp +++ b/zend/constantfuncs.cpp @@ -61,6 +61,77 @@ Value constant(const std::string &name) } /** + * Define a new constant + * @param name Name of the constant + * @param size Size of the name + * @param value Value of the constant + * @return bool + */ +bool define(const char *name, size_t size, const Value &value) +{ + // we need the tsrm_ls variable + TSRMLS_FETCH(); + + // the constant structure from the zend engine + zend_constant constant; + + // copy the name (note that name_len also includes the end-of-string '\0' byte) + constant.name = zend_strndup(name, size); + constant.name_len = size + 1; + + // only scalar values can be used for constants + if (value.isScalar()) + { + // make a full copy of the passed in zval + constant.value = *value._val; + zval_copy_ctor(&constant.value); + } + else + { + // we're going to convert the value object into a string, and use that + Value str = value.clone(Type::String); + + // use the copied value + constant.value = *str._val; + zval_copy_ctor(&constant.value); + } + + // constants are case sensitive (but not persistent, because this is a user + // space constant!) + constant.flags = CONST_CS; + + // as module number we use a fake module number + constant.module_number = PHP_USER_CONSTANT; + + // register the constant + return zend_register_constant(&constant TSRMLS_CC) == SUCCESS; +} + +/** + * Define a new constant + * @param name + * @param value + * @return bool + */ +bool define(const char *name, const Value &value) +{ + // define a constant + return define(name, ::strlen(name), value); +} + +/** + * Define a new constant + * @param name + * @param value + * @return bool + */ +bool define(const std::string &name, const Value &value) +{ + // pass on to the other define function + return define(name.c_str(), name.size(), value); +} + +/** * Check whether a constant exists * @param name * @param size |