From ec18c8779c6a806c6cbeb5fe12446955cd688221 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Thu, 10 Apr 2014 12:36:50 +0200 Subject: refactored ini settings --- include/extension.h | 53 ++++++++++ include/ini.h | 278 +++++++++++++++++++++++++------------------------ include/namespace.h | 50 +-------- zend/extensionimpl.cpp | 23 +++- zend/ini.cpp | 67 ++++++------ zend/namespace.cpp | 15 --- 6 files changed, 248 insertions(+), 238 deletions(-) diff --git a/include/extension.h b/include/extension.h index fcc0f72..e18e787 100644 --- a/include/extension.h +++ b/include/extension.h @@ -104,6 +104,52 @@ public: */ Extension &onIdle(const Callback &callback); + /** + * Add a ini entry to the extension by moving it + * @param ini The php.ini setting + * @return Extension Same object to allow chaining + */ + Extension &add(Ini &&ini) + { + // and add it to the list of classes + _ini_entries.emplace_back(new Ini(std::move(ini))); + + // allow chaining + return *this; + } + + /** + * Add a ini entry to the extension by copying it + * @param ini The php.ini setting + * @param Extension Same object to allow chaining + */ + Extension &add(const Ini &ini) + { + // and add it to the list of classes + _ini_entries.emplace_back(new Ini(ini)); + + // allow chaining + return *this; + } + + /** + * The total number of php.ini variables + * @return size_t + */ + size_t iniVariables() const + { + return _ini_entries.size(); + } + + /** + * Apply a callback to each php.ini variable + * + * The callback will be called with a reference to the ini variable. + * + * @param callback + */ + void iniVariables(const std::function &callback); + /** * Retrieve the module pointer * @@ -131,6 +177,13 @@ private: * @var ExtensionImpl */ ExtensionImpl *_impl; + + /** + * Ini entry defined by the extension + * @var list + */ + std::list> _ini_entries; + }; /** diff --git a/include/ini.h b/include/ini.h index 9d4cbd9..49587d7 100644 --- a/include/ini.h +++ b/include/ini.h @@ -1,16 +1,15 @@ /** * Ini.h * + * Class that can be instantiated in the get_module() startup function to + * define settings from the php.ini file that are supported. * - * - * - * @copyright 2013 Copernica BV + * @copyright 2014 Copernica BV */ /** - * Forward declaration + * Forward declarations */ - struct _zend_ini_entry; /** @@ -18,143 +17,150 @@ struct _zend_ini_entry; */ namespace Php { +/** + * Class definition + */ +class Ini +{ +public: + /** + * Supported place-types for ini setting + * + * The possible settings for where the configuration can be changed are: + * PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_SYSTEM and PHP_INI_ALL + * + * Usually you would choose where the setting can be changed based on how + * it is used. For example if you want to access the setting during RINIT + * stage then you would want PHP_INI_PERDIR because the setting would have + * no use after RINIT. + */ + enum Place : int { + User = (1<<0), // ZEND_INI_USER (1<<0) + Perdir = (1<<1), // ZEND_INI_PERDIR (1<<1) + System = (1<<2), // ZEND_INI_SYSTEM (1<<2) + All = (1<<0) | (1<<1) | (1<<2) // ZEND_INI_ALL (ZEND_INI_USER|ZEND_INI_PERDIR|ZEND_INI_SYSTEM) + }; + + /** + * Constructors for string values + * + * @param name Name of the php.ini variable + * @param value Default value + * @param orig Original value (if the user resets the variable, it is set back to this value) + * @param place Place where the ini setting can be changed + */ + Ini(const char *name, const char *value, const char *orig, const Place place = Place::All) : + _name(name), _value(value), _orig(orig), _place(place) {} + + Ini(const char *name, const char *value, const Place place = Place::All) : + _name(name), _value(value), _orig_empty(true), _place(place) {} + + /** + * Constructors for bool values + * + * @param name Name of the php.ini variable + * @param value Default value + * @param orig Original value (if the user resets the variable, it is set back to this value) + * @param place Place where the ini setting can be changed + */ + Ini(const char *name,const bool value, const bool orig, const Place place = Place::All) : + _name(name), _value(bool2str(value)), _orig(bool2str(orig)), _place(place) {} + + Ini(const char *name, const bool value, const Place place = Place::All) : + _name(name), _value(bool2str(value)), _orig_empty(true), _place(place) {} + + /** + * Constructors for integer values + * + * @param name Name of the php.ini variable + * @param value Default value + * @param orig Original value (if the user resets the variable, it is set back to this value) + * @param place Place where the ini setting can be changed + */ + Ini(const char *name, const int16_t value, const int16_t orig, const Place place = Place::All) : + _name(name), _value(std::to_string(value)), _orig(std::to_string(orig)), _place(place) {} + + Ini(const char *name, const int16_t value, const Place place = Place::All) : + _name(name), _value(std::to_string(value)), _orig_empty(true), _place(place) {} + + Ini(const char *name, const int32_t value, const int32_t orig, const Place place = Place::All) : + _name(name), _value(std::to_string(value)), _orig(std::to_string(orig)), _place(place) {} + + Ini(const char *name, const int32_t value, const Place place = Place::All) : + _name(name), _value(std::to_string(value)), _orig_empty(true), _place(place) {} + + Ini(const char *name, const int64_t value, const int64_t orig, const Place place = Place::All) : + _name(name), _value(std::to_string(value)), _orig(std::to_string(orig)), _place(place) {} + + Ini(const char *name, const int64_t value, const Place place = Place::All) : + _name(name), _value(std::to_string(value)), _orig_empty(true), _place(place) {} + + /** + * Constructors for floating point values + * + * @param name Name of the php.ini variable + * @param value Default value + * @param orig Original value (if the user resets the variable, it is set back to this value) + * @param place Place where the ini setting can be changed + */ + Ini(const char *name, const double value, const double orig, const Place place = Place::All) : + _name(name), _value(std::to_string(value)), _orig(std::to_string(orig)), _place(place) {} + + Ini(const char *name, const double value, const Place place = Place::All) : + _name(name), _value(std::to_string(value)), _orig_empty(true), _place(place) {} + /** - * Class definition + * Filling ini_entries + * @param ini_entry + * @param module_number */ - class Ini + void fill(struct _zend_ini_entry *ini_entry, int module_number); + +private: + /** + * Helper function to convert a boolean to a string + * @param value + * @return string + */ + static constexpr const char* bool2str(const bool value) { - public: - - /** - * Supported place-types for ini setting - * The possible settings for where the configuration can be changed are: - * PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_SYSTEM and PHP_INI_ALL - * Usually you would choose where the setting can be changed based on how it is used. For example if you want to access - * the setting during RINIT stage then you would want PHP_INI_PERDIR because the setting would have no use after RINIT. - */ - enum Place : int { - User = (1<<0), // ZEND_INI_USER (1<<0) - Perdir = (1<<1), // ZEND_INI_PERDIR (1<<1) - System = (1<<2), // ZEND_INI_SYSTEM (1<<2) - All = (1<<0) | (1<<1) | (1<<2) // ZEND_INI_ALL (ZEND_INI_USER|ZEND_INI_PERDIR|ZEND_INI_SYSTEM) - }; - - /** - * default constructors - */ - Ini(const char *name, const char *value, const char *orig_value, const Place place = Place::All) : - _name(name), _value(value), _orig_value(orig_value), _place(place) {} - - Ini(const char *name, const char *value, const Place place = Place::All) : - _name(name), _value(value), _orig_empty(true), _place(place) {} - - /** - * Constructors for bool value - */ - Ini(const char *name,const bool value, const bool orig_value, const Place place = Place::All) : - _name(name), _value(bool2str(value)), _orig_value(bool2str(orig_value)), _place(place) {} - - Ini(const char *name, const bool value, const Place place = Place::All) : - _name(name), _value(bool2str(value)), _orig_empty(true), _place(place) {} - - /** - * Constructors for integer value - * @param value - */ - Ini(const char *name, const int16_t value, const int16_t orig_value, const Place place = Place::All) : - _name(name), _value(std::to_string(value)), _orig_value(std::to_string(orig_value)), _place(place) {} - - Ini(const char *name, const int16_t value, const Place place = Place::All) : - _name(name), _value(std::to_string(value)), _orig_empty(true), _place(place) {} - - - Ini(const char *name, const int32_t value, const int32_t orig_value, const Place place = Place::All) : - _name(name), _value(std::to_string(value)), _orig_value(std::to_string(orig_value)), _place(place) {} - - Ini(const char *name, const int32_t value, const Place place = Place::All) : - _name(name), _value(std::to_string(value)), _orig_empty(true), _place(place) {} - - - Ini(const char *name, const int64_t value, const int64_t orig_value, const Place place = Place::All) : - _name(name), _value(std::to_string(value)), _orig_value(std::to_string(orig_value)), _place(place) {} - - Ini(const char *name, const int64_t value, const Place place = Place::All) : - _name(name), _value(std::to_string(value)), _orig_empty(true), _place(place) {} - - /** - * Constructors for float value - * @param value - */ - Ini(const char *name, const double value, const double orig_value, const Place place = Place::All) : - _name(name), _value(std::to_string(value)), _orig_value(std::to_string(orig_value)), _place(place) {} - - Ini(const char *name, const double value, const Place place = Place::All) : - _name(name), _value(std::to_string(value)), _orig_empty(true), _place(place) {} - - - /** - * Copy constructor - * @param Ini - */ - Ini(const Ini &that) : - _name(that._name), _value(that._value), _orig_value(that._orig_value), _orig_empty(that._orig_empty), _place(that._place) - {} - - /** - * Move constructor - * @param Ini - */ - Ini(Ini &&that) : - _name(that._name), _value(std::move(that._value)), _orig_value(std::move(that._orig_value)), _orig_empty(that._orig_empty), _place(that._place) - {} - - - /** - * Filling ini_entries - * @param zend_ini_entry *ini_entry, int module_number - * @param int module_number - */ - void fill(_zend_ini_entry *ini_entry, int module_number); - - - /** - * Compare by name - * A predicate that takes two arguments of type Ini. - * Used when adding elements of type Ini in the container std::set - */ - struct Compare - { - int operator()(const std::shared_ptr &s1, const std::shared_ptr &s2) const - { - return s1->_name.compare(s2->_name); - } - }; - - private: - - static constexpr const char* bool2str(const bool value) - { - return ( static_cast(value) ? "On" : "Off"); - } - - // ini entry name - std::string _name; - - // ini entry value - std::string _value; - - // ini entry original value - std::string _orig_value; - - // _orig_value is empty - bool _orig_empty = false; - - // plase where the configuration can be changed - Place _place; - }; + // cast to a string + return ( static_cast(value) ? "On" : "Off"); + } + + /** + * ini entry name + * @var std::string + */ + std::string _name; + + /** + * ini entry value + * @var std::string + */ + std::string _value; + + /** + * ini entry original value + * @var std::string + */ + std::string _orig; + + /** + * Is the orig value set or empty? + * @var bool + */ + bool _orig_empty = false; + + /** + * Place where the configuration can be changed + * @var Place + */ + Place _place; +}; /** * End of namespace diff --git a/include/namespace.h b/include/namespace.h index 1c9d457..828c12c 100644 --- a/include/namespace.h +++ b/include/namespace.h @@ -48,11 +48,6 @@ protected: */ std::list> _namespaces; - /** - * Ini entry defined by the extension - * @var list - */ - std::set, Ini::Compare> _ini_entries; public: /** @@ -164,39 +159,11 @@ public: return *this; } - /** - * Add a ini entry to the extension by moving it - * @param ini The class implementation - * @return Namespace Same object to allow chaining - */ - Namespace &add(Ini &&ini) - { - // and add it to the list of classes - _ini_entries.emplace(new Ini(std::move(ini))); - - // allow chaining - return *this; - } - - /** - * Add a ini entry to the extension by copying it - * @param ini The class implementation - * @param Namespace Same object to allow chaining - */ - Namespace &add(const Ini &ini) - { - // and add it to the list of classes - _ini_entries.emplace(new Ini(ini)); - - // allow chaining - return *this; - } - /** * The total number of functions * @return size_t */ - size_t functions() + size_t functions() const { // number of functions in this namespace int result = _functions.size(); @@ -208,15 +175,6 @@ public: return result; } - /** - * The total number of ini entries - * @return size_t - */ - size_t ini_size() - { - return _ini_entries.size(); - } - /** * Apply a callback to each registered function * @@ -237,12 +195,6 @@ public: */ void classes(const std::function &callback); - /** - * Filling ini entries into external zend_ini_entry array - * @param zend_ini_entry* - */ - void fill_ini(_zend_ini_entry *ini_entries, int module_number); - }; /** diff --git a/zend/extensionimpl.cpp b/zend/extensionimpl.cpp index 0308c63..5e03736 100644 --- a/zend/extensionimpl.cpp +++ b/zend/extensionimpl.cpp @@ -111,16 +111,31 @@ int ExtensionImpl::processStartup(int type, int module_number TSRMLS_DC) // initialize and allocate the "global" variables ZEND_INIT_MODULE_GLOBALS(phpcpp, init_globals, NULL); - // get the extension auto *extension = find(module_number TSRMLS_CC); // array contains ini settings - static zend_ini_entry *ini_entries = new zend_ini_entry[ extension->_data->ini_size()+1 ]; + zend_ini_entry *ini_entries = new zend_ini_entry[extension->_data->iniVariables()+1]; + + // the entry that we're filling + int i=0; - // Filling ini entries - extension->_data->fill_ini(ini_entries, module_number); + // Fill the php.ini entries + extension->_data->iniVariables([ini_entries, &i, module_number](Ini &ini) { + // initialize the function + zend_ini_entry *entry = &ini_entries[i]; + + // fill the property + ini.fill(entry, module_number); + + // move on to the next iteration + i++; + }); + + // last entry should be set to all zero's + memset(&ini_entries[i], 0, sizeof(zend_ini_entry)); + // register ini entries in Zend core REGISTER_INI_ENTRIES(); diff --git a/zend/ini.cpp b/zend/ini.cpp index 0c04d6a..25f081a 100644 --- a/zend/ini.cpp +++ b/zend/ini.cpp @@ -12,42 +12,41 @@ */ namespace Php { - /** - * Filling ini_entries - * @param zend_ini_entry *ini_entry, int module_number - * @param int module_number - */ - void Ini::fill(zend_ini_entry *ini_entry, int module_number) +/** + * Filling ini_entries + * @param zend_ini_entry *ini_entry, int module_number + * @param int module_number + */ +void Ini::fill(zend_ini_entry *ini_entry, int module_number) +{ + ini_entry->module_number = module_number; + ini_entry->modifiable = static_cast(this->_place); + ini_entry->name = const_cast(this->_name.c_str()); + ini_entry->name_length = this->_name.size()+1; + ini_entry->on_modify = OnUpdateString; + ini_entry->mh_arg1 = nullptr; + #ifdef ZTS + ini_entry->mh_arg2 = (void *) &phpcpp_globals_id; + #else + ini_entry->mh_arg2 = (void *) &phpcpp_globals; + #endif + ini_entry->mh_arg3 = nullptr; + ini_entry->value = const_cast(this->_value.c_str()); + ini_entry->value_length = this->_value.size(); + if( this->_orig_empty) + { + ini_entry->orig_value = nullptr; + ini_entry->orig_value_length = 0; + } + else { - ini_entry->module_number = module_number; - ini_entry->modifiable = static_cast(this->_place); - ini_entry->name = const_cast(this->_name.c_str()); - ini_entry->name_length = this->_name.size()+1; - ini_entry->on_modify = OnUpdateString; - ini_entry->mh_arg1 = nullptr; - #ifdef ZTS - ini_entry->mh_arg2 = (void *) &phpcpp_globals_id; - #else - ini_entry->mh_arg2 = (void *) &phpcpp_globals; - #endif - ini_entry->mh_arg3 = nullptr; - ini_entry->value = const_cast(this->_value.c_str()); - ini_entry->value_length = this->_value.size(); - if( this->_orig_empty) - { - ini_entry->orig_value = nullptr; - ini_entry->orig_value_length = 0; - } - else - { - ini_entry->orig_value = const_cast(this->_orig_value.c_str()); - ini_entry->orig_value_length = this->_orig_value.size(); - } - ini_entry->orig_modifiable = 0; - ini_entry->modified = 0; - ini_entry->displayer = nullptr; + ini_entry->orig_value = const_cast(this->_orig.c_str()); + ini_entry->orig_value_length = this->_orig.size(); } - + ini_entry->orig_modifiable = 0; + ini_entry->modified = 0; + ini_entry->displayer = nullptr; +} /** * End of namespace diff --git a/zend/namespace.cpp b/zend/namespace.cpp index 8b97c52..2b4b62a 100644 --- a/zend/namespace.cpp +++ b/zend/namespace.cpp @@ -127,21 +127,6 @@ void Namespace::classes(const std::functionfill(&ini_entries[Ind++], module_number); - - // add last empty ini entry (Zend, for some reason, it requires) - zend_ini_entry empty_entry { 0, 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, nullptr, 0, 0, 0, nullptr }; - ini_entries[Ind] = empty_entry; -} - /** * End namespace */ -- cgit v1.2.3