summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-10 11:36:44 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-10 11:36:44 +0200
commitf0dec5907bd49bb468089b0fe50d8cbf2979272e (patch)
treef6ca989d6233cfc591efe07660e6dbb774d5f505
parentec2ee67b805b3f431db4ce2f9cdfc8d74aadfe35 (diff)
parent3119060c9c8905b9d07e04a342a2c32cf0bf1358 (diff)
Merge pull request #76 from valmat/ini
Implemented issue # 64
-rw-r--r--include/call.h4
-rw-r--r--include/extension.h2
-rw-r--r--include/ini.h163
-rw-r--r--include/namespace.h51
-rw-r--r--phpcpp.h2
-rw-r--r--tests/cpp/h/ini_entries.h16
-rw-r--r--tests/cpp/include/ini_entries/001.h29
-rw-r--r--tests/cpp/main.cpp27
-rw-r--r--tests/php/dbg.php54
-rwxr-xr-xtests/php/php_alias.sh2
-rw-r--r--zend/extensionimpl.cpp22
-rw-r--r--zend/includes.h3
-rw-r--r--zend/ini.cpp57
-rw-r--r--zend/namespace.cpp15
14 files changed, 428 insertions, 19 deletions
diff --git a/include/call.h b/include/call.h
index 9be5c91..2fcc9b0 100644
--- a/include/call.h
+++ b/include/call.h
@@ -67,7 +67,7 @@ inline void unset(const HashMember<Value> &member) { member.unset(); }
/**
* The isset function conflicts with the 'isset' macro defined by the Zend engine
*/
-#pragma push_macro("isset");
+#pragma push_macro("isset")
#undef isset
/**
@@ -81,7 +81,7 @@ inline Value isset(const HashMember<Value> &member) { return member.exists() &&
/**
* Re-install the ISSET macro
*/
-#pragma pop_macro("isset");
+#pragma pop_macro("isset")
/**
* End of namespace
diff --git a/include/extension.h b/include/extension.h
index 84789d3..fcc0f72 100644
--- a/include/extension.h
+++ b/include/extension.h
@@ -123,7 +123,7 @@ public:
{
return module();
}
-
+
private:
/**
* The implementation object
diff --git a/include/ini.h b/include/ini.h
new file mode 100644
index 0000000..9d4cbd9
--- /dev/null
+++ b/include/ini.h
@@ -0,0 +1,163 @@
+/**
+ * Ini.h
+ *
+ *
+ *
+ *
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Forward declaration
+ */
+
+struct _zend_ini_entry;
+
+/**
+ * Set up namespace
+ */
+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)
+ };
+
+ /**
+ * 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<Ini> &s1, const std::shared_ptr<Ini> &s2) const
+ {
+ return s1->_name.compare(s2->_name);
+ }
+ };
+
+ private:
+
+ static constexpr const char* bool2str(const bool value)
+ {
+ return ( static_cast<bool>(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;
+ };
+
+
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/include/namespace.h b/include/namespace.h
index 1775061..1c9d457 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -48,6 +48,12 @@ protected:
*/
std::list<std::shared_ptr<Namespace>> _namespaces;
+ /**
+ * Ini entry defined by the extension
+ * @var list
+ */
+ std::set<std::shared_ptr<Ini>, Ini::Compare> _ini_entries;
+
public:
/**
* Constructor
@@ -159,6 +165,34 @@ public:
}
/**
+ * 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
*/
@@ -173,6 +207,15 @@ public:
// done
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
@@ -193,7 +236,13 @@ public:
* @param callback
*/
void classes(const std::function<void(const std::string &ns, ClassBase &clss)> &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/phpcpp.h b/phpcpp.h
index 90ef218..4e9735d 100644
--- a/phpcpp.h
+++ b/phpcpp.h
@@ -21,10 +21,12 @@
#include <list>
#include <exception>
#include <map>
+#include <set>
/**
* Include all headers files that are related to this library
*/
+#include <phpcpp/ini.h>
#include <phpcpp/exception.h>
#include <phpcpp/streams.h>
#include <phpcpp/type.h>
diff --git a/tests/cpp/h/ini_entries.h b/tests/cpp/h/ini_entries.h
new file mode 100644
index 0000000..a6fb10e
--- /dev/null
+++ b/tests/cpp/h/ini_entries.h
@@ -0,0 +1,16 @@
+/**
+ *
+ * Test ini entries
+ *
+ */
+
+
+#include "../include/ini_entries/001.h"
+//#include "../include/ini_entries/.h"
+//#include "../include/ini_entries/.h"
+
+
+
+
+
+
diff --git a/tests/cpp/include/ini_entries/001.h b/tests/cpp/include/ini_entries/001.h
new file mode 100644
index 0000000..649b0bd
--- /dev/null
+++ b/tests/cpp/include/ini_entries/001.h
@@ -0,0 +1,29 @@
+/**
+ *
+ * Test ini entries
+ * test ini_entries/001.phpt
+ *
+ */
+
+/**
+ * Set up namespace
+ */
+namespace TestIniEntries {
+
+
+ void iniTest1(Php::Parameters &params)
+ {
+ Php::out << "extension_for_tests.some_string ={{" << Php::ini_get("extension_for_tests.some_string") << "}}" << std::endl;
+ Php::out << "extension_for_tests.some_string2 ={{" << Php::ini_get("extension_for_tests.some_string2") << "}}" << std::endl;
+ Php::out << "extension_for_tests.some_string3 ={{" << Php::ini_get("extension_for_tests.some_string3") << "}}" << std::endl;
+ Php::out << "extension_for_tests.some_string3 ={{" << Php::ini_get("extension_for_tests.some_bool") << "}}" << std::endl;
+
+
+
+ return;
+ }
+/**
+ * End of namespace
+ */
+}
+
diff --git a/tests/cpp/main.cpp b/tests/cpp/main.cpp
index 84d95d8..2e0a1dc 100644
--- a/tests/cpp/main.cpp
+++ b/tests/cpp/main.cpp
@@ -11,6 +11,7 @@
#include "h/ValueIterator.h"
#include "h/Classes_and_objects.h"
#include "h/variables.h"
+#include "h/ini_entries.h"
@@ -128,6 +129,32 @@ extern "C"
extension.add(std::move(cObj2Scalar));
+ /**
+ * tests ini entries
+ *
+ */
+ extension
+ .add(Php::Ini("ini1", "valIni1"))
+ .add(Php::Ini("ini2", "valIni2", "OrigValIni2"))
+ .add(Php::Ini("ini3", "valIni3", "OrigValIni3", Php::Ini::System))
+ .add(Php::Ini("ini4", true, false, Php::Ini::Place::User))
+ .add(Php::Ini("ini5", false));
+
+ Php::Ini ini6("ini6", 55, 11);
+ extension
+ .add(ini6)
+ .add(Php::Ini("ini7", 74,5));
+
+ Php::Ini ini8("ini8", 3.1415926, 6.2831852);
+ Php::Ini ini9("ini9", 2.7182818, 5.4365636, Php::Ini::User);
+ extension.add(Php::Ini("ini9", 0.333333, 0.777777, Php::Ini::Perdir));
+
+ extension.add(ini8);
+ extension.add(std::move(ini9));
+
+ extension.add("TestIniEntries\\iniTest1", TestIniEntries::iniTest1);
+
+
diff --git a/tests/php/dbg.php b/tests/php/dbg.php
index 003c494..8de0bb8 100644
--- a/tests/php/dbg.php
+++ b/tests/php/dbg.php
@@ -13,14 +13,46 @@
-var_dump( TestBaseClass\MyClass::CONSTANT1 );
-var_dump( TestBaseClass\MyClass::EXP );
-var_dump( TestBaseClass\MyClass::CONSTANT2 );
-var_dump( TestBaseClass\MyClass::CONSTANT3 );
-
-var_dump( TestBaseClass\MyClass::$StatProp1 );
-var_dump( TestBaseClass\MyClass::$Exp );
-var_dump( TestBaseClass\MyClass::$StatProp2 );
-var_dump( TestBaseClass\MyClass::$StatProp3 );
-TestBaseClass\MyClass::$StatProp2 = "otherval";
-var_dump( TestBaseClass\MyClass::$StatProp2 );
+echo "\x1b[1;31m";
+(new ReflectionExtension('extension_for_tests') )->info();
+echo "\x1b[0m";
+echo "\x1b[0;34m";
+var_export( ini_get_all ( 'extension_for_tests' ) );
+echo "\x1b[0m", PHP_EOL;
+exit;
+
+TestIniEntries\iniTest1();
+
+//ini_set("extension_for_tests.some_string3", 'RFVBGT') ;
+echo PHP_EOL;
+echo "extension_for_tests.some_string ={{" , ini_get("extension_for_tests.some_string") , "}}", PHP_EOL;
+echo "extension_for_tests.some_string2 ={{" , ini_get("extension_for_tests.some_string2") , "}}", PHP_EOL;
+echo "extension_for_tests.some_string3 ={{" , ini_get("extension_for_tests.some_string3") , "}}", PHP_EOL;
+echo "extension_for_tests.some_string3 ={{" , ini_get("extension_for_tests.some_bool") , "}}", PHP_EOL;
+
+
+echo "\x1b[1;31m";
+(new ReflectionExtension('extension_for_tests') )->info();
+echo "\x1b[0m";
+
+echo "\x1b[0;34m";
+var_export( ini_get_all ( 'extension_for_tests' ) );
+echo "\x1b[0m", PHP_EOL;
+
+ini_set("extension_for_tests.some_string3", 'RFVBGT') ;
+echo "extension_for_tests.some_string3 ={{" , ini_get("extension_for_tests.some_string3") , "}}", PHP_EOL;
+ini_restore ( 'extension_for_tests.some_string3' );
+echo "extension_for_tests.some_string3 ={{" , ini_get("extension_for_tests.some_string3") , "}}", PHP_EOL;
+
+
+echo "extension_for_tests.some_bool :";
+var_dump(ini_get("extension_for_tests.some_bool"));
+echo PHP_EOL;
+
+ini_set("extension_for_tests.some_bool", 'off');
+
+echo "extension_for_tests.some_bool :";
+var_dump(ini_get("extension_for_tests.some_bool"));
+echo PHP_EOL;
+
+//var_export(php_sapi_name());
diff --git a/tests/php/php_alias.sh b/tests/php/php_alias.sh
index f4c7f8f..6947325 100755
--- a/tests/php/php_alias.sh
+++ b/tests/php/php_alias.sh
@@ -16,4 +16,4 @@ fi
LD_LIBRARY_PATH="$(cd $PWD/../.. && echo $PWD):${LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH
-/usr/bin/php -d extension_dir=../ext_dir -d extension=extfortest.so $1
+/usr/bin/php -d extension_dir=../ext_dir -d extension=extfortest.so -d ini7=47 -d extension_for_tests.frcli=frcli $1 $2 $3 $4 $5
diff --git a/zend/extensionimpl.cpp b/zend/extensionimpl.cpp
index b1ec6e8..0308c63 100644
--- a/zend/extensionimpl.cpp
+++ b/zend/extensionimpl.cpp
@@ -110,10 +110,20 @@ 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 ];
+
+ // Filling ini entries
+ extension->_data->fill_ini(ini_entries, module_number);
+ // register ini entries in Zend core
+ REGISTER_INI_ENTRIES();
+
// initialize the extension
extension->initialize(TSRMLS_C);
@@ -135,7 +145,13 @@ int ExtensionImpl::processShutdown(int type, int module_number TSRMLS_DC)
{
// get the extension
auto *extension = find(module_number TSRMLS_CC);
-
+
+
+ UNREGISTER_INI_ENTRIES();
+ // free memory from array ini entries
+ static zend_ini_entry *ini_entries;
+ delete [] ini_entries;
+
// is the callback registered?
if (extension->_onShutdown) extension->_onShutdown();
@@ -197,7 +213,7 @@ ExtensionImpl::ExtensionImpl(Extension *data, const char *name, const char *vers
_entry.zend_api = ZEND_MODULE_API_NO; // api number
_entry.zend_debug = ZEND_DEBUG; // debug mode enabled?
_entry.zts = USING_ZTS; // is thread safety enabled?
- _entry.ini_entry = NULL; // the php.ini record
+ _entry.ini_entry = NULL; // the php.ini record, will be filled by Zend engine
_entry.deps = NULL; // dependencies on other modules
_entry.name = name; // extension name
_entry.functions = NULL; // functions supported by this module (none for now)
diff --git a/zend/includes.h b/zend/includes.h
index 274ad85..4aa5eb0 100644
--- a/zend/includes.h
+++ b/zend/includes.h
@@ -15,6 +15,7 @@
#include <initializer_list>
#include <vector>
#include <map>
+#include <set>
#include <memory>
#include <list>
#include <exception>
@@ -34,6 +35,7 @@
#include <php.h>
#include <zend_exceptions.h>
#include <zend_interfaces.h>
+#include <zend_ini.h>
/**
* Macro to convert results to success status
@@ -43,6 +45,7 @@
/**
* Include other files from this library
*/
+#include "../include/ini.h"
#include "../include/exception.h"
#include "../include/streams.h"
#include "../include/type.h"
diff --git a/zend/ini.cpp b/zend/ini.cpp
new file mode 100644
index 0000000..0c04d6a
--- /dev/null
+++ b/zend/ini.cpp
@@ -0,0 +1,57 @@
+/**
+ * Ini.cpp
+ *
+ * Implementation for ....
+ *
+ * @copyright 2013 Copernica BV
+ */
+#include "includes.h"
+
+/**
+ * Set up namespace
+ */
+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)
+ {
+ ini_entry->module_number = module_number;
+ ini_entry->modifiable = static_cast<int>(this->_place);
+ ini_entry->name = const_cast<char*>(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<char*>(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<char*>(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;
+ }
+
+
+/**
+ * End of namespace
+ */
+}
+
+
diff --git a/zend/namespace.cpp b/zend/namespace.cpp
index 2b4b62a..8b97c52 100644
--- a/zend/namespace.cpp
+++ b/zend/namespace.cpp
@@ -128,6 +128,21 @@ void Namespace::classes(const std::function<void(const std::string &ns, ClassBas
}
/**
+ * Filling ini entries into external zend_ini_entry array
+ * @param zend_ini_entry*
+ */
+void Namespace::fill_ini(zend_ini_entry *ini_entries, int module_number)
+{
+ // loop through the ini entries
+ unsigned int Ind = 0;
+ for (auto &ini : _ini_entries) ini->fill(&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
*/
}