Functie in class toevoegen
Bestaat er een mogelijkheid om functies toe te voegen aan een class. Ik ben vna plan om een aantal plugins te gaan makenen dia via classes in de hoofd class toe te voegen.
Bijv.
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
Code (php)
dus de function addon_test() toevoegen aan de class clsMain.
Gewijzigd op 28/02/2011 18:08:44 door Kevin van der Burgt
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
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
<?php
interface Plugin
{
public function call();
public function getName();
}
// Kan ook
interface Plugin_Aware extends Plugin
{
public function setPlugable(Plugable $plugable);
}
abstract class Plugable
{
protected $plugins = array();
public function registerPlugin(Plugin $plugin)
{
$this->plugins[$plugin->getName()] = $plugin;
if($plugin instanceof Plugin_Aware)
$plugin->setPlugable($this);
}
public function callPlugin($name, $args = array())
{
if(isset($this->plugins[$name]))
return call_user_func_array(
array($this->plugins[$name], 'call'),
$args
);
throw new InvalidArgumentException(sprintf('Plugin "%s" not found', $name));
}
}
abstract class Plugable_Magic
{
public function __call($name, $args)
{
try {
return $this->callPlugin($name, $args);
}
// Deze exception is netter
catch(InvalidArgumentException $e) {
throw new BadMethodCallException($e->getMessage());
}
}
}
?>
interface Plugin
{
public function call();
public function getName();
}
// Kan ook
interface Plugin_Aware extends Plugin
{
public function setPlugable(Plugable $plugable);
}
abstract class Plugable
{
protected $plugins = array();
public function registerPlugin(Plugin $plugin)
{
$this->plugins[$plugin->getName()] = $plugin;
if($plugin instanceof Plugin_Aware)
$plugin->setPlugable($this);
}
public function callPlugin($name, $args = array())
{
if(isset($this->plugins[$name]))
return call_user_func_array(
array($this->plugins[$name], 'call'),
$args
);
throw new InvalidArgumentException(sprintf('Plugin "%s" not found', $name));
}
}
abstract class Plugable_Magic
{
public function __call($name, $args)
{
try {
return $this->callPlugin($name, $args);
}
// Deze exception is netter
catch(InvalidArgumentException $e) {
throw new BadMethodCallException($e->getMessage());
}
}
}
?>
Gewijzigd op 28/02/2011 18:43:02 door Pim -
Ik roep geen interne methodes aan met die functie. Wel goed kijken...
ohw slecht gekeken...Maar aan de ts, let er wel mee op hoe dit te gebruiken
Ja inderdaad, ben momenteel een beetje de draad kwijt. Want heb een template engine gemaakt in een class. Maar ik wil ook dat ik er addons ik kan gaan verwerken. Ik ben er nog niet helemaal over uit hoe ik dit wil gaan doen.
Snap je mijn voorbeeld een beetje? Zo niet, wat niet?
Pim - op 28/02/2011 19:03:06:
Snap je mijn voorbeeld een beetje? Zo niet, wat niet?
interface Plugin etc.. wat betekend interface dan allemaal?
En voor de CMS die ik aan het maken ben, heb ik veelal verschillende classes gemaakt. voor zoals het parsen van de template, de foutberichten etc.. Of is het verstandiger om alles in een enkele class te zetten?
Niels Kieviet op 28/02/2011 19:14:58:
Als je nog niet de beginselen van OO kunt raad ik je deze tutorial aan die je even klaarstoomt voor de beginselen van het OO denken, programmeren etc.
http://phptuts.nl/view/45/
http://phptuts.nl/view/45/
Ik weet wel hoe OOP werkt ;) Dat is het probleem niet.
Echter de communicatie tussen de classes is een beetje verwarrend.
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
interface Plugin
{
// De daadwerkelijke functie
public function call();
// Geef de naam van de plugin als string terug
public function getName();
}
abstract class Plugable
{
protected $plugins = array();
public function registerPlugin(Plugin $plugin)
{
$this->plugins[$plugin->getName()] = $plugin;
}
// Roep aan
public function callPlugin($name, $args = array())
{
if(isset($this->plugins[$name]))
return call_user_func_array(
array($this->plugins[$name], 'call'),
$args
);
throw new InvalidArgumentException(sprintf('Plugin "%s" not found', $name));
}
}
?>
interface Plugin
{
// De daadwerkelijke functie
public function call();
// Geef de naam van de plugin als string terug
public function getName();
}
abstract class Plugable
{
protected $plugins = array();
public function registerPlugin(Plugin $plugin)
{
$this->plugins[$plugin->getName()] = $plugin;
}
// Roep aan
public function callPlugin($name, $args = array())
{
if(isset($this->plugins[$name]))
return call_user_func_array(
array($this->plugins[$name], 'call'),
$args
);
throw new InvalidArgumentException(sprintf('Plugin "%s" not found', $name));
}
}
?>
Lees de klasse anders nog eens een keer aandachtig door.
http://test.development-server.nl/class_test/
Wat dus uiteindelijk gedaan moet worden is dit:
[#showimage http://www.google.nl/images/logos/ps_logo2a_cp.png#] omzetten in
<img src="http://www.google.nl/images/logos/ps_logo2a_cp.png" alt="Test" />
Maar stel, er komt later nog een extra plugin. En ik wil youtube video's embedden door [#youtube 5Y0AhNz3zgU#] te typen het word omgezet in <object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/5Y0AhNz3zgU?fs=1&hl=nl_NL"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/5Y0AhNz3zgU?fs=1&hl=nl_NL" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="390"></embed></object>
Je hebt dan twee keuzes:
- Elke helper geeft 1 helper functie, dat doet mijn code
- Elke publieke functie van de helper is beschikbaar, dat maakt het registreren een klein beetje lastiger.
Optie 1:
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
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
<?php
interface Helper
{
// De daadwerkelijke functie
public function call();
// Geef de naam van de plugin als string terug
public function getName();
}
class Helper_Registry
{
protected $helpers = array();
public function register(Helper $helper)
{
$this->helpers[$helper->getName()] = $helper;
}
// Roep aan
public function call($name, $args = array())
{
if(isset($this->helpers[$name]))
return call_user_func_array(
array($this->helpers[$name], 'call'),
$args
);
throw new InvalidArgumentException(sprintf('Helper"%s" not found', $name));
}
// Magisch
// Ik vind het vaak mooier om magische functies als wrapper te gebruiken
// en er dus geen echte code in te zetten
public function __call($name, $args)
{
return $this->call($name, $args);
}
}
?>
interface Helper
{
// De daadwerkelijke functie
public function call();
// Geef de naam van de plugin als string terug
public function getName();
}
class Helper_Registry
{
protected $helpers = array();
public function register(Helper $helper)
{
$this->helpers[$helper->getName()] = $helper;
}
// Roep aan
public function call($name, $args = array())
{
if(isset($this->helpers[$name]))
return call_user_func_array(
array($this->helpers[$name], 'call'),
$args
);
throw new InvalidArgumentException(sprintf('Helper"%s" not found', $name));
}
// Magisch
// Ik vind het vaak mooier om magische functies als wrapper te gebruiken
// en er dus geen echte code in te zetten
public function __call($name, $args)
{
return $this->call($name, $args);
}
}
?>
Optie 2:
Geen interface voor de helpers
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
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
<?php
class Helper_Registry
{
// funcName => object
protected $helpers = array();
public function register($helper)
{
$reflection = new ReflectionObject($helper);
// Iterate alle publieke methoden
foreach($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
$this->helpers[$method->name] = $helper;
}
// Roep aan
public function call($name, $args = array())
{
if(isset($this->helpers[$name]))
return call_user_func_array(
array($this->helpers[$name], $name),
$args
);
throw new InvalidArgumentException(sprintf('Helper "%s" not found', $name));
}
// Magisch
public function __call($name, $args)
{
return $this->call($name, $args);
}
}
?>
class Helper_Registry
{
// funcName => object
protected $helpers = array();
public function register($helper)
{
$reflection = new ReflectionObject($helper);
// Iterate alle publieke methoden
foreach($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
$this->helpers[$method->name] = $helper;
}
// Roep aan
public function call($name, $args = array())
{
if(isset($this->helpers[$name]))
return call_user_func_array(
array($this->helpers[$name], $name),
$args
);
throw new InvalidArgumentException(sprintf('Helper "%s" not found', $name));
}
// Magisch
public function __call($name, $args)
{
return $this->call($name, $args);
}
}
?>
Gebruik:
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
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
<?php
// Optie 1:
class LinkHelper implements Helper
{
public function getName()
{
return 'linkhelper';
}
public function call($arg1, $arg2)
{
return $arg1.$arg2;
}
}
// Optie 2:
class LinkHelper
{
public function linkhelper($arg1, $arg2)
{
return $arg1.$arg2;
}
}
class View
{
/**
* @var Helper_Registry
*/
public $helpers;
public function indexView()
{
return $this->helpers->linkhelper($arg1, $arg2);
}
// EDIT ook leuk
public function __invoke($args)
{
$name = array_shift($args);
return $this->helpers->call($name, $args);
}
public function anotherView()
{
return $this('linkhelper', $arg1, $arg2);
}
}
$view = new View;
$view->helpers = new Helper_Registry;
$view->helpers->register(new LinkHelper);
echo $view->indexView();
?>
// Optie 1:
class LinkHelper implements Helper
{
public function getName()
{
return 'linkhelper';
}
public function call($arg1, $arg2)
{
return $arg1.$arg2;
}
}
// Optie 2:
class LinkHelper
{
public function linkhelper($arg1, $arg2)
{
return $arg1.$arg2;
}
}
class View
{
/**
* @var Helper_Registry
*/
public $helpers;
public function indexView()
{
return $this->helpers->linkhelper($arg1, $arg2);
}
// EDIT ook leuk
public function __invoke($args)
{
$name = array_shift($args);
return $this->helpers->call($name, $args);
}
public function anotherView()
{
return $this('linkhelper', $arg1, $arg2);
}
}
$view = new View;
$view->helpers = new Helper_Registry;
$view->helpers->register(new LinkHelper);
echo $view->indexView();
?>
Ja?
Gewijzigd op 28/02/2011 20:46:24 door Pim -
Bedankt Pim!! Precies wat ik zocht. Snap het helemaal. (Wel een beetje google gebruikt voor 'public function __invoke($args)'. Thx!
Kies je optie 1 of 2?
Optie 2, maar optie 1 ga ik ook eens proberen :-)