You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+72-52Lines changed: 72 additions & 52 deletions
Original file line number
Diff line number
Diff line change
@@ -29,6 +29,7 @@ DeepCopy helps you create deep copies (clones) of your objects. It is designed t
29
29
1.[Contributing](#contributing)
30
30
1.[Tests](#tests)
31
31
32
+
32
33
## How?
33
34
34
35
Install with Composer:
@@ -65,22 +66,27 @@ Now you're in for a big mess :(
65
66
66
67

67
68
69
+
68
70
### Using simply `clone`
69
71
70
72

71
73
74
+
72
75
### Overridding `__clone()`
73
76
74
77

75
78
79
+
76
80
### With `DeepCopy`
77
81
78
82

79
83
84
+
80
85
## How it works
81
86
82
87
DeepCopy recursively traverses all the object's properties and clones them. To avoid cloning the same object twice it keeps a hash map of all instances and thus preserves the object graph.
83
88
89
+
84
90
## Going further
85
91
86
92
You can add filters to customize the copy process.
@@ -91,11 +97,13 @@ and `$matcher` implementing `DeepCopy\Matcher\Matcher`.
91
97
92
98
We provide some generic filters and matchers.
93
99
100
+
94
101
### Matchers
95
102
96
103
-`DeepCopy\Matcher` applies on a object attribute.
97
104
-`DeepCopy\TypeMatcher` applies on any element found in graph, including array elements.
98
105
106
+
99
107
#### Property name
100
108
101
109
The `PropertyNameMatcher` will match a property by its name:
@@ -107,6 +115,7 @@ $matcher = new PropertyNameMatcher('id');
107
115
// will apply a filter to any property of any objects named "id"
108
116
```
109
117
118
+
110
119
#### Specific property
111
120
112
121
The `PropertyMatcher` will match a specific property of a specific class:
@@ -118,6 +127,7 @@ $matcher = new PropertyMatcher('MyClass', 'id');
118
127
// will apply a filter to the property "id" of any objects of the class "MyClass"
119
128
```
120
129
130
+
121
131
#### Type
122
132
123
133
The `TypeMatcher` will match any element by its type (instance of a class or any value that could be parameter of [gettype()](http://php.net/manual/en/function.gettype.php) function):
@@ -129,12 +139,14 @@ $matcher = new TypeMatcher('Doctrine\Common\Collections\Collection');
129
139
// will apply a filter to any object that is an instance of Doctrine\Common\Collections\Collection
130
140
```
131
141
142
+
132
143
### Filters
133
144
134
145
-`DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher`.
135
146
-`DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher`.
136
147
137
-
#### `SetNullFilter`
148
+
149
+
#### `SetNullFilter` (filter)
138
150
139
151
Let's say for example that you are copying a database record (or a Doctrine entity), so you want the copy not to have any ID:
If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`:
189
+
190
+
```php
191
+
use DeepCopy\DeepCopy;
192
+
use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter;
193
+
use DeepCopy\Matcher\PropertyTypeMatcher;
194
+
195
+
$deepCopy = new DeepCopy();
196
+
$deepCopy->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection'));
197
+
$myCopy = $deepCopy->copy($myObject);
198
+
```
199
+
200
+
201
+
#### `DoctrineEmptyCollectionFilter` (filter)
202
+
203
+
If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the `DoctrineEmptyCollectionFilter`
204
+
205
+
```php
206
+
use DeepCopy\DeepCopy;
207
+
use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter;
208
+
use DeepCopy\Matcher\PropertyMatcher;
209
+
210
+
$deepCopy = new DeepCopy();
211
+
$deepCopy->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty'));
212
+
$myCopy = $deepCopy->copy($myObject);
213
+
214
+
// $myCopy->myProperty will return an empty collection
215
+
```
216
+
217
+
218
+
#### `DoctrineProxyFilter` (filter)
219
+
220
+
If you use Doctrine and use cloning on lazy loaded entities, you might encounter errors mentioning missing fields on a
221
+
Doctrine proxy class (...\\\_\_CG\_\_\Proxy).
222
+
You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class.
223
+
**Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded before other filters are applied!**
224
+
225
+
```php
226
+
use DeepCopy\DeepCopy;
227
+
use DeepCopy\Filter\Doctrine\DoctrineProxyFilter;
228
+
use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher;
229
+
230
+
$deepCopy = new DeepCopy();
231
+
$deepCopy->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher());
232
+
$myCopy = $deepCopy->copy($myObject);
233
+
234
+
// $myCopy should now contain a clone of all entities, including those that were not yet fully loaded.
235
+
```
236
+
237
+
238
+
#### `ReplaceFilter` (type filter)
173
239
174
240
1. If you want to replace the value of a property:
The `$callback` parameter of the `ReplaceFilter` constructor accepts any PHP callable.
210
276
211
-
#### `ShallowCopyFilter`
277
+
278
+
#### `ShallowCopyFilter` (type filter)
212
279
213
280
Stop *DeepCopy* from recursively copying element, using standard `clone` instead:
214
281
@@ -228,59 +295,12 @@ $myServiceWithMocks = new MyService(m::mock(MyDependency1::class), m::mock(MyDep
228
295
// all mocks will be just cloned, not deep-copied
229
296
```
230
297
231
-
#### `DoctrineCollectionFilter`
232
-
233
-
If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`:
234
-
235
-
```php
236
-
use DeepCopy\DeepCopy;
237
-
use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter;
238
-
use DeepCopy\Matcher\PropertyTypeMatcher;
239
-
240
-
$deepCopy = new DeepCopy();
241
-
$deepCopy->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection'));
242
-
$myCopy = $deepCopy->copy($myObject);
243
-
```
244
-
245
-
#### `DoctrineEmptyCollectionFilter`
246
-
247
-
If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the `DoctrineEmptyCollectionFilter`
248
-
249
-
```php
250
-
use DeepCopy\DeepCopy;
251
-
use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter;
252
-
use DeepCopy\Matcher\PropertyMatcher;
253
-
254
-
$deepCopy = new DeepCopy();
255
-
$deepCopy->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty'));
256
-
$myCopy = $deepCopy->copy($myObject);
257
-
258
-
// $myCopy->myProperty will return an empty collection
259
-
```
260
-
261
-
#### `DoctrineProxyFilter`
262
-
263
-
If you use Doctrine and use cloning on lazy loaded entities, you might encounter errors mentioning missing fields on a
264
-
Doctrine proxy class (...\\\_\_CG\_\_\Proxy).
265
-
You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class.
266
-
**Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded before other filters are applied!**
267
-
268
-
```php
269
-
use DeepCopy\DeepCopy;
270
-
use DeepCopy\Filter\Doctrine\DoctrineProxyFilter;
271
-
use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher;
272
-
273
-
$deepCopy = new DeepCopy();
274
-
$deepCopy->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher());
275
-
$myCopy = $deepCopy->copy($myObject);
276
-
277
-
// $myCopy should now contain a clone of all entities, including those that were not yet fully loaded.
0 commit comments