Bread09
@Bread09
Newonkiy

Как выполнить PHP скрипт на NodeJS?

Есть сайт на NodeJS expressjs. Хочу подключить виджет-карту от СДЭК, но у них скрипт запроса для для Api написан на php.

service.php
<?php

$service = new service(/**
 * Вставьте свой аккаунт\идентификатор для интеграции
 * Put your account for integration here
 */ 'cdek-login',

    /**
     * Вставьте свой пароль для интеграции
     * Put your password for integration here
     */ 'cdek-pass');
$service->process($_GET, file_get_contents('php://input'));

class service
{
    /**
     * @var string Auth login
     */
    private $login;
    /**
     * @var string Auth pwd
     */
    private $secret;
    /**
     * @var string Base Url for API 2.0 Production
     */
    private $baseUrl;
    /**
     * @var string Auth Token
     */
    private $authToken;
    /**
     * @var array Data From Request
     */
    private $requestData;

    public function __construct($login, $secret, $baseUrl = 'https://api.cdek.ru/v2')
    {
        $this->login = $login;
        $this->secret = $secret;
        $this->baseUrl = $baseUrl;
    }

    public function process($requestData, $body)
    {
        $this->requestData = array_merge($requestData, json_decode($body, true) ?: array());

        if (!isset($this->requestData['action'])) {
            $this->sendValidationError('Action is required');
        }

        $this->getAuthToken();

        switch ($this->requestData['action']) {
            case 'offices':
                $this->sendResponse($this->getOffices());
            case 'calculate':
                $this->sendResponse($this->calculate());
            default:
                $this->sendValidationError('Unknown action');
        }
    }

    private function sendValidationError($message)
    {
        $this->http_response_code(400);
        header('Content-Type: application/json');
        echo json_encode(array('message' => $message));
        exit();
    }

    private function getAuthToken()
    {
        $result = json_decode($this->httpRequest('oauth/token', array(
            'grant_type' => 'client_credentials',
            'client_id' => $this->login,
            'client_secret' => $this->secret,
        ), true), true);
        if (!isset($result['access_token'])) {
            throw new RuntimeException('Server not authorized to CDEK API');
        }

        $this->authToken = $result['access_token'];
    }

    private function httpRequest($method, $data, $useFormData = false, $useJson = false)
    {
        $ch = curl_init("$this->baseUrl/$method");

        $headers = array (
            'Accept: application/json',
        );

        if ($this->authToken) {
            $headers[] = "Authorization: Bearer $this->authToken";
        }

        if ($useFormData) {
            curl_setopt_array($ch, array(
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $data,
            ));
        } elseif ($useJson) {
            $headers[] = 'Content-Type: application/json';
            curl_setopt_array($ch, array(
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => json_encode($data),
            ));
        } else {
            curl_setopt($ch, CURLOPT_URL, "$this->baseUrl/$method?" . http_build_query($data));
        }

        curl_setopt_array($ch, array(
            CURLOPT_USERAGENT => 'widget/2.0',
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_RETURNTRANSFER => true,
        ));

        $result = curl_exec($ch);

        if ($result === false) {
            throw new RuntimeException(curl_error($ch), curl_errno($ch));
        }

        return $result;
    }

    private function sendResponse($data)
    {
        $this->http_response_code(200);
        header('Content-Type: application/json');
        echo $data;
        exit();
    }

    protected function getOffices()
    {
        return $this->httpRequest('deliverypoints', $this->requestData);
    }

    protected function calculate()
    {
        return $this->httpRequest('calculator/tarifflist', $this->requestData, false, true);
    }

    private function http_response_code($code)
    {
        switch ($code) {
            case 100: $text = 'Continue'; break;
            case 101: $text = 'Switching Protocols'; break;
            case 200: $text = 'OK'; break;
            case 201: $text = 'Created'; break;
            case 202: $text = 'Accepted'; break;
            case 203: $text = 'Non-Authoritative Information'; break;
            case 204: $text = 'No Content'; break;
            case 205: $text = 'Reset Content'; break;
            case 206: $text = 'Partial Content'; break;
            case 300: $text = 'Multiple Choices'; break;
            case 301: $text = 'Moved Permanently'; break;
            case 302: $text = 'Moved Temporarily'; break;
            case 303: $text = 'See Other'; break;
            case 304: $text = 'Not Modified'; break;
            case 305: $text = 'Use Proxy'; break;
            case 400: $text = 'Bad Request'; break;
            case 401: $text = 'Unauthorized'; break;
            case 402: $text = 'Payment Required'; break;
            case 403: $text = 'Forbidden'; break;
            case 404: $text = 'Not Found'; break;
            case 405: $text = 'Method Not Allowed'; break;
            case 406: $text = 'Not Acceptable'; break;
            case 407: $text = 'Proxy Authentication Required'; break;
            case 408: $text = 'Request Time-out'; break;
            case 409: $text = 'Conflict'; break;
            case 410: $text = 'Gone'; break;
            case 411: $text = 'Length Required'; break;
            case 412: $text = 'Precondition Failed'; break;
            case 413: $text = 'Request Entity Too Large'; break;
            case 414: $text = 'Request-URI Too Large'; break;
            case 415: $text = 'Unsupported Media Type'; break;
            case 500: $text = 'Internal Server Error'; break;
            case 501: $text = 'Not Implemented'; break;
            case 502: $text = 'Bad Gateway'; break;
            case 503: $text = 'Service Unavailable'; break;
            case 504: $text = 'Gateway Time-out'; break;
            case 505: $text = 'HTTP Version not supported'; break;
            default:
                exit('Unknown http status code "' . htmlentities($code) . '"');
                break;
        }

        $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
        header($protocol . ' ' . $code . ' ' . $text);
        $GLOBALS['http_response_code'] = $code;
    }
}


Запустил это все на тестовом сервере XAMPP все работает, но капризная какая-то
localhost/sim/index.php - работает
localhost/sim/index.php/ -
Uncaught SyntaxError: Unexpected token '<' (at cdek-widget.umd.js:1:1)


Так вот. Как сделать, чтобы NodeJS обрабатывал PHP скрипты? Хотя мне кажеться лучше переписать service.php под js.
  • Вопрос задан
  • 452 просмотра
Пригласить эксперта
Ответы на вопрос 3
yarkov
@yarkov
Помог ответ? Отметь решением.
Хотя мне кажеться лучше переписать service.php под js.

И это правильный ответ
Ответ написан
Steel_Balls
@Steel_Balls
Переписать на NodeJs - единственный вариант. Делов - на пару часов.
Ответ написан
@Nc_Soft
Можно запустить php из node, но лучше sdk поискать
const spawn = require('child_process').spawn;

(async () => {
  const promise = new Promise((resolve, reject) => {
    const output = {
      data: '',
      errors: '',
    };
    options = [
      'code.php',
    ];
    const process = spawn('/opt/homebrew/bin/php', options);
    process.stdout.on('data', (data) => {
      output.data += data.toString();
    });
    process.stderr.on('data', (data) => {
      output.errors += data.toString();
    });
    process.on('exit', (code) => {
      resolve(output);
    });
  });
  const data = await promise;
  console.info(data);
})();
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы