diff --git a/Examples/phpinfoExample/Makefile b/Examples/phpinfoExample/Makefile new file mode 100644 index 00000000..f048c706 --- /dev/null +++ b/Examples/phpinfoExample/Makefile @@ -0,0 +1,144 @@ +# +# Makefile template +# +# This is an example Makefile that can be used by anyone who is building +# his or her own PHP extensions using the PHP-CPP library. +# +# In the top part of this file we have included variables that can be +# altered to fit your configuration, near the bottom the instructions and +# dependencies for the compiler are defined. The deeper you get into this +# file, the less likely it is that you will have to change anything in it. +# + +# +# Name of your extension +# +# This is the name of your extension. Based on this extension name, the +# name of the library file (name.so) and the name of the config file (name.ini) +# are automatically generated +# + +PHP_VERSION := $(shell /usr/bin/php --version | head -n 1 | cut -d " " -f 2 | cut -c 1-3) +PHP_API_VER := $(shell /usr/bin/php -i | /bin/grep 'PHP API' | cut -d " " -f 4) + +NAME = phpinfoexample +LIBS_CMD = "pkg-config opencv --cflags --libs" + +# +# Php.ini directories +# +# In the past, PHP used a single php.ini configuration file. Today, most +# PHP installations use a conf.d directory that holds a set of config files, +# one for each extension. Use this variable to specify this directory. +# + +INI_DIR = /etc/php/${PHP_VERSION}/cli/conf.d + + +# +# The extension dirs +# +# This is normally a directory like /usr/lib/php5/20121221 (based on the +# PHP version that you use. We make use of the command line 'php-config' +# instruction to find out what the extension directory is, you can override +# this with a different fixed directory +# + +EXTENSION_DIR = $(shell php-config --extension-dir) + +# +# The name of the extension and the name of the .ini file +# +# These two variables are based on the name of the extension. We simply add +# a certain extension to them (.so or .ini) +# + +EXTENSION = ${NAME}.so +INI = ${NAME}.ini + + +# +# Compiler +# +# By default, the GNU C++ compiler is used. If you want to use a different +# compiler, you can change that here. You can change this for both the +# compiler (the program that turns the c++ files into object files) and for +# the linker (the program that links all object files into the single .so +# library file. By default, g++ (the GNU C++ compiler) is used for both. +# + +COMPILER = g++ +LINKER = g++ + + +# +# Compiler and linker flags +# +# This variable holds the flags that are passed to the compiler. By default, +# we include the -O2 flag. This flag tells the compiler to optimize the code, +# but it makes debugging more difficult. So if you're debugging your application, +# you probably want to remove this -O2 flag. At the same time, you can then +# add the -g flag to instruct the compiler to include debug information in +# the library (but this will make the final libphpcpp.so file much bigger, so +# you want to leave that flag out on production servers). +# +# If your extension depends on other libraries (and it does at least depend on +# one: the PHP-CPP library), you should update the LINKER_DEPENDENCIES variable +# with a list of all flags that should be passed to the linker. +# + +# Edit paths here as appropriate +COMPILER_FLAGS = -DUSE_OPENCV -DCPU_ONLY -D__STDC_CONSTANT_MACROS -I /var/phpcpp_github/PHP-CPP/include -I /usr/include/php/20170718/Zend -I /usr/local/include -I /usr/include/php/20170718/TSRM -I/usr/include/x86_64-linux-gnu -Wall -c -O2 -std=c++11 -fpic -o + +LINKER_FLAGS = -shared +LINKER_DEPENDENCIES = -lphpcpp + + +# +# Command to remove files, copy files and create directories. +# +# I've never encountered a *nix environment in which these commands do not work. +# So you can probably leave this as it is +# + +RM = rm -f +CP = cp -f +MKDIR = mkdir -p + +# +# All source files are simply all *.cpp files found in the current directory +# +# A builtin Makefile macro is used to scan the current directory and find +# all source files. The object files are all compiled versions of the source +# file, with the .cpp extension being replaced by .o. +# + +SOURCES = $(wildcard *.cpp) +OBJECTS = $(SOURCES:%.cpp=%.o) + +# +# From here the build instructions start +# + +all: ${OBJECTS} ${EXTENSION} + +${EXTENSION}: ${OBJECTS} + ${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS} ${LINKER_DEPENDENCIES} + +${OBJECTS}: + ${COMPILER} ${COMPILER_FLAGS} $@ ${@:%.o=%.cpp} + + +install: + ${CP} ${EXTENSION} ${EXTENSION_DIR} + ${CP} ${INI} ${INI_DIR} + ${CP} ${INI} /etc/php/${PHP_VERSION}/cli/conf.d/${NAME}.ini + +clean: + ${RM} ${EXTENSION} ${OBJECTS} + ${RM} /etc/php/${PHP_VERSION}/cli/conf.d/${NAME}.ini + ${RM} ${EXTENSION_DIR}/${NAME}.so + + + + diff --git a/Examples/phpinfoExample/phpinfoexample.cpp b/Examples/phpinfoExample/phpinfoexample.cpp new file mode 100644 index 00000000..eedf6fcb --- /dev/null +++ b/Examples/phpinfoExample/phpinfoexample.cpp @@ -0,0 +1,285 @@ +/** + * Simple.h + * + * A very simple extension that does almost nothing + * + * @author Emiel Bruijntjes + * @copyright 2013 Copernica BV + */ +#include +#include +#include +#include + +#include "phpinfoexample.hpp" + +/** + * Namespace to use + */ +using namespace std; + + +Php::Value bubblesort(Php::Parameters ¶ms) +{ + cout << "start bubblesort" << endl; + + // the array that was passed + Php::Value array(params[0]); + + cout << "go return" << endl; + + return array; + + // size of the array + int size = array.size(); + + cout << "convert to native" << endl; + + int *x = new int[size]; + for (int i=0; i infoMap; + + // Change info here as needed + infoMap["Extension Version"] = MODULEVERSION; + infoMap["Author"] = MODULE_AUTHOR; + infoMap["Copyright"] = MODULE_COPYRIGHT; + + // Headline + if (!isCLI) + Php::out << "

" << MODULENAME << " Information

\n" << std::endl; + else + Php::out << MODULENAME << " Information" << std::endl; + + // php_info_print_table_start() + if (!isCLI) + Php::out << "\n" << std::endl; + else + Php::out << "\n"; + + // php_info_print_table_header() + for (auto &iter : infoMap) { + if (! isCLI) { + Php::out << "" << std::endl; + Php::out << "" << std::endl; + Php::out << "" << std::endl; + Php::out << ""<< std::endl; + } else { + Php::out << iter.first << " => " << iter.second << std::endl; + } + } + + // php_info_print_table_end() + if (! isCLI) + Php::out << "
" << iter.first << "" << iter.second<< "
\n" << std::endl; + else + Php::out << "\n"; + + // Ini vars + int iniCount = (int) extension->iniVariables(); + + if (iniCount > 0) { + + if (!isCLI) { + Php::out << "Directive => Local Value => Master Value" << std::endl; + } else { + Php::out << "" << std::endl; + } + + extension->iniVariables([isCLI](Php::Ini &ini) { + + std::string name = ini.name(); + Php::IniValue master = Php::ini_get_orig(name.c_str()); + Php::IniValue local = Php::ini_get(name.c_str()); + std::string masterVal = master; + std::string localVal = local; + masterVal = (masterVal.empty()) ? "no value" : masterVal; + masterVal = (masterVal == "no value" && !isCLI) ? "" + masterVal + "" : masterVal; + localVal = (localVal.empty()) ? "no value" : localVal; + localVal = (localVal == "no value" && !isCLI) ? "" + localVal + "" : localVal; + + if (! isCLI) { + Php::out << "" << std::endl; + Php::out << "" << std::endl; + Php::out << ""<< std::endl; + } else { + Php::out << name << " => " << localVal << " => " << masterVal << std::endl; + } + }); + + // php_info_print_table_end() + if (! isCLI) + Php::out << "
DirectiveLocal ValueMaster Value
" << name << "" << localVal << "" << masterVal << "
\n" << std::endl; + else + Php::out << "\n"; + } + + Php::out << std::flush; +} + +// symbols are exported according to the "C" language +extern "C" +{ + // export the "get_module" function that will be called by the Zend engine + PHPCPP_EXPORT void *get_module() + { + // create extension + static Php::Extension extension(MODULENAME_LOWER, MODULEVERSION); + + // define the functions + extension.add("my_plus", { + Php::ByVal("a", Php::Type::Numeric), + Php::ByVal("b", Php::Type::Numeric), + Php::ByVal("c", "MyClass"), + Php::ByRef("d", Php::Type::String) + }); + + extension.add("bubblesort"); + + // define classes + Php::Class myCustomClass("my_class"); + myCustomClass.method<&MyCustomClass::myMethod>("mymethod"); + myCustomClass.method<&MyCustomClass::__construct>("__construct"); + + // add to extension + extension.add(myCustomClass); + + // Add a couple of INI settings + extension.add(Php::Ini(MODULENAME_LOWER ".some.value", "", Php::Ini::Place::All)); + extension.add(Php::Ini(MODULENAME_LOWER ".some.value2", "", Php::Ini::Place::All)); + + /* MODULE INFO - REGISTER A CALLBACK FOR PHPINFO() */ + Php::Extension *extPtr; + extPtr = &extension; + extension.onInfo([extPtr]() { + + // NOTE the EXTENSION NAME HERE ! + CALL_INFO_FUNC(phpinfoexample, extPtr); + }); + + // return the module entry + return extension.module(); + } +} + + diff --git a/Examples/phpinfoExample/phpinfoexample.hpp b/Examples/phpinfoExample/phpinfoexample.hpp new file mode 100644 index 00000000..071246af --- /dev/null +++ b/Examples/phpinfoExample/phpinfoexample.hpp @@ -0,0 +1,10 @@ +#define MODULENAME "PHPInfoExample" +#define MODULENAME_LOWER "phpinfoexample" +#define MODULEVERSION "1.0" +#define MODULE_AUTHOR "Some one" +#define MODULE_COPYRIGHT "Some Company LLC" + +#define INFO_FUNC(module) void info__##module(Php::Extension* extension) +#define CALL_INFO_FUNC(module, ex) info__##module(ex); + + diff --git a/Examples/phpinfoExample/phpinfoexample.ini b/Examples/phpinfoExample/phpinfoexample.ini new file mode 100644 index 00000000..0433848e --- /dev/null +++ b/Examples/phpinfoExample/phpinfoexample.ini @@ -0,0 +1,7 @@ +; configuration for phpcpp module +; priority=30 +extension=phpinfoexample.so + +phpinfoexample.some.value=FOO +phpinfoexample.some.value2=MASTER_VALUE + diff --git a/Examples/phpinfoExample/phpinfoexample.php b/Examples/phpinfoExample/phpinfoexample.php new file mode 100644 index 00000000..2232a9ea --- /dev/null +++ b/Examples/phpinfoExample/phpinfoexample.php @@ -0,0 +1,5 @@ +onInfo(callback); + + // allow chaining + return *this; +} + /** * Retrieve the module pointer * diff --git a/zend/extensionimpl.cpp b/zend/extensionimpl.cpp index 8f9bf80c..aef16dda 100644 --- a/zend/extensionimpl.cpp +++ b/zend/extensionimpl.cpp @@ -173,6 +173,21 @@ int ExtensionImpl::processIdle(int type, int module_number) return BOOL2SUCCESS(true); } +/** + * Function that is called when a request is ended + * @param type Module type + * @param number Module number + * @return int 0 on success + */ +void ExtensionImpl::processInfo(zend_module_entry* zend_module) +{ + // get the extension + auto *extension = find(zend_module->module_number); + + // is the callback registered? + if (extension->_onInfo) extension->_onInfo(); +} + /** * Function that is called when the PHP engine initializes with a different PHP-CPP * version for the libphpcpp.so file than the version the extension was compiled for @@ -218,7 +233,7 @@ ExtensionImpl::ExtensionImpl(Extension *data, const char *name, const char *vers _entry.module_shutdown_func = &ExtensionImpl::processShutdown; // shutdown function for the whole extension _entry.request_startup_func = &ExtensionImpl::processRequest; // startup function per request _entry.request_shutdown_func = &ExtensionImpl::processIdle; // shutdown function per request - _entry.info_func = NULL; // information for retrieving info + _entry.info_func = &ExtensionImpl::processInfo; // information for retrieving info _entry.version = version; // version string _entry.globals_size = 0; // size of the global variables _entry.globals_ctor = NULL; // constructor for global variables diff --git a/zend/extensionimpl.h b/zend/extensionimpl.h index 2451b142..9f0ba2f1 100644 --- a/zend/extensionimpl.h +++ b/zend/extensionimpl.h @@ -183,6 +183,13 @@ class ExtensionImpl : public ExtensionBase */ static int processIdle(int type, int module_number); + /** + * Function that is called when phpinfo() is invoked + * @param zend_module_entry Pointer to zend_module_entry + * @return void + */ + static void processInfo(zend_module_entry* zend_module); + /** * Function that is called when the PHP engine initializes with a different PHP-CPP * version for the libphpcpp.so file than the version the extension was compiled for