首页 > 解决方案 > Microsoft Translator API v3 - PHP 使用 cURL 代替 file_get_contents

问题描述

我想将以下代码从 file_get_contents 转换为 curl。这是因为如果 file_get_contents 失败,它不会从 API 返回错误消息。

这是 Microsoft 的示例 PHP 脚本(稍作修改),它按预期工作:

$key  = "my_valid_subscription_key_xxxxxxxxxxx";
$host = "https://api.cognitive.microsofttranslator.com";
$path = "/translate?api-version=3.0";

// Translate from English to Spanish.
$params = "&from=en&to=es";
$text   = "Hello world";

function create_guid()
{
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand(0, 0xffff), mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0x0fff) | 0x4000,
        mt_rand(0, 0x3fff) | 0x8000,
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
    );
}

function translate($host, $path, $key, $params, $content)
{
    $headers = "Content-type: application/json\r\n" .
    "Content-length: " . strlen($content) . "\r\n" .
    "Ocp-Apim-Subscription-Key: $key\r\n" .
    "X-ClientTraceId: " . create_guid() . "\r\n";

    $options = array(
        'http' => array(
            'header'  => $headers,
            'method'  => 'POST',
            'content' => $content,
        ),
    );
    $context = stream_context_create($options);
    $result  = file_get_contents($host . $path . $params, false, $context);
    return $result;
}

$request_body = [['Text' => $text]];
$content      = json_encode($request_body);
$result       = Translate($host, $path, $key, $params, $content);
$json         = json_decode($result);
echo $json[0]->{'translations'}[0]->{'text'}; // prints: Hola Mundo

这是我尝试让它与 curl 一起使用。它返回代码 401000 错误消息。该请求未获得授权,因为凭据丢失或无效。get_token() 函数按预期工作。

$key  = "my_valid_subscription_key_xxxxxxxxxxx";    
$auth_url = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";

// Translate from English to Spanish.
$string    = "Hello world";
$from_lang = 'en';
$to_lang   = 'es';
$host      = "https://api.cognitive.microsofttranslator.com";
$path      = "/translate?api-version=3.0";
$host_path = $host . $path;

function get_token($key, $auth_url)
{
    $azure_key   = $key;
    $ch          = curl_init();
    $data_string = json_encode('{body}');
    $headers     = [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($data_string),
        'Ocp-Apim-Subscription-Key: ' . $azure_key,
    ];
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_URL, $auth_url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}

function create_guid()
{
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand(0, 0xffff), mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0x0fff) | 0x4000,
        mt_rand(0, 0x3fff) | 0x8000,
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
    );
}

function translate($string, $from_lang, $to_lang, $host_path, $token, $guid)
{
    $headers = [
        "Authorization: Bearer " . $token . ", " .
        "Content-type: application/json, " .
        "Content-length: " . strlen($string) . ", " .
        "X-ClientTraceId: " . $guid
    ];

    $data = [
        'api-version' => '3.0',
        'body'        => urlencode($string),
        'from'        => 'en',
        'to'          => 'en',
        'textType'    => 'html',
    ];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $host_path);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($ch, CURLOPT_REFERER, $host_path);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    $result = curl_exec($ch);
    $info   = curl_getinfo($ch);
    var_dump($info, $result);

}

$token = get_token($key, $auth_url); // this works as expected
$guid  = create_guid();
translate($string, $from_lang, $to_lang, $host_path, $token, $guid);

这是 var_dump 的输出:

array (size=26)
  'url' => string 'https://api.cognitive.microsofttranslator.com/translate?api-version=3.0' (length=71)
  'content_type' => string 'application/json; charset=utf-8' (length=31)
  'http_code' => int 401
  'header_size' => int 308
  'request_size' => int 1239
  'filetime' => int -1
  'ssl_verify_result' => int 0
  'redirect_count' => int 0
  'total_time' => float 0.343
  'namelookup_time' => float 0.062
  'connect_time' => float 0.125
  'pretransfer_time' => float 0.265
  'size_upload' => float 62
  'size_download' => float 111
  'speed_download' => float 323
  'speed_upload' => float 180
  'download_content_length' => float 111
  'upload_content_length' => float 62
  'starttransfer_time' => float 0.343
  'redirect_time' => float 0
  'redirect_url' => string '' (length=0)
  'primary_ip' => string '40.90.141.99' (length=12)
  'certinfo' => 
    array (size=0)
      empty
  'primary_port' => int 443
  'local_ip' => string '192.168.0.103' (length=13)
  'local_port' => int 58143

string '{"error":{"code":401000,"message":"The request is not authorized because credentials are missing or invalid."}}' (length=111)

标签: phpcurlmicrosoft-translator

解决方案


推荐阅读