'Multiple DB-Tables in Repository - How to do this?

I have the following Code:

Controller

class UserController {
    
    public function __construct(userRepository $userRepository) {
        $this->userRepository = $userRepository;
    }
[...]

Repository

class UserRepository extends AbstractRepository {

    public function getTablename() {
        return "tbl_users";
    }

    public function getModel() {
        return "administration\\CMR\\UserModel";
    }
[...]

AbstractRepository

abstract class AbstractRepository {
    
    protected $pdo;

    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }
    
    abstract public function getTablename();
    abstract public function getModel();
    
    function readAll() {
        
        $table = $this->getTablename();
        $model = $this->getModel();
        
        $stmt = $this->pdo->query("SELECT * FROM $table");
        $res = $stmt->fetchAll(PDO::FETCH_CLASS, $model);
        return $res;
    }
[...]

My Problem is, that I need the "tbl_users" for one query and a secound table (tbl_locations) for another query. Could anyone please explain how to do this? I think it's unnecessary to write again the same readAll()-Function only with other variable.



Solution 1:[1]

Start by adding location repository

class LocationRepository extends AbstractRepository implements LocationRepositoryInterface {

    public function getTablename() {
        return "tbl_locations";
    }

    public function getModel() {
        return "administration\\CMR\\LocationModel";
    }
[...]

and put both repositories to upper layer, say UserLocationService.

class UserLocationService implements UserLocationInterface {
    public function __construct(
        protected UserRepositoryInterface $userRepository,
        protected LocationRepositoryInterface $locationRepository
    ) {
    }

[...]
}

This way you have separate repositories for users and locations, yet you can operate on both, in Service that does require both repositories to fulfill its' logic.

Solution 2:[2]

If I understand correctly, you want to be able to set the tablename to your likings. One possibility is to pass a tablename in the UserRepository constructor (and set a default), like this:

class UserRepository extends AbstractRepository {

    public function getTablename() {
        return $this->tablename;
    }

    public function getModel() {
        return "administration\\CMR\\UserModel";
    }
    [...]



abstract class AbstractRepository {
    
    protected $pdo;
    protected $tablename;

    public function __construct(PDO $pdo, string $tablename = "tbl_users") {
        $this->pdo = $pdo;
        $this->tablename = $tablename;
    }
    
    abstract public function getTablename();
    abstract public function getModel();
    
    function readAll() {
        
        $table = $this->getTablename();
        $model = $this->getModel();
        
        $stmt = $this->pdo->query("SELECT * FROM $table");
        $res = $stmt->fetchAll(PDO::FETCH_CLASS, $model);
        return $res;
    }
    [...]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 yergo
Solution 2 Jos Faber