[OOP] Login systeem

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Ventilatiesysteem Productontwikkelaar HBO WO Verwa

Samengevat: Zij bieden flexibele ventilatiematerialen, geluidsdempers, rookgasafvoer producten en industrieslangen. Ben jij een technisch productontwikkelaar? Heb jij ervaring met het ontwikkelen van nieuwe producten? Vaste baan: Technisch Productontwikkelaar HBO WO €3.000 - €4.000 Zij bieden een variëteit aan flexibele ventilatiematerialen, geluiddempers, rookgasafvoer producten, industrieslangen en ventilatieslangen voor de scheepsbouw. Met slimme en innovatieve materialen zorgen wij voor een gezonde en frisse leefomgeving. Deze werkgever is een organisatie die volop in ontwikkeling is met hardwerkende collega's. Dit geeft goede ontwikkelingsmogelijkheden. De branche van dit bedrijf is Techniek en Engineering. Functie: Voor de vacature als Technisch Productontwikkelaar Ede Gld HBO WO ga

Bekijk vacature »

Pagina: 1 2 volgende »

Jasper DS

Jasper DS

03/11/2012 21:01:04
Quote Anchor link
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?

Afbeelding

User_User
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?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
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?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
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
    
    class Session_Session
    {
        public function __construct($id)
        {

            $_SESSION['user_id'] = $id;
        }
    }


?>


Public/index.php
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?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!
Gewijzigd op 03/11/2012 21:02:25 door Jasper DS
 
PHP hulp

PHP hulp

16/04/2024 18:21:04
 
- Raoul -

- Raoul -

03/11/2012 21:57:42
Quote Anchor link
User_User is een beetje raar. Dat kan je gewoon vervangen door User en User_UserMapper door UserMapper.
Hetzelfde voor Session_Session. Als je zo wilt werken gebruik dan beter namespaces.
 
Wouter J

Wouter J

03/11/2012 22:48:38
Quote Anchor link
Raoul, het is niet raar eerder een oude versie van namespaces. Ik raad Jasper dan ook te gaan kijken naar het nieuwe namespace support in PHP, lees bijv. eens deze tutorial: http://net.tutsplus.com/tutorials/php/namespacing-in-php-2/

Verder ziet de code er goed uit, een beetje zoals ik hem ook al een paar had gemaakt. Je bent zeker enorme stappen opgeschoten sinds je laatste OO script!
Ik heb 4 tips voor je:

1. Programmeer naar een interface1
Het is altijd goed om naar een interface te programmeren, naar iets wat je klassen groepeert, wat je zekerheid biedt welke methods je kunt gebruiken en iets waar je op kunt vertrouwen. Maak bijv. een DataMapperInterface die methods als Mapper::populate(), Mapper::create(), Mapper::read(), Mapper::update(), Mapper::delete() verplicht stelt. En zo ook voor alle andere soorten.

2. Zie klassen meer als components dan als deel van een applicatie
Je ziet de klasse nog net iets te veel als deel van een applicatie. Je moet klassen zien als componenten die je overal kunt gebruiken. Vervolgens plaats je al deze componenten bij elkaar en maak je een klasse of een stukje flat PHP om al deze componenten om te zetten in een applicatie.

Dat zie je overal gebeuren in de OO wereld: Zend Framework bestaat uit 48 modules die los te gebruiken zijn en 1 module + wat flat PHP die deze vervolgens allemaal in elkaar zet en er een framework van maakt. Symfony werkt net zo.

Bij jou is dit nog niet zo. De sessie opsla klasse is nu alleen voor het opslaan van een user_id sessie, wat een beetje beperkt is. Ik zou sowieso de key variabel maken en misschien zou ik wel willen gaan voor een soort SessionMapper met de CRUD functies.

3. Maak gebruik van je setters/getters
Je setters moeten de enige methoden zijn die aan de properties mogen komen. Zij moeten er voor zorgen dat je de juiste waarde opslaat in de properties. Gebruik de setters en getters ook in een klasse, bijv. in de User constructor:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class User
{
    // ...

    public function __construct($name, $password)
    {

        $this->setName($name);
        $this->setName($password);
    }


    // ...
}
?>


4. Gebruik PHPdocs
Je code wil je zo duidelijk mogelijk maken, gebruik PHPdocs om aan te geven wat er allemaal in de functie moet gebeuren, bijv:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/**
 * A class that can handle sessions.
 *
 * @author Wouter J <http://wouterj.nl>
 */

class SessionStorage
{
    /**
     * Edits a session.
     *
     * @param string $id    The session name
     * @param mixed  $value The new value of the session
     *
     * @throws \InvalidArgumentException When the session did not exists
     *
     * @return string The new session
     */

    public function update($id, $value)
    {

        // ...
    }
}

?>



Nog een wat kleiner tipje: Ik zou wat precies zijn in je variabele. $value zegt niet heel veel, gebruik welke value dat is. Bijv niet setName($value) maar setName($name).

1) Met een interface wordt vaak een echt Interface bedoelt, het kan echter ook voorkomen dat er een abstracte klasse voor de 'superklasse' functie zorgt.
Gewijzigd op 03/11/2012 23:16:29 door Wouter J
 
Jasper DS

Jasper DS

03/11/2012 23:13:35
Quote Anchor link
Wouter, ontzettend bedankt voor de tips! Als ik je ooit eens tegen kom heb je een pintje van mij te goed. ;-)

Ik ga aan de slag. Die namespaces is inderdaad nog wel een belangrijk punt bij mij want User_User staat inderdaad niet.

bedankt!

Edit:

Je bedoelt dus met de CRUD-functions dat ik mijn sessie ook zou moeten kunnen wijzigen, lezen, maken, ... ? En eventueel ook koppel met de database (door middel van de mapper dan)?
Gewijzigd op 03/11/2012 23:19:12 door Jasper DS
 
Jasper DS

Jasper DS

05/11/2012 10:35:11
Quote Anchor link
Hoi,

ik denk dat ik de namespaces nu wel goed gebruik. Ik heb ook geprobeerd een mapperInterface toe te voegen maar ik denk dat deze nog niet echt klopt...

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

    namespace lib;

    interface MapperInterface
    {
        // protected $db; // db abstractielaag

        public function __construct(\PDO $db);


        public function populate(array $data);

        public function save();
        
        // public function delete();
    }

?>


De usermapper implementeert deze dan.
Ik heb ook geprobeerd PHPdocumentor te installeren maar dat is niet gelukt en ik snap ook nog niet 100% hoe het wel moet. De .php installer werkt niet op mijn pc.
 
Wouter J

Wouter J

05/11/2012 12:52:46
Quote Anchor link
Ik raad je aan de PSR-0 standaards voor namespaces te gebruiken. Die zegt dat namespaces er zou uit horen te zien:

namespace <app name/prefix>/<part>;

Ik prefix bijv. alles met Wj. Je krijgt dan bijv.:

namespace Wj\AdminBundle;

Vervolgens kan dit nog wat verder oplopen tot bijv. Wj\AdminBundle\Controller.

In jouw geval kan je bijv. dit doen:

namespace Jds\User;

De MapperInterface moet je ook weer in een namespace verder doen. Ik zou je mappen structuur zo maken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
src/ (of lib)
    Jds/
        User/
            User.php
            UserMapper.php
        Mapper/
            MapperInterface.php
        Storage/
            StorageInterface.php
            SessionStorage.php
            DataBaseStorage.php
            ...



Je interface ziet er gewoon goed uit, waarom zou hij niet werken?


Je hoeft niet eens PHPdocumentor the installeren, ik gebruik dat programma bijna nooit. Ik bedoel dat je de manier van documenteren, wat de standaard is in PHP, moet gaan gebruiken. Dus met annotations (@author, @return, @param, @version, @since, @throws, ...).


Quote:
Je bedoelt dus met de CRUD-functions dat ik mijn sessie ook zou moeten kunnen wijzigen, lezen, maken, ... ? En eventueel ook koppel met de database (door middel van de mapper dan)?

Ik zou allemaal storage klassen maken die je kunt gebruiken. Bijv: https://gist.github.com/4016844 (kijk naar de bestandsnaam om te zien in welke map ze staan).
 
Jasper DS

Jasper DS

06/11/2012 20:22:26
Quote Anchor link
Zo we zijn weer wat verder.

Wat is gelukt:
- Namespaces (PSR-0 methode) gebruiken
- Commentaar toevoegen op de PHPdoc methode
- MapperInterface maken

Wat mij niet lukt:
- De juiste objecten vinden (niet voor de hand liggende objecten)

Waar ik graag meer info over wil:
- Waarom moet classX een interface hebben en ClassY niet
- Waarom moet ClassX een parent hebben en ClassY niet

Stel nu dat ik een systeem maak met een auto een bestuurder en een copiloot dan begrijp ik dat er een klasse Auto is met als parent voertuig en een klasse bestuurder en copiloot die een child zijn van de klasse persoon.

Wat ik moeilijker vind is om dit te doen met bijvoorbeeld een Sessie of een database.

Graag zou ik dus samen met jullie bekijken welke Classen / interfaces / ... er allemaal nodig zijn in een login-systeem zonder speciale rechten of users. Ik wil dit eerst en vooral graag doen zonder code zodat ik de logica snap want daar ben ik soms nog niet helemaal met mee.

Een voorbeeldje van WouterJ dat ik bijvoorbeeld niet snap. Waarom moet er voor een Sessie nog een Storage class gemaakt worden? Ik begrijp dat een sessie inderdaad iets "bij houd" en dat doet de Storage class ook maar dan is de Mapper toch ook een storage want een database doet dat ook?

Dit is wat ik op deze moment zou doen:
Afbeelding

Alvast bedankt voor de vele hulp!
Gewijzigd op 06/11/2012 20:26:29 door Jasper DS
 
Reshad F

Reshad F

06/11/2012 20:42:13
Quote Anchor link
Session class maakt de sessie aan.
SessionStorage bewaart de sessie.

Je zou er eventueel een interface aan kunnen hangen voor de CRUD methodes.
 
Wouter J

Wouter J

06/11/2012 20:51:13
Quote Anchor link
Wat je nu hebt in dat uml diagram ziet er goed uit en is gewoon goed OO.

Je kan echter nog een stapje verder en dat zou ik ook doen, het hoeft niet ik zou het doen.

Je hebt nu namelijk nog 2 zwakke plekken:
1) elke klasse heeft in principe een parent, nu heeft Session dat niet;
2) als je nu MySQLi ipv PDO wilt gebruiken heb je een probleem, aangezien je dan alle mappers moet aanpassen.

Beide zijn in 1 klapt te vangen:
Het zijn allebei manieren om iets op te slaan, de sessie in een sessie en bij een database in een database. Waarom groeperen we ze niet onder een StorageInterface?
Die bevat dan de basis methoden om er zeker van te zijn dat je die kan gebruiken. Ik stel voor de CRUD methods te pakken.

Deze Storage klassen zijn dan een database abstractie layer, zoals we dat zo mooi noemen. Ze zijn de laag die de database voorstelt. Die kunnen we dan gebruiken in de Mapper en op andere plaatsen waar we iets willen opslaan. De Mapper is een klasse voor communicatie tussen het object en een database. Wat die database is maakt die mapper niks uit, als hij maar ergens wordt opgeslagen. Daar hebben we dus een speciaal object voor gemaakt. Je UML wordt dus:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
      +------------------+                          +------------+
      |   <<interface>>  |                          | UserMapper |
      | StorageInterface |                          +------------+
      +------------------+                          | ...        |
      | create(obj)      |        HEEFT_EEN         |            |
      | read(obj)        |  --------------------->  |            |
      | update(obj)      |                          +------------+
      | delete(obj)      |
      +------------------+
        ^               ^
 IS_EEN |"              | IS_EEN
+----------------+   +-----------------+
| SessionStorage |   | DatabaseStorage |
+----------------+   +-----------------+
| create(obj)    |   | create(obj)     |
| read(obj)      |   | read(obj)       |
| update(obj)    |   | update(obj)     |
| delete(obj)    |   | delete(obj)     |
+----------------+   | connect(...)    |
                     +-----------------+
 
Tom Swinkels

Tom Swinkels

06/11/2012 21:41:21
Quote Anchor link
Voor het opslaan van een session heb ik een session en sessionMapper klasse.

Ik het het zo gemaakt dat ik gewoon het object in de database opsla, dit doe ik met "serialize". Verder maak ik daarbij een cookie die voor het inloggen bijvoorbeeld "user" heet aan met een "hash". Deze "hash" staat ook weer opgeslagen in de database en op deze manier kan ik dus het user object ophalen. Maar zou ik andere dingen willen opslaan geen probleem, ik geef een andere naam mee aan de klasse en klaar.

Opslaan van een session:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
$session = new Session( 'user', $userOBJECT );
$sessionMapper->save( $session );


Ophalen van een session:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$loginData = $sessionMapper->getSession( 'user', $requestOBJECT );
 
Jasper DS

Jasper DS

06/11/2012 22:51:55
Quote Anchor link
@Wouter, oké goed ik ben weer mee! Mijn UML ziet er nu zo uit:
Afbeelding

Als ik dan toch even inga op de code. Mijn UserMapper of andere Mappers mogen nu geen PDO "commando's" meer gebruiken nu hé? Anders gaan we ons doel voorbij. Ik veronderstel dat de PDO "commando's" nu in de DatabaseStorage moeten en dat we die classe dan aanspreken in de Mappers zodat als we overschakelen op Mysqli dan we alleen de DatabaseStorage moeten aanpassen klopt?

Hoe zit dat nu bij de SessionStorage? Deze Class vervangt mijn class Session niet? Hoe zit dat nu concreet hoe moet ik de methode create bezien? Kan ik een volledig User Object in een Sessie steken? Nee dit moet zeker een int / string ofzo worden waarmee ik de User terug kan ophalen?

Dan nog even terugkomend op de UserMapper, je pijl loopt van de interface naar de Mapper, kan het zijn dat dat omgekeerd moet of interpreteer ik dat verkeerd?
We gaan door dat te doen afdwingen dat de UserMapper ook die methodes heeft?

@Tom, ik snap je manier van werken maar ik denk dat de methode van wouter abstracter is en dus dichter tegen het doel van OOP programmeren aanleunt dat jouw methode of zie ik dat verkeerd? Alleszins bedankt voor je inbreng, het deel van het opslaan in de database kan ik waarschijnlijk ook nog verwerken in wouter zijn manier. Dat is een kwestie van hoe je de functies vult denk ik...
Gewijzigd op 06/11/2012 22:54:37 door Jasper DS
 
Wouter J

Wouter J

06/11/2012 23:04:32
Quote Anchor link
Quote:
Ik veronderstel dat de PDO "commando's" nu in de DatabaseStorage moeten en dat we die classe dan aanspreken in de Mappers zodat als we overschakelen op Mysqli dan we alleen de DatabaseStorage moeten aanpassen klopt?

Kijk daar komt de OO denkende jasper voorbij gelopen! Dit heb je helemaal gelijk met als enige punt dat ik niet de DatabaseStorage zal aanpassen, maar gewoon een nieuwe klasse zou schrijven bijv. MySQLiDatabaseStorage. Je kan die PDODatabaseStorage altijd nog een keer gebruiken.

Merk overigens op dat de DatabaseStorage nog iets moet doen: verbinding maken met de db.

Quote:
Hoe zit dat nu bij de SessionStorage? Deze Class vervangt mijn class Session niet? Hoe zit dat nu concreet hoe moet ik de methode create bezien? Kan ik een volledig User Object in een Sessie steken? Nee dit moet zeker een int / string ofzo worden waarmee ik de User terug kan ophalen?

Lekker veel vragen:
2) Ja, dat klopt
3) Je kan hem zien zoals ik in het voorbeeld liet zien
4) Dit is de optie die ik liet zien
5) Dit kan je ook doen, is denk ik wat beter.

Quote:
ik snap je manier van werken maar ik denk dat de methode van wouter abstracter is en dus dichter tegen het doel van OOP programmeren aanleunt dat jouw methode of zie ik dat verkeerd?

Er zijn meerdere wegen naar Rome. Vooral voor het opslaan van gegevens kent OOP vele manieren, tom en ik leggen de manier uit die wij het best vinden, maar er zijn er nog veel meer (zoals ActiveRecord, ORMs, ect.).
 
Jasper DS

Jasper DS

07/11/2012 21:42:52
Quote Anchor link
Hmm oke, ik ben half mee... Ik snap dat de Mapper geen PDO commando's mag hebben omdat we dan niet makkelijk op een andere engine kunnen overstappen maar wat moet er dan in de Mapper?

Kan je als voorbeeld de methode create van de UserMapper geven? Ik veronderstel dat die een Object User binnen krijgt maar ik weet niet goed wat die moet returnen..
 
Wouter J

Wouter J

07/11/2012 21:51:02
Quote Anchor link
Op de eerste alinea: Ja

Quote:
Kan je als voorbeeld de methode create van de UserMapper geven? Ik veronderstel dat die een Object User binnen krijgt maar ik weet niet goed wat die moet returnen..

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?php
class User
{
    private $id = 0;
    private $name;
    // ...

    public function __construct($name)
    {

        $this->setName($name);
    }


    public function setName($name)
    {

        $this->name = (string) $name;
    }


    public function setId($id)
    {

        $this->id = (int) $id;
    }


    public function getName()
    {

        return $this->name;
    }


    public function getId()
    {

        return $this->id;
    }
}


class UserMapper implements DataMapperInterface
{
    private $storage;

    public function __construct(StorageInterface $storage)
    {

        $this->setStorage($storage);
    }


    protected function setStorage(StorageInterface $storage)
    {

        $this->storage = $storage;
    }


    protected function getStorage()
    {

        return $this->storage;
    }


    public function create(User $user)
    {

        $this->getStorage()->create('user', array(
            'name' => $user->getName(),
        ));


        $user->setId($this->getStorage()->getLastId());

        return $user;
    }
}

?>
 
Jasper DS

Jasper DS

08/11/2012 10:05:44
Quote Anchor link
Oke mooi ik ben mee denk ik!

Als ik een nieuwe User wil maken is de code zo dus:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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);

?>


Dan even concreet op de PDODatabaseStorage()
Die krijgt twee parameters binnen 'user' een een array. Ik veronderstel dat user naar de tabel in de database verwijst en de array naar de velden en de values verwijst?

Als ik tot nu toe nog correct aan het denken ben dan zit ik nu met een praktische vraag.
De parameter 'user' op de juiste plek te zetten zal nog wel lukken maar ik zit daar met een array die de velden als key hebben en de value als value. Hoe krijg ik die in mijn query? Heeft PDO daar een functie voor of moet ik de array uitlezen met een foreach?
 
Wouter J

Wouter J

08/11/2012 10:18:37
Quote Anchor link
Je bent nog goed aan het denken. Straks ga je ook nog andere methods maken als save, dan heb je iets als:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
$user
= new User('Jasper');
$user->setEmail('[email protected]');

$userMapper = ...;
$userMapper->create($user);

$user->setEmail('[email protected]');
$userMapper->save($user);
?>


Je ga merken dat het een beetje onpraktisch wordt om een UserMapper aan te maken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$pdo
= new PDO(...);
$pdoStorage = new PDODatabaseStorag($pdo);
$userMapper = new UserMapper($pdoStorage);
?>


Daarom ga je straks werken met een Service container:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$container
= new Container();

$container->set('storage.database.adapter', 'PDODatabaseStorage');
$container->set('storage.database.connection', function($c) {
    return new PDO(...);
});

$container->set('storage.database', function($c) {
    return new $c->get('storage.database.adapter')($c->get('storage.database.connection'));
});


$container->set('mapper.storage', 'storage.database');
$container->set('mapper.user', function($c) {
    return new UserMapper($c->get('mapper.storage'));
});


// in gebruik
$userMapper = $container->get('mapper.user');
$userMapper->create($user);
?>


Maar daar zullen we straks naar kijken, eerst even de storage klassen:

Quote:
Hoe krijg ik die in mijn query? Heeft PDO daar een functie voor of moet ik de array uitlezen met een foreach?

Ik zou het zoiets doen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
class PDODatabaseStorage extends DatabaseStorage
{
    // ...

    public function create($table, array $fields)
    {

        $fieldNames = array_keys($fields);
        $query = sprintf(
            'INSERT INTO %s(%s) VALUES (',
            $table,
            implode(', ', $fieldNames)
        );


        foreach ($fields as $field) {
            $query .= $field.',';
        }

        $query = substr($query, 0, -1).');';

        // $query is nu een correcte query
    }
}

?>
 
Jasper DS

Jasper DS

08/11/2012 11:03:47
Quote Anchor link
Oke, en waarom geven we de tabel niet mee met de PDODatabaseStorage?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
    $pdoStorage
= new PDODatabaseStorage($pdo, 'user');
?>


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
public function __construct(PDO $db, string $table)
    {

        $this->db = $db;
        $this->table = $table;
    }

?>


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
public function create(array $fields)
    {

        $fieldNames = implode(', ',array_keys($fields));
        foreach ($fields as $field)
        {

            $prepare .= '? ,';
        }


        $prepare = substr($prepare, 0, -1);

        $qry = $this->db->prepare("INSERT INTO ".getTable()." " . $fieldNames . "  VALUES (".$prepare.") ");
            
        $i = 1;

        foreach ($fields as $field)
        {

            $qry->bindParam($i, $field);
            $i++;
        }


        $qry->execute();
    }

?>
Gewijzigd op 08/11/2012 11:07:14 door Jasper DS
 
Wouter J

Wouter J

08/11/2012 22:35:48
Quote Anchor link
Omdat de PDODatabaseStorage, alle Storage klassen eigenlijk, niet 1 tabel voorstellen, maar gewoon een algemene klasse. Je kan hem dus vaker gebruiken voor verschillende velden.

Merk ook op dat we het nu als tabel gebruiken, maar dat hij met een sessie bijv. de array key kan voorstellen.
 
Jasper DS

Jasper DS

08/11/2012 22:47:18
Quote Anchor link
maar dat kan met mijn manier toch ook? Misschien moet ik $table dan wel vervangen door $key ofzo.

Toevoeging op 09/11/2012 09:56:21:

Mijn User class implements de StorableInterface en toch krijg ik deze error?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
Fatal error: Declaration of Jds\User\UserMapper::create() must be compatible with Jds\Store\Storage\StorageInterface::create(Jds\Store\Storable\StorableInterface $object) in C:\wamp\www\login_system\lib\Jds\User\UserMapper.php on line 7


Toevoeging op 09/11/2012 10:09:12:

Hier is mijn code: https://github.com/JasperDS/login_system
 
Wouter J

Wouter J

09/11/2012 10:15:19
Quote Anchor link
Jasper, je DataMapper is geen StorageInterface. Je kijkt het nu weer verkeerd: De storage klassen en datamappers zijn 2 andere dingen. De UserMapper moet de DataMapperInterface implementeren en niet een StorageInterface.
 
Jasper DS

Jasper DS

09/11/2012 10:27:15
Quote Anchor link
Oke correct, maar dan zit ik toch nog altijd met het probleem dat de create() uit PDODatabaseStorage een array als parameter heeft en niet een StorableInterface?

Toevoeging op 09/11/2012 10:40:20:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php

namespace Jds\Store\Storage;
use \PDO;
use \Jds\Store\Storage\StorageInterface;

class PDODatabaseStorage implements StorageInterface
{
    protected $db;
    protected $table;

    public function __construct(PDO $db, $table)
    {

        $this->db = $db;
        $this->table = $table;
    }


    public function getTable()
    {

        return $this->table();
    }


    
    public function create(array $fields)
    {

        $fieldNames = implode(', ',array_keys($fields));
        foreach ($fields as $field)
        {

            $prepare .= '? ,';
        }


        $prepare = substr($prepare, 0, -1);

        $qry = $this->db->prepare("INSERT INTO ".getTable()." " . $fieldNames . "  VALUES (".$prepare.") ");
            
        $i = 1;

        foreach ($fields as $field)
        {

            $qry->bindParam($i, $field);
            $i++;
        }


        $qry->execute();
    }
}


?>


PDODatabaseStorage->create($array) kan niet want $array is geen StorableInterface $object wat de StorageInterface wel afdwingt.
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.