request class
Pagina: « vorige 1 2 3 4 5 volgende »
Quote:
Wanneer zou je NIET createfromglobals willen gebruiken? Is toch makkelijker dan alles handmatig meegeven?
Op momenten dat je geen gebruik van de superglobals kunt/wilt maken, bijv. in een test omgeving of in een subrequest...
hmmm, okeej... maar als je dan een subrequest uitvoert... maak je dan opnieuw een request object aan? Maar dat kan toch niet, want $_SERVER, $_POST etc. is dan toch nog steeds hetzelfde?
Ja, en daarom maak je bij een subrequest je eigen superglobals en daarom kun je dus niet createFromGlobals gebruiken.
Euh... je eigen superglobals maken? En dat zou je dan doen omdat... ??
Ozzie PHP op 04/01/2013 19:55:01:
Euh... je eigen superglobals maken? En dat zou je dan doen omdat... ??
omdat:
Not Moose op 04/01/2013 18:55:45:
Bijvoorbeeld bij het testen. Als je een GET, POST, PUT, DELETE request wil testen, is het handig dat je een setRequestMethod functie hebt
Ah oke...
Maar afgezien van het testen zie ik ook het nut niet van een subrequest
Maar dat vind ik dus het lastige. Ik wil een simpel framework bouwen... en dan vraag ik me dus ook af waar ik dan die subrequests voor nodig zou hebben... en als ik dan al een subrequest zou hebben, waarvoor zou ik dan een nieuw request object moeten aanmaken.
Ik wil vooral zo effectief mogelijk programmeren en niet "programmeren om het programmeren". Testen ga ik niet doen, dus vandaar mijn vraag of ik de constructor dan niet gewoon private zou maken.
Tevens testen niet doen? Dat weet je zeker? Je weet dat zodra je gaat testen je code logischer wordt, je sneller script omdat je alles test en je weet dat testen je later extreem veel voordeel op gaat leveren? Denk bijv. aan fixen van een bug, allereerst moet je de bug kunnen nabootsen en vervolgens moet je er maar zeker van zijn dat alles in je framework nog werkt nadat je de bug denkt opgelost te hebben.
Wat je doet is dat je een test schrijft die de bug nabootst en dat je vervolgens de bug oplost en dan alle tests van het framework afspeelt, slagen alle tests dan weet je zeker dat alles in je framework niet werkt.
Ik ben best benieuwd naar jou redenen om niet te gaan testen.
Nou, zeg nooit nooit... maar ik wil me daar nu niet mee bezig houden. Zoveel tijd heb ik niet. Da's de voornaamste reden.
Voor de rest wil ik m'n framework lichtgewicht maken. Veilig, efficiënt en doeltreffend. Zonder veel rare fratsen.
Mijn reden waarom ik de contructor private zou maken, zou dan zijn om te voorkomen dat ik alle globals zou gaan doorgeven, terwijl er een makkelijkere methode is. Door de contstructor private te maken, dwing je jezelf om altijd de makkelijke functie te gebruiken.
Quote:
Door de contstructor private te maken, dwing je jezelf om altijd de makkelijke functie te gebruiken.
Dus alleen omdat je zelf geen goed beeld hebt van je klassen wil je toepassing onmogelijk maken? Vind het een erg klein argument als ik eerlijk mag zijn. Maar goed, heb wel weer genoeg gediscussieerd, schrijf je framework gewoon zoals jij het wilt, ik heb genoeg gedaan je over te halen....
Iedereen heeft z'n eigen stijl en ik sta ook zeker open voor alle argumenten. Ik heb in ieder geval weer een hoop dingen gehoord waar ik mee aan de slag kan. Thanks! ;)
Wouter, nog even terugkomend op de dependency injection container. Gebruik je die ook om bijvoorbeeld je session waardes te setten en te getten?
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$container->get('session.manager')->set('session_name', 'session value');
echo $container->get('session.manager')->get('session_name');
?>
$container->get('session.manager')->set('session_name', 'session value');
echo $container->get('session.manager')->get('session_name');
?>
Kun je misschien met een (simpel) code voorbeeldje eens laten zien hoe dit in elkaar steekt?
Hoe je zeg maar die session manager in de container stopt en hoe het setten en getten in z'n werk gaat?
(Hoeft niet heel uitgebreid hoor. Ik ben met name benieuwd hoe de session manager (ik neem aan dat dat een class is) in de container terecht komt en hoe de set en get functies werken Die zijn denk ik onderdeel van de session manager class?)
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
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
<?php
class Container
{
// ...
/**
* Sets a parameter.
*
* @param string $id The name of the parameter
* @param mixed $value
*/
public function setParameter($id, $value)
{}
/**
* Gets a parameter.
*
* @param string $id The name of the parameter
*
* @return mixed
*/
public function getParameter($id)
{}
/**
* Sets a factory which builds a service.
*
* @param string $id The name of the service
* @param \Closure $factory
* @param boolean $shared Optional, default is `true`, which means that it always returns the same instance
*/
public function set($id, \Closure $factory, $shared = true)
{}
/**
* Gets a service.
*
* @param string $id The name of the service
* @param boolean $raw Optional, default is `false`. If true, the factory is returned and not called
*
* @return object The result of the factory
*/
public function get($id, $raw = false)
{}
}
?>
class Container
{
// ...
/**
* Sets a parameter.
*
* @param string $id The name of the parameter
* @param mixed $value
*/
public function setParameter($id, $value)
{}
/**
* Gets a parameter.
*
* @param string $id The name of the parameter
*
* @return mixed
*/
public function getParameter($id)
{}
/**
* Sets a factory which builds a service.
*
* @param string $id The name of the service
* @param \Closure $factory
* @param boolean $shared Optional, default is `true`, which means that it always returns the same instance
*/
public function set($id, \Closure $factory, $shared = true)
{}
/**
* Gets a service.
*
* @param string $id The name of the service
* @param boolean $raw Optional, default is `false`. If true, the factory is returned and not called
*
* @return object The result of the factory
*/
public function get($id, $raw = false)
{}
}
?>
De klassen zelf ga ik hier niet maken, we houden het even kort. We gaan hier alleen de Container configureren en vervolgens gebruiken.
Allereerst moet je natuurlijk nadenken wat een service 'moet' zijn. Ik ben van mening dat elke globale klasse het verdient een service te zijn, hiermee bedoel ik dat bijv. SessionManager een service is, Database, maar niet globale klassen zoals Controller klassen moeten geen services zijn.
Dan de concepten van iedere Container. Je hebt namelijk 2 typen code die je kunt opslaan in een container: parameters en factories. De parameters zijn gewoon variabele die een waarde vasthouden, factories zijn Closures (anonymous functions) die ervoor zorgen dat de klasse aangemaakt wordt. Het voordeel van deze factories is dat hij pas wordt uitgevoerd als je hem opvraagt, dit betekend dat als je hem niet gebruikt hij geen tijd verspilt aan het aanmaken (speciaal voor jou ;-).
Wat ik altijd doe, en dat heb ik weer van symfony, is dat ik de klasse van de service opsla in een parameter. Mocht ik de klasse willen veranderen, maar de rest hetzelfde houden, dan hoef ik niet aan de factory te knoeien maar alleen 1 parameter (wat veel simpeler is).
Daarnaast moeten we bedenken wat voor dependencies the SessionManager in ons geval zou moeten hebben, in ieder geval een raw Session factory die een Session klasse aanmaakt, deze kunnen we dan gebruiken als we een nieuwe sessie willen aanmaken met de Manager. Daarnaast is het ook handig om een array te krijgen van de huidige sessies. Dit betekend dus dat we 1 service factory en 1 parameter moeten krijgen.
Dan vragen we ons af of we deze via de constructor of via een getter meegeven, aangezien de SessionManager niks kan zonder de Session factory moeten we die via de constructor meegeven en de huidige sessies moet ook via de constructor (die hebben we immers meteen nodig).
Tot zover het nadenken, aan de slag:
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
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
<?php
$container = new Container();
// session klasse
$container->setParameter('session.class', 'Ozzie\Framework\Session\Session');
// session service factory
$container->set('session', function ($c) {
return $c->getParameter('session.class')();
});
// de SessionManager klasse
$container->setParameter('session_manager.class', 'Ozzie\Framework\Session\SessionManager');
// de huidige sessies
$container->setParameter('session_manager.current_sessions', $_SESSION);
// de SessionManager factory
$container->set('session_manager', function ($c) {
return $c->getParameter('session_manager.class')(
$c->get('session', true),
$c->getParameter('session_manager.current_sessions')
);
});
?>
$container = new Container();
// session klasse
$container->setParameter('session.class', 'Ozzie\Framework\Session\Session');
// session service factory
$container->set('session', function ($c) {
return $c->getParameter('session.class')();
});
// de SessionManager klasse
$container->setParameter('session_manager.class', 'Ozzie\Framework\Session\SessionManager');
// de huidige sessies
$container->setParameter('session_manager.current_sessions', $_SESSION);
// de SessionManager factory
$container->set('session_manager', function ($c) {
return $c->getParameter('session_manager.class')(
$c->get('session', true),
$c->getParameter('session_manager.current_sessions')
);
});
?>
Nu hebben we de container helemaal geconfigureerd (dit doen we nu met PHP, later wil je hier misschien XML of Yaml voor gebruiken).
Tijd om hem te gebruiken:
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
use Ozzie\Framework\Controller\Controller;
use Ozzie\Framework\Controller\Http\Response;
class WelcomeController extends Controller
{
public function indexAction()
{
$html = '<!doctype html><meta charset=utf-8><title>hello world</title>';
$sm = $this->getContainer()->get('session_manager');
if (!$sm->has('visitor_name') {
// new visitor
$html .= '<h3>Welkom op deze website!</h3>';
} else {
// returning visitor
$html .= '<h3>Welkom terug, '.$sm->get('visitor_name').'!</h3>';
}
return new Response($html);
}
}
?>
use Ozzie\Framework\Controller\Controller;
use Ozzie\Framework\Controller\Http\Response;
class WelcomeController extends Controller
{
public function indexAction()
{
$html = '<!doctype html><meta charset=utf-8><title>hello world</title>';
$sm = $this->getContainer()->get('session_manager');
if (!$sm->has('visitor_name') {
// new visitor
$html .= '<h3>Welkom op deze website!</h3>';
} else {
// returning visitor
$html .= '<h3>Welkom terug, '.$sm->get('visitor_name').'!</h3>';
}
return new Response($html);
}
}
?>
In dit geval gaan ik ervan uit dat de Controller klasse van je framework de ContainerAware klasse overerft (die weer ContainerAwareInterface implementeerd) die ervoor zorgt dat we toegang hebben tot de getContainer en setContainer methods.
Edit:
Sorry, niet erg kort geworden. Naja, als je er wat aan hebt, nu heb ik tenminste ook weer een mooi bericht om vaker naar te linken.
Gewijzigd op 07/01/2013 19:48:12 door Wouter J
Bedoel je met "current_sessions" de inhoud (array velden) van de huidige sessie? Of bedoel je hier echt de afzonderlijke sessiebestanden op de server mee?
Ik moet nog even doorkrijgen wat nu precies het verschil is tussen session en session_manager.
(Merk dat ik niet heel scherp meer ben momenteel...)
Quote:
wat is dit eigenlijk? 'Ozzie\Framework\Session\SessionManager' Is dat het pad naar de Session Class?
Dit is de SessionManager klasse in de Ozzie\Framework\Session namespace.
Quote:
Bedoel je met "current_sessions" de inhoud (array velden) van de huidige sessie? Of bedoel je hier echt de afzonderlijke sessiebestanden op de server mee?
Kijk maar naar de definitie van current_sessions op regel 17.
Quote:
Ik moet nog even doorkrijgen wat nu precies het verschil is tussen session en session_manager.
Session is 1 enkele sessie en SessionManager is de DataMapper voor deze sessies.
Wat bedoel je precies met datamapper? Je kunt de gegevens toch uit de Session class halen? Ik snap niet helemaal waarom je daar 2 classes voor maakt.
De session klasse is toch maar 1 sessie? Daar kun je dan alleen de gegeven uit halen voor 1 sessie. Je hebt dan nog een klasse nodig die alle sessies groepeert en die ervoor zorgt dat je sessies kunt aanmaken, updaten, verwijderen en uitlezen?