forked from anthonyghr/PHP-ClassMixer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
156 lines (136 loc) · 5.41 KB
/
README
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*******************************************************************************
* PHP ClassMixer
*
* Authors:: anthony.gallagher@wellspringworldwide.com
*
* Copyright:: Copyright 2009, Wellspring Worldwide, LLC Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Description:
* ===========
* ClassMixer was inspired by the 'Mixins for PHP' article
* at http://www.advogato.org/article/470.html
* and the Common Lisp Object System (CLOS).
******************************************************************************/
PHP ClassMixer is a small, but powerful utility to enable the use of multiple inheritance
and a form of Aspect-Oriented Programming (AOP) in PHP.
It grew out of a sense of frustration with some of the limitations imposed by the PHP language,
and a desire to more closely adhere to the Don't Repeat Yourself (DRY) software
engineering principle.
ClassMixer has allowed Wellspring engineers to significantly decrease code duplication
throughout our codebase by encapsulating repeated patterns found in several of our classes
into reusable mixins, reducing the lines of code in many of our classes by over 50%.
As its name implies, ClassMixer is a utility that 'mixes' a set of 'parent' classes, resulting in
a 'child' class that has all the attributes and methods of the parents. In addition, ClassMixer
provides the ability to create 'before' and 'after' methods. These methods are similar to
pointcuts in AOP, allowing the interjection of code at the beginning (before) or the end (after)
of a method execution.
Installation
============
Installing ClassMixer is trivial. Simply copy the ClassMixer.php file to the directory of your choice,
and include/require it.
Requirements
============
To make use of the complete feature set of ClassMixer, PHP 5.0 or above must be installed on the system.
However, ClassMixer is still functional with a limited set of features using PHP 4.2 or above.
Examples
========
/******************************************************************************
* Example 1: Taken from sample4.php in the samples directory
* The following example demonstrates how a base "BasePerson" class is mixed
* with a mixin "ProgrammerMixin" to produce a "Person" class.
* Notice the usage of combinators to tell ClassMixer how to combine
* the methods in BasePerson and ProgrammerMixin.
******************************************************************************/
require_once(PATH_TO_CLASSMIXER . '/ClassMixer.php');
/**
* Base class with common person information
*/
abstract class BasePerson {
private $first_name;
private $last_name;
function __construct($fname, $lname) {
$this->first_name = $fname;
$this->last_name = $lname;
}
function sayName() {
return "Hi, my name is $this->first_name $this->last_name";
}
function hobby() {
return "I like to breath";
}
function anti_hobby() {
return "I don't like germs";
}
}
/**
* Mixin class to add additional programmer-like methods to a person
*/
abstract class ProgrammerMixin {
function hobby() {
return "I like to hack";
}
function anti_hobby() {
return "I don't like bugs";
}
}
/**
* Mixin class to add additional skier-like methods to a person
*/
abstract class SkierMixin {
function hobby() {
return "I like to ski";
}
}
/**
* A combinator: This function (which expects string arguments)
* concatenates all its arguments.
*
* @return <type>
*/
function and_concat() {
$args = func_get_args();
return implode(' and ', $args);
}
//Define that the ClassMixer should use the 'and_concat' combinator
// for merging the results of the 'hobby' and 'anti_hobby' methods
// in the parent classes.
// In addition, the parent classes to use, and the order in which they
// should be used is defined
$combinators = array('hobby' => array('and_concat',
array('ProgrammerMixin', 'SkierMixin')),
'anti_hobby' => array('and_concat',
array('ProgrammerMixin')));
//Create a mixed 'Person' class where ProgrammerMixin and SkierMixin
// have been added to BasePerson
ClassMixer::create_mixed_class('Person', 'BasePerson',
array('ProgrammerMixin',
'SkierMixin'),
$combinators);
//Show resulting functionality. When hobby is called, the 'hobby' methods
// on ProgrammerMixin and BasePerson are called, in that order (as specified
// in the array), and the results concatenated.
// Similarly, when anti_hobby is called, only the method on ProgrammerMixin
// is called
$p = new Person('Joe', 'Doe');
echo $p->sayName();
echo "\n";
echo $p->hobby();
echo "\n";
echo $p->anti_hobby();
echo "\n";
//---RESULTING OUTPUT---
//Hi, my name is Joe Doe
//I like to hack and I like to ski
//I don't like bugs