Hoi,

ik ben terug aan het programmeren geslagen en wou nog eens proberen een OOP member systeem maken. Ik heb daarvoor het dataMapper patern gebruikt dat WouterJ me eens had geleerd.

Kunnen jullie eens kijken of mijn structuur goed zit?



User_User

<?php

/* user class */

class User_User
{
	private $name;
	private $password;
	private $email;
	private $id;

	public function __construct($name, $password, $email)
	{
		$this->name = (string) $name;
		$this->password = (string) $password;
		$this->email = (string) $email;
	}

	public function setId($value)
	{
		$this->id = $value;
	}

	public function setName($value)
	{
		$this->name = $value;
	}

	public function setPassword($value)
	{
		$this->password = $value;
	}

	public function setEmail($value)
	{
		$this->email = $value;
	}

	public function getId()
	{
		return $this->id;
	}

	public function getName()
	{
		return $this->name;
	}

	public function getPassword()
	{
		return $this->password;
	}

	public function getEmail()
	{
		return $this->email;
	}
}


?>


User_UserMapper

<?php

class User_UserMapper
{
	protected $db; // db abstractielaag

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


	/**
     * Uit de database komt een array, populate maakt van de array een User object
     */
    public function populate(array $data)
    {
        $user = new User_User($data['name'], $data['password'], $data['email']);
        $user->setId($data['id']);

        return $user;
    }

	public function getUserById($id)
	{
		$qry = $this->db->prepare("SELECT name, password, email FROM users WHERE id = ?");

        $qry->execute(array((int) $id));
        $result = $qry->fetch(PDO::FETCH_ASSOC);
        $result['id'] = (int) $id;

        return $this->populate($result);
	}

	public function getUserByPassAndEmail($email, $password)
	{
		$qry = $this->db->prepare("SELECT id, name FROM users WHERE email = ? AND password = ?");

        $qry->execute(array($email, $password));
        $result = $qry->fetch(PDO::FETCH_ASSOC);
        $result['email'] = $email;
        $result['password'] = $password;

        return $this->populate($result);
	}

    public function saveUser(User $user)
    {

    }

    public function deleteUserById($id)
    {
        
    }
}

?>


Session_Session
<?php

class Session_Session
{
public function __construct($id)
{
$_SESSION['user_id'] = $id;
}
}

?>

Public/index.php
<?php
include('../lib/autoLoader.php');

$db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$userMapper = new User_UserMapper($db);
$jasper = $userMapper->getUserByPassAndEmail('jasp.***@gmail.com', 'test123');
echo $jasper->getName(); // geeft jasper -> OK
new Session_Session($jasper->getId());
echo $_SESSION['user_id']; // geeft 1 -> OK
?>

Bedankt!
Hoi,

ik ga het nog eens overlopen want ik ben weer even de weg kwijt. Ik heb volgende classes:


- User is gewoon het object User.
- UserMapper is de datalaag?
- PDODatabaseStorage is de databaselaag?

Als ik dus nu een user in de database wil steken krijgen we denk ik:
<?php
// User Object aanmaken
$user = new User('Jasper');
$user->setEmail('[email protected]');
$user->setPassword();

// Steek in de database
$pdo = new PDO(...);
$pdoStorage = new PDODatabaseStorage($pdo);
$userMapper = new UserMapper($pdoStorage);
$userMapper->create($user);
?>

dat klopt al hé?
Ja, wat je nu hebt is goed. Het User object is een Entity, een object dat gegevens vasthoudt en meer eigenlijk niet. De DatabaseStorage is de abstracte database layer, de laag over de database waardoor de database flexibel wordt. De UserMapper is een DataMapper, het object dat tussen de databaselaag en de User entity inzit.
Oke maar dan zit ik nog altijd met het probleem van een paar topics terug.

Hoe koppel ik mijn UserMapper aan mijn PDODatabaseStorage? Ik snap dat we de storage meegeven aan de UserMapper en dat we daar dan bijvoorbeeld de create functie op kunnen aanroepen. Maar volgens de StorageInterface moet create een storableInterface object binnenkrijgen, mijn functie krijgt een array binnen waardoor ik foutmeldingen kweek.

En hoe zit het met functie's zoals getById of getByEmailAndPass? Is dat allemaal via de read function?
We moeten die Storage anders gaan bouwen. Die moet een object binnenkrijgen en heel dat object gaan opslaan. Je moet alle get functies krijgen en dan deze opslaan in het bij behorende veld.
In het geval van een sessie wil je niet alles opslaan, dan kun je nog een 3e parameter toevoegen waarin je in een array zet welke velden je wilt opslaan.

Dit gaat wel erg gecompliceerd worden, dus ben je opzoek naar een uitdaging dan kun je hieraan beginnen, ik zal je wel her en der een duwtje in de rug geven. Maar eigenlijk raad ik je aan dan te gaan werken met een Object Relation Mapper, ORM, zoals Doctrine2. Dat is één van de meestgebruikte libraries voor het geen we hier nu aan het doen zijn.

De getById en getByEmailAndPass zijn gewoon aparte functies in de mapper en die gaan inderdaad via de read functie.
Oke, dat wil dus zeggen dan ik een lib moet gaan inladen van iemand anders?

Dat was eigenlijk net het gene dat ik niet wou doen, ik wou zoveel mogelijk code zelf schrijven omdat ik daar meer van leer. Indien ik het ORM gewoon moet zien als een pattern dan is dit oke voor mij. Ik zal eens wat googlen op die term en zien waar ik kom.

Bedankt!
Je kan het ook zelf maken, maar dat gaat je enorm veel tijd kosten. En als je echt niks van een ander wilt hebben ga je het nog moeilijk krijgen. Je moet gewoon dingen die erg ingewikkeld zijn en al een keer perfect zijn opgelost door anderen gebruiken.

Of ORM een pattern is weet ik niet, ik denk het niet. Meer een systeem.
Dus eigenlijk valt er geen net OOP login-systeempje te schrijven zonder het gebruik van het werk van derden?

Maar oke, ik zal mij gaan verdiepen in het ORM.
Dat kan wel, maar het gaat je heel veel, naar mijn mening, onnodig tijd kosten. Maar je kan eens gaan kijken of je je eigne ORM'tje kan maken.
Wouter, in deze dia reeks staat bij de lijst van ORM's o.a. PDO. Klopt het dat PDO ook een ORM is? Verder zie ik daar ORM's staan van verschillende frameworks zoals kohana en Zend. Ik veronderstel dat ze allemaal ongeveer hetzelfde werken en dat de keuze dus niet erg veel uitmaakt?
PDO zou je ook wel kunnen zien als een ORM, maar niet in de vorm hoe ik hem hier gebruik.

Ik raad je aan Doctrine te gebruiken, dat is een losstaande applicatie met enorm veel mogelijkheden, misschien wel te uitgebreid. Mocht je hem te uitgebreid vinden dan kun je misschien beter naar Propel kijken of inderdaad een van de frameworks.

Mocht je willen gaan werken met Doctrine of Propel dan raad ik je aan de Symfony2 documentatie te lezen. Ik weet het, het klinkt vreemd, maar het is een hele goede documentatie om je kennis te laten maken met Doctrine of Propel en heel erg veel heeft niks met Symfony2 te maken: Doctrine (generate:* commands zijn SF specifiek en je moet doctrine op een andere manier verkijgen dan $this->getDoctrine()) en propel.

Reageren