Вы захотите инкапсулировать cURL с помощью класса / метода или функции, чтобы вы могли легко повторить вызов. Если есть SDK, вероятно, стоит использовать. Если нет, попробуйте что-то вроде класса или инкапсуляции для очистки вашего кода.
Исходя из вашего собственного ответа, было бы лучше сделать функцию для части cURL:
# Contain all your call login inside this function,
# it keeps copy/paste down to minimum
function transmit($path, &$token, $attr = false, $method = 'get', $retry = true)
{
# I would trim any leading/trailing separator because it will add it
# automatically down below
$path = trim($path, '/');
# Fetch the token if it's not already set though ignore if login or
# it will likely do an infinite loop
if(empty($token) && $path != 'login')
$token = fetchToken();
# Since this will almost never change, just assign it here. If they ever change
# then you just change it in this one spot instead of every instance in your
# whole site where you copy/pasted it
$endpoint = "https://rota.com/publicapi";
# Create the query automatically
if($attr) {
$query = http_build_query($attr);
$attr = '?'.$query;
}
# Create the final path
# array_filter will remove empty attributes before imploding to a path
$url = implode('/', array_filter([
$endpoint,
# Make sure to remove the token on a login call
($path == 'login')? false : $token,
$path,
$attr
]));
# Standard start here
$curl = curl_init();
# Compile the endpoint
curl_setopt ($curl, CURLOPT_URL, $url);
# If you want to specifically post, then accommodate. Just change "$method" in
# when you call this function
if($method == 'post') {
# First check if there is a query already created
if($query)
curl_setopt($curl2, CURLOPT_POSTFIELDS, $query);
}
# Standard bit here
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
# Standard exec
$response = curl_exec($curl);
# Same ol
curl_close($curl);
# Just check for a portion of the string is necessary
if(stripos($response, 'Token not valid') !== false) {
# Fetch the token, if it fails, the program will throw exception
$token = fetchToken();
# If you have it set to retry original, it will try again
if($retry) {
# Set to stop retrying here. You don't want an infinite loop
return transmit($path, $token, $attr, $method, false);
}
# Stop at this point
return false;
}
# If token was valid, send back original response
return $response;
}
# Create a function to fetch the token in the background
function fetchToken()
{
# Send a post
$fetchToken = transmit('login', false, [
'username' => 'whatever',
'password' => 'whatever'
], 'post', false);
if($fetchToken) {
# Convert the string to xml
$xml = simplexml_load_string($output, null, LIBXML_NOCDATA);
# Assign token to session for storage and then also update the session
# for calls that happen after this call
$token = trim($xml->token->__toString());
}
# Stop the program if token not fetched
if(empty($token))
throw Exception('An error occurred fetching the security token.');
# Assign to session and return the token
return $_SESSION['rota_token'] = $token;
}
Таким образом, вы должны быть в состоянии сделать это следующим образом:
# Try and get token
# If this line throws error, use:
# $token = ($_SESSION['rota_token'])? $_SESSION['rota_token'] : false;
$token = ($_SESSION['rota_token'])?? false;
# Fetch the data and make sure to pass the token to each transmit()
$data = transmit('date/2020-04-02/locations/', $token);
print_r($data);
В любом случае, я не проверил это полностью, поэтому в синтаксисе может быть что-то, но он сильно прокомментирован, поэтому вы можете получить то, что должно произойти .