├── Examples
├── ConstStaticProp
│ ├── readme
│ ├── cpp
│ │ ├── mytestext.ini
│ │ ├── mytestext.h
│ │ ├── Makefile
│ │ └── mytestext.cpp
│ └── test.php
├── ReturnObject
│ ├── returnobject.ini
│ ├── child.h
│ ├── test.php
│ ├── master.h
│ └── main.cpp
├── EmptyExtension
│ ├── yourextension.ini
│ └── main.cpp
├── Makefile
├── Globals
│ ├── 30-globals.ini
│ ├── Makefile
│ ├── globals.php
│ └── globals.cpp
├── simple
│ ├── 30-phpcpp.ini
│ ├── Makefile
│ └── simple.php
├── Extension
│ ├── 30-phpcpp.ini
│ ├── extension.php
│ ├── extension.cpp
│ └── Makefile
├── DlUnrestricted
│ ├── dlunrestricted.ini
│ ├── dlunrestricted.php
│ └── dlunrestricted.cpp
├── FunctionVoid
│ ├── 30-functionvoid.ini
│ ├── functionvoid.php
│ ├── Makefile
│ └── functionvoid.cpp
├── CppClassesInPhp
│ ├── cppclassinphp.ini
│ ├── includeMyCustomClass.h
│ ├── cppclassinphp.php
│ └── check_map.php
├── CallPhpFunctions
│ ├── 30-callphpfunction.ini
│ ├── Makefile
│ ├── callphpfunction.php
│ └── callphpfunction.cpp
├── Exceptions
│ ├── ExceptionCatch
│ │ ├── 30-exceptionCatch.ini
│ │ ├── exception.php
│ │ ├── Makefile
│ │ └── exceptionCatch.cpp
│ └── ExceptionThrow
│ │ ├── 30-exceptionThrow.ini
│ │ ├── exception.php
│ │ ├── Makefile
│ │ └── exceptionThrow.cpp
├── FunctionReturnValue
│ ├── 30-functionreturnvalue.ini
│ ├── functionreturnvalue.php
│ ├── Makefile
│ └── functionreturnvalue.cpp
├── FunctionNoParameters
│ ├── 30-functionnoparameters.ini
│ ├── functionnoparameters.php
│ ├── Makefile
│ └── functionnoparameters.cpp
└── FunctionWithParameters
│ ├── 30-functionwithparameters.ini
│ ├── Makefile
│ └── functionwithparameters.php
├── .gitignore
├── include
├── version.h
├── noexcept.h
├── platform.h
├── deprecated.h
├── traversable.h
├── countable.h
├── modifiers.h
├── exception.h
├── type.h
├── classtype.h
├── streams.h
├── visibility.h
├── arrayaccess.h
├── parameters.h
├── serializable.h
├── message.h
├── byref.h
├── byval.h
├── globals.h
├── error.h
├── throwable.h
├── iterator.h
├── stream.h
├── function.h
├── file.h
├── interface.h
├── valueiterator.h
├── super.h
├── script.h
├── hashparent.h
├── inivalue.h
└── array.h
├── zend
├── module.cpp
├── sapi.cpp
├── error.cpp
├── function.cpp
├── hashmember.cpp
├── streams.cpp
├── global.cpp
├── delayedfree.h
├── functor.cpp
├── super.cpp
├── inivalue.cpp
├── streambuf.cpp
├── nullmember.h
├── notimplemented.h
├── compileroptions.h
├── lowercase.h
├── boolmember.h
├── numericmember.h
├── ini.cpp
├── valueiteratorimpl.h
├── floatmember.h
├── parametersimpl.h
├── init.h
├── member.h
├── extensionpath.h
├── invaliditerator.h
├── stream.cpp
├── functor.h
├── members.cpp
├── valueiterator.cpp
├── stringmember.h
├── globals.cpp
├── executestate.h
├── exists.cpp
├── eval.cpp
├── script.cpp
├── exception_handler.cpp
├── constant.cpp
├── zendcallable.cpp
├── nativefunction.h
├── opcodes.h
├── property.h
└── origexception.h
├── common
├── includes.h
├── modifiers.cpp
├── streambuf.cpp
├── streambuf.h
└── extensionbase.h
├── phpcpp.h
├── documentation
├── namespaces.html
├── ini.html
└── install.html
└── README.md
/Examples/ConstStaticProp/readme:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.a
3 | *.so
4 | *.txt
5 | *.a.*
6 | *.so.*
7 |
--------------------------------------------------------------------------------
/Examples/ReturnObject/returnobject.ini:
--------------------------------------------------------------------------------
1 | extension=returnobject.so
2 |
--------------------------------------------------------------------------------
/Examples/EmptyExtension/yourextension.ini:
--------------------------------------------------------------------------------
1 | extension=yourextension.so
2 |
--------------------------------------------------------------------------------
/Examples/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | cd simple; $(MAKE)
3 |
4 | clean:
5 | cd simple; $(MAKE) clean
6 |
--------------------------------------------------------------------------------
/Examples/Globals/30-globals.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=globals.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/simple/30-phpcpp.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=simple.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/Extension/30-phpcpp.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=extension.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/DlUnrestricted/dlunrestricted.ini:
--------------------------------------------------------------------------------
1 | ; configuration for dlunrestriced module
2 | extension=dlunrestricted.so
3 |
4 |
--------------------------------------------------------------------------------
/Examples/ConstStaticProp/cpp/mytestext.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=mytestext.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/FunctionVoid/30-functionvoid.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=functionvoid.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/CppClassesInPhp/cppclassinphp.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=cppclassinphp.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/CallPhpFunctions/30-callphpfunction.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=callphpfunction.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/Exceptions/ExceptionCatch/30-exceptionCatch.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=exceptionCatch.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/Exceptions/ExceptionThrow/30-exceptionThrow.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=exceptionThrow.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/FunctionReturnValue/30-functionreturnvalue.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=functionreturnvalue.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/FunctionNoParameters/30-functionnoparameters.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=functionnoparameters.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/FunctionWithParameters/30-functionwithparameters.ini:
--------------------------------------------------------------------------------
1 | ; configuration for phpcpp module
2 | ; priority=30
3 | extension=functionwithparameters.so
4 |
5 |
--------------------------------------------------------------------------------
/Examples/Extension/extension.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * An example file to show the working of an extension.
7 | */
8 |
9 | // print all the extensions currently loaded.
10 | print_r(get_loaded_extensions());
11 |
--------------------------------------------------------------------------------
/Examples/FunctionNoParameters/functionnoparameters.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * An example file to show the working of a function call without parameters.
7 | */
8 |
9 |
10 | //Run a function without parameters.
11 | echo my_no_parameters_function() . "\n";
12 |
--------------------------------------------------------------------------------
/Examples/FunctionReturnValue/functionreturnvalue.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * An example file to show the working of a function call with a return value.
7 | */
8 |
9 | /**
10 | * Run a function which returns a value.
11 | */
12 | echo my_return_value_function() . "\n";
13 |
--------------------------------------------------------------------------------
/Examples/FunctionVoid/functionvoid.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * An example file to show the working of a void function call.
7 | */
8 |
9 | /*
10 | * Run the function with the given name. As you can see, the given name
11 | * can be different from the actual function name.
12 | */
13 | my_void_function();
14 |
--------------------------------------------------------------------------------
/Examples/DlUnrestricted/dlunrestricted.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * An example file to show the working of a void function call.
7 | */
8 |
9 | /*
10 | * Run the function with the given name. As you can see, the given name
11 | * can be different from the actual function name.
12 | */
13 | my_void_function();
14 |
--------------------------------------------------------------------------------
/Examples/ConstStaticProp/cpp/mytestext.h:
--------------------------------------------------------------------------------
1 | /**
2 | * The includes.h
3 | */
4 |
5 | /**
6 | * Default Cpp libraries
7 | */
8 |
9 | #include
10 | #include
11 |
12 | /**
13 | * Our own library.
14 | */
15 | #include
16 |
17 | /**
18 | * Namespace to use
19 | */
20 | using namespace std;
21 |
22 | /**
23 | * The test class.
24 | */
25 | //#include "mycustomclass.h"
26 |
--------------------------------------------------------------------------------
/Examples/CppClassesInPhp/includeMyCustomClass.h:
--------------------------------------------------------------------------------
1 | /**
2 | * The includes.h
3 | */
4 |
5 | /**
6 | * Default Cpp libraries
7 | */
8 |
9 | #include
10 | #include
11 |
12 | /**
13 | * Our own library.
14 | */
15 | #include
16 |
17 | /**
18 | * Namespace to use
19 | */
20 | using namespace std;
21 |
22 | /**
23 | * The test class.
24 | */
25 | //#include "mycustomclass.h"
26 |
--------------------------------------------------------------------------------
/include/version.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Version.h
3 | *
4 | * Macro with API version. The API version number prevents that
5 | * extensions are loaded that are incompatible with the libphpcpp.so
6 | * library
7 | *
8 | * @author Emiel Bruijntjes
9 | * @copyright 2015 Copernica BV
10 | */
11 |
12 | /**
13 | * Macro with version number (this is incremented with every release)
14 | */
15 | #define PHPCPP_API_VERSION 20150126
16 |
--------------------------------------------------------------------------------
/Examples/ConstStaticProp/test.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2015 Copernica BV
8 | */
9 |
10 | /**
11 | * Dependencies
12 | */
13 | #include "includes.h"
14 |
15 | /**
16 | * Set up namespace
17 | */
18 | namespace Php {
19 |
20 | /**
21 | * The persistent handles
22 | * @var Module::Persistent
23 | */
24 | Module::Persistent Module::_persistent;
25 |
26 | /**
27 | * End of namespace
28 | */
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/common/includes.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Includes.h
3 | *
4 | * All includes for compiling the common module files of PHP-CPP library
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2014 Copernica BV
8 | */
9 |
10 | /**
11 | * Standard C and C++ libraries
12 | */
13 | #include
14 |
15 | /**
16 | * Public include files
17 | */
18 | #include "../include/visibility.h"
19 | #include "../include/modifiers.h"
20 |
21 | /**
22 | * Generic implementation header files
23 | */
24 | #include "streambuf.h"
25 |
--------------------------------------------------------------------------------
/include/noexcept.h:
--------------------------------------------------------------------------------
1 | /**
2 | * NoExcept.h
3 | *
4 | * Some compilers (hello microsoft!) do not yet support the "noexcept"
5 | * keyword. To overcome this, we use a macro that expands to "noexcept"
6 | *
7 | * @author Emiel Bruijntjes
8 | * @author atvive
9 | */
10 |
11 | /**
12 | * Macro to be able to support MSVC compiler
13 | */
14 | #ifndef _NOEXCEPT
15 | # ifndef _MSC_VER
16 | # define _NOEXCEPT noexcept
17 | # else
18 | # define _NOEXCEPT __declspec(nothrow)
19 | # endif
20 | #endif
21 |
22 |
--------------------------------------------------------------------------------
/zend/sapi.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Sapi.cpp
3 | *
4 | * This file holds the implementation for the Php::sapi_name() function
5 | *
6 | * @author Toon Schoenmakers
7 | */
8 |
9 | /**
10 | * Dependencies
11 | */
12 | #include "includes.h"
13 |
14 | /**
15 | * Open PHP namespace
16 | */
17 | namespace Php {
18 |
19 | /**
20 | * Retrieve the sapi name we're running on
21 | * @return const char*
22 | */
23 | const char *sapi_name()
24 | {
25 | return sapi_module.name;
26 | }
27 |
28 | /**
29 | * End of namespace
30 | */
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/Exceptions/ExceptionCatch/exception.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This example shows the working of a C++ function that throws an
8 | * exception, and that exception is then caught by PHP code.
9 | *
10 | */
11 |
12 | // call the second C++ function that accepts a callback
13 | my_catch_exception_function(function($a, $b, $c) {
14 |
15 | // throw an exception from PHP - the C++ code will catch this exception
16 | throw new Exception("Example exception");
17 | });
18 |
--------------------------------------------------------------------------------
/include/platform.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Platform.h
3 | *
4 | * Macro that we use to find out whether we run on 64bit or 32bit
5 | * platforms.
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2015 Copernica BV
9 | */
10 |
11 | // Check windows
12 | #if _WIN32 || _WIN64
13 | #if _WIN64
14 | #define PHPCPP_64BIT
15 | #else
16 | #define PHPCPP_32BIT
17 | #endif
18 | #endif
19 |
20 | // Check GCC and clang
21 | #if __GNUC__ || __clang__
22 | #if __x86_64__ || __ppc64__
23 | #define PHPCPP_64BIT
24 | #else
25 | #define PHPCPP_32BIT
26 | #endif
27 | #endif
28 |
--------------------------------------------------------------------------------
/zend/error.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Error.cpp
3 | *
4 | * @author Emiel Bruijntjes
5 | * @copyright 2014 - 2019 Copernica BV
6 | */
7 | #include "includes.h"
8 |
9 | /**
10 | * Set up namespace
11 | */
12 | namespace Php {
13 |
14 | /**
15 | * Report this error as a fatal error
16 | * @return bool
17 | */
18 | bool Error::report() const
19 | {
20 | // report the error
21 | zend_error(E_ERROR, "%s", what());
22 |
23 | // return true: it was reported
24 | return true;
25 | }
26 |
27 | /**
28 | * End of namespace
29 | */
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/include/deprecated.h:
--------------------------------------------------------------------------------
1 | /**
2 | * deprecated.h
3 | *
4 | * This file defines macros to mark a function as deprecated
5 | * in a way that works across different compilers.
6 | *
7 | * It is used for functions that still work, but should no
8 | * longer be used because they may be removed in an upcoming
9 | * version of PHP-CPP
10 | *
11 | * @copyright 2016 Copernica B.V.
12 | */
13 |
14 | #if __cplusplus >= 201402L
15 | #define PHPCPP_DEPRECATED [[deprecated]]
16 | #elif defined __GNUC__
17 | #define PHPCPP_DEPRECATED __attribute__((deprecated))
18 | #elif defined(_MSC_VER)
19 | #define PHPCPP_DEPRECATED __declspec(deprecated)
20 | #endif
21 |
--------------------------------------------------------------------------------
/zend/function.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Function.cpp
3 | *
4 | * Implementation file for the Function class
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2015 Copernica BV
8 | */
9 |
10 | /**
11 | * Dependencies
12 | */
13 | #include "includes.h"
14 |
15 | /**
16 | * Set up namespace
17 | */
18 | namespace Php {
19 |
20 | /**
21 | * Constructor
22 | * @param function The function to be wrapped
23 | */
24 | Function::Function(const std::function &function) : Value(Object(Functor::entry(), new Functor(function))) {}
25 |
26 | /**
27 | * End of namespace
28 | */
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/Examples/ReturnObject/child.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Child.h
3 | *
4 | * Class that is exported to PHP space
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2015 Copernica BV
8 | */
9 |
10 | /**
11 | * Include guard
12 | */
13 | #pragma once
14 |
15 | /**
16 | * Class definition
17 | */
18 | class Child : public Php::Base
19 | {
20 | public:
21 | /**
22 | * Constructor and destructor
23 | */
24 | Child() {}
25 | virtual ~Child() {}
26 |
27 | /**
28 | * Cast to a string
29 | * @return const char *
30 | */
31 | const char *__toString() const
32 | {
33 | return "this is the child";
34 | }
35 | };
36 |
37 |
--------------------------------------------------------------------------------
/include/traversable.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Traversable.h
3 | *
4 | * Interface that should be implemented by classes that want to be
5 | * traversable. A traversable objects can be iterated over in a PHP
6 | * foreach loop.
7 | *
8 | * @author Emiel Bruijntjes
9 | * @copyright 2014 Copernica BV
10 | */
11 |
12 | /**
13 | * Set up namespace
14 | */
15 | namespace Php {
16 |
17 | /**
18 | * Class definition
19 | */
20 | class PHPCPP_EXPORT Traversable
21 | {
22 | public:
23 | /**
24 | * Retrieve an instance of the iterator
25 | * @return Iterator
26 | */
27 | virtual Iterator *getIterator() = 0;
28 | };
29 |
30 | /**
31 | * End namespace
32 | */
33 | }
34 |
--------------------------------------------------------------------------------
/Examples/Exceptions/ExceptionThrow/exception.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This example shows the working of a C++ function that throws an
8 | * exception, and that exception is then caught by PHP code.
9 | *
10 | */
11 |
12 | // try-catch block to be able to handle the exception
13 | try
14 | {
15 | // the my_throw_exception function is implemented in C++. and
16 | // it is going to throw an exception
17 | my_throw_exception_function();
18 | }
19 | catch (Exception $exception)
20 | {
21 | // the exception object is thrown by C++ code, and caught by PHP
22 | // code
23 | echo $exception->getMessage(). "\n";
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/Extension/extension.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * extension.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of an extension.
6 | */
7 | // library include
8 | #include
9 |
10 | /**
11 | * Namespace to use
12 | */
13 | using namespace std;
14 |
15 | // Symbols are exported according to the "C" language
16 | extern "C"
17 | {
18 | // export the "get_module" function that will be called by the Zend engine
19 | PHPCPP_EXPORT void *get_module()
20 | {
21 | // create extension
22 | static Php::Extension extension("my_simple_extension","1.0");
23 |
24 | // return the extension module
25 | return extension.module();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Examples/ReturnObject/test.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2015 Copernica BV
7 | */
8 |
9 | /**
10 | * Construct master object
11 | * @var Master
12 | */
13 | $master = new Master();
14 |
15 | /**
16 | * Construct derived child object
17 | * @var Child
18 | */
19 | $child1 = new Child();
20 |
21 | /**
22 | * Fetch the child object that is stored as member var in the master
23 | * @var Child
24 | */
25 | $child2 = $master->child();
26 |
27 | /**
28 | * Show output, expected is:
29 | * this is the master
30 | * this is the child
31 | * this is the child
32 | */
33 | echo(strval($master)."\n");
34 | echo(strval($child1)."\n");
35 | echo(strval($child2)."\n");
36 |
37 |
--------------------------------------------------------------------------------
/include/countable.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Countable.h
3 | *
4 | * "Interface" that can be "implemented" by your class. If you do, you
5 | * create your class like this:
6 | *
7 | * class MyClass : public Php::Base, public Php::Countable { ... }
8 | *
9 | * You will have to implement the count() method, which should return the
10 | * number of elements in the object
11 | *
12 | * @author Emiel Bruijntjes
13 | * @copyright 2014 Copernica BV
14 | */
15 |
16 | /**
17 | * Set up namespace
18 | */
19 | namespace Php {
20 |
21 | /**
22 | * Class definition
23 | */
24 | class PHPCPP_EXPORT Countable
25 | {
26 | public:
27 | /**
28 | * Retrieve the number of items in the class
29 | * @return long
30 | */
31 | virtual long count() = 0;
32 |
33 | };
34 |
35 | /**
36 | * End namespace
37 | */
38 | }
39 |
--------------------------------------------------------------------------------
/zend/hashmember.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * HashMember.cpp
3 | *
4 | * @author Emiel Bruijntjes
5 | * @copyright 2013 Copernica BV
6 | */
7 | #include "includes.h"
8 |
9 | /**
10 | * Set up namespace
11 | */
12 | namespace Php {
13 |
14 | /**
15 | * Custom output stream operator
16 | * @param stream
17 | * @param value
18 | * @return ostream
19 | */
20 | std::ostream &operator<<(std::ostream &stream, const HashMember &value)
21 | {
22 | return stream << value.value();
23 | }
24 |
25 | /**
26 | * Custom output stream operator
27 | * @param stream
28 | * @param value
29 | * @return ostream
30 | */
31 | std::ostream &operator<<(std::ostream &stream, const HashMember &value)
32 | {
33 | return stream << value.value();
34 | }
35 |
36 | /**
37 | * End of namespace
38 | */
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/Examples/Globals/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | PHP_CONFIG = php-config
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = globals.so
13 |
14 | PHPINIFILE = 30-globals.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/Examples/Extension/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = extension.so
13 |
14 | PHPINIFILE = 30-phpcpp.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/include/modifiers.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modifiers.h
3 | *
4 | * In this file an enumeration type is with the possible
5 | * member modifiers
6 | *
7 | * @author Martijn Otto
8 | * @copyright 2014 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * The modifiers are constants
18 | */
19 | extern PHPCPP_EXPORT const int Static;
20 | extern PHPCPP_EXPORT const int Abstract;
21 | extern PHPCPP_EXPORT const int Final;
22 | extern PHPCPP_EXPORT const int Public;
23 | extern PHPCPP_EXPORT const int Protected;
24 | extern PHPCPP_EXPORT const int Private;
25 | extern PHPCPP_EXPORT const int Const;
26 |
27 | /**
28 | * Modifiers that are supported for methods and properties
29 | */
30 | extern PHPCPP_EXPORT const int MethodModifiers;
31 | extern PHPCPP_EXPORT const int PropertyModifiers;
32 |
33 | /**
34 | * End namespace
35 | */
36 | }
37 |
--------------------------------------------------------------------------------
/Examples/ConstStaticProp/cpp/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = mytestext.so
13 |
14 | PHPINIFILE = mytestext.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/Examples/FunctionVoid/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = functionvoid.so
13 |
14 | PHPINIFILE = 30-functionvoid.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/Examples/CallPhpFunctions/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = callphpfunction.so
13 |
14 | PHPINIFILE = 30-callphpfunction.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/Examples/Globals/globals.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * An example file to show the working of a void function call.
7 | */
8 |
9 | // we first need to set a number of globals
10 | $b = 10;
11 | $d = function($a,$b,$c) {
12 | return $a+$b+$c;
13 | };
14 |
15 | // fun global var
16 | $e = array(
17 | function($a) {
18 | return $a;
19 | }
20 | );
21 |
22 |
23 | // call the C++ function that will do something
24 | $d = process_globals();
25 |
26 | // the global variable $a should not have the value 1
27 | echo("a = $a\n");
28 |
29 | // the variable $b should not be 11
30 | echo("b = $b\n");
31 |
32 | // $c should be an array with value 200
33 | echo("c['member'] = ".$c['member']."\n");
34 |
35 | // $d is overwritten and now is 6
36 | echo("d = $d\n");
37 |
38 | // e should be replaced by a string
39 | echo("e = $e\n");
--------------------------------------------------------------------------------
/include/exception.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Exception.h
3 | *
4 | * Exception class that can be thrown and caught in C++ space and that
5 | * will end up in or can originate from PHP space.
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2019 Copernica BV
9 | */
10 |
11 | /**
12 | * Include guard
13 | */
14 | #pragma once
15 |
16 | /**
17 | * Begin of namespace
18 | */
19 | namespace Php {
20 |
21 | /**
22 | * Class definition
23 | */
24 | class PHPCPP_EXPORT Exception : public Throwable
25 | {
26 | public:
27 | /**
28 | * Constructor
29 | * @param message
30 | * @param code
31 | */
32 | Exception(const std::string &message, int code = 0) : Throwable(message, code) {}
33 |
34 | /**
35 | * Destructor
36 | */
37 | virtual ~Exception() = default;
38 | };
39 |
40 | /**
41 | * End of namespace
42 | */
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/Examples/Exceptions/ExceptionCatch/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = exceptionCatch.so
13 |
14 | PHPINIFILE = 30-exceptionCatch.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/Examples/Exceptions/ExceptionThrow/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = exceptionThrow.so
13 |
14 | PHPINIFILE = 30-exceptionThrow.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/Examples/FunctionNoParameters/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = functionnoparameters.so
13 |
14 | PHPINIFILE = 30-functionnoparameters.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/Examples/FunctionReturnValue/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = functionreturnvalue.so
13 |
14 | PHPINIFILE = 30-functionreturnvalue.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/Examples/FunctionWithParameters/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
4 |
5 | PREFIX = /usr
6 | #Edit these lines to correspond with your own directories
7 | LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
8 | PHP_CONFIG_DIR = /etc/php5/cli/conf.d
9 |
10 | LD = g++
11 | LD_FLAGS = -Wall -shared -O2
12 | RESULT = functionwithparameters.so
13 |
14 | PHPINIFILE = 30-functionwithparameters.ini
15 |
16 | SOURCES = $(wildcard *.cpp)
17 | OBJECTS = $(SOURCES:%.cpp=%.o)
18 |
19 | all: ${OBJECTS} ${RESULT}
20 |
21 | ${RESULT}: ${OBJECTS}
22 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
23 |
24 | clean:
25 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
26 |
27 | ${OBJECTS}:
28 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
29 |
30 | install:
31 | cp -f ${RESULT} ${LIBRARY_DIR}
32 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
33 |
--------------------------------------------------------------------------------
/include/type.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Type.h
3 | *
4 | * In this file an enumeration type is defined with all supported variable
5 | * types.
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2013 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Supported types for variables
18 | * The values are the same as the ones used internally in Zend
19 | */
20 | enum class PHPCPP_EXPORT Type : unsigned char {
21 | Null = 0, // Null will allow any type
22 | Numeric = 1,
23 | Float = 2,
24 | Bool = 3,
25 | Array = 4,
26 | Object = 5,
27 | String = 6,
28 | Resource = 7,
29 | Constant = 8,
30 | ConstantArray = 9,
31 | Callable = 10
32 | };
33 |
34 | /**
35 | * End of namespace
36 | */
37 | }
38 |
--------------------------------------------------------------------------------
/Examples/EmptyExtension/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /**
4 | * tell the compiler that the get_module is a pure C function
5 | */
6 | extern "C" {
7 |
8 | /**
9 | * Function that is called by PHP right after the PHP process
10 | * has started, and that returns an address of an internal PHP
11 | * strucure with all the details and features of your extension
12 | *
13 | * @return void* a pointer to an address that is understood by PHP
14 | */
15 | PHPCPP_EXPORT void *get_module()
16 | {
17 | // static(!) Php::Extension object that should stay in memory
18 | // for the entire duration of the process (that's why it's static)
19 | static Php::Extension extension("yourextension", "1.0");
20 |
21 | // @todo add your own functions, classes, namespaces to the extension
22 |
23 | // return the extension
24 | return extension;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/CallPhpFunctions/callphpfunction.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * An example file to show the working of a php function call in C++.
7 | */
8 |
9 | class MyClass
10 | {
11 | function method($a,$b,$c)
12 | {
13 | return $a+$b+$c;
14 | }
15 | }
16 |
17 | function myFunction($a,$b,$c)
18 | {
19 | return $a+$b+$c;
20 | }
21 |
22 | /**
23 | * Call a C++ function with a callable PHP function as its parameter.
24 | * The PHP function is then executed from the C++ code.
25 | * The PHP function is this case, adds three numbers.
26 | */
27 | echo(call_php_function(function($a, $b, $c){
28 | return $a + $b + $c;
29 | })."\n");
30 |
31 | echo(call_php_function("myFunction")."\n");
32 |
33 | echo(call_php_function(array(new MyClass(), 'method'))."\n");
34 |
--------------------------------------------------------------------------------
/zend/streams.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Streams.cpp
3 | *
4 | * Implementation of the streams
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2014 Copernica BV
8 | */
9 | #include "includes.h"
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Some static buffers for writing data
18 | * @var StreamBuf
19 | */
20 | static StreamBuf bufOut (0);
21 | static StreamBuf bufError (E_ERROR);
22 | static StreamBuf bufWarning (E_WARNING);
23 | static StreamBuf bufNotice (E_NOTICE);
24 | static StreamBuf bufDeprecated (E_DEPRECATED);
25 |
26 | /**
27 | * Create the actual steams
28 | * @var std::ostream
29 | */
30 | std::ostream out (&bufOut);
31 | std::ostream error (&bufError);
32 | std::ostream warning (&bufWarning);
33 | std::ostream notice (&bufNotice);
34 | std::ostream deprecated (&bufDeprecated);
35 |
36 | /**
37 | * End namespace
38 | */
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/include/classtype.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file classtype.h
3 | *
4 | * Internal class types enumeration.
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2014 Copernica BV
8 | */
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Enumeration definition.
17 | *
18 | * The PHP-CPP library tries to hide the Zend engine internals completely from
19 | * the user. Therefore, it does not include any of the Zend header files, nor
20 | * can it refer to the constants defined in the Zend header files. The
21 | * following constants have been copied from Zend. If the Zend engine ever
22 | * changes (which we do not expect) we should also copy the constant values
23 | * used here.
24 | *
25 | */
26 | enum class PHPCPP_EXPORT ClassType {
27 | Regular = 0x00,
28 | Abstract = 0x20,
29 | Final = 0x40,
30 | Interface = 0x80
31 | };
32 |
33 | /**
34 | * End namespace
35 | */
36 | }
37 |
--------------------------------------------------------------------------------
/Examples/simple/Makefile:
--------------------------------------------------------------------------------
1 | CPP = g++
2 | RM = rm -f
3 | CPP_FLAGS = -Wall -c -I. -I/home/work/include/ -O2 -std=c++11
4 |
5 | PREFIX = /home/work/
6 |
7 | #Edit these lines to correspond with your own directories
8 | LIBRARY_DIR = ${PREFIX}/local/php/lib/php/extensions/no-debug-non-zts-20090626/
9 |
10 | PHP_CONFIG_DIR = /home/work/local/php/lib/
11 |
12 | LD = g++
13 | LD_FLAGS = -Wall -Wl,-rpath,/home/work/lib -shared -O2 -L/home/work/lib
14 | RESULT = simple.so
15 |
16 | PHPINIFILE = 30-phpcpp.ini
17 |
18 | SOURCES = $(wildcard *.cpp)
19 | OBJECTS = $(SOURCES:%.cpp=%.o)
20 |
21 | all: ${OBJECTS} ${RESULT}
22 |
23 | ${RESULT}: ${OBJECTS}
24 | ${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp
25 |
26 | clean:
27 | ${RM} *.obj *~* ${OBJECTS} ${RESULT}
28 |
29 | ${OBJECTS}:
30 | ${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}
31 |
32 | install:
33 | cp -f ${RESULT} ${LIBRARY_DIR}
34 | cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}
35 |
--------------------------------------------------------------------------------
/include/streams.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Streams.h
3 | *
4 | * Just like the standard std::cout and std::cerr objects to output data, you
5 | * can use similar stream objects for outputting data to PHP. Php::out is the
6 | * C++ equivalent of the PHP echo() function, and Php::err() is the C++ stream
7 | * that behaves like calling trigger_error() from PHP.
8 | *
9 | * Php::out << "this is example text" << std::endl;
10 | * Php::err << "this is an error message" << std::endl;
11 | *
12 | * @author Emiel Bruijntjes
13 | * @copyright 2014 Copernica BV
14 | */
15 |
16 | /**
17 | * Set up namespace
18 | */
19 | namespace Php {
20 |
21 | /**
22 | * Define the out and err objects
23 | */
24 | extern PHPCPP_EXPORT std::ostream out;
25 | extern PHPCPP_EXPORT std::ostream error;
26 | extern PHPCPP_EXPORT std::ostream notice;
27 | extern PHPCPP_EXPORT std::ostream warning;
28 | extern PHPCPP_EXPORT std::ostream deprecated;
29 |
30 | /**
31 | * End namespace
32 | */
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/common/modifiers.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Modifiers.cpp
3 | *
4 | * In this file an enumeration type is with the possible
5 | * member modifiers
6 | *
7 | * @author Martijn Otto
8 | * @author Emiel Bruijntjes
9 | *
10 | * @copyright 2014 Copernica BV
11 | */
12 | #include "includes.h"
13 |
14 | /**
15 | * Set up namespace
16 | */
17 | namespace Php {
18 |
19 | /**
20 | * The modifiers are constants
21 | */
22 | const int Static = 0x01;
23 | const int Abstract = 0x02;
24 | const int Final = 0x04;
25 | const int Public = 0x100;
26 | const int Protected = 0x200;
27 | const int Private = 0x400;
28 | const int Const = 0;
29 |
30 | /**
31 | * Modifiers that are supported for methods and properties
32 | */
33 | const int MethodModifiers = Final | Public | Protected | Private | Static;
34 | const int PropertyModifiers = Final | Public | Protected | Private | Const | Static;
35 |
36 | /**
37 | * End namespace
38 | */
39 | }
40 |
--------------------------------------------------------------------------------
/zend/global.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Global.cpp
3 | *
4 | * Implementation for the global variable
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013 Copernica BV
8 | */
9 | #include "includes.h"
10 |
11 | /**
12 | * Namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Function that is called when the value is updated
18 | * @return Value
19 | */
20 | Global &Global::update()
21 | {
22 | // skip if the variable already exists
23 | if (_exists) return *this;
24 |
25 | // we need the TSRMLS variable
26 | TSRMLS_FETCH();
27 |
28 | // add the variable to the globals
29 | zend_hash_add(EG(active_symbol_table), _name.c_str(), _name.size()+1, &_val, sizeof(zval*), NULL);
30 |
31 | // add one extra reference because the variable now is a global var too
32 | Z_ADDREF_P(_val);
33 |
34 | // remember that the variable now exists
35 | _exists = true;
36 |
37 | // done
38 | return *this;
39 | }
40 |
41 | /**
42 | * End of namespace
43 | */
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/Examples/FunctionVoid/functionvoid.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * functionvoid.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of a void function call.
6 | */
7 |
8 | /**
9 | * Libraries used.
10 | */
11 | #include
12 | #include
13 |
14 | /**
15 | * Namespace to use
16 | */
17 | using namespace std;
18 |
19 | /**
20 | * my_function_void()
21 | */
22 | void my_function_void()
23 | {
24 | cout << "In my_function_void()" << endl;
25 | }
26 |
27 |
28 | // Symbols are exported according to the "C" language
29 | extern "C"
30 | {
31 | // export the "get_module" function that will be called by the Zend engine
32 | PHPCPP_EXPORT void *get_module()
33 | {
34 | // create extension
35 | static Php::Extension extension("my_function_void","1.0");
36 |
37 | // add function to extension
38 | extension.add("my_void_function");
39 |
40 | // return the extension module
41 | return extension.module();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Examples/FunctionReturnValue/functionreturnvalue.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * functionreturnvalue.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of a function call with a return value.
6 | */
7 |
8 | /**
9 | * Libraries used.
10 | */
11 | #include
12 |
13 | /**
14 | * Namespace to use
15 | */
16 | using namespace std;
17 |
18 | /**
19 | * my_return_value_function()
20 | * @return Php::Value
21 | */
22 | Php::Value my_return_value_function()
23 | {
24 | return "42";
25 | }
26 |
27 |
28 | // Symbols are exported according to the "C" language
29 | extern "C"
30 | {
31 | // export the "get_module" function that will be called by the Zend engine
32 | PHPCPP_EXPORT void *get_module()
33 | {
34 | // create extension
35 | static Php::Extension extension("my_function_return_value","1.0");
36 |
37 | // add function to extension
38 | extension.add("my_return_value_function");
39 |
40 | // return the extension module
41 | return extension.module();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/include/visibility.h:
--------------------------------------------------------------------------------
1 | /**
2 | * visibility.h
3 | *
4 | * This file defines macros used to define whether a symbol
5 | * should be exported. It is only used for classes and
6 | * functions that are defined in the public API to reduce
7 | * the size of the symbol table, make linking and loading
8 | * of the PHP-CPP library faster and generate more
9 | * optimized code as a result.
10 | *
11 | * @copyright 2015 Copernica B.V.
12 | */
13 |
14 | #if defined _WIN32 || defined __CYGWIN__
15 | #ifdef BUILDING_PHPCPP
16 | #ifdef __GNUC__
17 | #define PHPCPP_EXPORT __attribute__ ((dllexport))
18 | #else
19 | #define PHPCPP_EXPORT __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
20 | #endif
21 | #else
22 | #ifdef __GNUC__
23 | #define DLL_EXPORT __attribute__ ((dllimport))
24 | #else
25 | #define DLL_EXPORT __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
26 | #endif
27 | #endif
28 | #else
29 | #define PHPCPP_EXPORT __attribute__ ((visibility ("default")))
30 | #endif
31 |
--------------------------------------------------------------------------------
/Examples/FunctionNoParameters/functionnoparameters.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * functionnoparameters.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of a function call without parameters.
6 | */
7 |
8 | /**
9 | * Libraries used.
10 | */
11 | #include
12 |
13 | /**
14 | * Namespace to use
15 | */
16 | using namespace std;
17 |
18 | /**
19 | * my_no_parameters_function()
20 | * @return Php::Value
21 | */
22 | Php::Value my_no_parameters_function()
23 | {
24 | return "42";
25 | }
26 |
27 |
28 | // Symbols are exported according to the "C" language
29 | extern "C"
30 | {
31 | // export the "get_module" function that will be called by the Zend engine
32 | PHPCPP_EXPORT void *get_module()
33 | {
34 | // create extension
35 | static Php::Extension extension("my_function_no_parameters","1.0");
36 |
37 | // add function to extension
38 | extension.add("my_no_parameters_function");
39 |
40 | // return the extension module
41 | return extension.module();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/zend/delayedfree.h:
--------------------------------------------------------------------------------
1 | /**
2 | * DelayedFree.h
3 | *
4 | * Sometimes a piece of data must be freed when a function gets out of
5 | * scope. In stead of putting the efree() call right before every possible
6 | * function end point (exceptions, returns, zend_errors()), we can use
7 | * this simple class instead
8 | *
9 | * @author Emiel Bruijntjes
10 | * @copyright 2015 Copernica BV
11 | */
12 |
13 | /**
14 | * Set up namespace
15 | */
16 | namespace Php {
17 |
18 | /**
19 | * Class definition
20 | */
21 | class DelayedFree
22 | {
23 | private:
24 | /**
25 | * The data that has to be free'd when the object falls out of scope
26 | * @var void*
27 | */
28 | void *_data;
29 |
30 | public:
31 | /**
32 | * Constructor
33 | * @param data Data that will be freed on destruction
34 | */
35 | DelayedFree(void *data) : _data(data) {}
36 |
37 | /**
38 | * Destructor
39 | */
40 | virtual ~DelayedFree()
41 | {
42 | // free the data
43 | efree(_data);
44 | }
45 | };
46 |
47 | /**
48 | * End of namespace
49 | */
50 | }
51 |
--------------------------------------------------------------------------------
/zend/functor.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Functor.cpp
3 | *
4 | * Implementation file for the functor class
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2015 Copernica BV
8 | */
9 |
10 | /**
11 | * Dependencies
12 | */
13 | #include "includes.h"
14 |
15 | /**
16 | * Set up namespace
17 | */
18 | namespace Php {
19 |
20 | /**
21 | * The classentry
22 | * @var zend_class_entry
23 | */
24 | zend_class_entry *Functor::_entry = nullptr;
25 |
26 | /**
27 | * Initialize the class
28 | * @param tsrmls
29 | */
30 | void Functor::initialize(TSRMLS_D)
31 | {
32 | // leap out if the class entry is already set
33 | if (_entry) return;
34 |
35 | // construct functor object
36 | static std::unique_ptr functor(new Class("PhpCpp::Functor"));
37 |
38 | // initialize the functor class
39 | _entry = functor->implementation()->initialize(functor.get(), "" TSRMLS_CC);
40 | }
41 |
42 | /**
43 | * Shutdown the class
44 | * @param tsrmls
45 | */
46 | void Functor::shutdown(TSRMLS_D)
47 | {
48 | // we forget the entry
49 | _entry = nullptr;
50 | }
51 |
52 | /**
53 | * End of namespace
54 | */
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/zend/super.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Super.cpp
3 | *
4 | * @copyright 2014 Copernica BV
5 | * @author Emiel Bruijntjes
6 | */
7 | #include "includes.h"
8 |
9 | /**
10 | * Set up namespace
11 | */
12 | namespace Php {
13 |
14 | /**
15 | * A number of super-globals are always accessible
16 | */
17 | Super POST (TRACK_VARS_POST, "_POST");
18 | Super GET (TRACK_VARS_GET, "_GET");
19 | Super COOKIE (TRACK_VARS_COOKIE, "_COOKIE");
20 | Super SERVER (TRACK_VARS_SERVER, "_SERVER");
21 | Super ENV (TRACK_VARS_ENV, "_ENV");
22 | Super FILES (TRACK_VARS_FILES, "_FILES");
23 | Super REQUEST (TRACK_VARS_REQUEST, "_REQUEST");
24 |
25 | /**
26 | * Convert object to a value
27 | * @return Value
28 | */
29 | Value Super::value()
30 | {
31 | // we need the tsrm_ls pointer
32 | TSRMLS_FETCH();
33 |
34 | // call zend_is_auto_global to ensure that the just-in-time globals are loaded
35 | if (_name) { zend_is_auto_global(_name, ::strlen(_name) TSRMLS_CC); _name = nullptr; }
36 |
37 | // create a value object that wraps around the actual zval
38 | return Value(PG(http_globals)[_index]);
39 | }
40 |
41 | /**
42 | * End namespace
43 | */
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/Examples/ReturnObject/master.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Master.h
3 | *
4 | * Class that is exported to PHP space
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2015 Copernica BV
8 | */
9 |
10 | /**
11 | * Include guard
12 | */
13 | #pragma once
14 |
15 | /**
16 | * Dependencies
17 | */
18 | #include "child.h"
19 |
20 | /**
21 | * Class definition
22 | */
23 | class Master : public Php::Base
24 | {
25 | private:
26 | /**
27 | * One child
28 | * @var Php::Value
29 | */
30 | Php::Value _value;
31 |
32 | public:
33 | /**
34 | * Constructor
35 | */
36 | Master()
37 | {
38 | // create a child instance
39 | _value = Php::Object("Child", new Child());
40 | }
41 |
42 | /**
43 | * Destructor
44 | */
45 | virtual ~Master() {}
46 |
47 | /**
48 | * Retrieve the child
49 | * @return Php::Value
50 | */
51 | Php::Value child() const
52 | {
53 | return _value;
54 | }
55 |
56 | /**
57 | * Cast to a string
58 | * @return const char *
59 | */
60 | const char *__toString() const
61 | {
62 | return "this is the master";
63 | }
64 | };
65 |
66 |
--------------------------------------------------------------------------------
/Examples/Exceptions/ExceptionThrow/exceptionThrow.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * exception.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of a C++ function that
6 | * throws an exception, which can be caught by PHP.
7 | *
8 | */
9 |
10 | /**
11 | * Libraries used.
12 | */
13 | #include
14 |
15 | /**
16 | * Namespace to use
17 | */
18 | using namespace std;
19 |
20 | /**
21 | * my_throw_exception_function()
22 | * Throws an exception which should be caught by PHP.
23 | */
24 | void my_throw_exception_function()
25 | {
26 | throw Php::Exception("I threw an exception in my_throw_exception_function()");
27 | }
28 |
29 |
30 | // Symbols are exported according to the "C" language
31 | extern "C"
32 | {
33 | // export the "get_module" function that will be called by the Zend engine
34 | PHPCPP_EXPORT void *get_module()
35 | {
36 | // create extension
37 | static Php::Extension extension("my_exception_throw","1.0");
38 |
39 | // add function to extension
40 | extension.add("my_throw_exception_function");
41 |
42 | // return the extension module
43 | return extension.module();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/include/arrayaccess.h:
--------------------------------------------------------------------------------
1 | /**
2 | * ArrayAccess.h
3 | *
4 | * "Interface" that can be "implemented" by your class. If you do, you
5 | * create your class like this:
6 | *
7 | * class MyClass : public Php::Base, public Php::ArrayAccess { ... }
8 | *
9 | * @author Emiel Bruijntjes
10 | * @copyright 2014 Copernica BV
11 | */
12 |
13 | /**
14 | * Set up namespace
15 | */
16 | namespace Php {
17 |
18 | /**
19 | * Class definition
20 | */
21 | class PHPCPP_EXPORT ArrayAccess
22 | {
23 | public:
24 | /**
25 | * Check if a member is set
26 | * @param key
27 | * @return bool
28 | */
29 | virtual bool offsetExists(const Php::Value &key) = 0;
30 |
31 | /**
32 | * Set a member
33 | * @param key
34 | * @param value
35 | */
36 | virtual void offsetSet(const Php::Value &key, const Php::Value &value) = 0;
37 |
38 | /**
39 | * Retrieve a member
40 | * @param key
41 | * @return value
42 | */
43 | virtual Php::Value offsetGet(const Php::Value &key) = 0;
44 |
45 | /**
46 | * Remove a member
47 | * @param key
48 | */
49 | virtual void offsetUnset(const Php::Value &key) = 0;
50 | };
51 |
52 | /**
53 | * End namespace
54 | */
55 | }
56 |
--------------------------------------------------------------------------------
/include/parameters.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Parameters.h
3 | *
4 | * Wrapper around parameters that are passed to a
5 |
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013 Copernica BV
8 | */
9 |
10 | /**
11 | * Namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Forward declarations
17 | */
18 | class Base;
19 |
20 | /**
21 | * Class definition
22 | */
23 | class PHPCPP_EXPORT Parameters : public std::vector
24 | {
25 | private:
26 | /**
27 | * The base object
28 | * @var Base
29 | */
30 | Base *_object = nullptr;
31 |
32 | protected:
33 | /**
34 | * Protected constructor
35 | *
36 | * The constructor is protected because extension programmers are not
37 | * supposed to instantiate parameters objects themselves
38 | *
39 | * @param object The 'this' object
40 | */
41 | Parameters(Base *object) : _object(object) {}
42 |
43 | public:
44 | /**
45 | * Destructor
46 | */
47 | virtual ~Parameters() {}
48 |
49 | /**
50 | * The object that is being called
51 | * @return Base
52 | */
53 | Base *object() const
54 | {
55 | return _object;
56 | }
57 | };
58 |
59 | /**
60 | * End of namespace
61 | */
62 | }
63 |
--------------------------------------------------------------------------------
/zend/inivalue.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * IniValue.cpp
3 | *
4 | * Class IniValue designed for extracting values from ini entries
5 | *
6 | * @copyright 2013 Copernica BV
7 | */
8 | #include "includes.h"
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Cast to a number
17 | * @return uint64_t
18 | */
19 | int64_t IniValue::numericValue() const
20 | {
21 | return zend_ini_long(const_cast(_name.c_str()), _name.size()+1, _isorig);
22 |
23 | }
24 |
25 | /**
26 | * Get access to the raw buffer for read operationrs.
27 | * @return const char *
28 | */
29 | const char* IniValue::rawValue() const
30 | {
31 | return zend_ini_string(const_cast(_name.c_str()), _name.size()+1, _isorig);
32 | }
33 |
34 | /**
35 | * Cast to a floating point
36 | * @return double
37 | */
38 | IniValue::operator double() const
39 | {
40 | return zend_ini_double(const_cast(_name.c_str()), _name.size()+1, _isorig);
41 | }
42 |
43 | /**
44 | * Custom output stream operator
45 | * @param stream
46 | * @param ini_val
47 | * @return ostream
48 | */
49 | std::ostream &operator<<(std::ostream &stream, const IniValue &ini_val)
50 | {
51 | return stream << static_cast(ini_val);
52 | }
53 |
54 | /**
55 | * End of namespace
56 | */
57 | }
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Examples/ReturnObject/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "master.h"
3 | #include "child.h"
4 |
5 | /**
6 | * tell the compiler that the get_module is a pure C function
7 | */
8 | extern "C" {
9 |
10 | /**
11 | * Function that is called by PHP right after the PHP process
12 | * has started, and that returns an address of an internal PHP
13 | * strucure with all the details and features of your extension
14 | *
15 | * @return void* a pointer to an address that is understood by PHP
16 | */
17 | PHPCPP_EXPORT void *get_module()
18 | {
19 | // static(!) Php::Extension object that should stay in memory
20 | // for the entire duration of the process (that's why it's static)
21 | static Php::Extension extension("returnobjecy", "1.0");
22 |
23 | // we have to class - master and child
24 | Php::Class master("master");
25 | Php::Class child("child");
26 |
27 | // the master class has one method - to return a child
28 | master.method<&Master::child>("child");
29 |
30 | // add all classes to the extension
31 | extension.add(master);
32 | extension.add(child);
33 |
34 | // return the extension
35 | return extension;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Examples/CppClassesInPhp/cppclassinphp.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * An example file to show the working of using a C++ class in PHP.
7 | */
8 |
9 | class TestClass
10 | {
11 | public $x = 1223;
12 |
13 | public function __construct()
14 | {
15 | echo("TestClass::__construct\n");
16 | }
17 |
18 | }
19 |
20 | //create a MyCustomClass object, which is an object of a C++ class
21 | $object1 = new MyClass();
22 |
23 |
24 | $object2 = $object1->myMethod(1);
25 | $object2->myMethod(1);
26 |
27 | echo("unset\n");
28 |
29 | unset($object1);
30 |
31 | echo("got here\n");
32 |
33 | return;
34 |
35 | //echo("prop x: ".$object1->x."\n");
36 |
37 | $object1->x = 10;
38 | $object1->y = 20;
39 |
40 | echo("prop x: ".$object1->x."\n");
41 | echo("prop y: ".$object1->y."\n");
42 |
43 | $object2 = clone $object1;
44 |
45 | echo("prop x: ".$object2->x."\n");
46 | echo("prop y: ".$object2->y."\n");
47 |
48 |
49 | return;
50 |
51 | // run a function of the class
52 | $obj = $object->myMethod("MyClass");
53 |
54 | echo(get_class($obj)."\n");
55 | //echo($obj->format("Y-m-d")."\n");
56 |
57 | //echo($obj->x."\n");
58 |
59 | return;
60 |
61 | //$object->myMethod(2);
62 |
63 | echo($object->property1."\n");
64 | echo($object->property2."\n");
65 |
--------------------------------------------------------------------------------
/include/serializable.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Serializable interface
3 | *
4 | * This interface can be implemented to make an object that can be passed to
5 | * the PHP serialize() and unserialize() methods.
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2014 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class PHPCPP_EXPORT Serializable
20 | {
21 | public:
22 | /**
23 | * Method to serialize the object
24 | *
25 | * This method should return a string representation of the object that
26 | * can be passed to the unserialize() method and that will revive the object
27 | *
28 | * @return std::string
29 | */
30 | virtual std::string serialize() = 0;
31 |
32 | /**
33 | * Unserialize the object
34 | *
35 | * This method is called as an alternative __construct() method to initialize
36 | * the object. The passed in string parameter in in the format earlier returned
37 | * by a call to serialize()
38 | *
39 | * @param input String to parse
40 | * @param size Size of the string
41 | */
42 | virtual void unserialize(const char *input, size_t size) = 0;
43 | };
44 |
45 | /**
46 | * End namespace
47 | */
48 | }
49 |
--------------------------------------------------------------------------------
/zend/streambuf.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * StreamBuf.cpp
3 | *
4 | * Implementation file for the StreamBuf class
5 | *
6 | * @see http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
7 | *
8 | * @author Emiel Bruijntjes
9 | * @copyright 2014 Copernica BV
10 | */
11 | #include "includes.h"
12 |
13 | /**
14 | * Set up namespace
15 | */
16 | namespace Php {
17 |
18 | /**
19 | * Called when the internal buffer should be synchronized
20 | * @return int
21 | */
22 | int StreamBuf::sync()
23 | {
24 | // current buffer size
25 | size_t size = pptr() - pbase();
26 |
27 | // is this the error stream or the regular output stream?
28 | if (_error)
29 | {
30 | // write to error (the zend_error() method is a varargs function,
31 | // which means that we have to include a printf() like format as first
32 | // parameter. We can not specify pbase() directly, because (1) it is
33 | // not null terminated and (2) it could contain % signs and allow all
34 | // sorts of buffer overflows.
35 | zend_error(_error, "%.*s", (int)size, pbase());
36 | }
37 | else
38 | {
39 | // write to zend
40 | zend_write(pbase(), size);
41 | }
42 |
43 | // reset the buffer
44 | pbump(-size);
45 |
46 | // done
47 | return 0;
48 | }
49 |
50 | /**
51 | * End namespace
52 | */
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/include/message.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Errors.h
3 | *
4 | * In this file an enumeration type is defined with all error flags.
5 | *
6 | * @author Toon Schoenmakers
7 | * @copyright 2015 Copernica BV
8 | */
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Supported types of errors, this is mostly a copy from Zend/zend_errors.h
17 | */
18 | enum class PHPCPP_EXPORT Message : int {
19 | Error = (1 << 0L),
20 | Warning = (1 << 1L),
21 | Parse = (1 << 2L),
22 | Notice = (1 << 3L),
23 | CoreError = (1 << 4L),
24 | CoreWarning = (1 << 5L),
25 | CompileError = (1 << 6L),
26 | CompileWarning = (1 << 7L),
27 | UserError = (1 << 8L),
28 | UserWarning = (1 << 9L),
29 | UserNotice = (1 << 10L),
30 | Strict = (1 << 11L),
31 | RecoverableError = (1 << 12L),
32 | Deprecated = (1 << 13L),
33 | UserDeprecated = (1 << 14L),
34 |
35 | Core = (CoreError | CoreWarning),
36 | All = (Error | Warning | Parse | Notice | CoreError | CoreWarning | CompileError | CompileWarning | UserError | UserWarning | UserNotice | RecoverableError | Deprecated | UserDeprecated )
37 | };
38 |
39 | /**
40 | * End of namespace
41 | */
42 | }
43 |
--------------------------------------------------------------------------------
/Examples/ConstStaticProp/cpp/mytestext.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * cppclassinphp.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of using a C++ class in PHP.
6 | */
7 |
8 | #include "mytestext.h"
9 | /**
10 | * Namespace to use
11 | */
12 | using namespace std;
13 |
14 | class MyTestExt : public Php::Base
15 | {
16 |
17 | public:
18 | MyTestExt() {}
19 |
20 | virtual ~MyTestExt() {}
21 |
22 | virtual void __construct() {}
23 |
24 | };
25 |
26 |
27 |
28 | // Symbols are exported according to the "C" language
29 | extern "C"
30 | {
31 | // export the "get_module" function that will be called by the Zend engine
32 | PHPCPP_EXPORT void *get_module()
33 | {
34 | // create extension
35 | static Php::Extension extension("my_test_ext","0.1a");
36 |
37 | // add the custom class ot the extension
38 | extension.add(
39 | "MyTestClass",
40 | Php::Class({
41 |
42 | // Private PHP constructor! You can't instance object of MyTestClass
43 | Php::Private("__construct", Php::Method(&MyTestExt::__construct)),
44 |
45 | Php::Const("version", "v0.01-alpha"),
46 | Php::Const("PI", 3.14159265),
47 | Php::Const("IMISNULL"),
48 | })
49 | );
50 |
51 | // return the extension module
52 | return extension.module();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/zend/nullmember.h:
--------------------------------------------------------------------------------
1 | /**
2 | * NullMember.h
3 | *
4 | * Implementation for a property that is initially set to NULL
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013 Copernica BV
8 | */
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class NullMember : public Member
19 | {
20 | public:
21 | /**
22 | * Constructor
23 | * @param name
24 | * @param flags
25 | */
26 | NullMember(const char *name, int flags) : Member(name, flags) {}
27 |
28 | /**
29 | * Destructor
30 | */
31 | virtual ~NullMember() {}
32 |
33 | /**
34 | * Internal method to declare the property as constant
35 | * @param zend_class_entry
36 | * @param tsrm_ls
37 | */
38 | virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override
39 | {
40 | zend_declare_class_constant_null(entry, _name.c_str(), _name.size() TSRMLS_CC);
41 | }
42 |
43 | /**
44 | * Virtual method to declare the property
45 | * @param entry Class entry
46 | * @param tsrm_ls
47 | */
48 | virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override
49 | {
50 | // char* cast is necessary for php 5.3
51 | zend_declare_property_null(entry, (char *)_name.c_str(), _name.size(), _flags TSRMLS_CC);
52 | }
53 | };
54 |
55 | /**
56 | * End of namespace
57 | */
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/Examples/CallPhpFunctions/callphpfunction.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * callphpfunction.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of a php function call in C++.
6 | */
7 |
8 | /**
9 | * Libraries used.
10 | */
11 | #include
12 | #include
13 |
14 | /**
15 | * Namespace to use
16 | */
17 | using namespace std;
18 |
19 | /**
20 | * call_php_function()
21 | * Calls a function in PHP space.
22 | * @param ¶ms
23 | * @return Php::Value
24 | */
25 | Php::Value call_php_function(Php::Parameters ¶ms)
26 | {
27 | // check whether the parameter is callable
28 | if (!params[0].isCallable()) throw Php::Exception("Not a callable type.");
29 |
30 | // perform the callback
31 | return params[0](1,2,3);
32 | }
33 |
34 |
35 | // Symbols are exported according to the "C" language
36 | extern "C"
37 | {
38 | // export the "get_module" function that will be called by the Zend engine
39 | PHPCPP_EXPORT void *get_module()
40 | {
41 | // create extension
42 | static Php::Extension extension("call_php_function","1.0");
43 |
44 | // add function to extension
45 | extension.add("call_php_function", {
46 | Php::ByVal("addFunc", Php::Type::Callable),
47 | Php::ByVal("x", Php::Type::Numeric)
48 | });
49 |
50 | // return the extension module
51 | return extension.module();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/zend/notimplemented.h:
--------------------------------------------------------------------------------
1 | /**
2 | * NotImplemented.h
3 | *
4 | * Exception that is thrown and catched by the library internally to detect
5 | * if a magic method was implemented or not.
6 | *
7 | * Classes have magic methods (like __unset, __isset, etcetera). These methods
8 | * can be implemented by the extension writer, but they do not have to be.
9 | *
10 | * The default implementation of the methods _could_ be to pass on the method
11 | * to the original Zend engine, but the problem is that the magic methods from
12 | * the PHP-CPP library do not have the same signature as the functions in the
13 | * Zend engine. Passing them on directly is thus not possible.
14 | *
15 | * For that reason, the default implementation throw an exception that is
16 | * immediately caught by the PHP-CPP library, so that it knows that the user
17 | * has not overridden the methods, and the default Zend engine magic method
18 | * can be called instead
19 | *
20 | * @author Emiel Bruijntjes
21 | * @copyright 2014 Copernica BV
22 | */
23 |
24 | /**
25 | * Set up namespace
26 | */
27 | namespace Php {
28 |
29 | /**
30 | * Class definition
31 | */
32 | class NotImplemented : public std::exception
33 | {
34 | public:
35 | /**
36 | * Constructor
37 | */
38 | NotImplemented() : std::exception() {}
39 |
40 | /**
41 | * Destructor
42 | */
43 | virtual ~NotImplemented() throw() {}
44 |
45 | };
46 |
47 | /**
48 | * End namespace
49 | */
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/zend/compileroptions.h:
--------------------------------------------------------------------------------
1 | /**
2 | * CompilerOptions.h
3 | *
4 | * Helper class to temporarily set compiler options
5 | *
6 | * When an object is destructed, it automatically restored the previous compiler settings
7 | *
8 | * @author Emiel Bruijntjes
9 | * @copyright 2014 Copernica BV
10 | */
11 |
12 | /**
13 | * Open PHP namespace
14 | */
15 | namespace Php {
16 |
17 | /**
18 | * Class definition
19 | */
20 | class CompilerOptions
21 | {
22 | private:
23 | /**
24 | * The original compiler options
25 | * @var int
26 | */
27 | zend_uint _original;
28 |
29 | #ifdef ZTS
30 | /**
31 | * When in thread safety mode, we also keep track of the TSRM_LS var
32 | * @var void***
33 | */
34 | void ***tsrm_ls;
35 | #endif
36 |
37 | public:
38 | /**
39 | * Constructor
40 | * @param options
41 | */
42 | CompilerOptions(zend_uint options TSRMLS_DC)
43 | {
44 | // remember the old compiler options before we set temporary compile options
45 | _original = CG(compiler_options);
46 |
47 | // we're going to evaluate only once
48 | CG(compiler_options) = options;
49 |
50 | #ifdef ZTS
51 | // copy tsrm_ls param
52 | this->tsrm_ls = tsrm_ls;
53 | #endif
54 | }
55 |
56 | /**
57 | * Destructor
58 | */
59 | virtual ~CompilerOptions()
60 | {
61 | // restore original options
62 | CG(compiler_options) = _original;
63 | }
64 | };
65 |
66 | /**
67 | * End of namespace
68 | */
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/common/streambuf.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * StreamBuf.cpp
3 | *
4 | * Implementation file for the StreamBuf class
5 | *
6 | * @see http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
7 | *
8 | * @author Emiel Bruijntjes
9 | * @copyright 2014 Copernica BV
10 | */
11 | #include "includes.h"
12 |
13 | /**
14 | * Set up namespace
15 | */
16 | namespace Php {
17 |
18 | /**
19 | * Constructor
20 | * @param error
21 | */
22 | StreamBuf::StreamBuf(int error) : _error(error)
23 | {
24 | // we reserve one byte, so that when overflow is called, we still have one
25 | // byte extra in the buffer to put the overflowed byte int
26 | setp(_buffer, _buffer+1024-1);
27 | }
28 |
29 |
30 | /**
31 | * Method that is called when the internal buffer overflows
32 | * @param c
33 | * @return int
34 | */
35 | int StreamBuf::overflow(int c)
36 | {
37 | // for error buffers, overflow is simply discarded
38 | if (_error) return c;
39 |
40 | // end-of-file has not output, we call EOF directly, and by using the
41 | // comma operator we ensure that EOF is returned
42 | if (c == EOF) return sync(), EOF;
43 |
44 | // because we lied the underlying buffer about the size of the buffer
45 | // by one byte, there is no real overflow, and we can still add the byte
46 | // to the end of the buffer
47 | *pptr() = c;
48 |
49 | // increment buffer size
50 | pbump(1);
51 |
52 | // and now we're going to syn the buffer
53 | return sync() == -1 ? EOF : c;
54 | }
55 |
56 | /**
57 | * End namespace
58 | */
59 | }
60 |
--------------------------------------------------------------------------------
/include/byref.h:
--------------------------------------------------------------------------------
1 | /**
2 | * ByRef.h
3 | *
4 | * Overridden Argument class to specify by-reference function arguments
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013 Copernica BV
8 | */
9 |
10 | /**
11 | * Namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class PHPCPP_EXPORT ByRef : public Argument
19 | {
20 | public:
21 | /**
22 | * Constructor
23 | * @param name Name of the argument
24 | * @param type Argument type
25 | * @param required Is this argument required?
26 | */
27 | ByRef(const char *name, Type type = Type::Null, bool required = true) : Argument(name, type, required, true) {}
28 |
29 | /**
30 | * Constructor
31 | * @param name Name of the argument
32 | * @param classname Name of the class
33 | * @param nullable Can it be null?
34 | * @param required Is this argument required?
35 | */
36 | ByRef(const char *name, const char *classname, bool nullable = false, bool required = true) : Argument(name, classname, nullable, required, true) {}
37 |
38 | /**
39 | * Copy constructor
40 | * @param argument
41 | */
42 | ByRef(const ByRef &argument) : Argument(argument) {}
43 |
44 | /**
45 | * Move constructor
46 | * @param argument
47 | */
48 | ByRef(ByRef &&argument) _NOEXCEPT : Argument(argument) {}
49 |
50 | /**
51 | * Destructor
52 | */
53 | virtual ~ByRef() = default;
54 | };
55 |
56 | /**
57 | * End of namespace
58 | */
59 | }
60 |
--------------------------------------------------------------------------------
/include/byval.h:
--------------------------------------------------------------------------------
1 | /**
2 | * ByVal.h
3 | *
4 | * Overridden Argument class to specify by-value function arguments
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013 Copernica BV
8 | */
9 |
10 | /**
11 | * Namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class PHPCPP_EXPORT ByVal : public Argument
19 | {
20 | public:
21 | /**
22 | * Constructor
23 | * @param name Name of the argument
24 | * @param type Argument type
25 | * @param required Is this argument required?
26 | */
27 | ByVal(const char *name, Type type = Type::Null, bool required = true) : Argument(name, type, required, false) {}
28 |
29 | /**
30 | * Constructor
31 | * @param name Name of the argument
32 | * @param classname Name of the class
33 | * @param nullable Can it be null?
34 | * @param required Is this argument required?
35 | */
36 | ByVal(const char *name, const char *classname, bool nullable = false, bool required = true) : Argument(name, classname, nullable, required, false) {}
37 |
38 | /**
39 | * Copy constructor
40 | * @param argument
41 | */
42 | ByVal(const ByVal &argument) : Argument(argument) {}
43 |
44 | /**
45 | * Move constructor
46 | * @param argument
47 | */
48 | ByVal(ByVal &&argument) _NOEXCEPT : Argument(argument) {}
49 |
50 | /**
51 | * Destructor
52 | */
53 | virtual ~ByVal() = default;
54 | };
55 |
56 | /**
57 | * End of namespace
58 | */
59 | }
60 |
--------------------------------------------------------------------------------
/zend/lowercase.h:
--------------------------------------------------------------------------------
1 | /**
2 | * LowerCase.h
3 | *
4 | * Class to temporary convert a name to lowercase
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2016 Copernica BV
8 | */
9 |
10 | /**
11 | * Include guard
12 | */
13 | #pragma once
14 |
15 | /**
16 | * Begin of namespace
17 | */
18 | namespace Php {
19 |
20 | /**
21 | * Class definition
22 | */
23 | class LowerCase
24 | {
25 | private:
26 | /**
27 | * The lowercase name
28 | * @var char *
29 | */
30 | char *_name;
31 |
32 | public:
33 | /**
34 | * Constructor
35 | * @param name the original name
36 | * @param size size of the name
37 | */
38 | LowerCase(const char *name, size_t size) :
39 | _name(zend_str_tolower_dup(name, size)) {}
40 |
41 | /**
42 | * No copy'ing or moving
43 | * @param that
44 | */
45 | LowerCase(const LowerCase &that) = delete;
46 | LowerCase(LowerCase &&that) = delete;
47 |
48 | /**
49 | * Destructor
50 | */
51 | virtual ~LowerCase()
52 | {
53 | // release the data
54 | efree(_name);
55 | }
56 |
57 | /**
58 | * Expose internal value
59 | * @return const char *
60 | */
61 | const char *value()
62 | {
63 | // expose member
64 | return _name;
65 | }
66 |
67 | /**
68 | * Cast to a char *
69 | * @return char *
70 | */
71 | operator char * ()
72 | {
73 | // expose member
74 | return _name;
75 | }
76 | };
77 |
78 | /**
79 | * End of namespace
80 | */
81 | }
82 |
--------------------------------------------------------------------------------
/zend/boolmember.h:
--------------------------------------------------------------------------------
1 | /**
2 | * BoolMember.h
3 | *
4 | * Implementation for a property that is initially set to a boolean value
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013 Copernica BV
8 | */
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class BoolMember : public Member
19 | {
20 | private:
21 | /**
22 | * The value
23 | * @var bool
24 | */
25 | bool _value;
26 |
27 | public:
28 | /**
29 | * Constructor
30 | * @param name
31 | * @param value
32 | * @param flags
33 | */
34 | BoolMember(const char *name, bool value, int flags) : Member(name, flags), _value(value) {}
35 |
36 | /**
37 | * Destructor
38 | */
39 | virtual ~BoolMember() {}
40 |
41 | /**
42 | * Virtual method to declare a class constant
43 | * @param entry Class entry
44 | * @param tsrm_ls
45 | */
46 | virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override
47 | {
48 | zend_declare_class_constant_bool(entry, _name.c_str(), _name.size(), _value TSRMLS_CC);
49 | }
50 |
51 | /**
52 | * Virtual method to declare the property
53 | * @param entry Class entry
54 | * @param tsrm_ls
55 | */
56 | virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override
57 | {
58 | // char* cast is necessary for php 5.3
59 | zend_declare_property_bool(entry, (char *)_name.c_str(), _name.size(), _value, _flags TSRMLS_CC);
60 | }
61 | };
62 |
63 | /**
64 | * End of namespace
65 | */
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/zend/numericmember.h:
--------------------------------------------------------------------------------
1 | /**
2 | * NumericMember.h
3 | *
4 | * Implementation for a property that is initially set to a numeric value
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013, 2014 Copernica BV
8 | */
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class NumericMember : public Member
19 | {
20 | private:
21 | /**
22 | * The value
23 | * @var long
24 | */
25 | long _value;
26 |
27 | public:
28 | /**
29 | * Constructor
30 | * @param name
31 | * @param value
32 | * @param flags
33 | */
34 | NumericMember(const char *name, long value, int flags) : Member(name, flags), _value(value) {}
35 |
36 | /**
37 | * Destructor
38 | */
39 | virtual ~NumericMember() {}
40 |
41 | /**
42 | * Declare class constant
43 | * @param entry Class entry
44 | * @param tsrm_ls
45 | */
46 | virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override
47 | {
48 | zend_declare_class_constant_long(entry, _name.c_str(), _name.size(), _value TSRMLS_CC);
49 | }
50 |
51 | /**
52 | * Virtual method to declare the property
53 | * @param entry Class entry
54 | * @param tsrm_ls
55 | */
56 | virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override
57 | {
58 | // char* cast is necessary for php 5.3
59 | zend_declare_property_long(entry, (char *)_name.c_str(), _name.size(), _value, _flags TSRMLS_CC);
60 | }
61 | };
62 |
63 | /**
64 | * End of namespace
65 | */
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/zend/ini.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Ini.cpp
3 | *
4 | * Implementation for ....
5 | *
6 | * @copyright 2013 Copernica BV
7 | */
8 | #include "includes.h"
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Filling ini_entries
17 | * @param zend_ini_entry *ini_entry, int module_number
18 | * @param int module_number
19 | */
20 | void Ini::fill(zend_ini_entry *ini_entry, int module_number)
21 | {
22 | ini_entry->module_number = module_number;
23 | ini_entry->modifiable = static_cast(this->_place);
24 | ini_entry->name = const_cast(this->_name.c_str());
25 | ini_entry->name_length = this->_name.size()+1;
26 | ini_entry->on_modify = OnUpdateString;
27 | ini_entry->mh_arg1 = nullptr;
28 | #ifdef ZTS
29 | ini_entry->mh_arg2 = (void *) &phpcpp_globals_id;
30 | #else
31 | ini_entry->mh_arg2 = (void *) &phpcpp_globals;
32 | #endif
33 | ini_entry->mh_arg3 = nullptr;
34 | ini_entry->value = const_cast(this->_value.c_str());
35 | ini_entry->value_length = this->_value.size();
36 | if( this->_orig_empty)
37 | {
38 | ini_entry->orig_value = nullptr;
39 | ini_entry->orig_value_length = 0;
40 | }
41 | else
42 | {
43 | ini_entry->orig_value = const_cast(this->_orig.c_str());
44 | ini_entry->orig_value_length = this->_orig.size();
45 | }
46 | ini_entry->orig_modifiable = 0;
47 | ini_entry->modified = 0;
48 | ini_entry->displayer = nullptr;
49 | }
50 |
51 |
52 | /**
53 | * End of namespace
54 | */
55 | }
56 |
57 |
58 |
--------------------------------------------------------------------------------
/include/globals.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Globals.h
3 | *
4 | * Wrapper object that gives access to all global variables. You
5 | * can use it more or less the same as the $_GLOBALS object in
6 | * PHP.
7 | *
8 | * The global PHP variables are acessible via the Php::globals["varname"]
9 | * variables.
10 | *
11 | * @author Emiel Bruijntjes
12 | * @copyright 2013 Copernica BV
13 | */
14 |
15 | /**
16 | * Set up namespace
17 | */
18 | namespace Php {
19 |
20 | /**
21 | * Forward definitions
22 | */
23 | class Global;
24 |
25 | /**
26 | * Class definition
27 | */
28 | class PHPCPP_EXPORT Globals
29 | {
30 | public:
31 | /**
32 | * Disable copy and move operations
33 | */
34 | Globals(const Globals &globals) = delete;
35 | Globals(Globals &&globals) = delete;
36 |
37 | /**
38 | * Destructor
39 | */
40 | virtual ~Globals() {}
41 |
42 | /**
43 | * Get access to a global variable
44 | * @param name
45 | * @return Global
46 | */
47 | Global operator[](const char *name);
48 |
49 | /**
50 | * Get access to a global variable
51 | * @param name
52 | * @return Global
53 | */
54 | Global operator[](const std::string &name);
55 |
56 | private:
57 | /**
58 | * Constructor
59 | */
60 | Globals() {}
61 |
62 | public:
63 | /**
64 | * Get the one and only instance
65 | * @return Globals
66 | */
67 | static Globals &instance();
68 | };
69 |
70 | /**
71 | * We always have one instance of the GLOBALS instance
72 | * @var Globals
73 | */
74 | extern PHPCPP_EXPORT Globals &GLOBALS;
75 |
76 | /**
77 | * End of namespace
78 | */
79 | }
80 |
--------------------------------------------------------------------------------
/zend/valueiteratorimpl.h:
--------------------------------------------------------------------------------
1 | /**
2 | * ValueIteratorImpl.h
3 | *
4 | * Interface that describes what an implementation of a value iterator should
5 | * look like. This is an internal class that extension developers do not
6 | * need. It is used internally inside the ValueIterator class.
7 | *
8 | * @author Emiel Bruijntjes
9 | * @copyright 2014 Copernica BV
10 | */
11 |
12 | /**
13 | * Set up namespace
14 | */
15 | namespace Php {
16 |
17 | /**
18 | * Class definition
19 | */
20 | class ValueIteratorImpl
21 | {
22 | public:
23 | /**
24 | * Constructor
25 | */
26 | ValueIteratorImpl() {}
27 |
28 | /**
29 | * Destructor
30 | */
31 | virtual ~ValueIteratorImpl() {}
32 |
33 | /**
34 | * Clone the object
35 | * @param tsrm_ls
36 | * @return ValueIteratorImpl*
37 | */
38 | virtual ValueIteratorImpl *clone() = 0;
39 |
40 | /**
41 | * Increment position (pre-increment)
42 | * @param tsrm_ls
43 | * @return bool
44 | */
45 | virtual bool increment() = 0;
46 |
47 | /**
48 | * Decrement position (pre-decrement)
49 | * @return bool
50 | */
51 | virtual bool decrement() = 0;
52 |
53 | /**
54 | * Compare with other iterator
55 | * @param that
56 | * @return bool
57 | */
58 | virtual bool equals(const ValueIteratorImpl *that) const = 0;
59 |
60 | /**
61 | * Derefecence, this returns a std::pair with the current key and value
62 | * @return std::pair
63 | */
64 | virtual const std::pair ¤t() const = 0;
65 | };
66 |
67 | /**
68 | * End namespace
69 | */
70 | }
71 |
72 |
--------------------------------------------------------------------------------
/zend/floatmember.h:
--------------------------------------------------------------------------------
1 | /**
2 | * FloatMember.h
3 | *
4 | * Implementation for a property that is initially set to a boolean value
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013, 2014 Copernica BV
8 | */
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class FloatMember : public Member
19 | {
20 | private:
21 | /**
22 | * The value
23 | * @var double
24 | */
25 | double _value;
26 |
27 | public:
28 | /**
29 | * Constructor
30 | * @param name
31 | * @param value
32 | * @param flags
33 | */
34 | FloatMember(const char *name, double value, int flags) : Member(name, flags), _value(value) {}
35 |
36 | /**
37 | * Destructor
38 | */
39 | virtual ~FloatMember() {}
40 |
41 | /**
42 | * Virtual method to declare class constant
43 | * @param entry Class entry
44 | * @param tsrm_ls
45 | */
46 | virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override
47 | {
48 | zend_declare_class_constant_double(entry, _name.c_str(), _name.size(), _value TSRMLS_CC);
49 | }
50 |
51 | /**
52 | * Virtual method to declare the property
53 | * @param entry Class entry'
54 | * @param tsrm_ls
55 | */
56 | virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override
57 | {
58 | // converstion to char* necessary for php 5.3
59 | zend_declare_property_double(entry, (char *)_name.c_str(), _name.size(), _value, _flags TSRMLS_CC);
60 | }
61 | };
62 |
63 | /**
64 | * End of namespace
65 | */
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/zend/parametersimpl.h:
--------------------------------------------------------------------------------
1 | /**
2 | * ParametersImpl.h
3 | *
4 | * Extended parameters class that can be instantiated
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013 Copernica BV
8 | */
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class ParametersImpl : public Parameters
19 | {
20 | public:
21 | /**
22 | * Constructor
23 | * @param this_ptr Pointer to the object
24 | * @param argc Number of arguments
25 | * @param tsrm_ls
26 | */
27 | ParametersImpl(zval *this_ptr, int argc TSRMLS_DC) : Parameters(this_ptr ? ObjectImpl::find(this_ptr TSRMLS_CC)->object() : nullptr)
28 | {
29 | // reserve plenty of space
30 | reserve(argc);
31 |
32 | // loop through the arguments
33 | for (int i=0; i
8 | * @copyright 2013 Copernica BV
9 | */
10 |
11 | /**
12 | * Namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * The way how PHP C API deals with "global" variables is peculiar.
18 | *
19 | * The following macros are supposed to turn into a structure that is going
20 | * to be instantiated for each parallel running request, and for which the
21 | * PHP engine allocates a certain amount of memory, and a magic pointer that
22 | * is passed and should be forwarded to every thinkable PHP function.
23 | *
24 | * We don't use this architecture. We have our own environment object
25 | * that makes much more sense, and that we use. However, the Zend engine
26 | * expects this structure and this structure to exist.
27 | */
28 | ZEND_BEGIN_MODULE_GLOBALS(phpcpp)
29 | ZEND_END_MODULE_GLOBALS(phpcpp)
30 |
31 | /**
32 | * And now we're going to define a macro. This also is a uncommon architecture
33 | * from PHP to get access to a variable from the structure above.
34 | */
35 | #ifdef ZTS
36 | #define PHPCPP_G(v) TSRMG(phpcpp_globals_id, phpcpp_globals *, v)
37 | #else
38 | #define PHPCPP_G(v) (phpcpp_globals.v)
39 | #endif
40 |
41 | /**
42 | * We're almost there, we now need to declare an instance of the
43 | * structure defined above (if building for a single thread) or some
44 | * sort of impossible to understand magic pointer-to-a-pointer (for
45 | * multi-threading builds). We make this a static variable because
46 | * this already is bad enough.
47 | */
48 | extern ZEND_DECLARE_MODULE_GLOBALS(phpcpp)
49 |
50 | /**
51 | * End of namespace
52 | */
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/zend/member.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Member.h
3 | *
4 | * Base class for properties of a class
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2013, 2014 Copernica BV
8 | */
9 |
10 | /**
11 | * Namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class Member
19 | {
20 | public:
21 | /**
22 | * Constructor
23 | * @param name Name of the member
24 | * @param flags Flag access to a class member (public, protected etc)
25 | */
26 | Member(const char *name, int flags) : _name(name), _flags(flags) {}
27 |
28 | /**
29 | * Destructor
30 | */
31 | virtual ~Member() {}
32 |
33 | /**
34 | * Initialize the member
35 | * @param zend_class_entry
36 | * @param tsrm_ls
37 | */
38 | void initialize(struct _zend_class_entry *entry TSRMLS_DC)
39 | {
40 | if (_flags == Const) constant(entry TSRMLS_CC);
41 | else declare(entry TSRMLS_CC);
42 | }
43 |
44 | protected:
45 | /**
46 | * Internal method to declare the property as constant
47 | * @param zend_class_entry
48 | * @param tsrm_ls
49 | */
50 | virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) = 0;
51 |
52 | /**
53 | * Internal method to declare the property
54 | * @param zend_class_entry
55 | * @param tsrm_ls
56 | */
57 | virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) = 0;
58 |
59 | protected:
60 | /**
61 | * The member name
62 | * @var std::string
63 | */
64 | std::string _name;
65 |
66 | /**
67 | * The member flags
68 | * @var int
69 | */
70 | int _flags;
71 | };
72 |
73 | /**
74 | * End of namespace
75 | */
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/include/error.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Error.h
3 | *
4 | * In PHP7 errors are thrown as Error objects, while in PHP5 errors immediately
5 | * cause a fatal crash. Because the PHP-CPP-LEGACY class only supports PHP5,
6 | * the Error class in this file is thus never thrown from PHP space to C++ space.
7 | *
8 | * But to ensure that an extension can be compiled on PHP5 and PHP7, we have
9 | * still added it to the source code, so that it will not cause compile
10 | * errors.
11 | *
12 | * But you can use it to throw fatal errors.
13 | *
14 | * @author Emiel Bruijntjes
15 | * @copyright 2019 Copernica BV
16 | */
17 |
18 | /**
19 | * Include guard
20 | */
21 | #pragma once
22 |
23 | /**
24 | * Begin of namespace
25 | */
26 | namespace Php {
27 |
28 | /**
29 | * Class definition
30 | */
31 | class PHPCPP_EXPORT Error : public Throwable
32 | {
33 | public:
34 | /**
35 | * Constructor
36 | * @param message
37 | * @param code
38 | */
39 | Error(const std::string &message, int code = 0) : Throwable(message, code) {}
40 |
41 | /**
42 | * Destructor
43 | */
44 | virtual ~Error() = default;
45 |
46 | /**
47 | * Is this a native exception (one that was thrown from C++ code)
48 | * @return bool
49 | */
50 | virtual bool native() const
51 | {
52 | // although it is native, we return 0 because it should not persist
53 | // as exception, but it should live on as zend_error() in stead
54 | return false;
55 | }
56 |
57 | /**
58 | * Report this error as a fatal error
59 | * @return bool
60 | */
61 | virtual bool report() const override;
62 |
63 | };
64 |
65 | /**
66 | * End of namespace
67 | */
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/Examples/Globals/globals.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * functionvoid.cpp
3 | * @author Emiel Bruijntjes
4 | *
5 | * An example file to show how global variables can be accessed
6 | */
7 |
8 | /**
9 | * Libraries used.
10 | */
11 | #include
12 | #include
13 |
14 | /**
15 | * Namespace to use
16 | */
17 | using namespace std;
18 |
19 | /**
20 | * process_globals()
21 | *
22 | * This function reads and modifies global variables
23 | */
24 | Php::Value process_globals()
25 | {
26 | // all global variables can be accessed via the Php::GLOBALS variable,
27 | // which is more or less the same as the PHP $_GLOBALS variable
28 |
29 | // set a global variable
30 | Php::GLOBALS["a"] = 1;
31 |
32 | // increment a global variable
33 | Php::GLOBALS["b"] += 1;
34 |
35 | // set a global variable to be an array
36 | Php::GLOBALS["c"] = Php::Array();
37 |
38 | // add a member to an array
39 | Php::GLOBALS["c"]["member"] = 123;
40 |
41 | // and increment it
42 | Php::GLOBALS["c"]["member"] += 77;
43 |
44 | // change value e
45 | Php::GLOBALS["e"] = Php::GLOBALS["e"][0]("hello");
46 |
47 | // if a global variable holds a function, we can call it
48 | return Php::GLOBALS["d"](1,2,3);
49 | }
50 |
51 | // Symbols are exported according to the "C" language
52 | extern "C"
53 | {
54 | // export the "get_module" function that will be called by the Zend engine
55 | PHPCPP_EXPORT void *get_module()
56 | {
57 | // create extension
58 | static Php::Extension extension("globals","1.0");
59 |
60 | // add function to extension
61 | extension.add("process_globals");
62 |
63 | // return the extension module
64 | return extension.module();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/zend/extensionpath.h:
--------------------------------------------------------------------------------
1 | /**
2 | * ExtensionPath.h
3 | *
4 | * Simply utility class that turns a pathname for an extension into a full
5 | * pathname that also takes the global extension_dir setting into account.
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2015 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class ExtensionPath
20 | {
21 | private:
22 | /**
23 | * The actual value
24 | * @var std::string
25 | */
26 | std::string _path;
27 |
28 | public:
29 | /**
30 | * Constructor
31 | * @param path
32 | */
33 | ExtensionPath(const char *path TSRMLS_DC)
34 | {
35 | // was an absole path given?
36 | if (path[0] && path[0] == '/')
37 | {
38 | // for absolute pathnames no extension_dir has to be checked
39 | _path = path;
40 | }
41 | else
42 | {
43 | // start with the extension dir
44 | _path = PG(extension_dir);
45 |
46 | // append slash
47 | if (_path[_path.size()-1] != '/') _path.push_back('/');
48 |
49 | // and append path passed to the constructor
50 | _path.append(path);
51 | }
52 | }
53 |
54 | /**
55 | * Destructor
56 | */
57 | virtual ~ExtensionPath() {}
58 |
59 | /**
60 | * Cast to string
61 | * @return std::string
62 | */
63 | operator const std::string & () const
64 | {
65 | return _path;
66 | }
67 |
68 | /**
69 | * Cast to const-char*
70 | * @return const char *
71 | */
72 | operator const char * () const
73 | {
74 | return _path.c_str();
75 | }
76 | };
77 |
78 | /**
79 | * End of nmaespace
80 | */
81 | }
82 |
83 |
--------------------------------------------------------------------------------
/zend/invaliditerator.h:
--------------------------------------------------------------------------------
1 | /**
2 | * InvalidIterator.h
3 | *
4 | * Iterator class that is used for value objects that are not even
5 | * iteratable.
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2014 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class InvalidIterator : public ValueIteratorImpl
20 | {
21 | public:
22 | /**
23 | * Clone the object
24 | * @param tsrm_ls
25 | * @return ValueIteratorImpl
26 | */
27 | virtual ValueIteratorImpl *clone()
28 | {
29 | // create a new instance
30 | return new InvalidIterator(*this);
31 | }
32 |
33 | /**
34 | * Increment position (pre-increment)
35 | * @param tsrm_ls
36 | * @return bool
37 | */
38 | virtual bool increment() override
39 | {
40 | return false;
41 | }
42 |
43 | /**
44 | * Decrement position (pre-decrement)
45 | * @return bool
46 | */
47 | virtual bool decrement() override
48 | {
49 | return false;
50 | }
51 |
52 | /**
53 | * Compare with other iterator
54 | * @param that
55 | * @return bool
56 | */
57 | virtual bool equals(const ValueIteratorImpl *that) const override
58 | {
59 | // the other iterator is also an invalid-iterator, and all invalid
60 | // iterators are equal
61 | return true;
62 | }
63 |
64 | /**
65 | * Derefecence, this returns a std::pair with the current key and value
66 | * @return std::pair
67 | */
68 | virtual const std::pair ¤t() const override
69 | {
70 | // this method is never called, when it is, we create a static instance
71 | static std::pair result;
72 |
73 | // return it
74 | return result;
75 | }
76 | };
77 |
78 | /**
79 | * End namespace
80 | */
81 | }
82 |
83 |
--------------------------------------------------------------------------------
/Examples/Exceptions/ExceptionCatch/exceptionCatch.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * exception.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of a C++ function that
6 | * takes a callback function as parameter, and handles the
7 | * exception thrown by the callback function.
8 | */
9 |
10 | /**
11 | * Libraries used.
12 | */
13 | #include
14 | #include
15 |
16 | /**
17 | * Namespace to use
18 | */
19 | using namespace std;
20 |
21 | /**
22 | * my_catch_exception_function()
23 | * Catches the exception thrown by the PHP callback function.
24 | * @param Php::Parameters
25 | */
26 | void my_catch_exception_function(Php::Parameters ¶ms)
27 | {
28 | // the first parameter should be a callback
29 | Php::Value callback = params[0];
30 |
31 | // this must be a callable type
32 | if (!callback.isCallable()) throw Php::Exception("Parameter 0 is not a function");
33 |
34 | // we're going to call a function that could throw an exception, start a
35 | // try-catch block to deal with that
36 | try
37 | {
38 | // call the function
39 | callback("some","example","parameters");
40 | }
41 | catch (Php::Exception &exception)
42 | {
43 | // handle the exception that was thrown from PHP space
44 | std::cout << "exception caught in CPP code" << std::endl;
45 | }
46 | }
47 |
48 |
49 | // Symbols are exported according to the "C" language
50 | extern "C"
51 | {
52 | // export the "get_module" function that will be called by the Zend engine
53 | PHPCPP_EXPORT void *get_module()
54 | {
55 | // create extension
56 | static Php::Extension extension("my_exception_catch","1.0");
57 |
58 | // add function to extension
59 | extension.add("my_catch_exception_function");
60 |
61 | // return the extension module
62 | return extension.module();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/common/streambuf.h:
--------------------------------------------------------------------------------
1 | /**
2 | * StreamBuf.h
3 | *
4 | * PHP output stream buffer which is used by the Php::out object to
5 | * have an output stream just like the regular std::ostream buffers,
6 | * but that sends all output to PHP output
7 | *
8 | * @author Emiel Bruijntjes
9 | * @copyright 2014 Copernica BV
10 | */
11 |
12 | /**
13 | * Set up namespace
14 | */
15 | namespace Php {
16 |
17 | /**
18 | * Issue reported by user on a Windows / Mingw32 platform: EOF was
19 | * not defined. Let's defined it ourselves
20 | */
21 | #ifndef EOF
22 | # define EOF (-1)
23 | #endif
24 |
25 | /**
26 | * Class definition
27 | */
28 | class StreamBuf : public std::streambuf
29 | {
30 | public:
31 | /**
32 | * Constructor
33 | * @param error the error type, or 0 for regular output
34 | */
35 | StreamBuf(int error);
36 |
37 | /**
38 | * No copying or moving
39 | * @param that
40 | */
41 | StreamBuf(const StreamBuf &that) = delete;
42 | StreamBuf(StreamBuf &&that) = delete;
43 |
44 | /**
45 | * Destructor
46 | */
47 | virtual ~StreamBuf() {}
48 |
49 | /**
50 | * No copying or moving
51 | * @param that
52 | */
53 | StreamBuf &operator=(const StreamBuf &that) = delete;
54 | StreamBuf &operator=(StreamBuf &&that) = delete;
55 |
56 | protected:
57 | /**
58 | * Method that is called when the internal buffer overflows
59 | * @param c
60 | * @return int
61 | */
62 | virtual int overflow(int c = EOF) override;
63 |
64 | /**
65 | * Called when the internal buffer should be synchronized
66 | * @return int
67 | */
68 | virtual int sync() override;
69 |
70 | private:
71 | /**
72 | * The error type, or 0 for regular output
73 | * @var int
74 | */
75 | int _error;
76 |
77 | /**
78 | * The internal buffer
79 | * @var char[]
80 | */
81 | char _buffer[1024];
82 | };
83 |
84 | /**
85 | * End namespace
86 | */
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/Examples/DlUnrestricted/dlunrestricted.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * functionvoid.cpp
3 | * @author Jasper van Eck
4 | *
5 | * An example file to show the working of a void function call.
6 | */
7 |
8 | /**
9 | * Libraries used.
10 | */
11 | #include
12 |
13 | /**
14 | * Function to load every possible extension by pathname
15 | *
16 | * It takes one argument: the filename of the PHP extension, and returns a
17 | * boolean to indicate whether the extension was correctly loaded.
18 | *
19 | * This function goes further than the original PHP dl() fuction, because
20 | * it does not check whether the passed in extension object is stored in the
21 | * right directory. Literally every possible extension, also local ones
22 | * created by end users, can be loaded.
23 | *
24 | * @param params Vector of parameters
25 | * @return boolean
26 | */
27 | Php::Value dl_unrestricted(Php::Parameters ¶ms)
28 | {
29 | // get extension name
30 | std::string pathname = params[0];
31 |
32 | // should it be opened persistently?
33 | bool persistent = params.size() > 1 ? params[1].boolValue() : false;
34 |
35 | // load the extension
36 | return Php::dl(pathname, persistent);
37 | }
38 |
39 | /**
40 | * Switch to C context to ensure that the get_module() function
41 | * is callable by C programs (which the Zend engine is)
42 | */
43 | extern "C" {
44 | /**
45 | * Startup function that is called by the Zend engine
46 | * to retrieve all information about the extension
47 | * @return void*
48 | */
49 | PHPCPP_EXPORT void *get_module() {
50 | // create static instance of the extension object
51 | static Php::Extension myExtension("dl_unrestricted", "1.0");
52 |
53 | // the extension has one method
54 | myExtension.add("dl_unrestricted", {
55 | Php::ByVal("pathname", Php::Type::String)
56 | });
57 |
58 | // return the extension
59 | return myExtension;
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/include/throwable.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Throwable
3 | *
4 | * Base class for Php Exceptions.
5 | *
6 | * @author Jasper van Eck
7 | * @copyright 2013 - 2019 Copernica BV
8 | */
9 | #include
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class PHPCPP_EXPORT Throwable : public std::exception
20 | {
21 | private:
22 | /**
23 | * The exception message
24 | * @var char*
25 | */
26 | std::string _message;
27 |
28 | /**
29 | * The PHP exception code
30 | * @var int
31 | */
32 | int _code;
33 |
34 | /**
35 | * Has this exception been processed by native C++ code?
36 | * @var bool
37 | */
38 | bool _processed = false;
39 |
40 | protected:
41 | /**
42 | * Constructor
43 | * @param &string
44 | */
45 | Throwable(const std::string &message, int code = 0) : std::exception(), _message(message), _code(code) {}
46 |
47 | public:
48 | /**
49 | * Destructor
50 | */
51 | virtual ~Throwable() throw() {}
52 |
53 | /**
54 | * Overridden what method
55 | * @return const char *
56 | */
57 | virtual const char *what() const _NOEXCEPT override
58 | {
59 | return _message.c_str();
60 | }
61 |
62 | /**
63 | * Returns the message of the exception.
64 | * @return &string
65 | */
66 | const std::string &message() const throw()
67 | {
68 | return _message;
69 | }
70 |
71 | /**
72 | * Is this a native exception (one that was thrown from C++ code)
73 | * @return bool
74 | */
75 | virtual bool native() const
76 | {
77 | // yes, it is native
78 | return true;
79 | }
80 |
81 | /**
82 | * Report this error as a fatal error
83 | * @return bool
84 | */
85 | virtual bool report() const
86 | {
87 | // this is not done here
88 | return false;
89 | }
90 | };
91 |
92 | /**
93 | * End of namespace
94 | */
95 | }
96 |
--------------------------------------------------------------------------------
/zend/stream.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Stream.cpp
3 | *
4 | * Implementation file for the stream class.
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2019 Copernica BV
8 | */
9 |
10 | /**
11 | * Dependencies
12 | */
13 | #include "includes.h"
14 |
15 | /**
16 | * Begin of namespace
17 | */
18 | namespace Php {
19 |
20 | /**
21 | * Constructor
22 | * @param value value to be wrapped
23 | * @throws std::runtime_error
24 | */
25 | Stream::Stream(const Value &value) : _value(value)
26 | {
27 | // get the stream object
28 | php_stream_from_zval_no_verify(_stream, &_value._val);
29 |
30 | // was this indeed a stream?
31 | if (_stream == nullptr) throw std::runtime_error("variable does not hold a stream");
32 | }
33 |
34 | /**
35 | * Destructor
36 | */
37 | Stream::~Stream() {}
38 |
39 | /**
40 | * Size of the read-buffer (number of bytes that have already been read
41 | * from the underlying filesystem, but that are not yet passed to php space)
42 | * @return size_t
43 | */
44 | size_t Stream::readbuffer() const
45 | {
46 | // do the math
47 | return _stream->writepos - _stream->readpos;
48 | }
49 |
50 | /**
51 | * Get access to the internal filedescriptor
52 | * Note that not every stream is always associated with a filedescriptor,
53 | * in which case this function returns -1
54 | * @return int
55 | */
56 | int Stream::fd() const
57 | {
58 | // the return value
59 | int retval = -1;
60 |
61 | // cast the stream to a filedescriptor, the cast-internal parameter is supposed to be to get
62 | // rid of warnings about buffered data (this code was copied from streamfuncs.c). We use
63 | // "FOR_SELECT" casting, as that is the most simple operations (without "FOR_SELECT" it flushes too)
64 | auto result = php_stream_cast(_stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void **)&retval, 0);
65 |
66 | // on failure we return -1
67 | return result == SUCCESS ? retval : -1;
68 | }
69 |
70 | /**
71 | * End of namespace
72 | */
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/include/iterator.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Iterator.h
3 | *
4 | * Base class for iterators. Extension writers that want to create traversable
5 | * classes, should override the Php::Traversable base class. This base class
6 | * forces you to implement a getIterator() method that returns an instance of
7 | * a Php::Iterator class.
8 | *
9 | * In this file you find the signature of the Php::Iterator class. It mostly has
10 | * pure virtual methods, which means that you should create a derived class
11 | * that implements all these methods.
12 | *
13 | * @author Emiel Bruijntjes
14 | * @copyright 2014 Copernica BV
15 | */
16 |
17 | /**
18 | * Set up namespace
19 | */
20 | namespace Php {
21 |
22 | /**
23 | * Class definition
24 | */
25 | class PHPCPP_EXPORT Iterator
26 | {
27 | public:
28 | /**
29 | * Constructor
30 | * @param base Class over which the iterator is iterating
31 | */
32 | Iterator(Base *base) : _object(base) {}
33 |
34 | /**
35 | * Destructor
36 | */
37 | virtual ~Iterator() {}
38 |
39 | /**
40 | * Is the iterator on a valid position
41 | * @return bool
42 | */
43 | virtual bool valid() = 0;
44 |
45 | /**
46 | * The value at the current position
47 | * @return Value
48 | */
49 | virtual Value current() = 0;
50 |
51 | /**
52 | * The key at the current position
53 | * @return Value
54 | */
55 | virtual Value key() = 0;
56 |
57 | /**
58 | * Move to the next position
59 | */
60 | virtual void next() = 0;
61 |
62 | /**
63 | * Rewind the iterator to the front position
64 | */
65 | virtual void rewind() = 0;
66 |
67 | protected:
68 | /**
69 | * During the lifetime of the iterator, the object over which
70 | * it iterates is keps as a private variable. This ensures that
71 | * this object is not destructed as long as the iterator exists
72 | * @var Value
73 | */
74 | Value _object;
75 |
76 | };
77 |
78 | /**
79 | * End namespace
80 | */
81 | }
82 |
--------------------------------------------------------------------------------
/Examples/CppClassesInPhp/check_map.php:
--------------------------------------------------------------------------------
1 | $offset = $value;
41 | }
42 | }
43 | public function offsetExists($offset) {
44 | return isset($this->$offset);
45 | }
46 | public function offsetUnset($offset) {
47 | unset($this->$offset);
48 | }
49 | public function offsetGet($offset) {
50 | return isset($this->$offset) ? $this->$offset : null;
51 | }
52 |
53 | }
54 |
55 | class emptyClass {}
56 |
57 | $arr = array(
58 | 'qwe' => 'qweqweqweqw',
59 | 'asd' => 'Привет!', // check UTF-8 chars
60 | 'zxccvx' => 'sdfsecvyh6bug6yfty',
61 | 1=>2,
62 | '2'=>2,
63 | 44,
64 | new cl1(),
65 | '%'=>'%$%$%',
66 | );
67 |
68 | $arr = new cl1();
69 |
70 | $arr[5] = 55;
71 | $arr['strstr'] = 'strstrstrstrstrstr';
72 |
73 | //$arr = new emptyClass();
74 | //$arr = array();
75 |
76 |
77 | $q = new MyClass();
78 |
79 | var_export($arr);
80 |
81 | //$q->loopArray($arr);
82 |
83 | // Works for objects and arrays
84 | $q->loopObject($arr);
85 | //$q->loopObject($arr);
86 |
87 |
--------------------------------------------------------------------------------
/zend/functor.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Functor.h
3 | *
4 | * We want to be able to wrap a std::function in an object and pass
5 | * that to PHP. The normal "Closure" class from the Zend engine
6 | * would be very suitable for that. However, the Zend engine does
7 | * not really allow us to add a secret pointer to such closure object.
8 | *
9 | * Therefore, we create our own Closure class, this time using PHP-CPP
10 | * code, to wrap a std::function.
11 | *
12 | * @author Emiel Bruijntjes
13 | * @copyright 2015 Copernica BV
14 | */
15 |
16 | /**
17 | * Set up namespace
18 | */
19 | namespace Php {
20 |
21 | /**
22 | * Class definition
23 | */
24 | class Functor : public Base
25 | {
26 | public:
27 | /**
28 | * Constructor
29 | * @param function The function to wrap
30 | */
31 | Functor(const std::function &function) : _function(function) {}
32 |
33 | /**
34 | * Destructor
35 | */
36 | virtual ~Functor() {}
37 |
38 | /**
39 | * Invoke the functor
40 | * @param params
41 | * @return Value
42 | */
43 | Value __invoke(Parameters ¶ms) const
44 | {
45 | // pass on to the function
46 | return _function(params);
47 | }
48 |
49 | /**
50 | * Get the functor class entry
51 | * @return zend_class_entry
52 | */
53 | static zend_class_entry *entry()
54 | {
55 | // get the "member"
56 | return _entry;
57 | }
58 |
59 | /**
60 | * Initialize the class
61 | * @param tsrmls
62 | */
63 | static void initialize(TSRMLS_D);
64 |
65 | /**
66 | * Shutdown the class
67 | * @param tsrmls
68 | */
69 | static void shutdown(TSRMLS_D);
70 |
71 | private:
72 | /**
73 | * The std::function that is wrapped in PHP code
74 | * @var std::function
75 | */
76 | const std::function _function;
77 |
78 | /**
79 | * The classentry
80 | * @var zend_class_entry
81 | */
82 | static zend_class_entry *_entry;
83 |
84 | };
85 |
86 | /**
87 | * End of namespace
88 | */
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/phpcpp.h:
--------------------------------------------------------------------------------
1 | /**
2 | * phpcpp.h
3 | *
4 | * Library to build PHP extensions with CPP
5 | *
6 | * @copyright 2013 - 2019 Copernica BV
7 | * @author Emiel Bruijntjes
8 | */
9 |
10 | #ifndef PHPCPP_H
11 | #define PHPCPP_H
12 |
13 | /**
14 | * Other C and C++ libraries that PhpCpp depends on
15 | */
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
36 |
37 | If you like, you can use the Php::Namespace utility class for this. This is a
38 | class with exactly the same signature as the Php::Extension class, and
39 | that you can use to register classes and functions too.
40 |
41 |
42 |
#include <phpcpp.h>
43 |
44 | // function that we're going to export
45 | void myFunction()
46 | {
47 | }
48 |
49 | extern "C" {
50 | PHPCPP_EXPORT void *get_module() {
51 |
52 | // create extension object
53 | static Php::Extension extension("my_extension", "1.0");
54 |
55 | // create a namespace
56 | Php::Namespace myNamespace("myNamespace");
57 |
58 | // add the myFunction function to the namespace
59 | myNamespace.add("myFunction", myFunction);
60 |
61 | // @todo add more functions and classes to the namespace
62 |
63 | // create a nested namespace
64 | Php::Namespace nestedNamespace("nestedNamespace");
65 |
66 | // @todo add functions and classes to the nested namespace
67 |
68 | // add the nested namespace to the first namespace
69 | myNamespace.add(std::move(nestedNamespace));
70 |
71 | // add the namespace to the extension
72 | extension.add(std::move(myNamespace));
73 |
74 | // return the extension
75 | return extension;
76 | }
77 | }
78 |
79 |
80 | The Php::Namespace class is just a container that automatically adds a
81 | prefix to all classes and functions that you add to it. Nesting namespaces
82 | is possible too, as you saw in the example.
83 |
84 |
85 | In the example we used the std::move() function to move the nested namespace
86 | into the parent namespace, and to move the first namespace into the extension.
87 | Moving is more efficient that adding, although a regular extension.add(myNamespace)
88 | would have been valid too.
89 |
90 |
--------------------------------------------------------------------------------
/zend/exception_handler.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Exception_handler.cpp
3 | *
4 | * Set the exception handler
5 | *
6 | * @author Toon Schoenmakers
7 | */
8 |
9 | /**
10 | * Dependencies
11 | */
12 | #include "includes.h"
13 |
14 | /**
15 | * Open the PHP namespace
16 | */
17 | namespace Php {
18 |
19 | /**
20 | * Set a std::function as a php exception handler
21 | */
22 | Value set_exception_handler(const std::function &handler)
23 | {
24 | // we need the tsrm_ls variable
25 | TSRMLS_FETCH();
26 |
27 | // create a functor which wraps our callback
28 | Function functor(handler);
29 |
30 | // initialize our output value
31 | Value output;
32 |
33 | // turn our user_exception_handler into a Value so we can return the original one later on
34 | if (EG(user_exception_handler)) output = EG(user_exception_handler);
35 |
36 | // detach so we have the zval
37 | auto value = functor.detach(true);
38 |
39 | // allocate the user_exception_handler
40 | ALLOC_ZVAL(EG(user_exception_handler));
41 |
42 | // copy our zval into the user_exception_handler
43 | MAKE_COPY_ZVAL(&value, EG(user_exception_handler));
44 |
45 | // return the original handler
46 | return output;
47 | }
48 |
49 | /**
50 | * Set a std::function as a php error handler
51 | */
52 | Value set_error_handler(const std::function &handler, Message message)
53 | {
54 | // we need the tsrm_ls variable
55 | TSRMLS_FETCH();
56 |
57 | // create the functor which wraps our callback
58 | Function functor(handler);
59 |
60 | // initialize our output value
61 | Value output;
62 |
63 | // turn our user_error_handler into a Value if we have one, just so we can return it later on
64 | if (EG(user_error_handler)) output = EG(user_error_handler);
65 |
66 | // detach so we have the zval
67 | auto value = functor.detach(true);
68 |
69 | // alocate the user_error_handler
70 | ALLOC_ZVAL(EG(user_error_handler));
71 |
72 | // copy our zval into the user_error_handler
73 | MAKE_COPY_ZVAL(&value, EG(user_error_handler));
74 | EG(user_error_handler_error_reporting) = (int) message;
75 |
76 | // return the original handler
77 | return output;
78 | }
79 |
80 | /**
81 | * Modify the error reporting level, will return the old error reporting level.
82 | */
83 | Value error_reporting(Message message)
84 | {
85 | // we need the tsrm_ls variable
86 | TSRMLS_FETCH();
87 |
88 | // store the old error reporting value
89 | Value output(EG(error_reporting));
90 |
91 | // create a small temporary buffer
92 | char str[21];
93 |
94 | // write the level into this buffer
95 | int size = sprintf(str, "%d", (int) message);
96 |
97 | // if we failed for some reason we bail out
98 | if (size < 0) return false;
99 |
100 | // alter the ini on the fly
101 | zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), str, size, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
102 |
103 | // return the output
104 | return output;
105 | }
106 |
107 | /**
108 | * End of namespace
109 | */
110 | }
111 |
--------------------------------------------------------------------------------
/include/super.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Super.h
3 | *
4 | * The Super class is used to implement one of the super variables $_POST,
5 | * $_GET, $_SERVER, et cetera
6 | *
7 | * @copyright 2014 Copernica BV
8 | * @author Emiel Bruijntjes
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class PHPCPP_EXPORT Super
20 | {
21 | public:
22 | /**
23 | * Constructor
24 | *
25 | * Extension writers do not have to access the super-globals themselves.
26 | * They are always accessible via Php::POST, Php::GET, et cetera.
27 | *
28 | * @param index index number
29 | * @param name name of the variable in PHP
30 | */
31 | Super(int index, const char *name) : _index(index), _name(name) {}
32 |
33 | /**
34 | * Destructor
35 | */
36 | virtual ~Super() {}
37 |
38 | /**
39 | * Array access operator
40 | * This can be used for accessing associative arrays
41 | * @param key
42 | * @return Value
43 | */
44 | Value operator[](const std::string &key)
45 | {
46 | // convert object to a value object, and retrieve the key
47 | return value().get(key);
48 | }
49 |
50 | /**
51 | * Array access operator
52 | * This can be used for accessing associative arrays
53 | * @param key
54 | * @return Value
55 | */
56 | Value operator[](const char *key)
57 | {
58 | // convert object to a value object, and retrieve the key
59 | return value().get(key);
60 | }
61 |
62 | /**
63 | * Casting operator to cast to a value object
64 | * @return Value
65 | */
66 | operator Value ()
67 | {
68 | // we have a private function for this
69 | return value();
70 | }
71 |
72 | /**
73 | * Return an iterator for iterating over the variables
74 | * @return iterator
75 | */
76 | ValueIterator begin()
77 | {
78 | // convert to value, and call begin on the value object
79 | return value().begin();
80 | }
81 |
82 | /**
83 | * Return an iterator for iterating over the variables
84 | * @return iterator
85 | */
86 | ValueIterator end()
87 | {
88 | // convert to value, and call end on that object
89 | return value().end();
90 | }
91 |
92 | private:
93 | /**
94 | * Index number
95 | * @var int
96 | */
97 | int _index;
98 |
99 | /**
100 | * Name of the variable in PHP
101 | * @var name
102 | */
103 | const char *_name;
104 |
105 | /**
106 | * Turn the object into a value object
107 | * @return Value
108 | */
109 | Value value();
110 |
111 | };
112 |
113 | /**
114 | * A number of super-globals are always accessible
115 | */
116 | extern PHPCPP_EXPORT Super POST;
117 | extern PHPCPP_EXPORT Super GET;
118 | extern PHPCPP_EXPORT Super COOKIE;
119 | extern PHPCPP_EXPORT Super SERVER;
120 | extern PHPCPP_EXPORT Super ENV;
121 | extern PHPCPP_EXPORT Super FILES;
122 | extern PHPCPP_EXPORT Super REQUEST;
123 |
124 | /**
125 | * End namespace
126 | */
127 | }
128 |
--------------------------------------------------------------------------------
/zend/constant.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Constant.cpp
3 | *
4 | * Implementation file for the constant class
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2015 Copernica BV
8 | */
9 | #include "includes.h"
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Constructor
18 | * @param name Constant name
19 | * @param value Constant value
20 | */
21 | Constant::Constant(const char *name, std::nullptr_t value) :
22 | _impl(new ConstantImpl(name, value)) {}
23 |
24 | /**
25 | * Constructor
26 | * @param name Constant name
27 | * @param value Constant value
28 | */
29 | Constant::Constant(const char *name, bool value) :
30 | _impl(new ConstantImpl(name, value)) {}
31 |
32 | /**
33 | * Constructor
34 | * @param name Constant name
35 | * @param value Constant value
36 | */
37 | Constant::Constant(const char *name, int32_t value) :
38 | _impl(new ConstantImpl(name, value)) {}
39 |
40 | /**
41 | * Constructor
42 | * @param name Constant name
43 | * @param value Constant value
44 | */
45 | Constant::Constant(const char *name, int64_t value) :
46 | _impl(new ConstantImpl(name, value)) {}
47 |
48 | /**
49 | * Constructor
50 | * @param name Constant name
51 | * @param value Constant value
52 | */
53 | Constant::Constant(const char *name, double value) :
54 | _impl(new ConstantImpl(name, value)) {}
55 |
56 | /**
57 | * Constructor
58 | * @param name Constant name
59 | * @param value Constant value
60 | */
61 | Constant::Constant(const char *name, const char *value) :
62 | _impl(new ConstantImpl(name, value)) {}
63 |
64 | /**
65 | * Constructor
66 | * @param name Constant name
67 | * @param value Constant value
68 | * @param size Value size
69 | */
70 | Constant::Constant(const char *name, const char *value, size_t size) :
71 | _impl(new ConstantImpl(name, value, size)) {}
72 |
73 | /**
74 | * Constructor
75 | * @param name Constant name
76 | * @param value Constant value
77 | */
78 | Constant::Constant(const char *name, const std::string &value) :
79 | _impl(new ConstantImpl(name, value)) {}
80 |
81 | /**
82 | * Add the constant to a class
83 | *
84 | * You normally do not have to call this method yourself. You can simply
85 | * do one of the following method calls to create class constants:
86 | *
87 | * myclass.property("MY_CONSTANT", "value", Php::Const);
88 | * myclass.constant("MY_CONSTANT", "value");
89 | * myclass.add(Php::Constant("MY_CONSTANT", "value"));
90 | *
91 | * All of the calls have the same result, it is up to you to decide which
92 | * one suits you most. If you use the last one - using a Php::Constant
93 | * class - the PHP-CPP library will call this "addTo()" method internally
94 | * to forward the call to one of the other methods.
95 | *
96 | * @param clss Class to which the constant is added
97 | * @internal
98 | */
99 | void Constant::addTo(ClassBase &clss) const
100 | {
101 | // pass on to the implementation
102 | _impl->addTo(clss);
103 | }
104 |
105 | /**
106 | * End of namespace
107 | */
108 | }
109 |
110 |
--------------------------------------------------------------------------------
/include/script.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Script.h
3 | *
4 | * Class that can be used to evaluate a PHP script in the current PHP context.
5 | *
6 | * The difference between directly calling eval() is that the script object
7 | * will first evaluate the string, and then it can be executed multiple times.
8 | *
9 | * @author Emiel Bruijntjes
10 | * @copyright 2014 Copernica BV
11 | */
12 |
13 | /**
14 | * Forward declarations
15 | */
16 | struct _zend_op_array;
17 |
18 | /**
19 | * Set up namespace
20 | */
21 | namespace Php {
22 |
23 | /**
24 | * Forward declarations
25 | */
26 | class Opcodes;
27 |
28 | /**
29 | * Class definition
30 | */
31 | class PHPCPP_EXPORT Script
32 | {
33 | public:
34 | /**
35 | * Constructor
36 | *
37 | * The constructor will not throw any exceptions, even when invalid
38 | * PHP code is passed to it that can not be evaluated. You should call
39 | * the valid() to find out if the script was valid (could be parsed).
40 | *
41 | * @param name Name of the PHP script
42 | * @param source PHP source code to be evaluated
43 | * @param size Length of the source code
44 | */
45 | Script(const char *name, const char *source, size_t size) _NOEXCEPT;
46 |
47 | /**
48 | * Alternative constructor without a size
49 | * @param name Name of the PHP script
50 | * @param source PHP source code to be evaluated
51 | */
52 | Script(const char *name, const char *source) _NOEXCEPT : Script(name, source, ::strlen(source)) {}
53 |
54 | /**
55 | * Alternative constructor without a name
56 | * @param source PHP source code to be evaluated
57 | * @param size Length of the source code
58 | */
59 | Script(const char *source, size_t size) _NOEXCEPT : Script("Unknown", source, size) {}
60 |
61 | /**
62 | * Alternative constructor without a name and without a size
63 | * @param source PHP source code to be evaluated
64 | */
65 | Script(const char *source) _NOEXCEPT : Script("Unknown", source, ::strlen(source)) {}
66 |
67 | /**
68 | * Constructor based on a std::string
69 | * @param source PHP source code to be evaluated
70 | */
71 | Script(const std::string &source) _NOEXCEPT : Script("Unknown", source.c_str(), source.size()) {}
72 |
73 | /**
74 | * Destructor
75 | */
76 | virtual ~Script();
77 |
78 | /**
79 | * Is the script a valid PHP script without syntax errors?
80 | * @return bool
81 | */
82 | bool valid() const;
83 |
84 | /**
85 | * Execute the script
86 | * The return value of the script is returned
87 | * @return Value
88 | */
89 | Value execute() const;
90 |
91 | private:
92 | /**
93 | * The opcodes
94 | * @var Opcodes
95 | */
96 | Opcodes *_opcodes;
97 |
98 | /**
99 | * Helper function to compile the source code
100 | * @param name name of the script
101 | * @param script actual PHP code
102 | * @param size length of the string
103 | * @return opcodes
104 | */
105 | static struct _zend_op_array *compile(const char *name, const char *phpcode, size_t size);
106 |
107 | };
108 |
109 | /**
110 | * End of namespace
111 | */
112 | }
113 |
--------------------------------------------------------------------------------
/include/hashparent.h:
--------------------------------------------------------------------------------
1 | /**
2 | * HashParent.h
3 | *
4 | * Interface that is implemented by all objects that can be accessed with
5 | * array-access variables ([]). When the value of a hash-member is changed,
6 | * it will call one of the methods from this class to set the new property
7 | *
8 | * This is an internal class that you normally not need when writing
9 | * extensions. It is used by the PHP-CPP library when you use constructs
10 | * like value["x"]["y"] = 10;
11 | *
12 | * @author Emiel Bruijntjes
13 | * @copyright 2014 Copernica BV
14 | */
15 |
16 | /**
17 | * Set up namespace
18 | */
19 | namespace Php {
20 |
21 | /**
22 | * Forwards
23 | */
24 | class Value;
25 |
26 | /**
27 | * Class definition
28 | */
29 | class PHPCPP_EXPORT HashParent
30 | {
31 | protected:
32 | /**
33 | * Protected constructor - users should not instantiate HashParent
34 | * objects themselved. Use a Value object instead.
35 | */
36 | HashParent() {}
37 |
38 | public:
39 | /**
40 | * Destructor
41 | */
42 | virtual ~HashParent() {}
43 |
44 | /**
45 | * Check if a certain key exists in the array/object
46 | * @param key
47 | * @return bool
48 | */
49 | virtual bool contains(const std::string &key) const = 0;
50 |
51 | /**
52 | * Check if a certain index exists in the array/object
53 | * @param key
54 | * @return bool
55 | */
56 | virtual bool contains(int index) const = 0;
57 |
58 | /**
59 | * Check if a certain index exists in the array/object
60 | * @param key
61 | * @return bool
62 | */
63 | virtual bool contains(const Value &index) const = 0;
64 |
65 | /**
66 | * Retrieve the value at a string index
67 | * @param key
68 | * @return Value
69 | */
70 | virtual Value get(const std::string &key) const = 0;
71 |
72 | /**
73 | * Retrieve the value at a numeric index
74 | * @param index
75 | * @return Value
76 | */
77 | virtual Value get(int index) const = 0;
78 |
79 | /**
80 | * Retrieve the value at a value index
81 | * @param key
82 | * @return Value
83 | */
84 | virtual Value get(const Value &key) const = 0;
85 |
86 | /**
87 | * Overwrite the value at a certain string index
88 | * @param key
89 | * @param value
90 | */
91 | virtual void set(const std::string &key, const Value &value) = 0;
92 |
93 | /**
94 | * Overwrite the value at a certain numeric index
95 | * @param index
96 | * @param value
97 | */
98 | virtual void set(int index, const Value &value) = 0;
99 |
100 | /**
101 | * Overwrite the value at a certain variant index
102 | * @param key
103 | * @param value
104 | */
105 | virtual void set(const Value &key, const Value &value) = 0;
106 |
107 | /**
108 | * Unset a member by its index
109 | * @param index
110 | */
111 | virtual void unset(int index) = 0;
112 |
113 | /**
114 | * Unset a member by its key
115 | * @param key
116 | */
117 | virtual void unset(const std::string &key) = 0;
118 |
119 | /**
120 | * Unset a member by its key
121 | * @param key
122 | */
123 | virtual void unset(const Value &key) = 0;
124 |
125 | };
126 |
127 | /**
128 | * End namespace
129 | */
130 | }
131 |
--------------------------------------------------------------------------------
/documentation/ini.html:
--------------------------------------------------------------------------------
1 | Reading php.ini variables
2 |
3 | Reading settings from the php.ini file(s) is just as simple as it
4 | is to obtain these settings from a regular PHP script. Inside a PHP script
5 | you can use the built-in ini_get() function to read settings from the php.ini
6 | file, and in your C++ extension you use the Php::ini_get() function.
7 |
8 |
9 |
#include <phpcpp.h>
10 |
11 | /**
12 | * Simple function that is used to demonstrate how settings from the
13 | * php.ini file can be read
14 | */
15 | void myFunction()
16 | {
17 | // read in the "output_buffering" variable from the php.ini file
18 | int output_buffering = Php::ini_get("output_buffering");
19 |
20 | // read in the "variables_order" variable
21 | std::string variables_order = Php::ini_get("variables_order");
22 | }
23 |
24 | /**
25 | * Switch to C contect so that the get_module() function can be
26 | * called by the Zend engine
27 | */
28 | extern "C" {
29 | /**
30 | * The get_module() startup function
31 | * @return void*
32 | */
33 | PHPCPP_EXPORT void *get_module() {
34 |
35 | // create extension object
36 | static Php::Extension extension("my_extension", "1.0");
37 |
38 | // export one function
39 | extension.add("myFunction", myFunction);
40 |
41 | // return a pointer to the extension object
42 | return extension;
43 | }
44 | }
45 |
46 |
47 | The Php::ini_get() function returns an object that can be assigned to
48 | strings, integers and floating point numbers. In the above example we have
49 | used this to assign the settings directly to an integer and a std::string.
50 |
51 |
52 | You can only retrieve predefined variables from the php.ini. It is thus not
53 | possible to call Php::ini_get() with random strings. If you want to use
54 | your own variables, you must first register them in the get_module()
55 | function before you can call Php::ini_get() to retrieve the current values.
56 |
57 |
58 |
#include <phpcpp.h>
59 |
60 | /**
61 | * Simple function that is used to demonstrate how settings from the
62 | * php.ini file can be read
63 | */
64 | void myFunction()
65 | {
66 | // read in a variable defined for this extension
67 | int var1 = Php::ini_get("my_extension.var1");
68 |
69 | // read in a string variable
70 | std::string var2 = Php::ini_get("my_extension.var2");
71 | }
72 |
73 | /**
74 | * Switch to C contect so that the get_module() function can be
75 | * called by the Zend engine
76 | */
77 | extern "C" {
78 | /**
79 | * The get_module() startup function
80 | * @return void*
81 | */
82 | PHPCPP_EXPORT void *get_module() {
83 |
84 | // create extension object
85 | static Php::Extension extension("my_extension", "1.0");
86 |
87 | // export one function
88 | extension.add("myFunction", myFunction);
89 |
90 | // tell the PHP engine that the php.ini variables my_extension.var1
91 | // and my_extension.var2 are usable
92 | extension.add(Php::Ini("my_extension.var1", "default-value"));
93 | extension.add(Php::Ini("my_extension.var2", 12345));
94 |
95 | // return a pointer to the extension object
96 | return extension;
97 | }
98 | }
99 |
100 |
--------------------------------------------------------------------------------
/include/inivalue.h:
--------------------------------------------------------------------------------
1 | /**
2 | * IniValue.h
3 | *
4 | * Class IniValue designed for extracting values from ini entries
5 | *
6 | * @copyright 2014 Copernica BV
7 | */
8 |
9 | /**
10 | * Set up namespace
11 | */
12 | namespace Php {
13 |
14 | /**
15 | * Class IniValue designed for extracting values from ini entries.
16 | */
17 | class PHPCPP_EXPORT IniValue
18 | {
19 | public:
20 | /**
21 | * Constructors
22 | *
23 | * @param name Name of the php.ini variable
24 | * @param isorig Is the original value
25 | */
26 | IniValue(const char *name, const bool isorig) : _name(name), _isorig(isorig) {}
27 |
28 | /**
29 | * Cast to a 16-bit number
30 | * @return int16_t
31 | */
32 | operator int16_t () const
33 | {
34 | return static_cast(numericValue());
35 | }
36 |
37 | /**
38 | * Cast to a 32-bit number
39 | * @return int32_t
40 | */
41 | operator int32_t () const
42 | {
43 | return static_cast(numericValue());
44 | }
45 |
46 | /**
47 | * Cast to a 64-bit number
48 | * @return uint64_t
49 | */
50 | operator int64_t () const
51 | {
52 | return numericValue();
53 | }
54 |
55 | /**
56 | * Cast to a boolean
57 | * @return boolean
58 | */
59 | operator bool () const
60 | {
61 | return boolValue();
62 | }
63 |
64 | /**
65 | * Cast to a string
66 | * @return string
67 | */
68 | operator std::string () const
69 | {
70 | return stringValue();
71 | }
72 |
73 | /**
74 | * Cast to byte array
75 | * @return const char *
76 | */
77 | operator const char * () const
78 | {
79 | return rawValue();
80 | }
81 |
82 | /**
83 | * Cast to a floating point
84 | * @return double
85 | */
86 | operator double() const;
87 |
88 | /**
89 | * Retrieve the value as number
90 | *
91 | * We force this to be a int64_t because we assume that most
92 | * servers run 64 bits nowadays, and because we use int32_t, int64_t
93 | * almost everywhere, instead of 'long' and on OSX neither of
94 | * these intxx_t types is defined as 'long'...
95 | *
96 | * @return int64_t
97 | */
98 | int64_t numericValue() const;
99 |
100 | /**
101 | * Boolean value
102 | * @return bool
103 | */
104 | bool boolValue() const
105 | {
106 | return static_cast(numericValue());
107 | }
108 |
109 | /**
110 | * String value
111 | * @return std::string
112 | */
113 | std::string stringValue() const
114 | {
115 | auto value = rawValue();
116 | return std::string(value ? value : "");
117 | }
118 |
119 | /**
120 | * Get access to the raw buffer for read operations.
121 | * @return const char *
122 | */
123 | const char *rawValue() const;
124 |
125 |
126 | private:
127 |
128 |
129 | /**
130 | * ini entry name
131 | * @var std::string
132 | */
133 | std::string _name;
134 |
135 | /**
136 | * Is the orig value?
137 | * @var bool
138 | */
139 | bool _isorig = false;
140 | };
141 |
142 | /**
143 | * Custom output stream operator
144 | * @param stream
145 | * @param ini_val
146 | * @return ostream
147 | */
148 | PHPCPP_EXPORT std::ostream &operator<<(std::ostream &stream, const IniValue &ini_val);
149 |
150 |
151 | /**
152 | * End of namespace
153 | */
154 | }
155 |
--------------------------------------------------------------------------------
/include/array.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Array.h
3 | *
4 | * The Array is a wrapper around the value class that ensures that a
5 | * certain property always is an array
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2013, 2014 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class PHPCPP_EXPORT Array : public Value
20 | {
21 | public:
22 | /**
23 | * Constructor
24 | */
25 | Array() : Value(Type::Array) {}
26 |
27 | /**
28 | * Copy constructor from a value object
29 | * @param value
30 | */
31 | Array(const Value &value) : Value(value)
32 | {
33 | // type must be valid
34 | if (value.type() != Type::Array) throw Error("Assigning a non-array to an array variable");
35 | }
36 |
37 | /**
38 | * Move constructor from a value object
39 | * @param value
40 | */
41 | Array(Value &&value) : Value(std::move(value))
42 | {
43 | // type must be valid
44 | if (value.type() != Type::Array) throw Error("Moving a non-array to an array variable");
45 | }
46 |
47 | /**
48 | * Constructors from a vector (this will create an array)
49 | * @param value
50 | */
51 | template
52 | Array(const std::vector &input) : Value(input) {}
53 |
54 | /**
55 | * Constructor from a map (this will create an associative array)
56 | * @param value
57 | */
58 | template
59 | Array(const std::map &value) : Value(value) {}
60 |
61 | // old visual c++ environments have no support for initializer lists
62 | # if !defined(_MSC_VER) || _MSC_VER >= 1800
63 |
64 | /**
65 | * Constructor from an initializer list
66 | * @param value
67 | */
68 | Array(const std::initializer_list &value) : Value(value) {}
69 |
70 | // end of visual c++ check
71 | # endif
72 |
73 | /**
74 | * Destructor
75 | */
76 | virtual ~Array() {}
77 |
78 | /**
79 | * Change the internal type of the variable
80 | * @param Type
81 | */
82 | virtual Value &setType(Type type) override
83 | {
84 | // throw exception if things are going wrong
85 | if (type != Type::Array) throw Error("Changing type of a fixed array variable");
86 |
87 | // call base
88 | return Value::setType(Type::Array);
89 | }
90 |
91 | /**
92 | * Assignment operator
93 | * @param value
94 | * @return Array
95 | */
96 | Array &operator=(const Value &value)
97 | {
98 | // skip self assignment
99 | if (this == &value) return *this;
100 |
101 | // type must be valid
102 | if (value.type() != Type::Array) throw Error("Assigning a non-array to a fixed array variable");
103 |
104 | // call base
105 | Value::operator=(value);
106 |
107 | // done
108 | return *this;
109 | }
110 |
111 | /**
112 | * Move assignment operator
113 | * @param value
114 | * @return Array
115 | */
116 | Array &operator=(Value &&value)
117 | {
118 | // skip self assignment
119 | if (this == &value) return *this;
120 |
121 | // type must be valid
122 | if (value.type() != Type::Array) throw Error("Moving a non-array to a fixed array variable");
123 |
124 | // call base
125 | Value::operator=(std::move(value));
126 |
127 | // done
128 | return *this;
129 | }
130 | };
131 |
132 | /**
133 | * End of namespace
134 | */
135 | }
136 |
--------------------------------------------------------------------------------
/zend/zendcallable.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * callable.cpp
3 | *
4 | * A wrapper to handle a callback coming from
5 | * within PHP
6 | *
7 | * @author Martijn Otto
8 | * @copyright 2016 Copernica B.V.
9 | */
10 | #include "includes.h"
11 |
12 | /**
13 | * Start namespace
14 | */
15 | namespace Php {
16 |
17 | /**
18 | * Retrieve pointer to the object
19 | *
20 | * @param this_ptr Pointer to the object we need the C++ instance for
21 | * @return Pointer (as void because this cannot be templated!)
22 | */
23 | Base *ZendCallable::instance(struct _zval_struct *this_ptr)
24 | {
25 | // we need the tsrm_ls variable
26 | TSRMLS_FETCH();
27 |
28 | // find the object implementation and retrieve the base object
29 | return ObjectImpl::find(this_ptr TSRMLS_CC)->object();
30 | }
31 |
32 | /**
33 | * Check whether we have received valid parameters
34 | *
35 | * If this function returns false a warning will have been
36 | * generated and the return value has been set to NULL.
37 | *
38 | * @param return_value The return value to set on failure
39 | */
40 | bool ZendCallable::valid(int provided, struct _zval_struct *return_value)
41 | {
42 | // we need the tsrm_ls variable
43 | TSRMLS_FETCH();
44 |
45 | // how many parameters do we need as a bare minimum?
46 | int required = EG(current_execute_data)->function_state.function->common.required_num_args;
47 |
48 | // if we have the required minimum number of arguments there is no problem
49 | if (provided >= required) return true;
50 |
51 | // retrieve the function name to display the error
52 | auto *name = get_active_function_name(TSRMLS_C);
53 |
54 | // we do not have enough input parameters, show a warning about this
55 | Php::warning << name << "() expects at least " << required << " parameter(s), " << provided << " given" << std::flush;
56 |
57 | // set the return value to NULL
58 | RETVAL_NULL();
59 |
60 | // we are not in a valid state
61 | return false;
62 | }
63 |
64 | /**
65 | * Retrieve the input parameters for the function
66 | *
67 | * @param provided The number of arguments provided
68 | * @param this_ptr The 'this' pointer for the object we are working on
69 | * @return The input parameters
70 | */
71 | Parameters ZendCallable::parameters(int provided, struct _zval_struct *this_ptr)
72 | {
73 | // retrieve the TSRMLS structure
74 | TSRMLS_FETCH();
75 |
76 | // parse and return the parameters
77 | return ParametersImpl{ this_ptr, provided TSRMLS_CC };
78 | }
79 |
80 | /**
81 | * Handle exceptions
82 | *
83 | * @param exception The exception to handle
84 | */
85 | void ZendCallable::handle(Throwable &exception)
86 | {
87 | // we need the tsrm_ls variable
88 | TSRMLS_FETCH();
89 |
90 | // pass it on to the exception handler
91 | process(exception TSRMLS_CC);
92 | }
93 |
94 | /**
95 | * Yield (return) the given value
96 | *
97 | * @param return_value The return_value to set
98 | * @param value The value to return to PHP
99 | */
100 | void ZendCallable::yield(struct _zval_struct *return_value, std::nullptr_t value)
101 | {
102 | // set the return value to null
103 | RETVAL_NULL();
104 | }
105 |
106 | /**
107 | * Yield (return) the given value
108 | *
109 | * @param return_value The return_value to set
110 | * @param value The value to return to PHP
111 | */
112 | void ZendCallable::yield(struct _zval_struct *return_value, Php::Value &&value)
113 | {
114 | // copy the value over to the return value
115 | RETVAL_ZVAL(value._val, 1, 0);
116 | }
117 |
118 | /**
119 | * End namespace
120 | */
121 | }
122 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | PHP-CPP-LEGACY
2 | ==============
3 |
4 | The PHP-CPP-LEGACY library is a fork of the [PHP-CPP library](https://github.com/CopernicaMarketingSoftware/PHP-CPP)
5 | that can be used for old PHP5 deployments. If you no longer use PHP 5.*, we recommend
6 | using the master [PHP-CPP library](https://github.com/CopernicaMarketingSoftware/PHP-CPP) instead.
7 |
8 | The PHP-CPP and PHP-CPP-LEGACY library have an almost identical API. This means that you
9 | can easily port C++ extensions that you wrote for PHP5 to PHP7 (and the other way around).
10 |
11 |
12 | ABOUT
13 | =====
14 |
15 | PHP-CPP-LEGACY is created and maintained by Copernica (www.copernica.com). We write
16 | our code mostly in PHP and C++ and needed an effective way to combine these two
17 | languages. That's where PHP-CPP comes in. Do you appreciate our work and are you
18 | looking for other high quality solutions?
19 |
20 | Then check out our other solutions:
21 |
22 | * PHP-JS (www.php-js.com)
23 | * Copernica Marketing Suite (www.copernica.com)
24 | * MailerQ MTA (www.mailerq.com)
25 | * Responsive Email web service (www.responsiveemail.com)
26 |
27 | The power of PHP-CPP
28 | ====================
29 |
30 | Unlike regular PHP extensions - which are really hard to implement and require a deep
31 | knowledge of the Zend engine and pointer manipulation - extensions built with PHP-CPP
32 | are not difficult to develop at all. In fact, the only thing you need to do is write a function in
33 | C++, and the PHP-CPP library uses all the power offered by C++11 to convert the parameters and return
34 | values from your functions to/and from PHP:
35 |
36 | ```c
37 | Php::Value hello_world()
38 | {
39 | return "hello world!";
40 | }
41 | ```
42 |
43 | The function above is a native C++ function. With PHP-CPP you can export this function
44 | to PHP with only one single C++ method call:
45 |
46 | ```c
47 | extension.add("hello_world", hello_world);
48 | ```
49 |
50 | Working with parameters and return values is just as easy:
51 |
52 | ```c
53 | Php::Value my_plus(Php::Parameters ¶ms)
54 | {
55 | return params[0] + params[1];
56 | }
57 | ```
58 |
59 | The method call to export the above C++ function:
60 |
61 | ```c
62 | extension.add("my_plus", my_plus, {
63 | Php::ByVal("a", Php::numericType),
64 | Php::ByVal("b", Php::numericType)
65 | });
66 | ```
67 |
68 | The PHP-CPP library ensures that the variables
69 | from PHP (which internally are complicated C structures), are automatically converted into
70 | integers, passed to your function, and that the return value of your "my_plus" function is
71 | also converted back into a PHP variable.
72 |
73 | Type conversion between native C/C++ types and PHP variables is handled by PHP-CPP, using
74 | features from the C++11 language. It does not matter if your functions accept strings,
75 | integers, booleans or other native parameters: PHP-CPP takes care of the conversion.
76 | The return value of your function is also transformed by PHP-CPP into PHP.
77 |
78 | More complicated structures can be handled by PHP-CPP as well. If you would like to return
79 | a nested associative array from your function, you can do so too:
80 |
81 | ```c
82 | Php::Value get_complex_array()
83 | {
84 | Php::Value r;
85 | r["a"] = 123;
86 | r["b"] = 456;
87 | r["c"][0] = "nested value";
88 | r["c"][1] = "example";
89 | return r;
90 | }
91 | ```
92 |
93 | The C++ function above is equivalent to the following function in PHP:
94 |
95 | ```php
96 | function get_complex_array()
97 | {
98 | return array(
99 | "a" => 123,
100 | "b" => 456,
101 | "c" => array("nested_value","example")
102 | );
103 | }
104 | ```
105 |
106 | More information and more examples are available on the official website:
107 | http://www.php-cpp.com.
108 |
--------------------------------------------------------------------------------
/zend/nativefunction.h:
--------------------------------------------------------------------------------
1 | /**
2 | * NativeFunction.h
3 | *
4 | * The Function class is an extension of the Callable class that
5 | * forwards the function call directly to a native function in C/C++
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2013-2015 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class NativeFunction : public Callable
20 | {
21 | public:
22 | /**
23 | * Constructor
24 | *
25 | * @param name Function name
26 | * @param function The native C function
27 | */
28 | NativeFunction(const char *name, ZendCallback function, const Arguments &arguments = {}) : Callable(function, name, arguments) {}
29 |
30 | /**
31 | * Constructor
32 | * @param name Function name
33 | * @param function The native C function
34 | */
35 | NativeFunction(const char *name, const native_callback_0 &function, const Arguments &arguments = {}) : Callable(name, arguments), _type(0) { _function.f0 = function; }
36 | NativeFunction(const char *name, const native_callback_1 &function, const Arguments &arguments = {}) : Callable(name, arguments), _type(1) { _function.f1 = function; }
37 | NativeFunction(const char *name, const native_callback_2 &function, const Arguments &arguments = {}) : Callable(name, arguments), _type(2) { _function.f2 = function; }
38 | NativeFunction(const char *name, const native_callback_3 &function, const Arguments &arguments = {}) : Callable(name, arguments), _type(3) { _function.f3 = function; }
39 |
40 | /**
41 | * Copy constructor
42 | * @param that
43 | */
44 | NativeFunction(const NativeFunction &that) : Callable(that), _function(that._function), _type(that._type) {}
45 |
46 | /**
47 | * Move constructor
48 | * @param that
49 | */
50 | NativeFunction(NativeFunction &&that) : Callable(std::move(that)), _function(that._function), _type(that._type) {}
51 |
52 | /**
53 | * Destructor
54 | */
55 | virtual ~NativeFunction() {}
56 |
57 | /**
58 | * Method that gets called every time the function is executed
59 | * @param params The parameters that were passed
60 | * @return Variable Return value
61 | */
62 | virtual Value invoke(Parameters ¶ms) override
63 | {
64 | switch (_type) {
65 | case 0: _function.f0(); return Value();
66 | case 1: _function.f1(params); return Value();
67 | case 2: return _function.f2();
68 | case 3: return _function.f3(params);
69 | default: return Value();
70 | }
71 | }
72 |
73 | /**
74 | * Fill a function entry
75 | * @param prefix Active namespace prefix
76 | * @param entry Entry to be filled
77 | */
78 | void initialize(const std::string &prefix, zend_function_entry *entry)
79 | {
80 | // if there is a namespace prefix, we should adjust the name
81 | if (prefix.size()) _ptr = HiddenPointer(this, prefix+"\\"+(const char *)_ptr);
82 |
83 | // call base initialize
84 | Callable::initialize(entry);
85 | }
86 |
87 | private:
88 | /**
89 | * Union of supported callbacks
90 | * One of the callbacks will be set
91 | */
92 | union {
93 | native_callback_0 f0;
94 | native_callback_1 f1;
95 | native_callback_2 f2;
96 | native_callback_3 f3;
97 | } _function;
98 |
99 | /**
100 | * The callback that is set
101 | * @var integer
102 | */
103 | int _type;
104 | };
105 |
106 | /**
107 | * End of namespace
108 | */
109 | }
110 |
111 |
--------------------------------------------------------------------------------
/documentation/install.html:
--------------------------------------------------------------------------------
1 | How to install PHP-CPP
2 |
3 | Before you can build your own super fast native PHP extension using the
4 | PHP-CPP library, you will first have to install the PHP-CPP library on your
5 | system(s).
6 |
7 |
8 | Luckily, for most of us (those who use Linux or Apple environments), this
9 | will be a piece of cake. If you're on a different platform however, you are
10 | left on your own, because we (as in me, the PHP-CPP developer), only uses
11 | Linux systems. There is however no reason why this library should not also
12 | work on other platforms, because it only uses straight forward C++ code.
13 | Thus, if you are on a different platform and have managed to compile the
14 | library on it, please give us feedback so that we can update these
15 | installation instructions and include other platforms as well.
16 |
17 |
18 | Download
19 |
20 | Installation begins with downloading the source code. You can either
21 | download the latest release from our
22 | download page, or get the
23 | latest bleeding edge work-in-progress version from
24 | GitHub.
25 |
26 |
27 | To get the latest GitHub version, run the following command from the command
28 | line:
29 |
30 |
31 |
git clone https://github.com/CopernicaMarketingSoftware/PHP-CPP.git
32 |
33 |
34 | After you've downloaded the software (either from our website, or directly
35 | from GitHub), change your working directory to the PHP-CPP directory, and open
36 | the file named "Makefile" with your editor of choice.
37 |
38 |
39 | The Makefile is a file that holds settings and instructions for the compiler.
40 | In 96 out of 100 situations, the default settings in this Makefile will
41 | already be perfect for you, but you may want to have a look at it and make
42 | (small) changes to it. You can for example change the installation directory,
43 | and the compiler that is going to be used.
44 |
45 |
46 | After you've checked that all settings in the Makefile are correct, you can
47 | build the software. Do this by running the following command from within
48 | the PHP-CPP directory.
49 |
50 |
51 |
make
52 |
53 |
54 | This will start the compiler and build the library.
55 |
56 |
57 | After you ran 'make', and the PHP-CPP library was built, all that is left to do is
58 | install it on your system. You can use the "make install" command for it.
59 | This command should be executed as root, either by using "sudo", or by
60 | logging on as root first.
61 |
62 |
63 |
sudo make install
64 |
65 |
66 | We've heard reports from some users that when they try to run their first extension,
67 | an error is reported that the "libphpcpp.so" can not be located on their system.
68 | To fix this, you should update the shared library cache on your system. This
69 | can be done with the "ldconfig" command.
70 |
71 |
72 |
sudo make install
73 |
74 |
75 | That was it! After these steps you are now the happy owner of a system with
76 | PHP-CPP installed and nothing can stop you from building your first fast
77 | native PHP extension.
78 |
79 |
80 | Compiling on OSX?
81 |
82 | If you try to compile the software on OSX, you may run into linking and "unresolved
83 | symbol" errors. In that case you should make a change to the Makefile.
84 | Somewhere in the Makefile there is an option "LINKER_FLAGS". This option
85 | should be modified, the flag "-undefined dynamic_lookup" should
86 | be added to it.
87 |
88 |
89 |
--------------------------------------------------------------------------------
/zend/opcodes.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Opcodes.h
3 | *
4 | * Class represents a set of opcodes of a PHP script that can be executed. This
5 | * is an internal file that you normally do not have to instantiate yourself.
6 | * Better use the Php::Script of Php::File classes.
7 | *
8 | * @author Emiel Bruijntjes
9 | * @copyright 2014 Copernica BV
10 | */
11 |
12 | /**
13 | * Forward declarations
14 | */
15 | struct _zend_op_array;
16 |
17 | /**
18 | * Namespace
19 | */
20 | namespace Php {
21 |
22 | /**
23 | * Class definition
24 | */
25 | class Opcodes
26 | {
27 | public:
28 | /**
29 | * Constructor
30 | * @param opcodes
31 | */
32 | Opcodes(struct _zend_op_array *opcodes TSRMLS_DC) : _opcodes(opcodes)
33 | {
34 | #ifdef ZTS
35 | // copy tsrm_ls param
36 | this->tsrm_ls = tsrm_ls;
37 | #endif
38 | }
39 |
40 | /**
41 | * Destructor
42 | */
43 | virtual ~Opcodes()
44 | {
45 | // leap out if opcodes were not valid
46 | if (!_opcodes) return;
47 |
48 | // clean up opcodes
49 | destroy_op_array(_opcodes TSRMLS_CC);
50 | efree(_opcodes);
51 | }
52 |
53 | /**
54 | * Are the opcodes valid?
55 | * @return bool
56 | */
57 | bool valid() const
58 | {
59 | return _opcodes != nullptr;
60 | }
61 |
62 | /**
63 | * Execute the opcodes
64 | * @return Value
65 | */
66 | Value execute() const
67 | {
68 | // if the script could not be compiled, we return null
69 | if (!_opcodes) return nullptr;
70 |
71 | // pointer that is going to hold the return value of the script
72 | zval *retval_ptr = nullptr;
73 |
74 | // the zend engine is probably already busy processing opcodes, so we store
75 | // the current execute state before we're going to switch the runtime to
76 | // our own set of opcodes
77 | ExecuteState execState(0 TSRMLS_CC);
78 |
79 | // old execute state has been saved (and will automatically be restured when
80 | // the oldstate is destructed), so we can now safely overwrite all the settings
81 | EG(return_value_ptr_ptr) = &retval_ptr;
82 | EG(active_op_array) = _opcodes;
83 | EG(no_extensions) = 1;
84 | if (!EG(active_symbol_table)) zend_rebuild_symbol_table(TSRMLS_C);
85 | CG(interactive) = 0;
86 |
87 | // the current exception
88 | zval* oldException = EG(exception);
89 |
90 | // execute the code
91 | zend_execute(_opcodes TSRMLS_CC);
92 |
93 | // was an exception thrown inside the eval()'ed code? In that case we
94 | // throw a C++ new exception to give the C++ code the chance to catch it
95 | if (oldException != EG(exception) && EG(exception)) throw OrigException(EG(exception) TSRMLS_CC);
96 |
97 | // we're ready if there is no return value
98 | if (!retval_ptr) return nullptr;
99 |
100 | // wrap the return value
101 | Value result(retval_ptr);
102 |
103 | // destruct the zval (this function will decrement the reference counter,
104 | // and only destruct if there are no other references left)
105 | zval_ptr_dtor(&retval_ptr);
106 |
107 | // copy the pointer into a value object, and return that
108 | return result;
109 | }
110 |
111 | private:
112 | /**
113 | * The opcodes
114 | * @var zend_op_array
115 | */
116 | struct _zend_op_array *_opcodes;
117 |
118 | #ifdef ZTS
119 | /**
120 | * When in thread safety mode, we also keep track of the TSRM_LS var
121 | * @var void***
122 | */
123 | void ***tsrm_ls;
124 | #endif
125 |
126 | };
127 |
128 | /**
129 | * End of namespace
130 | */
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/zend/property.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Property.h
3 | *
4 | * Internal class for properties that are defined with a getter and setter method
5 | *
6 | * @author Emiel Bruijntjes
7 | * @copyright 2014 Copernica BV
8 | */
9 |
10 | /**
11 | * Set up namespace
12 | */
13 | namespace Php {
14 |
15 | /**
16 | * Class definition
17 | */
18 | class Property
19 | {
20 | private:
21 | /**
22 | * The getter
23 | * @var getter_callback
24 | */
25 | union {
26 | getter_callback_0 g0;
27 | getter_callback_1 g1;
28 | } _getter;
29 |
30 | /**
31 | * The setter
32 | * @var setter_callback
33 | */
34 | union {
35 | setter_callback_0 s0;
36 | setter_callback_1 s1;
37 | } _setter;
38 |
39 | /**
40 | * Type of getter
41 | * @var char
42 | */
43 | int _gtype = 0;
44 |
45 | /**
46 | * Type of setter
47 | * @var char
48 | */
49 | int _stype = 100;
50 |
51 | public:
52 | /**
53 | * Constructor
54 | * @param getter
55 | * @param setter
56 | */
57 | Property(const getter_callback_0 &getter) : _gtype(0)
58 | {
59 | _getter.g0 = getter;
60 | }
61 |
62 | /**
63 | * Constructor
64 | * @param getter
65 | * @param setter
66 | */
67 | Property(const getter_callback_1 &getter) : _gtype(1)
68 | {
69 | _getter.g1 = getter;
70 | }
71 |
72 |
73 | /**
74 | * Constructor
75 | * @param getter
76 | * @param setter
77 | */
78 | Property(const getter_callback_0 &getter, const setter_callback_0 &setter) : _gtype(0), _stype(0)
79 | {
80 | _getter.g0 = getter;
81 | _setter.s0 = setter;
82 | }
83 |
84 | /**
85 | * Constructor
86 | * @param getter
87 | * @param setter
88 | */
89 | Property(const getter_callback_1 &getter, const setter_callback_0 &setter) : _gtype(1), _stype(0)
90 | {
91 | _getter.g1 = getter;
92 | _setter.s0 = setter;
93 | }
94 |
95 | /**
96 | * Constructor
97 | * @param getter
98 | * @param setter
99 | */
100 | Property(const getter_callback_0 &getter, const setter_callback_1 &setter) : _gtype(0), _stype(1)
101 | {
102 | _getter.g0 = getter;
103 | _setter.s1 = setter;
104 | }
105 |
106 | /**
107 | * Constructor
108 | * @param getter
109 | * @param setter
110 | */
111 | Property(const getter_callback_1 &getter, const setter_callback_1 &setter) : _gtype(1), _stype(1)
112 | {
113 | _getter.g1 = getter;
114 | _setter.s1 = setter;
115 | }
116 |
117 | /**
118 | * Copy constructor
119 | * @param that
120 | */
121 | Property(const Property &that) :
122 | _getter(that._getter), _setter(that._setter), _gtype(that._gtype), _stype(that._stype) {}
123 |
124 | /**
125 | * Destructor
126 | */
127 | virtual ~Property() {}
128 |
129 | /**
130 | * Get the property
131 | * @param base Object to call it on
132 | * @return Value
133 | */
134 | Value get(Base *base)
135 | {
136 | if (_gtype == 0) return (base->*_getter.g0)();
137 | else return (base->*_getter.g1)();
138 | }
139 |
140 | /**
141 | * Set the property
142 | * @param base Object to call it on
143 | * @param value New value
144 | * @return bool
145 | */
146 | bool set(Base *base, const Value &value)
147 | {
148 | switch (_stype) {
149 | case 0: (base->*_setter.s0)(value); return true;
150 | case 1: (base->*_setter.s1)(value); return true;
151 | default: return false;
152 | }
153 | }
154 | };
155 |
156 | /**
157 | * End of namespace
158 | */
159 | }
160 |
161 |
--------------------------------------------------------------------------------
/zend/origexception.h:
--------------------------------------------------------------------------------
1 | /**
2 | * OrigException.h
3 | *
4 | * Class that wraps around an exception that was thrown by PHP code,
5 | * and that could - but not necessarily has to - be caught by C++
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2013 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class OrigException : public Value, public Exception
20 | {
21 | private:
22 | /**
23 | * Is this a an exception that was caught by extension C++ code.
24 | *
25 | * When the object is initially created, we assume that it will be caught
26 | * by C++ code. If it later turns out that the PHP-CPP can catch this
27 | * exception after the extension C++ code ran, the variable is set back
28 | * to false.
29 | *
30 | * @var bool
31 | */
32 | bool _handled = true;
33 |
34 | #ifdef ZTS
35 | /**
36 | * When we run in multi-thread mode, we store the thread handle
37 | * @var void***
38 | */
39 | TSRMLS_D;
40 | #endif
41 |
42 | public:
43 | /**
44 | * Constructor
45 | * @param val
46 | */
47 | OrigException(zval *val TSRMLS_DC) :
48 | Value(val), Exception("OrigException")
49 | {
50 | #ifdef ZTS
51 | // copy tsrm_ls
52 | this->TSRMLS_C = TSRMLS_C;
53 | #endif
54 | }
55 |
56 | /**
57 | * Copy constructor
58 | * @param exception
59 | */
60 | OrigException(const OrigException &exception) :
61 | Value(exception), Exception("OrigException"), _handled(exception._handled)
62 | {
63 | #ifdef ZTS
64 | // copy tsrm_ls
65 | TSRMLS_C = exception.TSRMLS_C;
66 | #endif
67 | }
68 |
69 | /**
70 | * Move constructor
71 | * @param exception
72 | */
73 | OrigException(OrigException &&exception) :
74 | Value(std::move(exception)), Exception("OrigException"), _handled(exception._handled)
75 | {
76 | // set other exception to handled so that it wont do anything on destruction
77 | exception._handled = true;
78 |
79 | #ifdef ZTS
80 | // copy tsrm_ls
81 | TSRMLS_C = exception.TSRMLS_C;
82 | #endif
83 | }
84 |
85 | /**
86 | * Destructor
87 | */
88 | virtual ~OrigException() throw()
89 | {
90 | // if the exception was not handled by C++ code, we're not going to do anything
91 | // and the exception stays active
92 | if (!_handled) return;
93 |
94 | // the exception was handled, so we should clean it up
95 | zend_clear_exception(TSRMLS_C);
96 | }
97 |
98 | /**
99 | * This is _not_ a native exception, it was thrown by a PHP script
100 | * @return bool
101 | */
102 | virtual bool native() const override
103 | {
104 | return false;
105 | }
106 |
107 | /**
108 | * Reactivate the exception
109 | */
110 | void reactivate()
111 | {
112 | // it was not handled by extension C++ code
113 | _handled = false;
114 | }
115 | };
116 |
117 | /**
118 | * Global function to process an exception
119 | * @param exception
120 | * @param tsrm_ls
121 | */
122 | inline void process(Throwable &exception TSRMLS_DC)
123 | {
124 | // is this a native exception?
125 | if (exception.native())
126 | {
127 | // the exception is native, call the zend throw method
128 | zend_throw_exception(zend_exception_get_default(TSRMLS_C), (char *)exception.what(), 0 TSRMLS_CC);
129 | }
130 |
131 | // or does it have its own report function?
132 | else if (!exception.report())
133 | {
134 | // this is not a native exception, so it was originally thrown by a
135 | // php script, and then not caught by the c++ of the extension, we are
136 | // going to tell to the exception that it is still active
137 | OrigException &orig = static_cast(exception);
138 |
139 | // reactive the exception
140 | orig.reactivate();
141 | }
142 | }
143 |
144 | /**
145 | * End of namespace
146 | */
147 | }
148 |
--------------------------------------------------------------------------------
/common/extensionbase.h:
--------------------------------------------------------------------------------
1 | /**
2 | * ExtensionBase.h
3 | *
4 | * Base class for ExtensionImpl objects. Common code used by both the Zend
5 | * and HHVM engine.
6 | *
7 | * @author Emiel Bruijntjes
8 | * @copyright 2013, 2014 Copernica BV
9 | */
10 |
11 | /**
12 | * Set up namespace
13 | */
14 | namespace Php {
15 |
16 | /**
17 | * Class definition
18 | */
19 | class ExtensionBase
20 | {
21 | protected:
22 | /**
23 | * Pointer to the extension object that is filled by the extension programmer
24 | * @var Extension
25 | */
26 | Extension *_data;
27 |
28 | /**
29 | * Callback that is called after the engine is initialized and before the
30 | * pageviews are going to be handled
31 | * @var Callback
32 | */
33 | Callback _onStartup;
34 |
35 | /**
36 | * Callback that is called in front of each request
37 | * @var Callback
38 | */
39 | Callback _onRequest;
40 |
41 | /**
42 | * Callback that is called right after each request
43 | * @var Callback
44 | */
45 | Callback _onIdle;
46 |
47 | /**
48 | * Callback that is called right before the engine is closing down
49 | * @var Callback
50 | */
51 | Callback _onShutdown;
52 |
53 | public:
54 | /**
55 | * Constructor
56 | * @param data Extension object created by the extension programmer
57 | */
58 | ExtensionBase(Extension *data) : _data(data) {}
59 |
60 | /**
61 | * No copy'ing and no moving
62 | */
63 | ExtensionBase(const ExtensionImpl &extension) = delete;
64 | ExtensionBase(ExtensionImpl &&extension) = delete;
65 |
66 | /**
67 | * Destructor
68 | */
69 | virtual ~ExtensionBase() {}
70 |
71 | /**
72 | * Register a function to be called when the PHP engine is ready
73 | *
74 | * The callback will be called after all extensions are loaded, and all
75 | * functions and classes are available, but before the first pageview/request
76 | * is handled. You can register this callback if you want to be notified
77 | * when the engine is ready, for example to initialize certain things.
78 | *
79 | * @param callback
80 | */
81 | void onStartup(const Callback &callback)
82 | {
83 | // copy callback
84 | _onStartup = callback;
85 | }
86 |
87 | /**
88 | * Register a function to be called when the PHP engine is going to stop
89 | *
90 | * The callback will be called right before the process is going to stop.
91 | * You can register a function if you want to clean up certain things.
92 | *
93 | * @param callback
94 | */
95 | void onShutdown(const Callback &callback)
96 | {
97 | // copy callback
98 | _onShutdown = callback;
99 | }
100 |
101 | /**
102 | * Register a callback that is called at the beginning of each pageview/request
103 | *
104 | * You can register a callback if you want to initialize certain things
105 | * at the beginning of each request. Remember that the extension can handle
106 | * multiple requests after each other, and you may want to set back certain
107 | * global variables to their initial variables in front of each request
108 | *
109 | * @param callback
110 | */
111 | void onRequest(const Callback &callback)
112 | {
113 | // copy callback
114 | _onRequest = callback;
115 | }
116 |
117 | /**
118 | * Register a callback that is called to cleanup things after a pageview/request
119 | *
120 | * The callback will be called after _each_ request, so that you can clean up
121 | * certain things and make your extension ready to handle the next request.
122 | * This method is called onIdle because the extension is idle in between
123 | * requests.
124 | *
125 | * @param callback
126 | */
127 | void onIdle(const Callback &callback)
128 | {
129 | // copy callback
130 | _onIdle = callback;
131 | }
132 | };
133 |
134 | /**
135 | * End of namespace
136 | */
137 | }
138 |
139 |
--------------------------------------------------------------------------------