summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile146
-rw-r--r--include/arrayaccess.h94
-rw-r--r--include/class.h36
-rw-r--r--include/classbase.h14
-rw-r--r--include/countable.h8
-rw-r--r--phpcpp.h1
-rw-r--r--src/callable.cpp5
-rw-r--r--src/classbase.cpp6
-rw-r--r--src/countable.cpp32
-rw-r--r--src/includes.h1
10 files changed, 227 insertions, 116 deletions
diff --git a/Makefile b/Makefile
index 30b83c6..734590b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,141 +1,141 @@
#
-# PHP-CPP Makefile
+# PHP-CPP Makefile
#
-# This makefile has a user friendly order: the top part of this file contains
-# all variable settings that you may alter to suit your own system, while at
-# the bottom you will find instructions for the compiler in which you will
-# probably not have to make any changes
-#
+# This makefile has a user friendly order: the top part of this file contains
+# all variable settings that you may alter to suit your own system, while at
+# the bottom you will find instructions for the compiler in which you will
+# probably not have to make any changes
+#
#
-# Zend header files
+# Zend header files
#
-# The variable PHP_DIR contains the location on your system where the regular
-# header files of the Zend engine can be found. Usually this is either
-# /usr/include/php5 or /usr/local/include/php5. Inside this directory you
-# will find sub-directories named TSRM, Zend, ext and main.
+# The variable PHP_DIR contains the location on your system where the regular
+# header files of the Zend engine can be found. Usually this is either
+# /usr/include/php5 or /usr/local/include/php5. Inside this directory you
+# will find sub-directories named TSRM, Zend, ext and main.
#
-PHP_DIR = /usr/include/php5
+PHP_DIR = /usr/include/php5
#
-# Installation directory
+# Installation directory
#
-# When you install the PHP-CPP library, it will place a number of C++ *.h
-# header files in your system include directory, and a libphpcpp.so shared
-# library file in your system libraries directory. Most users set this to
-# the regular /usr/include and /usr/lib directories, or /usr/local/include
-# and /usr/local/lib. You can of course change it to whatever suits you best
-#
+# When you install the PHP-CPP library, it will place a number of C++ *.h
+# header files in your system include directory, and a libphpcpp.so shared
+# library file in your system libraries directory. Most users set this to
+# the regular /usr/include and /usr/lib directories, or /usr/local/include
+# and /usr/local/lib. You can of course change it to whatever suits you best
+#
-INSTALL_PREFIX = /usr
-INSTALL_HEADERS = ${INSTALL_PREFIX}/include
-INSTALL_LIB = ${INSTALL_PREFIX}/lib
+INSTALL_PREFIX = /usr
+INSTALL_HEADERS = ${INSTALL_PREFIX}/include
+INSTALL_LIB = ${INSTALL_PREFIX}/lib
#
-# Name of the target library name
+# Name of the target library name
#
-# The PHP-CPP library will be installed on your system as libphpcpp.so.
-# This is a brilliant name. If you want to use a different name for it,
-# you can change that here
+# The PHP-CPP library will be installed on your system as libphpcpp.so.
+# This is a brilliant name. If you want to use a different name for it,
+# you can change that here
#
-RESULT = libphpcpp.so
+RESULT = libphpcpp.so
#
-# Compiler
+# 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 a single .so
-# library file. By default, g++ (the GNU C++ compiler) is used for both.
+# 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 a single .so
+# library file. By default, g++ (the GNU C++ compiler) is used for both.
#
-COMPILER = g++
-LINKER = g++
+COMPILER = g++
+LINKER = g++
#
-# Compiler flags
+# Compiler 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).
+# 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).
#
-COMPILER_FLAGS = -Wall -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext -I${PHP_DIR}/Zend -I${PHP_DIR}/TSRM -O2 -std=c++11 -fpic -o
+COMPILER_FLAGS = -Wall -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext -I${PHP_DIR}/Zend -I${PHP_DIR}/TSRM -g -std=c++11 -fpic -o
#
-# Linker flags
+# Linker flags
#
-# Just like the compiler, the linker can have flags too. The default flag
-# is probably the only one you need.
+# Just like the compiler, the linker can have flags too. The default flag
+# is probably the only one you need.
#
-LINKER_FLAGS = -shared
+LINKER_FLAGS = -shared
#
-# Command to remove files, copy files and create directories.
+# 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
+# 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
+RM = rm -f
+CP = cp -f
+MKDIR = mkdir -p
#
-# The source files
+# The source files
#
-# For this we use a special Makefile function that automatically scans the
-# src/ directory for all *.cpp files. No changes are probably necessary here
+# For this we use a special Makefile function that automatically scans the
+# src/ directory for all *.cpp files. No changes are probably necessary here
#
-SOURCES = $(wildcard src/*.cpp)
+SOURCES = $(wildcard src/*.cpp)
#
-# The object files
+# The object files
#
-# The intermediate object files are generated by the compiler right before
-# the linker turns all these object files into the libphpcpp.so shared library.
-# We also use a Makefile function here that takes all source files.
+# The intermediate object files are generated by the compiler right before
+# the linker turns all these object files into the libphpcpp.so shared library.
+# We also use a Makefile function here that takes all source files.
#
-OBJECTS = $(SOURCES:%.cpp=%.o)
+OBJECTS = $(SOURCES:%.cpp=%.o)
#
-# End of the variables section. Here starts the list of instructions and
-# dependencies that are used by the compiler.
+# End of the variables section. Here starts the list of instructions and
+# dependencies that are used by the compiler.
#
-all: ${OBJECTS} ${RESULT}
+all: ${OBJECTS} ${RESULT}
${RESULT}: ${OBJECTS}
- ${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS}
+ ${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS}
clean:
- ${RM} ${OBJECTS} ${RESULT}
+ ${RM} ${OBJECTS} ${RESULT}
${OBJECTS}:
- ${COMPILER} ${COMPILER_FLAGS} $@ ${@:%.o=%.cpp}
+ ${COMPILER} ${COMPILER_FLAGS} $@ ${@:%.o=%.cpp}
install:
- ${MKDIR} ${INSTALL_HEADERS}/phpcpp
- ${CP} phpcpp.h ${INSTALL_HEADERS}
- ${CP} include/*.h ${INSTALL_HEADERS}/phpcpp
- ${CP} ${RESULT} ${INSTALL_LIB}
+ ${MKDIR} ${INSTALL_HEADERS}/phpcpp
+ ${CP} phpcpp.h ${INSTALL_HEADERS}
+ ${CP} include/*.h ${INSTALL_HEADERS}/phpcpp
+ ${CP} ${RESULT} ${INSTALL_LIB}
diff --git a/include/arrayaccess.h b/include/arrayaccess.h
new file mode 100644
index 0000000..6ee3163
--- /dev/null
+++ b/include/arrayaccess.h
@@ -0,0 +1,94 @@
+/**
+ * ArrayAccess.h
+ *
+ * "Interface" that can be "implemented" by your class. If you do, you
+ * create your class like this:
+ *
+ * class MyClass : public Php::Base, public Php::ArrayAccess { ... }
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2014 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class ArrayAccess
+{
+public:
+ /**
+ * Check if a member is set
+ * @param key
+ * @return bool
+ */
+ virtual bool offsetExists(const Php::Value &key) = 0;
+
+ /**
+ * Set a member
+ * @param key
+ * @param value
+ */
+ virtual void offsetSet(const Php::Value &key, const Php::Value &value) = 0;
+
+ /**
+ * Retrieve a member
+ * @param key
+ * @return value
+ */
+ virtual Php::Value offsetGet(const Php::Value &key) = 0;
+
+ /**
+ * Remove a member
+ * @param key
+ */
+ virtual void offsetUnset(const Php::Value &key) = 0;
+
+ /**
+ * Alternative offsetExists as it is initially called
+ * @param params
+ * @return bool
+ */
+ virtual Php::Value offsetExists(Php::Parameters &params)
+ {
+ return offsetExists(params[0]);
+ }
+
+ /**
+ * Alternative set member function as it is initially called
+ * @param params
+ */
+ virtual void offsetSet(const Php::Parameters &params)
+ {
+ offsetSet(params[0], params[1]);
+ }
+
+ /**
+ * Alternative retrieve member function that is initially called
+ * @param params
+ * @return value
+ */
+ virtual Php::Value offsetGet(Php::Parameters &params)
+ {
+ return offsetGet(params[0]);
+ }
+
+ /**
+ * Alternative function to remove a member that is initally called
+ * @param params
+ */
+ virtual void offsetUnset(Php::Parameters &params)
+ {
+ return offsetUnset(params[0]);
+ }
+};
+
+/**
+ * End namespace
+ */
+}
+
diff --git a/include/class.h b/include/class.h
index a22b9a8..3326507 100644
--- a/include/class.h
+++ b/include/class.h
@@ -16,6 +16,12 @@
*/
/**
+ * Zend/SPL interfaces that we support
+ */
+extern struct _zend_class_entry *spl_ce_Countable;
+extern struct _zend_class_entry *spl_ce_ArrayAccess;
+
+/**
* Set up namespace
*/
namespace Php {
@@ -38,7 +44,35 @@ public:
Class(const char *name) : ClassBase(name)
{
// check for special classes
- if (std::is_base_of<Countable, T>::value) ClassBase::interface(Countable::implementation());
+ if (std::is_base_of<Countable, T>::value)
+ {
+ // register the interface (we register a pointer-to-a-pointer here,
+ // because when this code runs (during the get_module() call), the
+ // interfaces are not yet initialized by the zend engine, this
+ // happens later when the all classes are registered (after the
+ // get_module() call)
+ interface(&spl_ce_Countable);
+
+ // add the count method
+ method("count", &T::count, {});
+ }
+
+ // check for special classes
+ if (std::is_base_of<ArrayAccess, T>::value)
+ {
+ // register the interface (we register a pointer-to-a-pointer here,
+ // because when this code runs (during the get_module() call), the
+ // interfaces are not yet initialized by the zend engine, this
+ // happens later when the all classes are registered (after the
+ // get_module() call)
+ interface(&spl_ce_ArrayAccess);
+
+ // add the count method
+ method("count", &T::offsetSet);
+ method("count", &T::offsetGet);
+ method("count", &T::offsetUnset);
+ method("count", &T::offsetExists);
+ }
}
/**
diff --git a/include/classbase.h b/include/classbase.h
index 3792fdb..92e637d 100644
--- a/include/classbase.h
+++ b/include/classbase.h
@@ -19,6 +19,7 @@
*/
struct _zend_object_value;
struct _zend_object_handlers;
+struct _zend_class_entry;
/**
* Set up namespace
@@ -66,6 +67,7 @@ public:
_type(that._type),
_methods(that._methods),
_members(that._members),
+ _interfaces(that._interfaces),
_entry(nullptr) {}
/**
@@ -77,6 +79,7 @@ public:
_type(that._type),
_methods(std::move(that._methods)),
_members(std::move(that._members)),
+ _interfaces(std::move(that._interfaces)),
_entry(that._entry)
{
// other entry are invalid now (not that it is used..., class objects are
@@ -188,9 +191,16 @@ protected:
* It does however make sense to support implementing extension-specific
* interface. We may add this feature in the future.
*
+ * This method is called _during_ the get_module() call when all classes
+ * are defined by the extension. However, at that time the Zend engine has
+ * not yet initialized the zend_class_entry's with the interface addresses.
+ * That's why we ask for a pointer-to-a-pointer. Later, when the classes
+ * are really registered, the Zend engine is with registering interfaces
+ * and the pointers point to a valid variable.
+ *
* @param interface
*/
- void interface(struct _zend_class_entry *interface)
+ void interface(struct ::_zend_class_entry **interface)
{
// register the interface
_interfaces.push_back(interface);
@@ -274,7 +284,7 @@ private:
* All interfaces that are implemented
* @var std::list
*/
- std::list<struct _zend_class_entry*> _interfaces;
+ std::list<struct ::_zend_class_entry**> _interfaces;
};
diff --git a/include/countable.h b/include/countable.h
index 12d87d5..1b99463 100644
--- a/include/countable.h
+++ b/include/countable.h
@@ -25,17 +25,11 @@ class Countable
{
public:
/**
- * Implementation of the countable interface
- * @return zend_class_entry*
- * @internal
- */
- static struct _zend_class_entry *implementation();
-
- /**
* Retrieve the number of items in the class
* @return Value
*/
virtual Value count() = 0;
+
};
/**
diff --git a/phpcpp.h b/phpcpp.h
index 91abe0c..428e0da 100644
--- a/phpcpp.h
+++ b/phpcpp.h
@@ -40,6 +40,7 @@
#include <phpcpp/modifiers.h>
#include <phpcpp/base.h>
#include <phpcpp/countable.h>
+#include <phpcpp/arrayaccess.h>
#include <phpcpp/classtype.h>
#include <phpcpp/classbase.h>
#include <phpcpp/class.h>
diff --git a/src/callable.cpp b/src/callable.cpp
index 66333d5..5229722 100644
--- a/src/callable.cpp
+++ b/src/callable.cpp
@@ -76,6 +76,9 @@ void Callable::initialize(zend_function_entry *entry, const char *classname, int
entry->num_args = _argc;
entry->flags = flags;
+ std::cout << entry->fname << " num_args " << entry->num_args << std::endl;
+ std::cout << entry->fname << " flags " << entry->flags << std::endl;
+
// we should fill the first argument as well
#if PHP_VERSION_ID >= 50400
initialize((zend_internal_function_info *)entry->arg_info, classname);
@@ -101,6 +104,8 @@ void Callable::initialize(zend_internal_function_info *info, const char *classna
info->required_num_args = _required;
info->_type_hint = (unsigned char)_return;
+ std::cout << "required_num_args " << info->required_num_args << std::endl;
+
// we do not support return-by-reference
info->return_reference = false;
diff --git a/src/classbase.cpp b/src/classbase.cpp
index 19ac6bc..48746ec 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -248,7 +248,11 @@ void ClassBase::initialize(const std::string &prefix)
_entry->ce_flags = (int)_type;
// mark the interfaces as being implemented
- for (auto &interface : _interfaces) zend_do_implement_interface(_entry, interface);
+ for (auto &interface : _interfaces)
+ {
+ std::cout << "interface: " << interface << std::endl;
+ zend_do_implement_interface(_entry, *interface);
+ }
// declare all member variables
for (auto &member : _members) member->initialize(_entry);
diff --git a/src/countable.cpp b/src/countable.cpp
deleted file mode 100644
index 6182afd..0000000
--- a/src/countable.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Countable.cpp
- *
- * Implementation of the Countable interface
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2014 Copernica BV
- */
-#include "includes.h"
-
-#include "spl/spl_iterators.h"
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Implementation of the countable interface
- * @return zend_class_entry*
- * @internal
- */
-struct _zend_class_entry *Countable::implementation()
-{
- return spl_ce_Countable;
-}
-
-/**
- * End namespace
- */
-}
-
diff --git a/src/includes.h b/src/includes.h
index 60783eb..e9718f3 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -59,6 +59,7 @@
#include "../include/modifiers.h"
#include "../include/base.h"
#include "../include/countable.h"
+#include "../include/arrayaccess.h"
#include "../include/classtype.h"
#include "../include/classbase.h"
#include "../include/class.h"