Search code examples
phpoopdesign-patternspdodatamapper

PHP DataMapper pattern: My class needs an instance of PDO, I want to wrap it inside a Db class


here's what I have:

class Entry
{
    public $id;
    public $name;
    public $seoName;
    public $timeCreated;

    public function someFunction()
    {

    }

}

class EntryMapper
{
    protected $db;

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

    public function saveEntry(Entry &$entry)
    {
        if($entry->id){
            $sql = "";
    }
    else {
        $sql = "INSERT INTO tbl_entry (name, seo_name, time_created) VALUES (:name, :seo_name, :time_created)";
        $stmt = $this->db->prepare($sql);
        $stmt->bindParam("name", $entry->name);
        $stmt->bindParam("seo_name", $entry->seoName);
        $stmt->bindParam("time_created", $entry->timeCreated);
        $stmt->execute();
        $entry->id = $this->db->lastInsertId();
        }
    }

}

Now, here's how I use it in my view file (currently just testing insert command):

$entry = new Entry();

$entry->name = "Some Company LLC";
$entry->seoName = "some-company-llc";
$entry->timeCreated = date("Y-m-d H:i:s");

$entryMapper = new EntryMapper(new PDO("mysql:host=....."));
$entryMapper->saveEntry($entry);

I want to have the $entryMapper line like this:

$entryMapper = new EntryMapper(new Database());

meaning I should have a separate class Database.php where I would establish the connection.

I tried that, but since my class EntryMapper.php needs an instance of PDO directly, i'm getting an error. I have tried Database extend from PDO but that also raises error saying that PDO constructor was not called in EntryMapper

Any thoughts?

EDIT: if you see any signs of code coupling or similar, let me know because I want to learn to code properly. Thank you very much!


Solution

  • This is how I finally solved it (if a better implementation arises, I will for sure recode). It is an implementation of solution under the accepted answer here: Global or Singleton for database connection?

    My ConnFactory.php

    include('config/config.php');
    
    class ConnFactory
    {
        private static $factory;
    
        public static function getFactory()
        {
            if(!self::$factory){
                self::$factory = new ConnFactory();
                return self::$factory;
            }
    
        }
    
        private $db;
    
    public function pdo()
    {
        if(!$this->db){
            $options = array(
                PDO::ATTR_PERSISTENT => true,
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_EMULATE_PREPARES => false,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
            );
            $this->db = new PDO("mysql:host=".DB_HOST.";port=".DB_PORT.";dbname=".DB_SCHEMA."", DB_USER, DB_PASS, $options);
        }
        return $this->db;
        }
    
    }
    

    Usage in my view/html file (just a test of insert functionalty):

    $entry = new Entry();
    $entry->name = "Kartonaža ad Gradačac";
    $entry->seoName = "kartonaza-ad-gradacac";
    $entry->timeCreated = date("Y-m-d H:i:s");
    
    $entryMapper = new EntryMapper(ConnFactory::getFactory()->pdo());
    $entryMapper->saveEntry($entry);