phpv8 / v8js

V8 Javascript Engine for PHP — This PHP extension embeds the Google V8 Javascript Engine
http://pecl.php.net/package/v8js
MIT License
1.83k stars 200 forks source link

Is there any way to make HTTP requests? #344

Closed mrcsmcln closed 6 years ago

mrcsmcln commented 6 years ago

Title pretty much says it all. typeof XMLHttpRequest returns "undefined", as expected. I tried using axios, which works both client- and server-side for Node environments, but it depends on the http module, which is obviously unavailable.

Is there any way I can make HTTP requests or do I need to inject that functionality before executing JS? For example:

PHP:

$v8js->client = new \GuzzleHttp\Client();
stesie commented 6 years ago

This extension just provides access to V8 itself + bindings to add to it from PHP side. This is you get a vanilla JavaScript interpreter. XMLHttpRequest is a browser extension to JavaScript, http is a Node.js module.

TL;DR you are right, by default php-v8js does not allow to do HTTP requests. So if you want your JS code to be able to fire HTTP requests, you need to expose something from PHP side first (e.g. exposing Guzzle)

chenos commented 6 years ago

Perhaps you can write like this:

class XMLHttpRequest
{
    protected $rootUrl;

    protected $url;

    protected $method;

    protected $async;

    protected $user;

    protected $password;

    public $status;

    public $readyState;

    public $responseText;

    public $onreadystatechange;

    public function __construct($rootUrl = null)
    {
        $this->rootUrl = $rootUrl;
    }

    public function open($method, $url, $async = true, $user = '', $password = '')
    {
        $this->method = $method;
        $this->url = $url;
        $this->async = $async;
        $this->user = $user;
        $this->password = $password;
    }

    public function send($data = '')
    {
        if (!$this->isUrl($this->url) && $this->isUrl($this->rootUrl)) {
            $this->url = $this->rootUrl.$this->url;
        }

        if (is_object($data)) {
            $data = get_object_vars($data);
        } elseif (is_string($data)) {
            $data = http_build_query($data)
        }

        $context = stream_context_create([
            'http' => [
                'method'  => $this->method,
                'header'  => 'Content-type: application/x-www-form-urlencoded',
                'content' => $data,
            ],
        ]);

        $this->responseText = file_get_contents($this->url, false, $context);
        $this->status = 200;
        $this->readyState = 4;

        if (is_callable($this->onreadystatechange)) {
            call_user_func($this->onreadystatechange);
        }
    }

    protected function isUrl($url)
    {
        return filter_var($url, FILTER_VALIDATE_URL) !== false;
    }
}

$v8 = new \V8Js();

$v8->XMLHttpRequest = function () {
    return new XMLHttpRequest;
};

$v8->executeString('
    var XMLHttpRequest = PHP.XMLHttpRequest;
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
        // 
    }
    ajax.send({foo: "bar"});
');
andrii-trush commented 5 years ago

@chenos it crashes on $v8->XMLHttpRequest

Are there any ideas?