Symfony Использование сервиса в другом сервисе

У меня есть приложение Symfony 4, которое вызывает службу базы данных из службы сеанса.

Служба базы данных имеет __construct методы, которые получают учетные данные БД из services.yaml

БД Сервис

namespace App\Services;

class Database {

private $conn;

public function __construct($host, $name, $user, $pass){

$this->conn = mysqli_connect($host,$user,$pass,$name) or die('error: cannot connect');
}

//...
}

конфиг / services.yaml

services:
App\Services\Database:
arguments:
$host: '1.2.3.4.5'
$name: 'database_name'
$user: 'username'
$pass: 'password'

Я использую этот сервис в сервисе Sessions, используемом контроллером входа в систему.

Контроллер входа

namespace App\Controller;

use App\Services\Database;
use App\Services\Session;

// ...
// ...
if($login_valid){
//...
$session = new Session();
$session->create();
}

Сервис сеансов

namespace App\Services;

use App\Services\Database;

class Session {

private $DB;

public function __construct(){

$this->DB = new Database();  // ** ERROR **
}

public function create(){

$this->DB->insert('a new session'); // (pseudo-code)
}
//...
}

Это приводит к ошибке при настройке экземпляра службы БД в службе сеансов. Ошибка заключается в следующем:
введите описание изображения ей <! DOCTYPE html><html itemscope itemtype=

Symfony PHP — Использование сервиса в другом сервисе — Переполнение стека






















Решение

У меня есть приложение Symfony 4, которое вызывает службу базы данных из службы сеанса.

Служба базы данных имеет __construct методы, которые получают учетные данные БД из services.yaml

БД Сервис

namespace App\Services;

class Database {

private $conn;

public function __construct($host, $name, $user, $pass){

$this->conn = mysqli_connect($host,$user,$pass,$name) or die('error: cannot connect');
}

//...
}

конфиг / services.yaml

services:
App\Services\Database:
arguments:
$host: '1.2.3.4.5'
$name: 'database_name'
$user: 'username'
$pass: 'password'

Я использую этот сервис в сервисе Sessions, используемом контроллером входа в систему.

Контроллер входа

namespace App\Controller;

use App\Services\Database;
use App\Services\Session;

// ...
// ...
if($login_valid){
//...
$session = new Session();
$session->create();
}

Сервис сеансов

namespace App\Services;

use App\Services\Database;

class Session {

private $DB;

public function __construct(){

$this->DB = new Database();  // ** ERROR **
}

public function create(){

$this->DB->insert('a new session'); // (pseudo-code)
}
//...
}

Это приводит к ошибке при настройке экземпляра службы БД в службе сеансов. Ошибка заключается в следующем:
введите описание изображения здесь

__construct вызывается метод для БД, который принимает 4 аргумента (определенных глобально в services.yaml), который я не предоставляю при создании экземпляра службы БД внутри службы Session.

Но это не тот случай, когда я таким образом создаю службу БД прямо в контроллере.

Кроме того, не является одним из преимуществ использования __construct с сервисными аргументами, установленными в services.yaml чтобы избежать необходимости передавать эти аргументы каждый раз?

Symfony знает, чтобы стрелять __construct когда вызывается служба БД, и необходимые ей аргументы устанавливаются прямо в services.yaml — что дает?

самый старый «data-shortcut =» O

Другие решения

Короче говоря, вам нужно использовать внедрение зависимости.

Вы правы, регистрируя Database аргументы класса в services.ymlSymfony может вводить эти значения во время создания. Однако это делается только автоматически при использовании контейнера внедрения зависимостей.

Вам нужно будет использовать это как в LoginController и в вашем Session оказание услуг.

LoginController

namespace App\Controller

use App\Services\Session;

class LoginController
{
private $session;

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

сессия

namespace App\Services;

use App\Services\Database;

class Session
{
private $db;

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

public function create(){

$this->db->insert('a new session'); // (pseudo-code)
}
}
голосует «data-shortcut =» V

3