Can anyone suggest me
If you haven’t heard of this before, it’s called Rubber Duck Debugging. You dont… actually need a rubber duck, but i use one.
The explanation is on wikipedia, but in short: Explain the relevant block of code to someone else - whether its a rubber duck, a teddy bear, a pet, or another person (The idea of it being a rubber duck is that you’re not interrupting someone else’s day to do this). Go line by line and explain what each line does, and usually you’ll find you get to a point where you find your problem because you’ll try to explain the line while looking at the code, and your brain will tell you “no, that’s not what it does.”
Alternatively, I have “rubber duck answered” myself more than once by starting to write a forum post here, explaining what i’ve done, and gotten to the same point - my explanation of the problem (if using enough detail) points my brain at where the problem lies, and I solve my problem before even pushing “Post”.
(and for the record, yes, that is [one of] my duck[s], and my screen.)
Well there’s a new one on me, “Rubber Duck Debugging” - I’ve never heard that term. But that method, having to explain what your code is supposed to do, is a good one.
Another thing I have to do, assuming my PHP is executing and also sending out HTML to my screen, is write debugging lines into a log file rather than the screen. If I output debug to the screen, it’s all over the place, interspersed with HTML. So I can look at the log file in an orderly way. I have a couple routines that take a log message, add the time, the calling routine, etc, and append the message to the log. I have a global “const DEBUG = true;” that turns debug logging on and off.
What I did just last night is I try to isolate the problem with error logs. Here’s an example of what I just did:
<?php
require_once __DIR__ . '/../config/starlite_config.php';
require_once "vendor/autoload.php";
use clearwebconcepts\{
ErrorHandler,
Database,
LoginRepository as Login
};
// Initialize
$errorHandler = new ErrorHandler();
set_exception_handler([$errorHandler, 'handleException']);
$database = new Database();
$pdo = $database->createPDO();
$login = new Login($pdo);
// Check if already logged in
if ($login->check_login_token()) {
header('Location: member.php');
exit();
}
// CSRF token for form protection
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// Cookie settings
$isLocal = in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1']);
$cookieDomain = $isLocal ? '' : 'www.phototechguru.com';
$cookieSecure = !$isLocal;
// Process login
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
error_log("Processing login form submission");
error_log("POST data: " . print_r($_POST, true));
error_log("Session before login: " . print_r($_SESSION, true));
if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
$username = strip_tags($_POST['username']);
$password = $_POST['password'];
if ($login->verify_credentials($username, $password)) {
error_log("Login successful");
error_log("Session after login: " . print_r($_SESSION, true));
error_log("Cookies after login: " . print_r($_COOKIE, true));
header('Location: member.php');
exit;
} else {
error_log("Login failed - invalid credentials");
$error = 'Invalid username or password';
}
} else {
error_log("CSRF token mismatch");
error_log("Session token: " . $_SESSION['csrf_token']);
error_log("POST token: " . $_POST['csrf_token']);
$error = 'Invalid form submission';
}
}
that way I can narrow it down to a section of code, plus I took breaks when I was getting frustrated.
I’ve done that so many times.
Rubber ducking without even realising it.
And now I know what those PHP elephants are for.
Well for me at least, these are the questions I ask myself when I’m debugging.
- What is the functionality/behavior I’m trying to achieve?
- What am I currently seeing?
- Terminate the code earlier with a custom random message such as “Exiting foreach loop” or “Inside Dinosaur class” or something like that.
- This helps you understand where the code is at during execution and helps determine if the execution is skipping certain checks or going into a logic that you didn’t intend to activate.
- Re-read the error message multiple times.
- Determine where the error is happening and what the error is telling you. Do you have a typo? Did you put in the wrong variable name? Did you reference something that didn’t exist?
- A lot of programming languages have pretty straightforward error messages, I know PHP does. Things such as
Undefined index: productid
screams “You dummy, you are referencing something in this array that doesn’t exists.” So next step would be to ask yourself “Why doesn’t it exist?” and then go from there.
- Test your code with multiple variations. Is it behaving how you intend it to be?
That’s how I usually troubleshoot.
As we often say on these forums… “What is it doing that it shouldnt be doing, or not doing that it should be?”
Try using Xdebug with a local server or tools like Ray or Laravel Telescope—they give deeper insights than console logs alone.