Description
Hey!
I wonder if there is medium that could be added between the standard setup and the setup with FORCE_ARRAY?
We use FORCE_ARRAY mostly for legacy reasons (many years ago, it was easy to segfault standard mode from user code, whereas FORCE_ARRAY was mostly protected), but also because 99% of the time when passing back objects, associative arrays are want we want in PHP.
However, the benefit of standard mode is the use of 'this'. A basic example of how we sort of implement things:
// the main runner...
$v8js = new V8Js('cs');
$userCode = ...get user code...;
$result = $v8js->executeString('
function userCode() {
' . $userCode . '
}
result = userCode();
', null, V8Js::FLAG_FORCE_ARRAY);
and some example 'userCode':
return {
main: function (param1, param2) {
}
somefunc: function (param1) {
}
}
This means the user can write 'hooks' that are called on the $result
, e.g. $result['main']($someval, $otherVal);
at various points. This works well, but as userCode gets more complex, you often want to use this
to organise things better:
return {
name: "foo",
main: function (param1, param2) {
return somevar = this.somefunc(param1) + param2;
},
somefunc: function (param1) {
return this.name;
}
another: function () {
return [
"foo": "alice",
"bar": "bob"
];
}
}
or something like that. The problem though, is FORCE_ARRAY returns, well, an array and not a V8Object, so the concept of this
doesn't exist.
On the flipside, if we use it as standard without FORCE_ARRAY, then (using the last example):
function someThingInPHP(array $array) {
}
someThingInPHP($result->another());
This will result in a fatal error because $result->another()
will return a V8Object, not an array so the typehint will fatal.
So I guess I'm wondering if there is a halfway house, where BOTH could be used somewhat. MAYBE something like:
- Add an extra option, such as AUTO_CONVERT or whatever (doesn't matter what it's called at this point)
- This will essentially work 99% like FORCE_ARRAY entirely, with some exceptions:
- Date objects and some of the other clever things, those will remain - so anything not a V8Function or V8Object will remain as they are. PHP will get the object.
- Then - either a class can be instantiated in JS (and as its constructor.name is not V8Object, it will be left alone) - or an extra feature/special wrapper object can be utilised to wrap a JS object to 'protect' it from conversion to an array.
- Otherwise, any other associative array would be converted to a PHP associative array.
- This would apply to both assoc arrays returned from JS, as well as those passed in to extra custom functions attached to the V8Js instance (i.e.
$v8js->someFunc = function (array $settings) { };
)
TLDR: Introduce an option almost entirely like FORCE_ARRAY, but with a handful of exceptions and the ability to skip conversion at runtime for certain objects.
Any thoughts? @stesie