mysteryfollow
mysteryfollow

Reputation: 59

How to implement php function in slim 3

I just learn slim 3 and I want to convert my slim 2 project to slim 3 but stuck in PHP function especially with argument. I don't know how to create function with argument and how to pass it.

For example I have one important function to get my user detail, I don't know how to convert to Slim 3.

Thank you

function internalUserDetails($input) {
    
    try {
        $db = getDB(); //when convert to slim 3, I declared the DB in dependencies so I have to call the DB with '$this->db'
        $sql = "SELECT user_id, name, email, username FROM users WHERE username=:input or email=:input";
        $stmt = $db->prepare($sql);
        $stmt->bindParam("input", $input,PDO::PARAM_STR);
        $stmt->execute();
        $usernameDetails = $stmt->fetch(PDO::FETCH_OBJ);
        $usernameDetails->token = apiToken($usernameDetails->user_id);
        $db = null;
        return $usernameDetails;
        
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}';
    }
    
}

This is the DB dependency code

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

When I run I got error

Using $this when not in object context

Upvotes: 0

Views: 591

Answers (2)

odan
odan

Reputation: 4952

In Slim 3 you should use the container to get the database instance.

Insert and adjust the necessary connection settings in the file config/settings.php

// Database settings
$config['db']['host'] = '127.0.0.1';
$config['db']['username'] = 'root';
$config['db']['password'] = '';
$config['db']['database'] = 'test';
$config['db']['charset'] = 'utf8';
$config['db']['collation'] = 'utf8_unicode_ci';

Add a container entry for the PDO connection

$container['db'] = function (Container $container) {
    $settings = $container->get('settings');
    $host = $settings['db']['host'];
    $dbname = $settings['db']['database'];
    $username = $settings['db']['username'];
    $password = $settings['db']['password'];
    $charset = $settings['db']['charset'];
    $collate = $settings['db']['collation'];
    $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);
};

Then inject the PDO instance into your controller class and access it via member variable.

protected $db;

public function __construct(Container $container)
{
    $this->db = $container->get('db');
}

public function internalUserDetails(Request $request, Response $response)
{
    $this->db ...
}

If you use the route callback then access the PDO instance like this:

$app->get('/', function (Request $request, Response $response, array $args) {
    $db = $this->get('db');
    // do something

    return $response;
});

Upvotes: 1

Nate
Nate

Reputation: 114

Create a class for your database:

<?php

class Database
{
    /**
     * Database username
     *
     * @var string
     */
    protected $username;

    /**
     * Database password
     *
     * @var string
     */
    protected $password;

    /**
     * Database host
     *
     * @var string
     */
    protected $host;

    /**
     * Database name
     *
     * @var string
     */
    protected $name;

    /**
     * Database constructor;
     */
    public function __construct()
    {
        try {

            // iniate $c... I'm not sure how you're getting the value..
            $c = [
                'settings' => [
                    'db' => [
                        'host'   => '',
                        'dbname' => '',
                        'user'   => '',
                        'pass'   => '',
                    ],
                ],
            ];
            $this->host     = $c['settings']['db']['host'];
            $this->name     = $c['settings']['db']['dbname'];
            $this->username = $c['settings']['db']['user'];
            $this->password = $c['settings']['db']['pass'];

            return $this->connect();
        }
    }

    /**
     * Connect to your database
     *
     * @return pdo
     */
    public function connect()
    {
        try{
            $pdo = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->name,
            $this->username, $this->password);

            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

            return $pdo;   
        } catch (Exception $ex){
            return $ex->getMessage();
        }

    }

}

Inside your class create a _construct for example:

/**
 * My Database
 *
 * @class 
 */
protected $db;

/**
 * Class constructor
 */
public function __construct(Database $database){
    $this->db = $database;
}

Your $this->db will then be assigned, so you can use it inside your methods

Upvotes: 0

Related Questions