php-cpp extension class arrayaccess return self reference

281 views Asked by At

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 !

0

There are 0 answers