OOP
Ik was weer aan het experimenteren met OOP maar ik stuiterde op een vraag waar ik niet uit kwam en het niet precies op Google kon vinden..
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
28
29
30
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
class Database {
protected $_hostname = 'localhost';
protected $_username = 'root';
protected $_password = '';
protected $_database = 'rob';
public function connect() {
$connection = mysqli_connect($this->_hostname, $this->_username, $this->_password, $this->_database);
if(!$connection) {
printf('Error met verbinding');
exit();
}
}
}
class User extends Database {
public $test = 'test';
public function __construct() {
$database = new Database;
$database->connect()->real_escape_string($test);
}
}
$database = new Database();
$database->connect();
$user = new User;
protected $_hostname = 'localhost';
protected $_username = 'root';
protected $_password = '';
protected $_database = 'rob';
public function connect() {
$connection = mysqli_connect($this->_hostname, $this->_username, $this->_password, $this->_database);
if(!$connection) {
printf('Error met verbinding');
exit();
}
}
}
class User extends Database {
public $test = 'test';
public function __construct() {
$database = new Database;
$database->connect()->real_escape_string($test);
}
}
$database = new Database();
$database->connect();
$user = new User;
Hoe kan ik in de User class de variable $connection aanroepen voor bv. real escape string toe te passen?
Of zou ik hier in de Database class functions voor moeten aan maken of dergelijk?
Toevoeging op 14/02/2017 17:59:08:
UPDATE CODE:
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
class Database {
protected $_hostname = 'localhost';
protected $_username = 'root';
protected $_password = '';
protected $_database = 'rob';
public $connection;
public function connect() {
$this->connection = mysqli_connect($this->_hostname, $this->_username, $this->_password, $this->_database);
if(!$this->connection) {
printf('Error met verbinding');
exit();
}
}
}
class User extends Database {
public $test = 'test';
public function __construct() {
$database = new Database;
$con = $database->connection;
$con->real_escape_string($test);
}
}
protected $_hostname = 'localhost';
protected $_username = 'root';
protected $_password = '';
protected $_database = 'rob';
public $connection;
public function connect() {
$this->connection = mysqli_connect($this->_hostname, $this->_username, $this->_password, $this->_database);
if(!$this->connection) {
printf('Error met verbinding');
exit();
}
}
}
class User extends Database {
public $test = 'test';
public function __construct() {
$database = new Database;
$con = $database->connection;
$con->real_escape_string($test);
}
}
error bij de code is:
Fatal error: Uncaught Error: Call to a member function real_escape_string() on null in C:\xampp\htdocs\index.php:28 Stack trace: #0 C:\xampp\htdocs\index.php(35): User->__construct() #1 {main} thrown in C:\xampp\htdocs\index.php on line 28
Gewijzigd op 14/02/2017 18:00:39 door - Rob -
1. Waarom extendt de User class de Database class? Wat denk je hiermee te bereiken?
2. Je zegt nergens $database->connect() dus zal $database->connection nooit gevuld zijn, zoals je foutmelding aangeeft.
2. Waar moet ik connect() dan aangeven? Als ik dat toevoeg, dus zo: $database->connect(); geef hij nog steeds de zelfde error?
Heeft iemand misschien een voorbeeld van hoe ik dit moet doen?
Toevoeging op 14/02/2017 18:45:19:
Laat het voorbeeld maar ;-)
Ik heb nog even goed ernaar gekeken en kwam hierop uit:
$database = new Database;
$database->connect();
$database->connection->real_escape_string($this->test);
data mapper pattern wilt kijken. Dan krijg je namelijk dit:
User <—> UserMapper <—> Database
Je moet véél abstracter leren denken als je de vergissing zoals class User extends Database begaat. De user is namelijk geen database. En de user vult de database ook niet aan. Klinkt raar, maar zo logisch is het wel.
In plaats daarvan krijg je:
• een user die een user is (en niet meer dan dat);
• een database om dingen in op te slaan en dingen uit te halen;
• een mapper die een user uit de database haalt of in de database opslaat.
Ik denk dat je inderdaad eens naar het User <—> UserMapper <—> Database
Je moet véél abstracter leren denken als je de vergissing zoals class User extends Database begaat. De user is namelijk geen database. En de user vult de database ook niet aan. Klinkt raar, maar zo logisch is het wel.
In plaats daarvan krijg je:
• een user die een user is (en niet meer dan dat);
• een database om dingen in op te slaan en dingen uit te halen;
• een mapper die een user uit de database haalt of in de database opslaat.
Maar in de User class wil ik functions aan maken zoals givePromotion() moet dit dan ook via de mapper? Want ik had een paar oude bestanden een daar heette de Database class Object en werd het class User extends Object
Is dat dan wel goed gedaan? Of zit ik nu gewoon erg mis?
Begin gewoon vanaf het begin, en ga niet zitten "oefenen" zonder dat je begrijpt wat je oefent. Er zijn boeken volgeschreven over OOP.
de class gebruiker is niet voor de gebruikers zelf, maar voor de functies voor de gebruikers en administrators voor de gebruikers zoals: Promoties geven, degraderen, etc.
Dan nog is het geen database. Vreemde opstelling, dat wel.
Dan klopt de naamgeving van de class dus niet.
Kan een User promotie geven of een Administrator?
Je moet het zo zien:
Een auto is een object, die gebruikt benzine.
Maar is het benzinestation dan ook onderdeel van de auto?
Dus een database (het benzine station)
Is nooit een onderdeel can een User (auto).
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
28
29
30
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
<?php
class User /* Ik weet enkel en alleen maar waar een user uit bestaat en van de rest van de wereld weet ik niets */
{
private $name;
private $email;
/* dit noemen we ook wel een setter */
public function setName($name)
{
$this->name = $name;
}
/* dit noemen we ook wel een getter */
public function getName()
{
return $this->name;
}
/* hier nog een setter en getter voor $email */
public function setEmail($email)
{
$this->email = $email;
}
public function getEmail()
{
return $this->email;
}
}
?>
class User /* Ik weet enkel en alleen maar waar een user uit bestaat en van de rest van de wereld weet ik niets */
{
private $name;
private $email;
/* dit noemen we ook wel een setter */
public function setName($name)
{
$this->name = $name;
}
/* dit noemen we ook wel een getter */
public function getName()
{
return $this->name;
}
/* hier nog een setter en getter voor $email */
public function setEmail($email)
{
$this->email = $email;
}
public function getEmail()
{
return $this->email;
}
}
?>
Hier een basis Mapper:
Code (php)
Dan een UserMapper die de eigenschappen van de basis Mapper overerft. (Handig als je later ook andere mappers wilt toevoegen)
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
28
29
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
<?php
class UserMapper extends Mapper
{
public function __construct($db)
{
parent::__construct($db);
}
public function getUser($id)
{
$result = $this->db->query("SELECT * FROM users WHERE id=" . $id);
if($result->num_rows == 1)
{
$row = $result->fetch_assoc();
$user = new User();
$user->setName($row['name']);
$user->setEmail($row['email']);
return $user;
}
return null;
}
/* andere functies zoals getAllUsers(), createUser(), updateUser() en deleteUser() nog toe te voegen */
}
?>
class UserMapper extends Mapper
{
public function __construct($db)
{
parent::__construct($db);
}
public function getUser($id)
{
$result = $this->db->query("SELECT * FROM users WHERE id=" . $id);
if($result->num_rows == 1)
{
$row = $result->fetch_assoc();
$user = new User();
$user->setName($row['name']);
$user->setEmail($row['email']);
return $user;
}
return null;
}
/* andere functies zoals getAllUsers(), createUser(), updateUser() en deleteUser() nog toe te voegen */
}
?>
test:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
/* eigenlijk zou je ook een database class moeten hebben maar gemakshalve gebruiken we hier de standaard php mysqli class even */
$db = new mysqli("localhost", "db_user", "db_pass", "db_name");
/* check connection */
if ($db->connect_errno) {
printf("Connect failed: %s\n", $db->connect_error);
exit();
}
// maak een instantie van UserMapper aan
$userMapper = new UserMapper($db);
// laad user met id 1 uit de database
$user = $userMapper->getUser(1);
// testje
echo $user->getEmail();
?>
/* eigenlijk zou je ook een database class moeten hebben maar gemakshalve gebruiken we hier de standaard php mysqli class even */
$db = new mysqli("localhost", "db_user", "db_pass", "db_name");
/* check connection */
if ($db->connect_errno) {
printf("Connect failed: %s\n", $db->connect_error);
exit();
}
// maak een instantie van UserMapper aan
$userMapper = new UserMapper($db);
// laad user met id 1 uit de database
$user = $userMapper->getUser(1);
// testje
echo $user->getEmail();
?>
Let op: Dit is slechts een voorbeeld en verre van compleet. Maar het geeft je hopelijk een kickstart...
Er zijn nog allerlei zaken die je later moet toevoegen om het echt lekker te laten werken.
Gewijzigd op 15/02/2017 00:29:26 door Frank Nietbelangrijk
Het hangt ook af wat je verstaat onder (een object van of objecten van) de User class: vertegenwoordigt een object van de User class de huidige (ingelogde) gebruiker van een systeem of een generiek object die een willekeurige (en niet zozeer de huidige) gebruiker uit het systeem representeert waar je bewerkingen op uit kunt voeren. In dit laatste geval is de aanpak met een Mapper weer geschikter.
Oftewel: @Rob, waar wil jij een User (object) voor gebruiken? Of wat voor idee steekt er achter jouw User class?
Thomas van den Heuvel op 16/02/2017 10:57:10:
Alternatief: een referentie van het database-object rechtstreeks meegeven bij de constructie van een user-object (als het gaat om de "huidige gebruiker", zie hieronder)?
Ik heb er zelf nog wat lagen tussen zitten:
• class Connection extends PDO
• abstract class AbstractModel uses Connection
• abstract class AbstractDAO extends AbstractModel
• class UserMapper extends AbstractDAO
• class User
Het Data Access Object (DAO) kan de vier standaardqueries uitvoeren: INSERT, SELECT, UPDATE en DELETE. Zo kun je er met efficiënt weinig extra code zo veel mappers aan hangen als je wilt.
Gewijzigd op 16/02/2017 11:44:09 door Ward van der Put