Vraag over URL in MVC
Ik heb een vraagje m.b.t. OO programmeren met het MVC model.
Stel je hebt www.voorbeeld.nl/?url=product/toevoegen.
Met een router (of hoe heet dat?) bekijk je de waarde van url (url weglaten met htaccess rewrite).
Daarna zeg je: het eerste deel 'product' is de controller (die ga je dus requiren).
Het tweede deel (als gegeven) is de functie, dus zeg je zoek in de controller-product-class naar de 'toevoegen' functie (en voer deze uit).
Je kan ook bijvoorbeeld hebben www.voorbeeld.nl/product/bewerken/1
Het derde deel (als gegeven) is een argument van de functie, het tweede deel. Je zegt dus te zoeken in de controller-product-class, naar de functie 'bewerken', met als argument '1'.
Maar nu mijn vraag: stel je hebt ook een 'bekijk' functie. De URL ziet er dan als volgt uit: www.voorbeeld.nl/product/bekijk/1.
Dit ziet er echter een beetje raar uit, dus vroeg ik me af hoe je er voor kan zorgen dat je deze 'bekijk' in de url weg kan laten, dat de URL wordt: 'www.voorbeeld.nl/product/1'.
Misschien met een standaard functie? Als er geen gegeven is, laad die functie bijvoorbeeld. Maar hoe doe ik dat het best? En hoe moet je PHP 'uitleggen' dat de '1' geen functie is, maar een argument van de standaardfunctie?
- Aar -:
Topictitel aangepast van 'Vraag MVC' naar: 'Vraag over URL in MVC'. Gelieve voortaan duidelijk je vraagstelling of probleem in de topictitel te vermelden. Iets als 'Vraag over...' is onduidelijk voor iedereen.
Gewijzigd op 06/02/2014 19:06:43 door - Ariën -
ja standaard functie meestal index() of indexAction() genoemd
www.voorbeeld.nl/pagina/5, dat er geen functie is gegeven, maar dat '5' een argument is voor de standaardfunctie, en geen controller?
En hoe moet ik php laten weten dat bv bij Gewijzigd op 05/02/2014 18:48:16 door Jony V
Heb je er al iets?
Probeer je er een te schrijven?
Wil je een paar voorbeelden zodat je ideeën kunt opdoen?
Wat heb je op het moment qua code?
Zelf vind ik routers die alleen met "controller/method/arg1/arg2" achtige urls overweg kunnen niet fijn.
Dit is wat ik nu heb, als router class:
(code kan rommelig en niet goed zijn (ben nog maar net begonnen), je kan misschien zeggen wat er beter kan)
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
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?php
class router {
public $url;
public function __construct() {
/********************
* Waarde van ?url=
*******************/
if (isset($_GET['url']) && !empty($_GET['url'])) {
$this->url = $_GET['u'];
$this->url = explode('/', $this->url);
$controller = $this->url[0];
if (isset($this->url[1]) && !empty($this->url[1])) { $method = $this->url[1]; };
if (isset($this->url[2]) && !empty($this->url[2])) { $argument = $this->url[2]; };
} else {
/****************
* Startpagina
***************/
$controller = 'homepage';
$method = 'IndexAction';
$argument = null;
}
/***********************************
* checken of controller bestaat
**********************************/
$filename = $controller . '__controller.php';
$filelocation = __CONTROLLER_FOLDER__ . $filename;
if (file_exists($filelocation)) {
require_once $filelocation;
$application = new $controller;
if (isset($method) && !empty($method)) {
if (!isset($argument) && empty($argument)) {
if (method_exists($application, $method)) {
$application->$method();
} else {
/***********************************************
* check voor default function
* deze manier (waarschijnlijk niet de juiste)
* heeft nu als nadeel dat als er wel een method
* in de url staat, maar deze niet bestaat,
* de router automatisch de default function
* opstart (terwijl dit eigenlijk enkel zou moeten
* zijn als er geen method is gedefiniëerd (maar
* mogelijk wel een argument))
**********************************************/
if (method_exists($application, 'IndexAction')) {
$application->IndexAction();
} else {
/****************************************************
* error pagina
***************************************************/
show_404();
}
}
}
if (isset($argument) && !empty($argument)) {
if (method_exists($application, $method)) {
$application->$method($argument);
} else {
show_404();
}
}
} else {
if (method_exists($application, 'IndexAction')) {
$application->IndexAction();
}
}
} else {
/*********************************
* De controller file bestaat niet
********************************/
show_404();
}
}
}
[/code]
class router {
public $url;
public function __construct() {
/********************
* Waarde van ?url=
*******************/
if (isset($_GET['url']) && !empty($_GET['url'])) {
$this->url = $_GET['u'];
$this->url = explode('/', $this->url);
$controller = $this->url[0];
if (isset($this->url[1]) && !empty($this->url[1])) { $method = $this->url[1]; };
if (isset($this->url[2]) && !empty($this->url[2])) { $argument = $this->url[2]; };
} else {
/****************
* Startpagina
***************/
$controller = 'homepage';
$method = 'IndexAction';
$argument = null;
}
/***********************************
* checken of controller bestaat
**********************************/
$filename = $controller . '__controller.php';
$filelocation = __CONTROLLER_FOLDER__ . $filename;
if (file_exists($filelocation)) {
require_once $filelocation;
$application = new $controller;
if (isset($method) && !empty($method)) {
if (!isset($argument) && empty($argument)) {
if (method_exists($application, $method)) {
$application->$method();
} else {
/***********************************************
* check voor default function
* deze manier (waarschijnlijk niet de juiste)
* heeft nu als nadeel dat als er wel een method
* in de url staat, maar deze niet bestaat,
* de router automatisch de default function
* opstart (terwijl dit eigenlijk enkel zou moeten
* zijn als er geen method is gedefiniëerd (maar
* mogelijk wel een argument))
**********************************************/
if (method_exists($application, 'IndexAction')) {
$application->IndexAction();
} else {
/****************************************************
* error pagina
***************************************************/
show_404();
}
}
}
if (isset($argument) && !empty($argument)) {
if (method_exists($application, $method)) {
$application->$method($argument);
} else {
show_404();
}
}
} else {
if (method_exists($application, 'IndexAction')) {
$application->IndexAction();
}
}
} else {
/*********************************
* De controller file bestaat niet
********************************/
show_404();
}
}
}
[/code]
Gewijzigd op 06/02/2014 17:53:02 door Jony V
Ik geef in een bestand alle geldige routes op, de bijbehorende controller en optioneel de functie (action) die aangeroepen dient te worden. Indien geen action wordt opgegeven roept hij de indexAction aan.
routes.php:
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
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
<?php
$routes = array(
array(
'url' => '/',
'controller' => 'home',
),
array(
'url' => 'about',
'controller' => 'home',
'action' => 'about',
),
array(
'url' => 'contact',
'controller' => 'home',
'action' => 'contact',
),
array(
'url' => 'contact/send',
'controller' => 'home',
'action' => 'send',
),
array(
'url' => 'signup/activate/:id/:hash',
'controller' => 'signup',
'action' => 'activate',
),
);
?>
$routes = array(
array(
'url' => '/',
'controller' => 'home',
),
array(
'url' => 'about',
'controller' => 'home',
'action' => 'about',
),
array(
'url' => 'contact',
'controller' => 'home',
'action' => 'contact',
),
array(
'url' => 'contact/send',
'controller' => 'home',
'action' => 'send',
),
array(
'url' => 'signup/activate/:id/:hash',
'controller' => 'signup',
'action' => 'activate',
),
);
?>
In de laatste route (url) zie je :id en :hash staan. Dit zijn variabelen. Mijn router zorgt er bij deze route voor dat de onderstaande controller / action wordt aangeroepen:
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
31
32
33
34
35
36
37
38
39
40
41
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
<?php
namespace system\controllers;
use system\classes\BaseController;
class SignupController extends BaseController
{
public function indexAction()
{
$data = array(
'pageTitle' => 'Activation',
);
$this->loadPage('activate', $data);
}
public function activateAction($id, $hash)
{
$data = array(
'pageTitle' => 'Activation',
'message' => 'Helaas konden we je account niet activeren. neem contact met ons op.',
);
// haal de gegevens uit de database aan de hand van het id
$user = $this->em->find('User', $id);
if($user)
{
// controlleer of de hash juist is
if($user->getActivateKey() == $hash)
{
$user->setEmailVerified('Y');
$data['message'] = 'Gefeliciteerd. Je account is geactiveerd!';
}
}
$this->loadPage('signup_activate', $data);
}
}
?>
namespace system\controllers;
use system\classes\BaseController;
class SignupController extends BaseController
{
public function indexAction()
{
$data = array(
'pageTitle' => 'Activation',
);
$this->loadPage('activate', $data);
}
public function activateAction($id, $hash)
{
$data = array(
'pageTitle' => 'Activation',
'message' => 'Helaas konden we je account niet activeren. neem contact met ons op.',
);
// haal de gegevens uit de database aan de hand van het id
$user = $this->em->find('User', $id);
if($user)
{
// controlleer of de hash juist is
if($user->getActivateKey() == $hash)
{
$user->setEmailVerified('Y');
$data['message'] = 'Gefeliciteerd. Je account is geactiveerd!';
}
}
$this->loadPage('signup_activate', $data);
}
}
?>
Het gaat hier dus om de activateAction. Deze action krijgt dan ook twee parameters binnen. Indien de gebruiker een ongeldige route opgeeft dan wordt de speciaal daarvoor aangemaakte errorController aangeroepen.
Toevoeging op 06/02/2014 18:58:27:
Waar ik dus zelf niet voor gekozen heb is een vast patroon in de url in de volgorde van www.website.nl/controller/action/var1/var2 met name door de door jouw zelf aangedragen reden dat je dan soms langere url's krijgt dan wenselijk.
Gewijzigd op 06/02/2014 18:53:22 door Frank Nietbelangrijk
Frank, bedankt voor je reactie. Weet je misschien een tutorial voor dergelijke routers? Ik heb al gezocht, maar alle gevonden tutorials gaan over een vast patroon (controller/method/argument)...