OOP gedachtengang
Pagina: « vorige 1 2 3 4 5 volgende »
Maar waarom staat deze regel daar nu in die functie?
bij procedurele queries moet je eerst fetchen, en komt er een array uit, of een object, of net wat je zelf wilt. je zult dan wel nog jouw benodigde gegevens uit die array of object moeten halen.
hetzelfde hier, $result is alleen nog maar gefetcht. en is een array. dus met $result['id'] haal je het id uit de array.
en waarom zou ik dat willen doen in die desbetreffende functie?
hmm das inderdaad gek ja. ik dacht dat je de regel niet begreep, maar ik snap zelf het nut eigenlijk ook niet, nee.
Ik begreep de syntax en de inhoud wel maar de bedoeling niet. ;)
Het id is namelijk al bekend en hoef je dus niet uit de database te halen, maar kan je direct in het object zetten. Anders zou je in het select ook 'id' moeten opnemen in de kolomnamen.
Tevens, waarom de id niet in de constructor? Omdat een User niet verplicht een ID heeft. Als je een nieuwe user aanmaakt weet je nog geen ID, je hebt immers alleen het object. Pas als je het in de DB plaats met de UserMapper weet je het ID en die moet je dus apart kunnen zetten. (dat zie je ook automatisch gebeuren in UserMapper::create(). Daar zie je dat na het aanmaken van de User de User::setId() method wordt aangeroepen en de user het laatst aangemaakte ID krijgt (weet niet of die regel helemaal klopt in het script, maar gaat om het idee).
Quote:
En moet er telkens aangeduid worden welk type? Ik dacht dat dat in php niet hoefde in tegenstelling tot andere programmeertalen zoals java en C.
Dat klopt. Alleen ik hou altijd van controle. In een klasse wil ik zeker weten dat de waarde van de properties de waarde hebben die ik verwacht, vandaar dat ik ze allemaal typecast. Ik noem het maar een goede gewoonte.
Wouter, heb je misschien een voorbeeld in de praktijk van hoe je nu bijv. je User class verwerkt i.c.m. een form en validatie? Dat is mij nog niet helemaal duidelijk namelijk.
Code (php)
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
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
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$errors = array();
if (!(isset($_POST['name'])) || ($_POST['name'] === '')) {
$errors[] = 'Je bent vergeten een username in te vullen.';
}
if (!(isset($_POST['password'])) || ($_POST['password'] === '')) {
$errors[] = 'Je bent vergeten een wachtwoord in te vullen.';
}
if (!(isset($_POST['email'])) || ($_POST['email'] === '')) {
$errors[] = 'Je bent vergeten een email adres in te vullen';
}
if (count($errors) > 0) {
// geen fouten, registreer user
// maak een User object aan
$user = new User($_POST['name'], $_POST['password'], $_POST['email']);
$userMapper = new UserMapper();
$user = $userMapper->create($user);
$message = 'Hallo '.$user->getName().', welkom op deze website!';
}
}
// ...
?>
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$errors = array();
if (!(isset($_POST['name'])) || ($_POST['name'] === '')) {
$errors[] = 'Je bent vergeten een username in te vullen.';
}
if (!(isset($_POST['password'])) || ($_POST['password'] === '')) {
$errors[] = 'Je bent vergeten een wachtwoord in te vullen.';
}
if (!(isset($_POST['email'])) || ($_POST['email'] === '')) {
$errors[] = 'Je bent vergeten een email adres in te vullen';
}
if (count($errors) > 0) {
// geen fouten, registreer user
// maak een User object aan
$user = new User($_POST['name'], $_POST['password'], $_POST['email']);
$userMapper = new UserMapper();
$user = $userMapper->create($user);
$message = 'Hallo '.$user->getName().', welkom op deze website!';
}
}
// ...
?>
Eventueel zou je het formulier validatie ook kunnen laten doen door een Form klasse, maar dat gaat wel erg ver voor dit topic (en om eerlijk te zijn heb ik dat zelf ook nog niet helemaal door...).
Bedankt :-)
Code (php)
Maar het lijkt me handiger om RunTime fouten af te handelen met gewone normale error systemen, omdat je meerdere fouten tegelijkertijd wilt tonen.
Nu was ik aan het denken om aan mijn User class een functie login() toe te voegen en aan mijn UserMapper een functie getByNameAndPass(). In de login functie word de sessie dan aangemaakt en de getByNameAndPass() checkt of de user bestaat en populate() hem als die bestaat zodat ik kan inloggen.
Zit ik juist?
Heel strict genomen mag een User object zelf geen login uitvoeren en heb je daar een eigen klasse voor nodig. Maar ik denk dat het in dit geval wel goed zou zijn.
PRODUCELE CODE:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
try
{
$db = new PDO('mysql:host=localhost;dbname=visit_report','root','***');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set Errorhandling to Exception
}
catch(PDOException $e)
{
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$userMapper = new UserMapper($db);
$user = new User('jasper' , sha1('test'));
echo $userMapper->getByNameAndPass($user);
echo 'Id: ' . $user->getId();
echo '<br/> Name: ' . $user->getName();
echo '<br/> Password: ' .$user->getPassword();
?>
try
{
$db = new PDO('mysql:host=localhost;dbname=visit_report','root','***');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set Errorhandling to Exception
}
catch(PDOException $e)
{
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$userMapper = new UserMapper($db);
$user = new User('jasper' , sha1('test'));
echo $userMapper->getByNameAndPass($user);
echo 'Id: ' . $user->getId();
echo '<br/> Name: ' . $user->getName();
echo '<br/> Password: ' .$user->getPassword();
?>
UserMapper->getByNameAndPass(User $user)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
public function getByNameAndPass(User $user)
{
$stmt = $this->db->prepare("SELECT COUNT(gebruikersid) AS tel, gebruikersid, naam, wachtwoord FROM gebruikers WHERE naam = :name and wachtwoord = :password");
$stmt->execute(array(
':name' => $user->getName(),
':password' => $user->getPassword()
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if($result['tel'] < 1)
{
return 'Geen resultaat gevonden';
}
else
{
return $this->populate($result);
}
}
?>
public function getByNameAndPass(User $user)
{
$stmt = $this->db->prepare("SELECT COUNT(gebruikersid) AS tel, gebruikersid, naam, wachtwoord FROM gebruikers WHERE naam = :name and wachtwoord = :password");
$stmt->execute(array(
':name' => $user->getName(),
':password' => $user->getPassword()
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if($result['tel'] < 1)
{
return 'Geen resultaat gevonden';
}
else
{
return $this->populate($result);
}
}
?>
Zoals je ziet return mijn functie 'Geen resultaat gevonden' als de gegevens niet kloppen maar als het wel klopt returnt de functie de populate functie die op zijn beurt een volledig object return waardoor ik volgdende fout krijg.
Dus je wilt de return asignen aan een variabele welke je vervolgens kan echoen zoals je in de regels daaronder al deed. Echter echo je daar de gegevens van de $user die je zelf aanmaakt (jasper) ipv het resultaat van je query.
Jasper, ik zou het wat anders doen. Als er iets fout gaat return je false en anders de User object. Errors handel je met Exceptions af.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
public function getByNameAndPass(User $user)
{
$stmt = $this->db->prepare("SELECT COUNT(gebruikersid) AS tel, gebruikersid, naam, wachtwoord FROM gebruikers WHERE naam = :name and wachtwoord = :password");
$stmt->execute(array(
':name' => $user->getName(),
':password' => $user->getPassword()
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if($result['tel'] < 1)
{
return false; // Geen resultaat gevonden
}
else
{
return $this->populate($result);
}
}
?>
public function getByNameAndPass(User $user)
{
$stmt = $this->db->prepare("SELECT COUNT(gebruikersid) AS tel, gebruikersid, naam, wachtwoord FROM gebruikers WHERE naam = :name and wachtwoord = :password");
$stmt->execute(array(
':name' => $user->getName(),
':password' => $user->getPassword()
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if($result['tel'] < 1)
{
return false; // Geen resultaat gevonden
}
else
{
return $this->populate($result);
}
}
?>
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/* Login testen */
try
{
$db = new PDO('mysql:host=localhost;dbname=visit_report','root','jasper');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set Errorhandling to Exception
}
catch(PDOException $e)
{
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$userMapper = new UserMapper($db);
$user = new User('jasper' , sha1('test'));
if($userMapper->getByNameAndPass($user) == false)
{
echo 'Uw gegevens zijn niet correct.';
}
echo 'Id: ' . $user->getId();
echo '<br/> Name: ' . $user->getName();
echo '<br/> Password: ' .$user->getPassword();
?>
/* Login testen */
try
{
$db = new PDO('mysql:host=localhost;dbname=visit_report','root','jasper');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set Errorhandling to Exception
}
catch(PDOException $e)
{
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$userMapper = new UserMapper($db);
$user = new User('jasper' , sha1('test'));
if($userMapper->getByNameAndPass($user) == false)
{
echo 'Uw gegevens zijn niet correct.';
}
echo 'Id: ' . $user->getId();
echo '<br/> Name: ' . $user->getName();
echo '<br/> Password: ' .$user->getPassword();
?>
Ja, alleen doe je nu niks met de geretourneerde user klasse. Sla deze op in $user.
Dan nu het degelijk opslaan van mijn classes. Ik heb voorlopig 2 classes. De User en de Usermapper. Zet ik deze in 2 apparte bestanden of wat doe ik daarmee? Moet ik dan ook telkens al mijn classes inladen of laad ik deze in in één bestand dat ik nadien inlaad in mijn andere pagina's?
/project/
/project/lib/User/User.php
/project/lib/User/UserMapper.php
/project/lib/Post/Article.php
/project/lib/Post/PostMapper.php
/project/lib/Post/PostFactory.php
/project/lib/Post/BlogPost.php
Dan kun je mooi en makkelijk gaan werken met autoloaders. Zorg dat je klassennamen de PSR-0 standaard volgen en je kunt heel simpel hun spl autoloader gebruiken. Dat werkt dan ong. zo:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
function my_spl_autoloader($class)
{
// functie wordt elke keer bij het aanmaken van
// een onbekende klasse aangeroepen, zodat je de
// klasse kunt laden
// do some fancy stuff
// laad het bestand
require __DIR__.DIRECTORY_SEPARATOR.$class;
}
// registreer de autoloader
spl_autoload_register('my_sql_autoloader');
?>
function my_spl_autoloader($class)
{
// functie wordt elke keer bij het aanmaken van
// een onbekende klasse aangeroepen, zodat je de
// klasse kunt laden
// do some fancy stuff
// laad het bestand
require __DIR__.DIRECTORY_SEPARATOR.$class;
}
// registreer de autoloader
spl_autoload_register('my_sql_autoloader');
?>