使用Doctrine DBAL的Php Symfony 3.1异常

问题描述:

I'm trying to use Doctrine DBAL in my Symfony web project.

What I've done:

Config.yml

# Doctrine Configuration
doctrine:
    dbal:
        driver:   pdo_pgsql
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8

parameters.yml

parameters:
    database_host: 127.0.0.1
    database_port: 5432
    database_name: my_project_db
    database_user: postgres
    database_password: my_password

My controller for company profile

/**
 * @Route("/profile/{userId}/{sessionKey}", name="profile")
 */

public function profileAction($userId=null, $sessionKey=null)
{
    $securityController = new SecurityController();
    $securityController->userId = $userId;
    $securityController->sessionKey = $sessionKey;
    if ($securityController->sessionKeyIsValid())
    {
        return new Response('Profile');
    }
    else
    {
        return $this->redirectToRoute('login');
    }
}

And my securityController where I'm trying to connect to my Postresql

class SecurityController extends Controller
{
    public $userId;
    public $sessionKey;

    public function sessionKeyIsValid()
    {
        $conn = $this->get('database_connection');
        //$conn->fetchAll('select * from main.users;');
        return false;
    }
}

Exception (Error: Call to a member function get() on null) appears on this string of code $conn = $this->get('database_connection'); What I'm doing wrong? It seems that I followed step by step as is it advised in Symfony cookBook http://symfony.com/doc/current/cookbook/doctrine/dbal.html

In a Symfony project, you never instantiate yourself a controller. If you want to separate your logic from your controller, create a service and inject what you need as a dependency.

Your service for instance may look like this :

namespace AppBundle\Service;

use Doctrine\DBAL\Connection;

class SecurityService 
{
    protected $db;
    public $userId;
    public $sessionKey;

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

    public function sessionKeyIsValid()
    {
        // $this->db->fetchAll('select * from main.users;');
    }
}

And you declare it in your services.yml like this :

services:
    app_security:
       class:        AppBundle\Service\SecurityService
       arguments:   [ "@database_connection" ]

Then, in any controller, you have access to a shared instance of SecurityService :

public function profileAction($userId=null, $sessionKey=null)
{
    $security = $this->get('app_security');

    // ...
}

I must warn you however that accessing directly to the database layer is probably not the correct way. You should read the Databases and Doctrine section from the documentation first.

Container is not set, so you cann't call its methods.

$securityController = new SecurityController();
$securityController->userId = $userId;
$securityController->sessionKey = $sessionKey
$securityController->setContainer($this->container);

I think that it is not good idea to use SecurityController as controller, it is a service.