Build URL Query - die Function ist eine Winzigkeit falsch, aber was?

Status
Dieses Thema wurde gelöst! Zur Lösung gehen…

loddarmattheus

Erfahrenes Mitglied
Nabend allerseits,
ich benötige mal wieder eine kurzen Schubs in die richtige Richtung.
Die Abfrage delete_order.php
PHP:
include('api.php');

$response = signedRequest('DELETE', 'api/v3/order', [
    'symbol' => 'BNBUSDT',
    'origClientOrderId' => 'eKpkXrBHAicWRoI5ZWVCNj'
  ]);

greift auf die function signedRequest in der api.php zu
Code:
$BASE_URL = 'https://testnet.binance.vision/'; // testnet

function signature($query_string, $secret) {
    return hash_hmac('sha256', $query_string, $secret);
}

function sendRequest($method, $path) {
  global $KEY;
  global $BASE_URL;
 
  $url = "${BASE_URL}${path}";

  echo "requested URL: ". PHP_EOL;
  echo $url. PHP_EOL;
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-MBX-APIKEY:'.$KEY));   
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_POST, $method == "POST" ? true : false);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $execResult = curl_exec($ch);
  $response = curl_getinfo($ch);
    
  // if you wish to print the response headers
  // echo print_r($response);

  curl_close ($ch);
  return json_decode($execResult, true);
}

function signedRequest($method, $path, $parameters = []) {
  global $SECRET;

  $parameters['timestamp'] = round(microtime(true) * 1000);
  $query = buildQuery($parameters);
  $signature = signature($query, $SECRET);
  return sendRequest($method, "${path}?${query}&signature=${signature}");
}

function buildQuery(array $params)
{
    $query_array = array();
    foreach ($params as $key => $value) {
        if (is_array($value)) {
            $query_array = array_merge($query_array, array_map(function ($v) use ($key) {
                return urlencode($key) . '=' . urlencode($v);
            }, $value));
        } else {
            $query_array[] = urlencode($key) . '=' . urlencode($value);
        }
    }
    return implode('&', $query_array);
}

Doch in dieser Codezeile höchstwahrscheinlich
PHP:
return sendRequest($method, "${path}?${query}&signature=${signature}");

wird die URL falsch zusammengebaut, wie mir die print_r($response) verrät. So kommt sie heraus:
requested URL: https://testnet.binance.vision/api/v3/order?symbol=BNBUSDT&origClientOrderId=eKpkXrBHAicWRoI5ZWVCNj×tamp=1659889249186&signature=9d5bff87c3ff63189519efbcbff96ae93c59e7d93e86eef5e250145f77f6f118

aber an der gekennzeichneten Stelle sollte nicht "×tamp" stehen sondern "&timestamp".

Kann mal bitte einer mit geübtem Auge darüberschauen?
 

Sempervivum

Erfahrenes Mitglied
Hier:
PHP: urlencode - Manual
wird das Problem angesprochen:
Seien Sie vorsichtig beim Umgang mit Variablen, die HTML-Entities enthalten könnten. Angaben wie &amp, &copy und &pound werden vom Browser geparst und die eigentliche Entität wird anstelle des gewünschten Variablennamens verwendet.
In diesem Thread:
cURL request converting "htmlentities" in the URL query string
handelte es sich um ein simples Missverständnis: Nur bei der Anzeige wandelte der Browser die Entity um.
Ich habe das mal getestet und konnte es bestätigen: Bei der Anzeige, die var_dump produziert, hatte ich ebenfalls den fehlerhaften String aber im Quelltext der Seite war es richtig:
entity-issue.jpg
Weil es außerhalb des <pre> steht, interpretiert der Browser die Entity.
Prüfe ob bei dir das gleiche der Fall ist.
 
Status
Dieses Thema wurde gelöst! Zur Lösung gehen…