Class extenden en functies met dezelfde naam
Op dit moment heb ik een vrij groot systeem ontworpen (CMS, Webwinkel, Administratie) en dat allemaal OOP. Er is nu echter een klant die het systeem anders wilt laten werken (functies moeten veranderd worden) maar i.v.m. updates wil ik de 'standaardscripts' niet aanpassen. Als oplossing dacht ik dus om het volgende te doen:
In /lib/ gooi ik alle classes waar in aangepast mag worden. Deze extenden de standaardclasses die in /lib/default/ staan.
Een PHP script in /lib/ ziet er dan zo uit:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
require_once('default/shopItems.php');
class shopItems extends def_shopItems {
}
?>
require_once('default/shopItems.php');
class shopItems extends def_shopItems {
}
?>
Op PHP.net heb ik gevonden dat wanneer je een functie aanmaakt in bovenstaande class het de functie vervangt in de class die je 'extend'. Echter krijg ik een wit scherm (geen foutmelding).
Voorbeeldje:
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
require_once('default/shopOrders.php');
class shopOrders extends def_shopOrders {
/*
MAATWERK **********
*/
function handle(){
switch($this->_params['action']){
case 'checkout':
/* MAATWERK *********! $_this->_params['lid'] */
return $this->postOrder($_SESSION['cmsUserNo_'], $this->_params['cart'], $this->_params['reference'], $this->_params['shipping'], $this->_params['payment'], $this->_params['comment'], $this->_params['coupon'], $this->_params['lid']);
break;
case 'getOrderLines':
return $this->getOrderLines($this->_params['No_']);
break;
}
}
}
?>
require_once('default/shopOrders.php');
class shopOrders extends def_shopOrders {
/*
MAATWERK **********
*/
function handle(){
switch($this->_params['action']){
case 'checkout':
/* MAATWERK *********! $_this->_params['lid'] */
return $this->postOrder($_SESSION['cmsUserNo_'], $this->_params['cart'], $this->_params['reference'], $this->_params['shipping'], $this->_params['payment'], $this->_params['comment'], $this->_params['coupon'], $this->_params['lid']);
break;
case 'getOrderLines':
return $this->getOrderLines($this->_params['No_']);
break;
}
}
}
?>
de functie 'postOrder' staat eveneens in dat script echter kan ik dat niet gaan posten. Deze functie staat ook in de class die 'extended' wordt.
Ik hoop dat iemand kan helpen want anders kan deze klant niet van updates genieten gezien het niet te doen is om alles handmatig te gaan knippen / plakken.
Gewijzigd op 16/08/2011 12:05:19 door P Widdershoven
Zijn de functies en variabelen die je aanroept wel allemaal pubic of protected?
Cascading file system:
Dit vereist niet zo veel aanpassing en lijkt op wat je zelf zegt. Je maakt dan een intelligente factory die eerst kijkt of er een aangepaste versie bestaat en anders de standaard laadt:
Code (php)
http://kohanaframework.org/3.0/guide/kohana/files
Dat lijkt me niet zo moeilijk, maar het is niet zo mooi en overzichtelijk.
Event dispatcher:
Dit vereist veel herschrijf werk. Voor en na bepaalde handelingen (events) vraag je aan de regelaar (dispatcher/observer) of er luisteraars (listeners) zijn die de data voor- of achteraf willen aanpassen. Als je je originele code wil aanpassen, voeg je bij de specifieke applicatie specifieke luisteraars toe.
http://codemill.studio-connect.com/2010/06/06/implementing-the-observer-pattern-with-splobserver-and-splsubject/
http://symfony.com/doc/current/book/internals.html#the-event-dispatcher (Je kan de symfony2 dispatcher ook als los component gebruiken)
Uitbreidbare dependency injection container:
http://fabien.potencier.org/article/11/what-is-dependency-injection (algemeen)
Wanneer je dan elke applicatie een eigen DIC geeft, die de originele uitbreidt, kan je heel netjes de services aanpassen. Dit vereist waarschijnlijk wel dat je je code praktisch herschrijft.
Je kan dan ook de Symfony DIC als component gebruiken, die is uitgebreid en door caching heel snel, maar wel wat ingewikkeld.
http://symfony.com/doc/current/book/service_container.html
De mooiste oplossing lijkt me de DIC, eventueel aangevuld door de Event dispatcher. Dit is echter niet echt makkelijk toe te passen.
Oplossing was in mijn geval:
Maar hoe en waar bepaal je nou welke klasse geïnstantieerd moet worden?