PDO Not Found in Class


#1

I use the Slim Framework Skeleton and followed the user guide to get started. As part of guide i created a db container in the dependencies.php

    $container['db'] = function ($c) {
    $settings = $c->get('settings')['db'];
    $pdo = new PDO("mysql:host=" . $settings['host'] . ";dbname=" . $settings['dbname'],
        $settings['user'], $settings['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    return $pdo;
    };

now i can call stuff like this on my routes page which works fine

`$result  = $this->db->query("CALL user_info.`sp_user_login`('$userid', '$passwd')");`

but as this is not the best way i would like to move some db functions in to classes which i will call from my routes page like this

    $app->get('/test', function (Request $request, Response $response, array $args) {
    $blackObj = new Security\BlackList($this->db);
    $Success = $blackObj->check_token($_SERVER['REMOTE_ADDR']);
    echo $Success;
    });

the below code runs fine on the routes page but fails in my class

    public function check_token($ip)
    {
      $sth = $this->db->prepare('CALL `user_info`.`sp_ip_blacklist`(?)');
      $sth->bindParam(1, $IP, PDO::PARAM_STR, 20);
      $sth->execute();
      $todos = $sth->fetchAll();

      return count($todos);
     }

The error i am getting is

Type: Error Message:
Class ‘Security\PDO’ not found File: /var/www/html/api/src/Security/BlackList.php
Line: 46

So how do i make PDO known in my class, i inject the $this->db when calling my function but i guess thats not enough


#2

Are you importing PDO in your class? Is it namespaced?

use PDO;
// ...
$sth->bindParam(1, $IP, \PDO::PARAM_STR, 20);

#3

Nope i did not as i thought using the db which is a PDO object would be good enough. But yes adding use pdo to my class did the trick.


#4

You need use PDO because of the line above that you have in your class, or you can do \PDO::PARAM_STR, but this would mean doing it multiple places if you use a PDO constant anywhere else.


#5

By adding use pdo I was able to use the PDO::PARM_STR without the slash

Also is there a way to get access to the db which I created in the dependencies.php without injecting it in the call to the function ?


#6

Passing it to the class’s constructor from the container is the preferred way.


#7

Not to sound like a newbee to Slim OOP (which i am) can you provide a sample or link to one ?

This is how i do it right now hope thats what you mean …

$app->get('/black', function (Request $request, Response $response, array $args) {
$ipAddress = $request->getAttribute('ip_address');
$blackObj = new Security\BlackList($this->db);
$Success = $blackObj->check_ip_blacklist($ipAddress);
if ($Success == 1)
 {
  echo "user on black list";
 }
  else {
   echo "Your Ip ".$ipAddress." is not blacklisted";
 }
});

And my class look like this now

namespace Security;
use pdo;

final class BlackList
{
public $db;

public function __construct($db) {
	$this->db = $db;
}

public function check_token($ip)
{
  $sth = $this->db->prepare('CALL `user_info`.`sp_ip_blacklist`(?)');
  $sth->bindParam(1, $ip, PDO::PARAM_STR, 20);
  $sth->execute();
  $todos = $sth->fetchAll();

  return $todos;
}

#8

You are pretty much doing it by passing $this->db to your class. So it is clear that your class needs the db in order to function. There is a good overview of this here Dependency Injection Factories for Slim Controllers with some code examples.


#9

Namespaces may be case-insensitive, but autoloaders most often do. Write use PDO; instead.