Connect PDO in slim 3 for API creation


#1

I’m creating API using slim 3 but i dont know how to access pdo connection variable in Middleware and models if anyone have example code please share.

Thank you.
Guna.


#2

Within a middleware closure you can access all container entries via $this->get('{id}');

Example

use Slim\Container;
use Slim\Http\Request;
use Slim\Http\Response;

// middleware
$app->add(function (Request $request, Response $response, $next) {
    /** @var Container $this */
    /** @var PDO $pdo */
    $pdo = $this->get('pdo'); // <--- customize this name

    $userRows = $pdo->query('SELECT * FROM users')->fetchAll();

    // ...

    return $response;
});

Edit:

i try to access pdo in model its saying PDO not found

Slim uses a dependency container to prepare, manage, and inject application dependencies.

Add a PDO service to Slim container (e.g. in dependencies.php)

$container = $app->getContainer();

$container['pdo'] = function (Container $container) {
    // better load the settings with $container->get('settings')
    $host = '127.0.0.1';
    $dbname = 'test';
    $username = 'root';
    $password = '';
    $charset = 'utf8';
    $collate = 'utf8_unicode_ci';
    $dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";
    $options = [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_PERSISTENT => false,
        PDO::ATTR_EMULATE_PREPARES => false,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES $charset COLLATE $collate"
    ];

    return new PDO($dsn, $username, $password, $options);
};

#3

Hi Odan,

First of all Thank you for your valuable reply.

It’s working only on routes not in models if try to access models its showing not found PDO variable on models actually i’m using MVC structure inside src->appName->models. using auto load PSR-4

Thank you.


#4

Ok then please give us more context informations and show us code of your existing model class.


#5

Hi Odan,

Thank you for quick reply please find below details.

Folder Structure:
Slim3_folder_structure

index.php
<?php
use Test\Middleware\Authentication as TestAuth;

        	require 'config/Constents.php';
        	require 'config/DbParams.php';
        	require 'vendor/autoload.php';

        	$config = [
        	    'settings' => [
        	        'displayErrorDetails' => true, // set to false in production

        	        // Database connection settings
        	        "db" => [
        	            "host" => DbHost,
        	            "dbname" => DbName,
        	            "user" => DbUser,
        	            "pass" => DbPass
        	        ],
        	    ],
        	];

        	$app = new \Slim\App ($config);


        	// DIC configuration
        	$container = $app->getContainer();

        	// PDO database library 
        	$container ['con'] = 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;
        	};

        	$app->add (new TestAuth ($container));

        	$app->get('/hello/{name}', function ($request, $response, $args) {
        		$email = "test@gmail.com";
        		$password = "1798";

        		$stmt = $this->con->prepare("SELECT * FROM users WHERE email=?");

        		$stmt->execute([$email]);
        		$num_rows = $stmt->rowCount();
        		// return $num_rows>0;

        	    $name = $args['name'];
        	    // $response->getBody()->write("Hello, $name");
        	   	$user_id = $request->getAttribute('UserData');
        	    return $response->withJson ($user_id);
        	});

        	$app->run();
    ?>

Authentication.php

<?php
	
	namespace Test\Middleware;

	use Test\Models\TokenHandler;
	use Test\Models\User;

	class Authentication {

		private $container;

	    public function __construct ($container) {
	        $this->container = $container ['con'];
	    }

		public function __invoke ($request, $response, $next) {

			$Auth 		= $request->getHeader('Authorization');
	        $Apikey 	= $Auth[0];
	        $ApikeyTemp = substr($Apikey, strpos($Apikey, ' '));
	        // Create TokenHandler Object
	        $TokenHandler = new TokenHandler ();
	        // Decryption
	        $Apikey 	= $TokenHandler->decryption (trim($ApikeyTemp));

	        $user = new User ($this->container);

	        if (!is_object ($Apikey) || !$user->isVerification(@$Apikey->email, @$Apikey->password)) {
	            $response->withStatus(401);
	            return $response;
	        }

	        $request = $request->withAttribute('UserData', $Apikey);
	        $response = $next($request, $response);

	        return $response;

		} // __invoke - End

	} // class - End
?>

User.php

<?php

	namespace Test\Models;

	class User {

		// DbConnection variable
		public $con;

		function __construct ($db) {
			$this->con = $db;
		} // __construct - End

		// User Verification
		public function isVerification ($email, $password) {
	   		try {
	   			$sql = "SELECT * FROM users WHERE email=? AND password=?";
				$stmt = $this->con->prepare($sql);
				$stmt->execute([$email, $password]);
				$num_rows = $stmt->rowCount();
				return $num_rows>0;
			} catch (PDOException $e) {

				die($e->getMessage());
			}

	   } // isUserLoginCheck - End

	} // class - End

In User.php im not able to access the PDO Connection but in Authentication.php middleware i’m able to access and hello route call also i’m able to access please tell me for user.php model?

if is it possible please tell me through PSR-4 autoload.

Thank you.


#6

Just pass the database connection (PDO) object (and not the container) into the User object.

This line is confusing in Authentication.php:

public function __construct ($container) {
    $this->container = $container ['con'];
}

Change it to:

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

Then change this line

$user = new User ($this->container);

to:

$user = new User($this->container->con);

In User.php change:

public $con;

to

private $con;

#7

Hi Odan,

Thanks for your reply but its working i know. I want to access the PDO connection variable on models directly.

I know how to access from middleware and routes file when you call
$app->get('/', \HomeController::class . ':home');
like this i want to access PDO variable from models

Thanks.