Serjio Serjio - 7 months ago 24
SQL Question

pdo connection not working in php function

I have this function which is for throttling login, but I have problem, the pdo connections do not work inside the function, it gives me error for "undefined $conn or call to a member query function on null", if I'm correct it is due to the scope, is there any work around this?

<?php
function check(){
function get_multiple_rows($getfailed) {
$rows = array();
while($row = $getfailed->fetch(PDO::FETCH_ASSOC)) {
$rows[] = $row;
}
return $rows;
}
$throttle = array(1 => 1, 5 => 2, 30 => 10);
if ($getfailed = $conn->query("SELECT MAX(attempted) AS attempted FROM failed_logins")){
$rows = get_multiple_rows($getfailed);
$getfailed->closeCursor();
$latest_attempt = (int) date('U', strtotime($rows[0]['attempted']));
if ($getfailed = $conn->query("SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)")){
$rows = get_multiple_rows($getfailed);
$getfailed->closeCursor();
$failed_attempts = (int) $rows[0]['failed'];
krsort($throttle);
foreach ($throttle as $attempts => $delay){
if ($failed_attempts > $attempts) {
$remaining_delay = (time() - $latest_attempt) - $delay;
if ($remaining_delay < 0){
echo "You have exceeded the login attempts limit";
}
return false;
break;
}else{
return true;
}
}
}
}
}
?>

Answer

You could try to make your check Function receive an Argument like so:

<?php 
    function check(PDO $conn){
        function get_multiple_rows(PDOStatement $getfailed) {
            $rows = array();
            while($row = $getfailed->fetch(PDO::FETCH_ASSOC)) {
                $rows[] = $row;
            }
            return $rows;
        }
        $throttle = array(1 => 1, 5 => 2, 30 => 10);
        if ($getfailed = $conn->query("SELECT MAX(attempted) AS attempted FROM failed_logins")){
            $rows = get_multiple_rows($getfailed);
            $getfailed->closeCursor();
            $latest_attempt = (int) date('U', strtotime($rows[0]['attempted']));
            if ($getfailed = $conn->query("SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)")){
                $rows = get_multiple_rows($getfailed);
                $getfailed->closeCursor();
                $failed_attempts = (int) $rows[0]['failed'];
                krsort($throttle);
                foreach ($throttle as $attempts => $delay){
                    if ($failed_attempts > $attempts) {
                        $remaining_delay = (time() - $latest_attempt) - $delay;
                        if ($remaining_delay < 0){
                            echo "You have exceeded the login attempts limit";
                        }
                        return false;
                        break;
                    }else{
                        return true;
                    }
                }
            }
        }
    }

Now you can pass the $conn to your Function like so:

<?php
    check($conn);

Hope this helps...