copernicamarketingsoftware / php-cpp Goto Github PK
View Code? Open in Web Editor NEWLibrary to build PHP extensions with C++
Home Page: http://www.php-cpp.com/
License: Apache License 2.0
Library to build PHP extensions with C++
Home Page: http://www.php-cpp.com/
License: Apache License 2.0
Heeeeey Emiel.
Welcome to the world of open source software (or in short, OSS).
So, here's a tip. Try implementing continues integration (CI) for your projects. It's free!
When you have two extensions written using PHP-CPP and you both add them to your PHP configuration (php.ini):
Any PHP code that uses functionality from one of the loaded extensions will crash when execution ends. The crash happends in extension.cpp in the request_shutdown
method, on the following line:;
bool success = extension->endRequest(*environment) && environment->finalize();
This crash is occurs because extension
is a NULL pointer. Somehow, something goes wrong when loading two extensions. When I only use one, everything seems to be alright.
I'm still researching the issue.
When you create your own custom class, you extend from Php::Base. However, inside the methods you do not yet have access to the PHP object as it is seen from user space, so there is no way to update the properties of the object in this method.
Under the hood, the Zend engine passes a this_ptr to every method call, and this pointer is also passed to the Php::Parameters object that is passed to every method call. So we could add a Parameter::self() method to retrieve the Php::Value object that represents the object being called.
However, this Php::Parameters method is not always available (methods are not required to accept parameters), and it would be more logical from an API point of view if the 'this' pointer was not passed in as a parameter, but would always be accessible from custom classes.
Problem: if you added a _self member variable to the Php::Base class, every object would hold a reference to itself, and the refcount would never reach zero, and objects would therefore never get destructed. A smarter solution is thus necessary. My suggestion:
class MyClass : public Php::Base
{
public:
void myMethod()
{
// get access to ourselves
Php::Object self(this);
// update a public property
self["prop1"] = 1234;
}
};
This is a public issue. I will eventually solve this myself, but since my time is limited and this is an open source project, it would be cool if someone could help me with this.
PHP 5.4.4-14+deb7u5
gcc version 4.7.2 (Debian 4.7.2-5)
Error:
g++ -Wall -c php-config --includes
-g -std=c++11 -fpic -o src/argument.o src/argument.cpp
In file included from src/includes.h:94:0,
from src/argument.cpp:9:
src/traverseiterator.h: In member function ‘bool Php::TraverseIterator::read()’:
src/traverseiterator.h:186:64: error: cannot convert ‘zval_struct’ to ‘char__’ in argument passing
make: *_* [src/argument.o] Error 1
I saw that you have implemented the support of static functions. But the corresponding modifier is missing.
Also, I noticed that the super global variables are not working like it should:
php: $_GET['var'] == 5
c++: std::string var = "var";
auto get = Php::GET[var].numericValue();
get == 0
Php::Value G = Php::GLOBALS["_GET"][var];
auto get = G.numericValue();
get == 5
See. full example
From the example in README.md:
Php::Value get_complex_array()
{
Php::Value r;
r["a"] = 123;
r["b"] = 456;
r["c"][0] = "nested value";
r["c"][1] = "example";
return r;
}
This example does not compile:
In file included from /usr/include/phpcpp.h:41:0,
from main.cpp:8:
/usr/include/phpcpp/hashmember.h: In instantiation of ‘Php::HashMember<Type> Php::HashMember<Type>::operator[](int) [with Type = std::basic_string<char>]’:
include/variables.h:53:14: required from here
/usr/include/phpcpp/hashmember.h:154:50: error: no matching function for call to ‘Php::HashMember<int>::add(Php::HashMember<std::basic_string<char> >* const)’
return _base->get(_index)[index].add(this);
^
/usr/include/phpcpp/hashmember.h:154:50: note: candidate is:
In file included from /usr/include/phpcpp.h:41:0,
from main.cpp:8:
/usr/include/phpcpp/hashmember.h:387:17: note: Php::HashMember<Type>& Php::HashMember<Type>::add(Php::HashMember<Type>*) [with Type = int]
HashMember &add(HashMember *parent)
^
/usr/include/phpcpp/hashmember.h:387:17: note: no known conversion for argument 1 from ‘Php::HashMember<std::basic_string<char> >* const’ to ‘Php::HashMember<int>*’
c++
void value_types(Php::Parameters ¶ms) {
Php::Value arr = params[0];
std::cout << "\nNull: " << bool2str( arr.get("Null").type() == Php::Type::Null );
std::cout << "\nNumeric: " << bool2str( arr.get("Numeric").type() == Php::Type::Numeric );
std::cout << "\nFloat: " << bool2str( arr.get("Float").type() == Php::Type::Float );
std::cout << "\nBool: " << bool2str( arr.get("Bool").type() == Php::Type::Bool );
std::cout << "\nArray: " << bool2str( arr.get("Array").type() == Php::Type::Array );
std::cout << "\nObject: " << bool2str( arr.get("Object").type() == Php::Type::Object );
std::cout << "\nString: " << bool2str( arr.get("String").type() == Php::Type::String );
std::cout << "\nResource: " << bool2str( arr.get("Resource").type() == Php::Type::Resource );
std::cout << "\nConstant: " << bool2str( arr.get("Constant").type() == Php::Type::Constant );
std::cout << "\nConstantArray: " << bool2str( arr.get("ConstantArray").type() == Php::Type::ConstantArray );
std::cout << "\nCallable: " << bool2str( arr.get("Callable").type() == Php::Type::Callable );
}
...
extension.add("TestVariables\\value_types", TestVariables::value_types);
php
$arr = array(
'Null' => NULL,
'Numeric' => 2014,
'Float' => 3.14,
'Bool' => true,
'Array' => array(5,'a' => 33, 'str'),
'Object' => new stdClass(),
'String' => 'String',
'Resource' => 7,
'Constant' => 5,
'ConstantArray' => 11,
'Callable' => function () {return 5;}
);
TestVariables\value_types($arr);
---- EXPECTED OUTPUT
Null: Yes
Numeric: Yes
Float: Yes
Bool: Yes
Array: Yes
Object: Yes
String: Yes
Resource: No
Constant: No
ConstantArray: No
Callable: Yes
---- ACTUAL OUTPUT
Null: Yes
Numeric: Yes
Float: Yes
Bool: Yes
Array: Yes
Object: Yes
String: Yes
Resource: No
Constant: No
ConstantArray: No
Callable: No
Did not work: Php::Type::Callable
PS
I will explain where it all came from. I, as I promised, started to write tests. And surfaced minor bugs. I am sure that every bug is fixed one-two lines, but I'm not going to look for how to fix it, and will focus on the tests.
My new extension doesn't get loaded, instead an error is thrown:
sudo ~/.phpbrew/php/php-5.5.1/sbin/php-fpm drgomesp@MacBook-Pro-de-Daniel
[15-Mar-2014 19:38:39] NOTICE: PHP message: PHP Warning: PHP Startup: hello_world: Unable to initialize module
Module compiled with module API=20090626
PHP compiled with module API=20121212
These options need to match
in Unknown on line 0
<br />
<b>Warning</b>: PHP Startup: hello_world: Unable to initialize module
Module compiled with module API=20090626
PHP compiled with module API=20121212
These options need to match
in <b>Unknown</b> on line <b>0</b><br />
Any tips?
I have a segmentation fault during module initialization when a class implements a specific interface. This fault is possible when interface is not initialized yet, so interface->_entry
is null in classimpl.cpp:1409
// register the classes
for (auto &interface : _interfaces)
{
// register this interface
zend_class_implements(_entry TSRMLS_CC, 1, interface->_entry);
}
Valgrind profile shows this too:
==7155== Memcheck, a memory error detector
==7155== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==7155== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==7155== Command: php
==7155==
==7155== Invalid read of size 8
==7155== at 0x6A8967: zend_hash_merge_ex (in /usr/bin/php5)
==7155== by 0x682067: zend_do_implement_interface (in /usr/bin/php5)
==7155== by 0x6A1910: zend_class_implements (in /usr/bin/php5)
==7155== by 0x80D26DF: Php::ClassImpl::initialize(Php::ClassBase*, std::string const&) (classimpl.cpp:1409)
==7155== by 0x80D8A77: Php::Namespace::initialize(std::string const&) (namespace.cpp:126)
==7155== by 0x80D8AF3: Php::Namespace::initialize(std::string const&) (namespace.cpp:129)
==7155== by 0x80D376F: Php::Extension::onStartup(int, int) (extension.cpp:118)
==7155== by 0x69C3FD: zend_startup_module_ex (in /usr/bin/php5)
==7155== by 0x6A8553: zend_hash_apply (in /usr/bin/php5)
==7155== by 0x6A0159: zend_startup_modules (in /usr/bin/php5)
==7155== by 0x647E24: php_module_startup (in /usr/bin/php5)
==7155== by 0x72D66C: ??? (in /usr/bin/php5)
==7155== Address 0x178 is not stack'd, malloc'd or (recently) free'd
==7155==
==7155==
==7155== Process terminating with default action of signal 11 (SIGSEGV)
==7155== Access not within mapped region at address 0x178
==7155== at 0x6A8967: zend_hash_merge_ex (in /usr/bin/php5)
==7155== by 0x682067: zend_do_implement_interface (in /usr/bin/php5)
==7155== by 0x6A1910: zend_class_implements (in /usr/bin/php5)
==7155== by 0x80D26DF: Php::ClassImpl::initialize(Php::ClassBase*, std::string const&) (classimpl.cpp:1409)
==7155== by 0x80D8A77: Php::Namespace::initialize(std::string const&) (namespace.cpp:126)
==7155== by 0x80D8AF3: Php::Namespace::initialize(std::string const&) (namespace.cpp:129)
==7155== by 0x80D376F: Php::Extension::onStartup(int, int) (extension.cpp:118)
==7155== by 0x69C3FD: zend_startup_module_ex (in /usr/bin/php5)
==7155== by 0x6A8553: zend_hash_apply (in /usr/bin/php5)
==7155== by 0x6A0159: zend_startup_modules (in /usr/bin/php5)
==7155== by 0x647E24: php_module_startup (in /usr/bin/php5)
==7155== by 0x72D66C: ??? (in /usr/bin/php5)
==7155== If you believe this happened as a result of a stack
==7155== overflow in your program's main thread (unlikely but
==7155== possible), you can try to increase the size of the
==7155== main thread stack using the --main-stacksize= flag.
==7155== The main thread stack size used in this run was 8388608.
==7155==
==7155== HEAP SUMMARY:
==7155== in use at exit: 2,336,316 bytes in 17,073 blocks
==7155== total heap usage: 18,465 allocs, 1,392 frees, 2,492,133 bytes allocated
==7155==
==7155== LEAK SUMMARY:
==7155== definitely lost: 0 bytes in 0 blocks
==7155== indirectly lost: 0 bytes in 0 blocks
==7155== possibly lost: 642 bytes in 16 blocks
==7155== still reachable: 2,335,674 bytes in 17,057 blocks
==7155== suppressed: 0 bytes in 0 blocks
==7155== Rerun with --leak-check=full to see details of leaked memory
==7155==
==7155== For counts of detected and suppressed errors, rerun with: -v
==7155== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Later i found a bug in order of std::move
for namespaces, so pointer for an interface wasn't valid. However it will be better to throw an exception to show this information for developers. One more proposed change is to call zend_do_implement_interface
function directly instead of zend_class_implements
.
For properties we need documentation, and a better system for defining properties in which the setter and getter method can be explicitly set (instead of setting properties directly via the Zend engine, without any checking)
Hi,
As part of making php-cpp builds using config file, I began to port it to windows (using vc13 and later vc11 to match upstream windows binary).
1st result:
https://gist.github.com/pierrejoye/593d8bf8ba3c5a81987c
Looks like some cpp features used need some tweeks.
besides:
1st config.w32 (pretty much the same then for config.m4):
// vim:ft=javascript
//
ARG_ENABLE('php-cpp', 'Enable php-cpp library', 'no');
if (PHP_PHP_CPP != "no") {
ADD_SOURCES("sapi/php-cpp/src", "argument.cpp base.cpp callable.cpp classbase.cpp exception.cpp global.cpp globals.cpp
hashmember.cpp iterator.cpp members.cpp modifiers.cpp namespace.cpp object.cpp origexception.cpp
parameters.cpp streambuf.cpp streams.cpp super.cpp value.cpp valueiterator.cpp", "phpcpp");
SAPI('phpcpp', 'src/extension.cpp', 'php' + PHP_VERSION + 'phpcpp.lib');
// PHP_INSTALL_HEADERS("sapi/phpcpp", "src/*.h");
}
it will allow to build php-cpp as part of php as a "sapi", which makes allows some optimizations later. Once it works I will try to provide another one to rely only on phpize, so php-cpp can be distributed easily.
php functionwithparameters.php
PHP Catchable fatal error: Argument 1 passed to my_with_defined_object_parameters_function() must be an instance of yextension.so, instance of MyPhpClass given in ~/PHP-CPP/Examples/FunctionWithParameters/functionwithparameters.php on line 70
What minimal PHP version supported by PH-CPP. I cannot compile it for PHP ver.5.3.10....?
Strings are always fully copied into a Value object. This is a waste of time, because some strings are hardcoded, and no copy to dynamic memory is necessary.
This code make for example an unnecessary copy of a string:
Value x("example");
make is throwing me lots of errors Here are some of them:
error: is_array is not a member of Php
error: array_key_exists is not a member of Php
error: isset is not a member of Php
error: ambiguous overload for ‘operator[]’ (operand types are ‘Php::Array’ and ‘Php::Value’)
error: ambiguous overload for 'operator[]' (operand types are 'Php::Value' and 'Php::Value')
PHP code: http://pastebin.com/ZMdkarPu
C++ code: http://pastebin.com/8U11V90V
I'm trying to compile the following extension:
#include <phpcpp.h>
#include <iostream>
void myFunction()
{
std::cout << "example output" << std::endl;
}
extern "C" {
PHPCPP_EXPORT void *get_module() {
static Php::Extension extension("hello_world", "1.0");
extension.add("myFunction", myFunction);
return extension;
}
}
With the following Makefile:
#
# Makefile template
#
# This is an example Makefile that can be used by anyone who is building
# his or her own PHP extensions using the PHP-CPP library.
#
# In the top part of this file we have included variables that can be
# altered to fit your configuration, near the bottom the instructions and
# dependencies for the compiler are defined. The deeper you get into this
# file, the less likely it is that you will have to change anything in it.
#
#
# Name of your extension
#
# This is the name of your extension. Based on this extension name, the
# name of the library file (name.so) and the name of the config file (name.ini)
# are automatically generated
#
NAME = hello_world
#
# Php.ini directories
#
# In the past, PHP used a single php.ini configuration file. Today, most
# PHP installations use a conf.d directory that holds a set of config files,
# one for each extension. Use this variable to specify this directory.
#
INI_DIR = /Users/drgomesp/.phpbrew/php/php-5.3.28/etc
#
# The extension dirs
#
# This is normally a directory like /usr/lib/php5/20121221 (based on the
# PHP version that you use. We make use of the command line 'php-config'
# instruction to find out what the extension directory is, you can override
# this with a different fixed directory
#
EXTENSION_DIR = $(shell php-config --extension-dir)
#
# The name of the extension and the name of the .ini file
#
# These two variables are based on the name of the extension. We simply add
# a certain extension to them (.so or .ini)
#
EXTENSION = ${NAME}.so
INI = ${NAME}.ini
#
# Compiler
#
# By default, the GNU C++ compiler is used. If you want to use a different
# compiler, you can change that here. You can change this for both the
# compiler (the program that turns the c++ files into object files) and for
# the linker (the program that links all object files into the single .so
# library file. By default, g++ (the GNU C++ compiler) is used for both.
#
COMPILER = clang
LINKER = clang
#
# Compiler and linker flags
#
# This variable holds the flags that are passed to the compiler. By default,
# we include the -O2 flag. This flag tells the compiler to optimize the code,
# but it makes debugging more difficult. So if you're debugging your application,
# you probably want to remove this -O2 flag. At the same time, you can then
# add the -g flag to instruct the compiler to include debug information in
# the library (but this will make the final libphpcpp.so file much bigger, so
# you want to leave that flag out on production servers).
#
# If your extension depends on other libraries (and it does at least depend on
# one: the PHP-CPP library), you should update the LINKER_DEPENDENCIES variable
# with a list of all flags that should be passed to the linker.
#
COMPILER_FLAGS = -arch x86_64 -arch i386 -c -I. `php-config --includes` -g -std=c++11 -fpic -o
LINKER_FLAGS = -shared -undefined dynamic_lookup `php-config --ldflags`
LINKER_DEPENDENCIES = -lphpcpp
#
# Command to remove files, copy files and create directories.
#
# I've never encountered a *nix environment in which these commands do not work.
# So you can probably leave this as it is
#
RM = rm -f
CP = cp -f
MKDIR = mkdir -p
#
# All source files are simply all *.cpp files found in the current directory
#
# A built-in Makefile macro is used to scan the current directory and find
# all source files. The object files are all compiled versions of the source
# file, with the .cpp extension being replaced by .o.
#
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:%.cpp=%.o)
#
# From here the build instructions start
#
all: ${OBJECTS} ${EXTENSION}
${EXTENSION}: ${OBJECTS}
${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS} ${LINKER_DEPENDENCIES}
${OBJECTS}:
${COMPILER} ${COMPILER_FLAGS} $@ ${@:%.o=%.cpp}
install:
${CP} ${EXTENSION} ${EXTENSION_DIR}
${CP} ${INI} ${INI_DIR}
clean:
${RM} ${EXTENSION} ${OBJECTS}
And the following error occurs:
make drgomesp@MacBook-Pro-de-Daniel
clang -arch x86_64 -arch i386 -c -I. `php-config --includes` -g -std=c++11 -fpic -o Main.o Main.cpp
In file included from Main.cpp:2:
In file included from /usr/local/include/phpcpp.h:46:
/usr/local/include/phpcpp/iterator.h:131:72: error: unknown type name 'uint'; did you mean 'int'?
static int key(struct _zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key);
^
/usr/local/include/phpcpp/iterator.h:131:91: error: unknown type name 'ulong'; did you mean 'long'?
static int key(struct _zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key);
^
2 errors generated.
make: *** [Main.o] Error 1
I'm on OSX, with PHP-CPP compiled and installed to /usr/local/include
.
Any tips?
I was debating using this library to build some extensions, but I'm hitting an error I don't quite understand. The error is as posted above, zend_mm_heap corrupted
.
$ php --version
PHP 5.5.9 (cli) (built: Apr 6 2014 20:53:20)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.2, Copyright (c) 1999-2013, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
#include <phpcpp.h>
Php::Value array_append(Php::Parameters ¶meters)
{
parameters[0].set(parameters[0].count(), parameters[1]);
return parameters[0];
}
extern "C" {
PHPCPP_EXPORT void *get_module() {
static Php::Extension extension("my_example", "1.0");
extension.add("array_append", array_append, {
Php::ByVal("a", Php::Type::Array),
Php::ByVal("b", Php::Type::String)
});
return extension;
}
}
<?php
$input = [];
for ($i = 0; $i < 50000; $i++) {
echo $i . PHP_EOL;
$input = array_append($input, 'test');
}
1
2
3
....
2990
2991
zend_mm_heap corrupted
When passed by reference(Php::ByRef
) the error does not occur, though this changes how the function works.
The following implementation appears to not having this corruption issue:
Php::Value array_append(Php::Parameters ¶meters)
{
Php::Array array = parameters[0];
array.set(parameters[0].count(), parameters[1]);
return array;
}
Valgrind reports some memory issues when you run scripts that use __get and __set. This has to be further investigated.
I made a small example extension to check whether I am able to load my example extension, but this fails because the module APIs of the extension and my PHP installation does not match.
jan@urdbrunnen ~/Workspace/PHP-CPP$ make
g++ -Wall -c -O2 -std=c++11 -fpic -o example.o example.cpp
g++ -shared -o example.so example.o -lphpcpp
jan@urdbrunnen ~/Workspace/PHP-CPP$ sudo make install
cp -f example.so /usr/lib/php/extensions/no-debug-non-zts-20100525
cp -f example.ini /Library/Server/Web/Config/php
jan@urdbrunnen ~/Workspace/PHP-CPP$ php -m
PHP Warning: PHP Startup: example: Unable to initialize module
Module compiled with module API=268435456
PHP compiled with module API=20100525
These options need to match
in Unknown on line 0
It also feels like I always get another module API version (incl. negative!)
Module compiled with module API=-1342177280
Hi,
I want write php extension for windows(dll) . But i didn't see anywhere that related documents for php-cpp.
Is this possible?
The PHP-CPP library does not yet have a way to instantiate classes. You can store already-created objects in a Php::Value object, but there is no way to create a new instance.
My suggestion is to have a Php::Object class (that derives from Php::ForcedValue) and that can be used to create new instances. The constructor gets the name of the classes, and a list of parameters that are passed to the __construct function:
// create a new PHP DateTime object representing the current time
Php::Object now("DateTime", "now");
// show it
std::cout << now.call("format", "Y-m-d H:i:s") << std::endl;
This is a public issue. I will eventually solve this myself, but since my time is limited and this is an open source project, it would be cool if someone could help me with this.
include/base.h:16 class MixedObject;
src/mixedobject.h:19 struct MixedObject;
I suppose struct is meant, as there is no implementation and members are public anyway.
We already have a Php::GLOBALS variable to access all global variables. In line with PHP code, we also need a Php::GET, Php::REQUEST, Php::POST, Php::COOKIES and Php::SERVER variable.
In the classbase.cpp file in the source directory, there is a clone_object() function that is not yet implemented. As a consequence, we do not yet have a good way to clone objects. This should be implemented. Cloning an object should (first) run the normal clone operation on the underlying Php::Value/zval object (which should create a new Php::Value/zval object with the same properties as the original one), and then it should call the copy constructor of the original custom C++ class to create a new instance of the copied class.
This is a public issue. I will eventually solve this myself, but since my time is limited and this is an open source project, it would be cool if someone could help me with this.
pass_rest_by_reference is not used anymore in 5.6+
FYI, from the upgrading guide:
ZEND_ARG_VARIADIC_INFO(0, name) /\* pass rest by value */
ZEND_ARG_VARIADIC_INFO(1, name) /\* pass rest by reference */
ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, name)
/\* pass rest by prefer-ref */
typedef struct _zend_arg_info {
const char *class_name;
zend_uint class_name_len;
zend_uchar type_hint;
+ zend_uchar pass_by_reference;
zend_bool allow_null;
- zend_bool pass_by_reference;
+ zend_bool is_variadic;
} zend_arg_info;
typedef struct _zend_internal_function_info {
zend_uint required_num_args;
zend_uchar _type_hint;
zend_bool return_reference;
- zend_bool pass_rest_by_reference;
+ zend_bool _allow_null;
+ zend_bool _is_variadic;
} zend_internal_function_info;
We should be able to declare Interfaces in C++ that are then available in PHP. And we should be able to create in C++ classes that implement these interfaces.
It this feature already exists, the documentation should then be updated with examples.
Magic methods can be resolved at compile time. This means that a user has more freedom in choosing the signature for their magic methods.
Also: now I think that __compare is a better alternative for the operator<, because now we call the operator< twice, instead of only once.
First i want to thank you about this wonderful piece of software which makes my life so much easier 👍
My Setting:
Windows 7(x64), Apache 2.4.7(x86), Php 5.5.10ts(x86) and Visual Studio 2013.
I'm able to compile php-cpp with php and everything works except the global Php::SERVER. I was able to debug my Problem and noticed that "PG(http_globals)[_index]" _index == 3 -> get me an NULL Pointer. Can you reproduce that or could that be a problem with my setting ?
BIG THX
#include <phpcpp.h>
using namespace std;
class Dummy : public Php::Base {
public:
Php::Value add(Php::Parameters ¶ms) {
return 0;
}
};
extern "C" {
PHPCPP_EXPORT void *get_module() {
static Php::Extension extension("example", "0.1");
Php::Class<Dummy> dummy("Example\\Dummy");
dummy.method("add", &Dummy::add, {
Php::ByVal("a", Php::Type::Numeric),
Php::ByVal("b", Php::Type::Numeric)
});
extension.add(std::move(dummy));
return extension;
}
}
extension=example.so
NAME = example
INI_DIR = /Library/Server/Web/Config/php
jan@urdbrunnen ~/Workspace/Example$ make
g++ -Wall -c -O2 -std=c++11 -fpic -o example.o example.cpp
g++ -shared -o example.so example.o -lphpcpp
jan@urdbrunnen ~/Workspace/Example$ sudo make install
cp -f example.so /usr/lib/php/extensions/no-debug-non-zts-20100525
cp -f example.ini /Library/Server/Web/Config/php
jan@urdbrunnen ~/Workspace/Example$ php -m | grep example
example
$dummy = new Example\Dummy;
$dummy->add(1, 2);
jan@urdbrunnen ~/Workspace/Example$ php example.php
int(0)
Segmentation fault: 11
I have already mentioned this feature.
The fact that php uses its own output stream for printing text.
std::cout
sends data to standard output stream, std::cerr
in the standard error output stream.
std::cout
can only be used in CLI mode php. For creating web applications, this method does not work.
The simplest method to solve the issue is to write a wrapper around the zend_write
:
void echo(std::string str) {
zend_write( str.c_str(), str.size());
}
I just checked. This function works!
Basically, in this form it is enough, but we can go ahead and implement something like this:
Php::echo << "PI equals " << 3.14;
On the following page:
http://www.php-cpp.com/documentation/ten-reasons-for-using-php-cpp
"There are many reasons for using PHP-CPP. Let's name a view."
Is view a pun or should it be few?
Maybe I am wrong, but I cannot find a way to declare a class property with a negative default value because all property()
signatures, in include/class.h, with integer values, are using uint_*_t
.
I've tried to make PHP-CPP (v0.9) on my laptop, but it fails 😢
jan@himinbjorg ~/Workspace$ git clone https://github.com/CopernicaMarketingSoftware/PHP-CPP.git
Cloning into 'PHP-CPP'...
remote: Reusing existing pack: 2337, done.
remote: Counting objects: 176, done.
remote: Compressing objects: 100% (176/176), done.
remote: Total 2513 (delta 114), reused 0 (delta 0)
Receiving objects: 100% (2513/2513), 889.51 KiB | 379.00 KiB/s, done.
Resolving deltas: 100% (1648/1648), done.
Checking connectivity... done.
jan@himinbjorg ~/Workspace$ cd PHP-CPP
jan@himinbjorg ~/Workspace/PHP-CPP (master)$ git checkout v0.9
jan@himinbjorg ~/Workspace/PHP-CPP ((v0.9))$ make
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/argument.o src/argument.cpp
In file included from src/includes.h:93:0,
from src/argument.cpp:9:
src/notimplemented.h:43:13: error: looser throw specifier for ‘virtual Php::NotImplemented::~NotImplemented()’
In file included from /usr/include/c++/4.7/new:42:0,
from /usr/include/c++/4.7/ext/new_allocator.h:34,
from /usr/include/x86_64-linux-gnu/c++/4.7/./bits/c++allocator.h:34,
from /usr/include/c++/4.7/bits/allocator.h:48,
from /usr/include/c++/4.7/string:43,
from src/includes.h:14,
from src/argument.cpp:9:
/usr/include/c++/4.7/exception:66:13: error: overriding ‘virtual std::exception::~exception() noexcept (true)’
make: *** [src/argument.o] Error 1
jan@himinbjorg ~/Workspace/PHP-CPP ((v0.9))$ gcc --version
gcc (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
jan@himinbjorg ~/Workspace/PHP-CPP ((v0.9))$ g++ --version
g++ (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
jan@himinbjorg ~/Workspace/PHP-CPP ((v0.9))$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.4 LTS"
This seems to be related to missing php-dev. I have php installed from source.
cd src; make
make[1]: Entering directory `/usr/local/src/PHP-CPP/src'
g++ -g -Wno-write-strings -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -O2 -std=c++11 -fpic -o argument.o argument.cpp
In file included from argument.cpp:9:0:
includes.h:33:17: fatal error: php.h: No such file or directory
compilation terminated.
make[1]: *** [argument.o] Error 1
make[1]: Leaving directory `/usr/local/src/PHP-CPP/src'
make: *** [all] Error 2
The extension which is compiled for make test
assumes an installed phpcpp and refers to a phpcpp.h. If the test should happen before the installation (which would be a good thing imho), the test extension should build against the current working directory.
OSX 10.9.3
mario@xenjibook ~/D/S/PHP-CPP> g++ -v master!?
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
hi,
First thanks a lot for this awesome c++ helper!
It would be nice to add config.m4/w32 to the examples. Doing so will allow anyone to compile extensions using phpize and even better, release them via pecl :)
Keep the good work!
I have a suggestion.
Now the methods Class::method(...)
return type void
.
And when declaring class we write something like this:
Php::Class<Counter> counter("Counter");
counter.method("increment", &Counter::increment);
// some comment
counter.method("decrement", &Counter::decrement);
counter.method("value", &Counter::value);
// add the class to the extension
myExtension.add(std::move(counter));
If slightly modify the prototype (slightly fix just 15 consecutive lines):
void method(const char *name, void (T::*method)(), int flags, const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_0>(method), flags, args);}
//...
to
Class&& method(const char *name, void (T::*method)(), int flags, const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_0>(method), flags, args); return *this;}
//...
Then we can write this:
// add the class to the extension
myExtension.add
(
Php::Class<Counter>("Counter")
.method("increment", &Counter::increment)
// some comment
.method("decrement", &Counter::decrement)
.method("value", &Counter::value)
);
The same applies to the Class::property(...)
In such record, there are no ambiguities and potential pitfalls for the compiler. And return *this by ref does not copy. Therefore, the additional overhead there is no.
Of the advantages I see
std::move(...)
(object of Php::Class in such a record already rvalue)That would have been sure that it is really possible to do without std::move(...)
I have prepared some illustrating examples:
#include <iostream>
class Chaining
{
public:
Chaining() {}
Chaining& meth1() &
{
std::cout << "meth1 &" << std::endl;
}
Chaining& meth2() &
{
std::cout << "meth2 &" << std::endl;
}
Chaining& meth3() &
{
std::cout << "meth3 &" << std::endl;
}
Chaining&& meth1() &&
{
std::cout << "meth1 &&" << std::endl;
}
Chaining&& meth2() &&
{
std::cout << "meth2 &&" << std::endl;
}
Chaining&& meth3() &&
{
std::cout << "meth3 &&" << std::endl;
}
};
int main(){
Chaining()
.meth1()
.meth2()
.meth3();
Chaining obj;
obj.meth1();
obj.meth2();
obj.meth3();
return 0;
};
output:
meth1 &&
meth2 &&
meth3 &&
meth1 &
meth2 &
meth3 &
#include <iostream>
class Chaining
{
public:
Chaining() {}
Chaining& meth1()
{
std::cout << "meth1 &" << std::endl;
}
Chaining& meth2()
{
std::cout << "meth2 &" << std::endl;
}
Chaining& meth3()
{
std::cout << "meth3 &" << std::endl;
}
};
int main(){
Chaining()
.meth1()
.meth2()
.meth3();
Chaining obj;
obj.meth1();
obj.meth2();
obj.meth3();
return 0;
};
output:
meth1 &
meth2 &
meth3 &
meth1 &
meth2 &
meth3 &
#include <iostream>
class Chaining
{
public:
Chaining() {}
Chaining&& meth1()
{
std::cout << "meth1 &&" << std::endl;
}
Chaining&& meth2()
{
std::cout << "meth2 &&" << std::endl;
}
Chaining&& meth3()
{
std::cout << "meth3 &&" << std::endl;
}
};
int main(){
Chaining()
.meth1()
.meth2()
.meth3();
Chaining obj;
obj.meth1();
obj.meth2();
obj.meth3();
return 0;
};
output:
meth1 &&
meth2 &&
meth3 &&
meth1 &&
meth2 &&
meth3 &&
Hi!
I get a compilation error with latest sources, here is the build output :
g++ -Wall -c -g -std=c++11 -fpic -o common/modifiers.o common/modifiers.cpp
g++ -Wall -c -g -std=c++11 -fpic -o common/streambuf.o common/streambuf.cpp
g++ -Wall -c -g -std=c++11 -fpic `php-config --includes` -o zend/base.o zend/base.cpp
g++ -Wall -c -g -std=c++11 -fpic `php-config --includes` -o zend/callable.o zend/callable.cpp
g++ -Wall -c -g -std=c++11 -fpic `php-config --includes` -o zend/classbase.o zend/classbase.cpp
g++ -Wall -c -g -std=c++11 -fpic `php-config --includes` -o zend/classimpl.o zend/classimpl.cpp
g++ -Wall -c -g -std=c++11 -fpic `php-config --includes` -o zend/extension.o zend/extension.cpp
g++ -Wall -c -g -std=c++11 -fpic `php-config --includes` -o zend/extensionimpl.o zend/extensionimpl.cpp
zend/extensionimpl.cpp: In member function ‘zend_module_entry* Php::ExtensionImpl::module()’:
zend/extensionimpl.cpp:267:6: error: call of overloaded ‘apply(Php::ExtensionImpl::module()::<lambda(const string&, Php::Function&)>)’ is ambiguous
zend/extensionimpl.cpp:267:6: note: candidates are:
In file included from zend/includes.h:74:0,
from zend/extensionimpl.cpp:7:
zend/../include/namespace.h:185:10: note: void Php::Namespace::apply(const std::function<void(const std::basic_string<char>&, Php::Function&)>&)
zend/../include/namespace.h:195:10: note: void Php::Namespace::apply(const std::function<void(const std::basic_string<char>&, Php::ClassBase&)>&)
zend/extensionimpl.cpp: In member function ‘void Php::ExtensionImpl::initialize()’:
zend/extensionimpl.cpp:293:6: error: call of overloaded ‘apply(Php::ExtensionImpl::initialize()::<lambda(const string&, Php::ClassBase&)>)’ is ambiguous
zend/extensionimpl.cpp:293:6: note: candidates are:
In file included from zend/includes.h:74:0,
from zend/extensionimpl.cpp:7:
zend/../include/namespace.h:185:10: note: void Php::Namespace::apply(const std::function<void(const std::basic_string<char>&, Php::Function&)>&)
zend/../include/namespace.h:195:10: note: void Php::Namespace::apply(const std::function<void(const std::basic_string<char>&, Php::ClassBase&)>&)
make: *** [zend/extensionimpl.o] Error 1
BUILD FAILED (exit value 2, total time: 6s)
I use the given MAKEFILE with no modifications.
My g++ version is 4:4.7.3-1ubuntu10
Found a fix here : https://stackoverflow.com/questions/4111647/disambiguating-calls-to-functions-taking-stdfunctions
After applying it (see https://github.com/hectorj/PHP-CPP/compare/fixAmbiguousLambdaCalls1), it compiles but the make test
fails (100%).
Here is the test output but it doesn't say much except that everything fails :
PHP : /usr/bin/php
PHP_SAPI : cli
PHP_VERSION : 5.4.9-4ubuntu2.4
ZEND_VERSION: 2.4.0
PHP_OS : Linux - Linux hjwm 3.8.0-35-generic #50-Ubuntu SMP Tue Dec 3 01:24:59 UTC 2013 x86_64
INI actual : /etc/php5/cli/php.ini
More .INIs : /etc/php5/cli/conf.d/10-pdo.ini,/etc/php5/cli/conf.d/20-curl.ini,/etc/php5/cli/conf.d/20-gd.ini,/etc/php5/cli/conf.d/20-gmp.ini,/etc/php5/cli/conf.d/20-mysql.ini,/etc/php5/cli/conf.d/20-mysqli.ini,/etc/php5/cli/conf.d/20-pdo_mysql.ini,/etc/php5/cli/conf.d/20-xdebug.ini,/etc/php5/cli/conf.d/20-xmlrpc.ini,/etc/php5/cli/conf.d/20-xsl.ini,/etc/php5/cli/conf.d/mcrypt.ini,/etc/php5/cli/conf.d/phpbitcoin.ini,/etc/php5/cli/conf.d/ssh2.ini
CWD : /var/www/PHP-CPP-src/tests
Extra dirs :
VALGRIND : Not used
=====================================================================
Running selected tests.
FAIL Test constructor & destructor [php/phpt/class_obj/001.phpt]
FAIL Test constructor & destructor [php/phpt/class_obj/002.phpt]
FAIL Test comparable objects [php/phpt/class_obj/003-comparable.phpt]
FAIL Test class with static function [php/phpt/class_obj/004-static-funct.phpt]
FAIL Test class with static property and class constant [php/phpt/class_obj/005-static-prop.phpt]
FAIL Iterate array [php/phpt/valueiterator/001.phpt]
FAIL Iterate object of stdClass [php/phpt/valueiterator/002.phpt]
FAIL Iterate object [php/phpt/valueiterator/003.phpt]
FAIL Iterate itarable oblect [php/phpt/valueiterator/004.phpt]
FAIL Iterate itarable oblect [php/phpt/valueiterator/005.phpt]
FAIL Iterate itarable oblect [php/phpt/valueiterator/006.phpt]
FAIL Iterate internal array [php/phpt/valueiterator/007-Iterate-internal-array.phpt]
FAIL Global variables in PHP-CPP [php/phpt/variables/001-process_globals.phpt]
FAIL get_complex_array [php/phpt/variables/002-get_complex_array.phpt]
FAIL get_complex_array [php/phpt/variables/003-value-types.phpt]
FAIL Test variables defined in PHP-CPP [php/phpt/variables/004-store-scalar-variables.phpt]
FAIL cast objects to scalars [php/phpt/variables/005-cast-objects-to-scalars.phpt]
FAIL Test Php::Value casting operators (object to string) [php/phpt/variables/006-casting-obj2str.phpt]
FAIL Test Php::Value overloaded operators [php/phpt/variables/007-overloaded-operators.phpt]
FAIL Test Php::Value arrays [php/phpt/variables/008-value-arrays.phpt]
FAIL Test Php::Value object #1 [php/phpt/variables/009-value-object.phpt]
FAIL Test Php::Value object #2 [php/phpt/variables/010-value-object2.phpt]
FAIL Test Php::Value casting operators [php/phpt/variables/011-value-casting-operators.phpt]
FAIL Test Php::Value casting operators (double) [php/phpt/variables/012-value-casting-operators-double.phpt]
FAIL calling-php-functions from userspace [php/phpt/variables/013-calling-php-functions.phpt]
FAIL calling-php-Callback-functions [php/phpt/variables/014-calling-php-functions.phpt]
FAIL calling-php-Callback-functions (lambda) [php/phpt/variables/015-calling-php-functions.phpt]
FAIL calling-php-Callback-functions (__invoke) [php/phpt/variables/016-calling-php-functions.phpt]
FAIL calling-php-Callback-functions (method of class) [php/phpt/variables/017-calling-php-functions.phpt]
FAIL calling-php-callable [php/phpt/variables/018-calling-php-functions.phpt]
FAIL get_complex_array (test HashMember #1) [php/phpt/variables/019-HashMember-1.phpt]
FAIL get_complex_array (test HashMember #2) [php/phpt/variables/020-HashMember-2.phpt]
FAIL get_complex_array (test HashMember #3) [php/phpt/variables/021-HashMember-3.phpt]
FAIL get_complex_array (test HashMember #4) [php/phpt/variables/022-HashMember-4.phpt]
=====================================================================
Number of tests : 34 34
Tests skipped : 0 ( 0.0%) --------
Tests warned : 0 ( 0.0%) ( 0.0%)
Tests failed : 34 (100.0%) (100.0%)
Expected fail : 0 ( 0.0%) ( 0.0%)
Tests passed : 0 ( 0.0%) ( 0.0%)
---------------------------------------------------------------------
Time taken : 2 seconds
=====================================================================
=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
Test constructor & destructor [php/phpt/class_obj/001.phpt]
Test constructor & destructor [php/phpt/class_obj/002.phpt]
Test comparable objects [php/phpt/class_obj/003-comparable.phpt]
Test class with static function [php/phpt/class_obj/004-static-funct.phpt]
Test class with static property and class constant [php/phpt/class_obj/005-static-prop.phpt]
Iterate array [php/phpt/valueiterator/001.phpt]
Iterate object of stdClass [php/phpt/valueiterator/002.phpt]
Iterate object [php/phpt/valueiterator/003.phpt]
Iterate itarable oblect [php/phpt/valueiterator/004.phpt]
Iterate itarable oblect [php/phpt/valueiterator/005.phpt]
Iterate itarable oblect [php/phpt/valueiterator/006.phpt]
Iterate internal array [php/phpt/valueiterator/007-Iterate-internal-array.phpt]
Global variables in PHP-CPP [php/phpt/variables/001-process_globals.phpt]
get_complex_array [php/phpt/variables/002-get_complex_array.phpt]
get_complex_array [php/phpt/variables/003-value-types.phpt]
Test variables defined in PHP-CPP [php/phpt/variables/004-store-scalar-variables.phpt]
cast objects to scalars [php/phpt/variables/005-cast-objects-to-scalars.phpt]
Test Php::Value casting operators (object to string) [php/phpt/variables/006-casting-obj2str.phpt]
Test Php::Value overloaded operators [php/phpt/variables/007-overloaded-operators.phpt]
Test Php::Value arrays [php/phpt/variables/008-value-arrays.phpt]
Test Php::Value object #1 [php/phpt/variables/009-value-object.phpt]
Test Php::Value object #2 [php/phpt/variables/010-value-object2.phpt]
Test Php::Value casting operators [php/phpt/variables/011-value-casting-operators.phpt]
Test Php::Value casting operators (double) [php/phpt/variables/012-value-casting-operators-double.phpt]
calling-php-functions from userspace [php/phpt/variables/013-calling-php-functions.phpt]
calling-php-Callback-functions [php/phpt/variables/014-calling-php-functions.phpt]
calling-php-Callback-functions (lambda) [php/phpt/variables/015-calling-php-functions.phpt]
calling-php-Callback-functions (__invoke) [php/phpt/variables/016-calling-php-functions.phpt]
calling-php-Callback-functions (method of class) [php/phpt/variables/017-calling-php-functions.phpt]
calling-php-callable [php/phpt/variables/018-calling-php-functions.phpt]
get_complex_array (test HashMember #1) [php/phpt/variables/019-HashMember-1.phpt]
get_complex_array (test HashMember #2) [php/phpt/variables/020-HashMember-2.phpt]
get_complex_array (test HashMember #3) [php/phpt/variables/021-HashMember-3.phpt]
get_complex_array (test HashMember #4) [php/phpt/variables/022-HashMember-4.phpt]
=====================================================================
Any idea on how to fix this?
Is it compatible with Windows(XP/7/8)?
What's the development environment? PHP version, vc++ ?
I known how to use a c compiler.
how to add the parameters in php.ini just like date.timezone = UTC ?
After building PHP-CPP on my laptop (Ubuntu) failed, I've tried to build it on my Mac OSX laptop (branch: master), but it fails 😢 Do I need a specific minimum PHP version to build PHP-CPP?
jan@urdbrunnen ~/Workspace$ git clone [email protected]:CopernicaMarketingSoftware/PHP-CPP.git
jan@urdbrunnen ~/Workspace$ cd PHP-CPP
jan@urdbrunnen ~/Workspace$ make
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/argument.o src/argument.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/base.o src/base.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/callable.o src/callable.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/classbase.o src/classbase.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/exception.o src/exception.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/extension.o src/extension.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/global.o src/global.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/globals.o src/globals.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/hashmember.o src/hashmember.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/iterator.o src/iterator.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/members.o src/members.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/modifiers.o src/modifiers.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/namespace.o src/namespace.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/object.o src/object.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/origexception.o src/origexception.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/parameters.o src/parameters.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/super.o src/super.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/value.o src/value.cpp
g++ -Wall -c -I. -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/ext -I/usr/include/php5/Zend -I/usr/include/php5/TSRM -g -std=c++11 -fpic -o src/valueiterator.o src/valueiterator.cpp
src/valueiterator.cpp:96:5: error: use of undeclared identifier 'zend_hash_get_current_key_zval_ex'; did you mean 'zend_hash_get_current_data_ex'?
zend_hash_get_current_key_zval_ex(_table, key._val, &_position);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
zend_hash_get_current_data_ex
/usr/include/php5/Zend/zend_hash.h:181:14: note: 'zend_hash_get_current_data_ex' declared here
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
^
src/valueiterator.cpp:96:47: error: cannot initialize a parameter of type 'void **' with an lvalue of type 'struct _zval_struct *'
zend_hash_get_current_key_zval_ex(_table, key._val, &_position);
^~~~~~~~
/usr/include/php5/Zend/zend_hash.h:181:66: note: passing argument to parameter 'pData' here
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
^
2 errors generated.
make: *** [src/valueiterator.o] Error 1
jan@urdbrunnen ~/Workspace/PHP-CPP$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
jan@urdbrunnen ~/Workspace/PHP-CPP$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
jan@urdbrunnen ~/Workspace/PHP-CPP$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.9.2
BuildVersion: 13C64
Currently, there is no simple way to define inheritance for classes and interfaces from PHP side of view. All classes are registered via zend_register_internal_class
, no usage of zend_register_internal_class_ex
that allow to define inheritance for classes.
My suggestion is to add a constructor for Php::Class
that will accept another instance of Php::Class
or zend_class_entry *
, then this information will be used in ClassBase
. One more way is to add new method extends
to the Php::Class
, for example:
Php::Class<SomeClass> someClass("SomeClass");
Php::Class<SomeChild> someChild("SomeChild");
someChild.extends(someClass);
// or alternative way
zend_class_entry *classEntry = zend_exception_get_default(TSRMLS_C);
someChild.extend(classEntry);
Interfaces can be implemented in the same way, by adding implements
method to the Php::Class
:
Php::Interface customInterface("CustomInterface");
Php::Class<SomeClass> someClass("SomeClass");
someClass.implements(spl_ce_Countable); // external zend_class_entry *
someClass.implements(customInterface); // explicit usage of Php::Interface for class
Thoughts?
System:
Linux 12.04 64 bit, 3.2.0-23 kernel
PHP: 5.5.9
Compilation seems OK, generated/installed libphpcpp.so in /usr/lib.
Copied the so into /usr/lib/php5/20121212, which is indicated by php.ini.
tryied to "php -i | grep libphpcpp" to see if the so lib is loaded and prompted:
PHP Warning: PHP Startup: Invalid library (maybe not a PHP library) 'libphpcpp.so' in Unknown on line 0
Any steps I am missing here?
It would be cool if all (or the most important) PHP functions are directly accessible as PHP-CPP functions. I am thinking about functions like
Php::call_user_func()
Php::count()
Php::isset()
Php::array_key_exists()
Php::strlen()
et cetera. This would make it much more easier to call PHP functions from within your own PHP-CPP extension. The only way to call PHP builtin functions now, is to store them in a Php::Value objects:
// how you can now call builtin PHP functions
Php::Value strlen("strlen");
Php::Value length = strlen("some-string");
// how it would be nicer:
Php::Value length = Php::call_user_func("strlen", "some-string");
// and how it would be really cool
Php::Value length = Php::strlen("some-string");
(Of course, this strlen() function is not so realistic, and you would probably be calling the C strlen version instead, but you get the idea).
This is a public issue. I will eventually solve this myself, but since my time is limited and this is an open source project, it would be cool if someone could help me with this.
I'm trying to compile using a phpbrew version of PHP, and I'm getting this errors:
make drgomesp@MacBook-Pro-de-Daniel
g++ -Wall -c -I. -I/Users/drgomesp/.phpbrew/php/php-5.5.1/include/php -I/Users/drgomesp/.phpbrew/php/php-5.5.1/include/php/main -I/Users/drgomesp/.phpbrew/php/php-5.5.1/include/php/ext -I/Users/drgomesp/.phpbrew/php/php-5.5.1/include/php/Zend -I/Users/drgomesp/.phpbrew/php/php-5.5.1/include/php/TSRM -g -std=c++11 -fpic -o src/value.o src/value.cpp
src/value.cpp:690:62: error: call to member function 'operator=' is ambiguous
Value &Value::operator%=(const Value &value) { return operator=(numericValue() % value.numericValue()); }
^~~~~~~~~
src/value.cpp:469:15: note: candidate function
Value &Value::operator=(int16_t value)
^
src/value.cpp:489:15: note: candidate function
Value &Value::operator=(int32_t value)
^
src/value.cpp:509:15: note: candidate function
Value &Value::operator=(int64_t value)
^
src/value.cpp:529:15: note: candidate function
Value &Value::operator=(bool value)
^
src/value.cpp:549:15: note: candidate function
Value &Value::operator=(char value)
^
src/value.cpp:609:15: note: candidate function
Value &Value::operator=(double value)
^
src/value.cpp:332:15: note: candidate function
Value &Value::operator=(Value &&value)
^
src/value.cpp:402:15: note: candidate function
Value &Value::operator=(const Value &value)
^
src/value.cpp:449:15: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &Value::operator=(std::nullptr_t value)
^
src/value.cpp:569:15: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &Value::operator=(const std::string &value)
^
src/value.cpp:589:15: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &Value::operator=(const char *value)
^
src/value.cpp:691:62: error: call to member function 'operator=' is ambiguous
Value &Value::operator%=(int16_t value) { return operator=(numericValue() % value); }
^~~~~~~~~
src/value.cpp:469:15: note: candidate function
Value &Value::operator=(int16_t value)
^
src/value.cpp:489:15: note: candidate function
Value &Value::operator=(int32_t value)
^
src/value.cpp:509:15: note: candidate function
Value &Value::operator=(int64_t value)
^
src/value.cpp:529:15: note: candidate function
Value &Value::operator=(bool value)
^
src/value.cpp:549:15: note: candidate function
Value &Value::operator=(char value)
^
src/value.cpp:609:15: note: candidate function
Value &Value::operator=(double value)
^
src/value.cpp:332:15: note: candidate function
Value &Value::operator=(Value &&value)
^
src/value.cpp:402:15: note: candidate function
Value &Value::operator=(const Value &value)
^
src/value.cpp:449:15: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &Value::operator=(std::nullptr_t value)
^
src/value.cpp:569:15: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &Value::operator=(const std::string &value)
^
src/value.cpp:589:15: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &Value::operator=(const char *value)
^
src/value.cpp:692:62: error: call to member function 'operator=' is ambiguous
Value &Value::operator%=(int32_t value) { return operator=(numericValue() % value); }
^~~~~~~~~
src/value.cpp:469:15: note: candidate function
Value &Value::operator=(int16_t value)
^
src/value.cpp:489:15: note: candidate function
Value &Value::operator=(int32_t value)
^
src/value.cpp:509:15: note: candidate function
Value &Value::operator=(int64_t value)
^
src/value.cpp:529:15: note: candidate function
Value &Value::operator=(bool value)
^
src/value.cpp:549:15: note: candidate function
Value &Value::operator=(char value)
^
src/value.cpp:609:15: note: candidate function
Value &Value::operator=(double value)
^
src/value.cpp:332:15: note: candidate function
Value &Value::operator=(Value &&value)
^
src/value.cpp:402:15: note: candidate function
Value &Value::operator=(const Value &value)
^
src/value.cpp:449:15: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &Value::operator=(std::nullptr_t value)
^
src/value.cpp:569:15: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &Value::operator=(const std::string &value)
^
src/value.cpp:589:15: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &Value::operator=(const char *value)
^
src/value.cpp:694:62: error: call to member function 'operator=' is ambiguous
Value &Value::operator%=(bool value) { return operator=(numericValue() % value); }
^~~~~~~~~
src/value.cpp:469:15: note: candidate function
Value &Value::operator=(int16_t value)
^
src/value.cpp:489:15: note: candidate function
Value &Value::operator=(int32_t value)
^
src/value.cpp:509:15: note: candidate function
Value &Value::operator=(int64_t value)
^
src/value.cpp:529:15: note: candidate function
Value &Value::operator=(bool value)
^
src/value.cpp:549:15: note: candidate function
Value &Value::operator=(char value)
^
src/value.cpp:609:15: note: candidate function
Value &Value::operator=(double value)
^
src/value.cpp:332:15: note: candidate function
Value &Value::operator=(Value &&value)
^
src/value.cpp:402:15: note: candidate function
Value &Value::operator=(const Value &value)
^
src/value.cpp:449:15: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &Value::operator=(std::nullptr_t value)
^
src/value.cpp:569:15: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &Value::operator=(const std::string &value)
^
src/value.cpp:589:15: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &Value::operator=(const char *value)
^
src/value.cpp:695:62: error: call to member function 'operator=' is ambiguous
Value &Value::operator%=(char value) { return operator=(numericValue() % value); }
^~~~~~~~~
src/value.cpp:469:15: note: candidate function
Value &Value::operator=(int16_t value)
^
src/value.cpp:489:15: note: candidate function
Value &Value::operator=(int32_t value)
^
src/value.cpp:509:15: note: candidate function
Value &Value::operator=(int64_t value)
^
src/value.cpp:529:15: note: candidate function
Value &Value::operator=(bool value)
^
src/value.cpp:549:15: note: candidate function
Value &Value::operator=(char value)
^
src/value.cpp:609:15: note: candidate function
Value &Value::operator=(double value)
^
src/value.cpp:332:15: note: candidate function
Value &Value::operator=(Value &&value)
^
src/value.cpp:402:15: note: candidate function
Value &Value::operator=(const Value &value)
^
src/value.cpp:449:15: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &Value::operator=(std::nullptr_t value)
^
src/value.cpp:569:15: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &Value::operator=(const std::string &value)
^
src/value.cpp:589:15: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &Value::operator=(const char *value)
^
src/value.cpp:696:62: error: call to member function 'operator=' is ambiguous
Value &Value::operator%=(const std::string &value) { return operator=(numericValue() % atoi(value.c_str())); }
^~~~~~~~~
src/value.cpp:469:15: note: candidate function
Value &Value::operator=(int16_t value)
^
src/value.cpp:489:15: note: candidate function
Value &Value::operator=(int32_t value)
^
src/value.cpp:509:15: note: candidate function
Value &Value::operator=(int64_t value)
^
src/value.cpp:529:15: note: candidate function
Value &Value::operator=(bool value)
^
src/value.cpp:549:15: note: candidate function
Value &Value::operator=(char value)
^
src/value.cpp:609:15: note: candidate function
Value &Value::operator=(double value)
^
src/value.cpp:332:15: note: candidate function
Value &Value::operator=(Value &&value)
^
src/value.cpp:402:15: note: candidate function
Value &Value::operator=(const Value &value)
^
src/value.cpp:449:15: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &Value::operator=(std::nullptr_t value)
^
src/value.cpp:569:15: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &Value::operator=(const std::string &value)
^
src/value.cpp:589:15: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &Value::operator=(const char *value)
^
src/value.cpp:697:62: error: call to member function 'operator=' is ambiguous
Value &Value::operator%=(const char *value) { return operator=(numericValue() % atoi(value)); }
^~~~~~~~~
src/value.cpp:469:15: note: candidate function
Value &Value::operator=(int16_t value)
^
src/value.cpp:489:15: note: candidate function
Value &Value::operator=(int32_t value)
^
src/value.cpp:509:15: note: candidate function
Value &Value::operator=(int64_t value)
^
src/value.cpp:529:15: note: candidate function
Value &Value::operator=(bool value)
^
src/value.cpp:549:15: note: candidate function
Value &Value::operator=(char value)
^
src/value.cpp:609:15: note: candidate function
Value &Value::operator=(double value)
^
src/value.cpp:332:15: note: candidate function
Value &Value::operator=(Value &&value)
^
src/value.cpp:402:15: note: candidate function
Value &Value::operator=(const Value &value)
^
src/value.cpp:449:15: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &Value::operator=(std::nullptr_t value)
^
src/value.cpp:569:15: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &Value::operator=(const std::string &value)
^
src/value.cpp:589:15: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &Value::operator=(const char *value)
^
src/value.cpp:698:62: error: call to member function 'operator=' is ambiguous
Value &Value::operator%=(double value) { return operator=(numericValue() % (int)value); }
^~~~~~~~~
src/value.cpp:469:15: note: candidate function
Value &Value::operator=(int16_t value)
^
src/value.cpp:489:15: note: candidate function
Value &Value::operator=(int32_t value)
^
src/value.cpp:509:15: note: candidate function
Value &Value::operator=(int64_t value)
^
src/value.cpp:529:15: note: candidate function
Value &Value::operator=(bool value)
^
src/value.cpp:549:15: note: candidate function
Value &Value::operator=(char value)
^
src/value.cpp:609:15: note: candidate function
Value &Value::operator=(double value)
^
src/value.cpp:332:15: note: candidate function
Value &Value::operator=(Value &&value)
^
src/value.cpp:402:15: note: candidate function
Value &Value::operator=(const Value &value)
^
src/value.cpp:449:15: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &Value::operator=(std::nullptr_t value)
^
src/value.cpp:569:15: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &Value::operator=(const std::string &value)
^
src/value.cpp:589:15: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &Value::operator=(const char *value)
^
src/value.cpp:765:62: error: ambiguous conversion for functional-style cast from 'long' to 'Php::Value'
Value Value::operator%(const Value &value) { return Value(numericValue() % value.numericValue()); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/value.cpp:58:8: note: candidate constructor
Value::Value(int16_t value)
^
src/value.cpp:69:8: note: candidate constructor
Value::Value(int32_t value)
^
src/value.cpp:80:8: note: candidate constructor
Value::Value(int64_t value)
^
src/value.cpp:91:8: note: candidate constructor
Value::Value(bool value)
^
src/value.cpp:102:8: note: candidate constructor
Value::Value(char value)
^
src/value.cpp:136:8: note: candidate constructor
Value::Value(double value)
^
src/value.cpp:208:8: note: candidate constructor
Value::Value(const Value &that)
^
src/value.cpp:265:8: note: candidate constructor
Value::Value(Value &&that)
^
src/value.cpp:766:62: error: ambiguous conversion for functional-style cast from 'long' to 'Php::Value'
Value Value::operator%(int16_t value) { return Value(numericValue() % value); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/value.cpp:58:8: note: candidate constructor
Value::Value(int16_t value)
^
src/value.cpp:69:8: note: candidate constructor
Value::Value(int32_t value)
^
src/value.cpp:80:8: note: candidate constructor
Value::Value(int64_t value)
^
src/value.cpp:91:8: note: candidate constructor
Value::Value(bool value)
^
src/value.cpp:102:8: note: candidate constructor
Value::Value(char value)
^
src/value.cpp:136:8: note: candidate constructor
Value::Value(double value)
^
src/value.cpp:208:8: note: candidate constructor
Value::Value(const Value &that)
^
src/value.cpp:265:8: note: candidate constructor
Value::Value(Value &&that)
^
src/value.cpp:767:62: error: ambiguous conversion for functional-style cast from 'long' to 'Php::Value'
Value Value::operator%(int32_t value) { return Value(numericValue() % value); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/value.cpp:58:8: note: candidate constructor
Value::Value(int16_t value)
^
src/value.cpp:69:8: note: candidate constructor
Value::Value(int32_t value)
^
src/value.cpp:80:8: note: candidate constructor
Value::Value(int64_t value)
^
src/value.cpp:91:8: note: candidate constructor
Value::Value(bool value)
^
src/value.cpp:102:8: note: candidate constructor
Value::Value(char value)
^
src/value.cpp:136:8: note: candidate constructor
Value::Value(double value)
^
src/value.cpp:208:8: note: candidate constructor
Value::Value(const Value &that)
^
src/value.cpp:265:8: note: candidate constructor
Value::Value(Value &&that)
^
src/value.cpp:769:62: error: ambiguous conversion for functional-style cast from 'long' to 'Php::Value'
Value Value::operator%(bool value) { return Value(numericValue() % value); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/value.cpp:58:8: note: candidate constructor
Value::Value(int16_t value)
^
src/value.cpp:69:8: note: candidate constructor
Value::Value(int32_t value)
^
src/value.cpp:80:8: note: candidate constructor
Value::Value(int64_t value)
^
src/value.cpp:91:8: note: candidate constructor
Value::Value(bool value)
^
src/value.cpp:102:8: note: candidate constructor
Value::Value(char value)
^
src/value.cpp:136:8: note: candidate constructor
Value::Value(double value)
^
src/value.cpp:208:8: note: candidate constructor
Value::Value(const Value &that)
^
src/value.cpp:265:8: note: candidate constructor
Value::Value(Value &&that)
^
src/value.cpp:770:62: error: ambiguous conversion for functional-style cast from 'long' to 'Php::Value'
Value Value::operator%(char value) { return Value(numericValue() % value); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/value.cpp:58:8: note: candidate constructor
Value::Value(int16_t value)
^
src/value.cpp:69:8: note: candidate constructor
Value::Value(int32_t value)
^
src/value.cpp:80:8: note: candidate constructor
Value::Value(int64_t value)
^
src/value.cpp:91:8: note: candidate constructor
Value::Value(bool value)
^
src/value.cpp:102:8: note: candidate constructor
Value::Value(char value)
^
src/value.cpp:136:8: note: candidate constructor
Value::Value(double value)
^
src/value.cpp:208:8: note: candidate constructor
Value::Value(const Value &that)
^
src/value.cpp:265:8: note: candidate constructor
Value::Value(Value &&that)
^
src/value.cpp:771:62: error: ambiguous conversion for functional-style cast from 'long' to 'Php::Value'
Value Value::operator%(const std::string &value) { return Value(numericValue() % atoi(value.c_str())); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/value.cpp:58:8: note: candidate constructor
Value::Value(int16_t value)
^
src/value.cpp:69:8: note: candidate constructor
Value::Value(int32_t value)
^
src/value.cpp:80:8: note: candidate constructor
Value::Value(int64_t value)
^
src/value.cpp:91:8: note: candidate constructor
Value::Value(bool value)
^
src/value.cpp:102:8: note: candidate constructor
Value::Value(char value)
^
src/value.cpp:136:8: note: candidate constructor
Value::Value(double value)
^
src/value.cpp:208:8: note: candidate constructor
Value::Value(const Value &that)
^
src/value.cpp:265:8: note: candidate constructor
Value::Value(Value &&that)
^
src/value.cpp:772:62: error: ambiguous conversion for functional-style cast from 'long' to 'Php::Value'
Value Value::operator%(const char *value) { return Value(numericValue() % atoi(value)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/value.cpp:58:8: note: candidate constructor
Value::Value(int16_t value)
^
src/value.cpp:69:8: note: candidate constructor
Value::Value(int32_t value)
^
src/value.cpp:80:8: note: candidate constructor
Value::Value(int64_t value)
^
src/value.cpp:91:8: note: candidate constructor
Value::Value(bool value)
^
src/value.cpp:102:8: note: candidate constructor
Value::Value(char value)
^
src/value.cpp:136:8: note: candidate constructor
Value::Value(double value)
^
src/value.cpp:208:8: note: candidate constructor
Value::Value(const Value &that)
^
src/value.cpp:265:8: note: candidate constructor
Value::Value(Value &&that)
^
src/value.cpp:773:62: error: ambiguous conversion for functional-style cast from 'long' to 'Php::Value'
Value Value::operator%(double value) { return Value(numericValue() % (int)value); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/value.cpp:58:8: note: candidate constructor
Value::Value(int16_t value)
^
src/value.cpp:69:8: note: candidate constructor
Value::Value(int32_t value)
^
src/value.cpp:80:8: note: candidate constructor
Value::Value(int64_t value)
^
src/value.cpp:91:8: note: candidate constructor
Value::Value(bool value)
^
src/value.cpp:102:8: note: candidate constructor
Value::Value(char value)
^
src/value.cpp:136:8: note: candidate constructor
Value::Value(double value)
^
src/value.cpp:208:8: note: candidate constructor
Value::Value(const Value &that)
^
src/value.cpp:265:8: note: candidate constructor
Value::Value(Value &&that)
^
In file included from src/value.cpp:27:
In file included from src/includes.h:89:
src/arithmetic.h:163:16: error: call to member function 'assign' is ambiguous
return assign(value.numericValue());
^~~~~~
src/value.cpp:629:90: note: in instantiation of member function 'Php::Arithmetic<std::plus>::assign' requested here
Value &Value::operator+=(const Value &value) { return Arithmetic<std::plus>(this).assign(value); }
^
src/arithmetic.h:171:12: note: candidate function
Value &assign(int16_t value)
^
src/arithmetic.h:185:12: note: candidate function
Value &assign(int32_t value)
^
src/arithmetic.h:199:12: note: candidate function
Value &assign(int64_t value)
^
src/arithmetic.h:213:12: note: candidate function
Value &assign(bool value)
^
src/arithmetic.h:227:12: note: candidate function
Value &assign(char value)
^
src/arithmetic.h:266:12: note: candidate function
Value &assign(double value)
^
src/arithmetic.h:157:12: note: candidate function
Value &assign(const Value &value)
^
src/arithmetic.h:244:12: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &assign(const std::string &value)
^
src/arithmetic.h:255:12: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &assign(const char *value)
^
src/arithmetic.h:177:24: error: call to member function 'operator=' is ambiguous
return _value->operator=(F<long>()(_value->numericValue(), value));
~~~~~~~~^~~~~~~~~
src/value.cpp:630:90: note: in instantiation of member function 'Php::Arithmetic<std::plus>::assign' requested here
Value &Value::operator+=(int16_t value) { return Arithmetic<std::plus>(this).assign(value); }
^
src/../include/value.h:151:12: note: candidate function
Value &operator=(int16_t value);
^
src/../include/value.h:152:12: note: candidate function
Value &operator=(int32_t value);
^
src/../include/value.h:153:12: note: candidate function
Value &operator=(int64_t value);
^
src/../include/value.h:154:12: note: candidate function
Value &operator=(bool value);
^
src/../include/value.h:155:12: note: candidate function
Value &operator=(char value);
^
src/../include/value.h:158:12: note: candidate function
Value &operator=(double value);
^
src/../include/value.h:142:12: note: candidate function
Value &operator=(Value &&value);
^
src/../include/value.h:150:12: note: candidate function
Value &operator=(const Value &value);
^
src/../include/value.h:149:12: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &operator=(std::nullptr_t value);
^
src/../include/value.h:156:12: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &operator=(const std::string &value);
^
src/../include/value.h:157:12: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &operator=(const char *value);
^
In file included from src/value.cpp:27:
In file included from src/includes.h:89:
src/arithmetic.h:191:24: error: call to member function 'operator=' is ambiguous
return _value->operator=(F<long>()(_value->numericValue(), value));
~~~~~~~~^~~~~~~~~
src/value.cpp:631:90: note: in instantiation of member function 'Php::Arithmetic<std::plus>::assign' requested here
Value &Value::operator+=(int32_t value) { return Arithmetic<std::plus>(this).assign(value); }
^
src/../include/value.h:151:12: note: candidate function
Value &operator=(int16_t value);
^
src/../include/value.h:152:12: note: candidate function
Value &operator=(int32_t value);
^
src/../include/value.h:153:12: note: candidate function
Value &operator=(int64_t value);
^
src/../include/value.h:154:12: note: candidate function
Value &operator=(bool value);
^
src/../include/value.h:155:12: note: candidate function
Value &operator=(char value);
^
src/../include/value.h:158:12: note: candidate function
Value &operator=(double value);
^
src/../include/value.h:142:12: note: candidate function
Value &operator=(Value &&value);
^
src/../include/value.h:150:12: note: candidate function
Value &operator=(const Value &value);
^
src/../include/value.h:149:12: note: candidate function not viable: no known conversion from 'long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
Value &operator=(std::nullptr_t value);
^
src/../include/value.h:156:12: note: candidate function not viable: no known conversion from 'long' to 'const std::string' (aka 'const basic_string<char, char_traits<char>,
allocator<char> >') for 1st argument
Value &operator=(const std::string &value);
^
src/../include/value.h:157:12: note: candidate function not viable: no known conversion from 'long' to 'const char *' for 1st argument
Value &operator=(const char *value);
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [src/value.o] Error 1
We have just added the Php::Countable interface that can be implemented by your own class:
class MyClass : public Php::Base, public Php::Countable
{
public:
virtual Php::Value count() override
{
return 12;
}
};
If you make a class that extends from this Php::Countable "interface", your class is automatically converted into a PHP class that implements the built-in Countable interface from the SPL. In my opinion this is the most simple, most straight forward and most intuitive way to implement SPL interfaces, as the C++ code is almost identical to the PHP code that achieves the same.
There is however a drawback. In PHP it is possible to create an abstract class that implements the Countable interface, but that does not have an implementation for the count() method:
abstract class MyClass implements Countable
{
}
This would not be possible in C++. The compiler would always complain that an implementation for the count() method is missing. Is this a big problem? I think not, but I'd like to hear other arguments.
Further more, when you now implement the interface, the count() method is not yet automatically registered too. You still have to register this method by hand when you set up the Php::Extension object. This should not be necessary: implementing the interface should be enough. This should be fixed.
Once we have finished this Php::Countable interface, other SPL interfaces should be added too: Php::ArrayAccess, Php::Iterator, et cetera.
This is a public issue. I will eventually solve this myself, but since my time is limited and this is an open source project, it would be cool if someone could help me with this.
Hi there,
I've managed to get PHP-CPP compiling and linking on OSX (10.9.2) targeting PHP5.5. Because it uses clang on OSX by default, there were some issues to be resolved with both compilation and linking. The Makefile is changed as well.
I will open a pull request tomorrow while I review and clean some things. This is just a heads up, so you'll know it is working. I cannot test is on Linux, since I don't have access to a Linux machine for now, so I don't know how GCC behaves on the changes. I;m fearing it will break the build.
Tomorrow I can access a Linux machine at work, so I can test it myself before opening a pull request, if it's desired.
Thanks!
Perhaps this might be of use to you.
Hey Emiel,
Sup sup,
I'd like to point out that whatever is going on here is probably not what should be happening. This, in fact, is happening on multiple places. There are tools to fix that for you.
I just thought I'd point this out, in case you'd forget.
Magic methods that still need to be implemented:
__construct()
__destruct()
__clone()
__callStatic()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.