Reusing variable names seems harmless until you’re deep in a debugging session wondering why your logs don’t match reality. Here’s a common trap and how to avoid it.
The Bug
You’re calling a payment gateway API. You build the request payload, send it, get a response. Standard stuff:
public function processPayment($amount, $currency)
{
$data = [
'amount' => $amount,
'currency' => $currency,
'merchant_id' => config('payment.merchant_id'),
];
Log::info('Sending payment request', ['data' => $data]);
$response = Http::post('https://api.paymentgateway.com/charge', $data);
$data = $response->json();
if ($data['status'] === 'success') {
Log::info('Payment succeeded', ['data' => $data]);
return $data['transaction_id'];
}
Log::error('Payment failed', ['data' => $data]);
throw new PaymentException($data['message']);
}
Looks fine. But when you check logs after an error, you see:
Sending payment request: {"status":"failed","message":"Invalid merchant"}
Payment failed: {"status":"failed","message":"Invalid merchant"}
Wait, what? The “sending” log shows the response, not the request.
What Happened
You logged $data before the API call, but $data got overwritten by the response on line 11. Laravel’s logger is lazy—it doesn’t serialize variables immediately. When the log actually writes, $data now holds the response, not the request.
Result: both log entries show the same value (the response), making debugging a nightmare.
The Fix: Use Different Variable Names
Don’t reuse $data for two conceptually different things:
public function processPayment($amount, $currency)
{
$payload = [
'amount' => $amount,
'currency' => $currency,
'merchant_id' => config('payment.merchant_id'),
];
Log::info('Sending payment request', ['payload' => $payload]);
$response = Http::post('https://api.paymentgateway.com/charge', $payload);
$responseData = $response->json();
if ($responseData['status'] === 'success') {
Log::info('Payment succeeded', ['response' => $responseData]);
return $responseData['transaction_id'];
}
Log::error('Payment failed', ['response' => $responseData]);
throw new PaymentException($responseData['message']);
}
Now your logs are correct:
Sending payment request: {"amount":1000,"currency":"USD","merchant_id":"123"}
Payment failed: {"status":"failed","message":"Invalid merchant"}
Why This Matters
- Logs are your debugging lifeline. If they lie, you’re lost.
$data,$result,$response— these names are magnets for reuse.- Lazy logging (common in Laravel, Monolog, etc.) means variable references get resolved later, not when you call
Log::info().
Rule of Thumb
If you’re logging a variable, don’t overwrite it afterward. Give each conceptual “thing” its own name: $request, $response, $payload, $result.
Debugging is hard enough. Don’t let your variable names lie to you.
Leave a Reply