I have trouble with a custom extension in php. I am extening Php::ArrayAccess for a self made object and I am able to use my object in PHP juste like a native array. BUT I can not chain the operators [] even though I am returning a reference to my object in the implementation of offsetGet. I get this error :
PHP Fatal error: Cannot use object of type Jq as array in ... (myfile.php on line 0)
#include <phpcpp.h>
#include <iostream>
#include <sstream>
#include <algorithm>
class Jq : public Php::Base, public Php::ArrayAccess
{
public:
Jq()
{
}
virtual ~Jq()
{
}
void __construct(Php::Parameters& params)
{
std::string localParam1 = params[0];
std::string localParam2 = params[1];
_pathToJq = localParam1;
_pathToCacheFile = localParam2;
}
Php::Value __toString()
{
return asString();
}
Php::Value asString()
{
std::ostringstream os;
os << _pathToJq << ' ' << _pathToCacheFile << " : " << _filters.str();
return os.str();
}
virtual bool offsetExists(const Php::Value &key) override
{
return true;
}
virtual Php::Value offsetGet(const Php::Value& key) override
{
return &((*this)[key]);
}
virtual void offsetSet(const Php::Value &key, const Php::Value &value) override
{
}
virtual void offsetUnset(const Php::Value &key) override
{
}
Jq& operator[] (const std::string& key)
{
const std::string offset = key;
if (is_number(offset)) {
if (_filters.tellp() > 0) {
_filters << '[' << offset << ']';
} else {
_filters << ".[" << offset << ']';
}
} else {
_filters << '.' << offset;
}
return *this;
}
private:
std::string _pathToJq;
std::string _pathToCacheFile;
std::ostringstream _filters;
std::ostringstream _chainedOutput;
bool is_number(const std::string& s)
{
return !s.empty() && std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c); }) == s.end();
}
};
/**
* tell the compiler that the get_module is a pure C function
*/
extern "C" {
/**
* Function that is called by PHP right after the PHP process
* has started, and that returns an address of an internal PHP
* strucure with all the details and features of your extension
*
* @return void* a pointer to an address that is understood by PHP
*/
PHPCPP_EXPORT void *get_module()
{
// static(!) Php::Extension object that should stay in memory
// for the entire duration of the process (that's why it's static)
static Php::Extension extension("jq", "0.0.1");
// @todo add your own functions, classes, namespaces to the extension
Php::Class<Jq> jq("Jq");
jq.method("__construct", &Jq::__construct);
jq.method("__toString", &Jq::__toString);
jq.method("asString", &Jq::asString);
//jq.method("offsetGet", &Jq::offsetGet);
// add the class to the extension
extension.add(std::move(jq));
// return the extension
return extension;
}
}
and the php code to be executed:
<?php
$jqa = new Jq("pathJQ", "pathCache");
// This is fine !
echo $jqa['test'] . PHP_EOL;
// This is fine too !
echo $jqa . PHP_EOL;
// But This is not !
echo $jqa['coc']['players'][0]['name'] . PHP_EOL;
Thank's for your help !