phpv8 / php-v8

PHP extension for V8 JavaScript engine
https://php-v8.readthedocs.io
MIT License
217 stars 14 forks source link

Pros / cons with v8js? #8

Closed tahpot closed 7 years ago

tahpot commented 8 years ago

I just came across your project and it looks very interesting.

What motivated you to start this project?

What are the pros / cons of php-v8 vs v8js?

Thanks!

pinepain commented 8 years ago

Hi, thanks for you attention.

I initially started with v8js about two years ago, but then hit a limit with doing deep php/js objects integration for one of my side projects. I was thinking about providing some patch to v8js, but then realized that v8js goals may not be the same as mine.

There are also short section in readme about what php-v8 is, but I will try to cover the difference in advance, I wouldn't say that php-v8 and v8js have some advantages one over another, it seems to be they pursuit slightly different goals and are somehow different in it nature.

php-v8 is just V8 C++ API bridged to PHP. So you can do anything you want right from PHP. There are some simplification like you don't need to enter/leave Isolate and Context while it's done automatically and there are time and memory limits on per-isolate level (like in v8js).

With php-v8, v8js interface can be done on top of it purely in PHP userland. It wasn't my goal and this comparison is just to give you and further readers better perspective how these two projects php-v8 and v8js differs.

TL;DR

In my task I need to execute user submitted code, which can be anything, so I need some general-purpose language which is familiar to vast majority and secure sandbox where to execute that code.

After playing around v8js it came up that while it hides a lot of low-level interaction with v8, it doesn't fits well my need for arbitrary code execution. It propagate V8Js php object right to js, so it is possible to arbitrary code modify it properties intentionally or unintentionally for different purposes, e.g. start allocating php memory and kind of escape from v8js memory limits, overwrite some passed API objects and function, but not limited to. This could be eliminated by adding some V8Js::Set($name, $value, $flag='read/write/delete') method to be able to set readonly or even immutable properties on v8js root object (which available as a PHP in global space in js runtime).

Also there are few default functions which passed to js land like sleep() and exit() which also doesn't fits my need and even could be harmful in some of my use cases. Such issues could be solved by making exported functions deleteable (they were readonly, at least they were at that time I gave a look to v8js). Initially, I have v8js patched to remove readonly restriction and was unsetting these functions before executing user code.

Another, more complicated problem, is to pass and receive object to and from v8js, which can done via PHP object in global namespace or by returning result from script or from V8Function function call. These problems are negligible when you use v8js just to eval some code, but when it comes up to integrate some PHP api into it and start passing back and forth complex objects, which needs to be reflected in js in a specific way, they becomes noticeable, at least in my case. One of trickiest problems for me was triggering getting/setting/enumerating mechanism on PHP objects passed to v8 runtime. While v8js wrap php objects and then access/set all properties on every invocation, in my case where I had to pass a lot of domain objects which are intended for js runtime usage only and are not meant to be returned back to php runtime, it just doesn't make sense to propagate properties from js object back to php.

I don't think v8js is not good or designed improperly or whatever, it is really easy to get alongside with it, but for my tasks it doesn't fit well, so that how php-v8 appeared. But I was quite happy and used v8js in early stages of my project, so in most cases it should be enough.

php-v8 is just a tiny wrapper over V8 C++ API available as a PHP extension. You can now do anything you want right from PHP. I abstracted from entering/leaving Isolate and Context, it's done under the php-v8 hood. We can determine when we need to enter and what Isolate or Context we need to enter. For now we enter and then leave Isolate/Context on every case we need to do that, but it's on my list to do not leave Isolate/Conter premature to reduce that enter/leave cycles, but real effect should be measured because I'm not sure whether performance benefit (if any) worth potential codebase complication. I also added time and memory limits based on idea how v8js did that, but I have plan to switch to node's resource-guard approach to track resources usage, see guard.cc.

pinepain commented 8 years ago

I also package php-v8 for ubuntu, as well as it libv8 dependency, so you can get straight to using it and can easily integrate it into you ansible/chef/puppet/salt/whatever SCM do you use process. If you use OS X, there are also homebrew formula available to install php-v8 and v8 for it and I will maybe add it to official homebrew/php tap, it just needs to be figured out how to deal with libv8 shipped with it while I stick to latest V8 version to use all latest features and have more bugs fixed (if any).

Anyway, installation process is described in readme under Installation section so you can give it a try once you'll fine this extension interesting. I personally will appreciate any feedback and will try to provide assistance if there will be any questions.

pinepain commented 7 years ago

Closing as not an issue. Both projects are nice and I personally used v8js for some time.

TL;DR v8js is simpler and has simpler API which provides some high-level abstractions on top of V8, so I'd say it is more easier to get starting with. php-v8 is V8 API wrapper. It tends to be a low-level wrapper, anything above should be a part of userland PHP library. Both extensions do the job. Pick what better fits your needs.