[DCOM-175] Proxies return private properties in __sleep, which is not supported by PHP. Created: 27/Mar/12 Updated: 19/Apr/13 |
|
| Status: | In Progress |
| Project: | Doctrine Common |
| Component/s: | None |
| Affects Version/s: | 2.4 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major |
| Reporter: | Ryan Mauger | Assignee: | Marco Pivetta |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
__sleep should not return private parent property names (see http://php.net/__sleep) this raises notices, and also results in the value of the property being 'N' (null) instead of keeping its value. I am unfortunately stuck having to serialize proxies in my revision tracking, as doctrine seems to be currently ignoring the fetch="EAGER" I set on the related properties. Proxies should use the Serializable interface, and not __sleep, or not return parent property names which are private, it serves no purpose, and is not supported by PHP itself anyway. Also, if you keep __sleep, but do not return the parent property names, then it will only include the items you return, so it would be better to simply drop the __sleep method, I cannot actually see any useful purpose it serves. |
| Comments |
| Comment by Ryan Mauger [ 27/Mar/12 ] |
|
just updated the issue body, realised that I worded something badly. |
| Comment by Marco Pivetta [ 23/Jan/13 ] |
|
Ryan Mauger I think that's a limitation we have. We use `__sleep` to avoid serializing fields like the initializers and the persisters of course. Even by implementing serializable, it would only work if the end user implemented it in the parent class. Tempted to mark it as "can't fix" |
| Comment by Marco Pivetta [ 24/Jan/13 ] |
|
I think there's a solution by having something like following: class SomeGeneratedProxyName extends RealName implements \Serializable { public function unserialize($data) { $reflectionClass = new ReflectionClass($this); foreach ($reflectionClass->getProperties(ReflectionProperty::IS_PRIVATE) as $privateProp) { $privateProp->setAccessible(true); $privateProp->setValue($this, $data[$privateProp->getName()]); } // ... other props ... } public function serialize() { $data = array(); $reflectionClass = new ReflectionClass($this); foreach ($reflectionClass->getProperties(ReflectionProperty::IS_PRIVATE) as $privateProp) { $privateProp->setAccessible(true); $data[$privateProp->getName()] = $privateProp->getValue($this); } // ... other props ... return $data; } } |
| Comment by Marco Pivetta [ 23/Feb/13 ] |
|
Ryan Mauger I started implementing this one at https://github.com/Ocramius/common/compare/hotfix;DCOM-175 and so far it looks promising. The only doubts so far are with handling cases like following: class MyEntity implements Serializable { public function serialize() { // [...] } public function unserialize($serialized) { // [...] } public function __sleep() { // [...] } public function __wakeup() { // [...] } } So far I didn't get to write tests that demonstrate the exact behaviour for this case, but it looks like when `Serializable` is implemented, `_sleep` and `_wakeup` are ignored. Any thoughts on this? |
| Comment by Marco Pivetta [ 19/Apr/13 ] |
|
A possible solution is to use something like http://eval.in/16806, and thus exploiting the ability of php to retrieve an object's private properties by using the special chr(0) . 'Foo' . chr(0) . 'bar' trick. This can be abstracted by using array_keys((array) $object); , which retrieves also those special keys |
[DCOM-189] Doctrine Proxies may conflict with interfaced constructors Created: 03/May/13 Updated: 03/May/13 |
|
| Status: | Reopened |
| Project: | Doctrine Common |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Documentation | Priority: | Major |
| Reporter: | Harmen M | Assignee: | Marco Pivetta |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
The Doctrine ProxyGenerator generates for a proxy a constructor. The documentation of Doctrine states that the constructor is never called. For a project, I created a group of entities with a interfaced constructor in order to enforce a common interface. This results in a incompatible proxy and so a fatal error. |
| Comments |
| Comment by Marco Pivetta [ 03/May/13 ] |
|
Cannot fix this - the constructor is required to override instantiation logic |
| Comment by Harmen M [ 03/May/13 ] |
|
Edit: added the correct description. I accidentially submitted the form before editing the description. |
| Comment by Marco Pivetta [ 03/May/13 ] |
|
Harmen M why do you have a constructor in an interface? That's a very bad practice, and it makes things quite hard to handle. I can think of a workaround, but I first want to be sure there's a real advantage in changing the current implementation to use unserialize() just to handle this specific use case. |
| Comment by Benjamin Eberlei [ 03/May/13 ] |
|
Adding __construct to an interface is an anti pattern and shouldn't be done. |
| Comment by Harmen M [ 03/May/13 ] |
|
Ok, then I change my implementation. But, maybe it is an idea to update the documentation of the ORM and state that constructor interfacing is not possible? |
[DCOM-165] Entities seems not be recognized by AnnotationDriver Created: 02/Sep/12 Updated: 23/Jan/13 |
|
| Status: | Open |
| Project: | Doctrine Common |
| Component/s: | Annotations |
| Affects Version/s: | 2.2, 2.3 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Trivial |
| Reporter: | Maarten de Keizer | Assignee: | Marco Pivetta |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | annotationdriver, realpath, symlink, windows | ||
| Environment: |
Windows 7 Profesional, Enterprise and Windows Server 2003 and 2008; Common: 2.2.3 DBAL: 2.2.2 ORM: 2.2.3; PHP 5.4.5 and 5.3.5 |
||
| Description |
|
Problem: Debug steps: file AnnotationDriver.php method getAllClassNames() file AnnotationDriver.php method getAllClassNames() the following output will be displayed: It seems that Doctrine includes the file from f: but ReflectionClass say it is loaded from F:. The in_array() will fail and Doctrine will not recognized the entity. But this is not the full problem. I created a new debug point: file AnnotationDriver.php method getAllClassNames() This will result in the following output: So the conversion of the F: to f: is done by realpath; its look like A simple fix should be in AnnotationDriver.php / getAllClassNames() After I did that, the problem still exists. So I add to echo's (one with realpath and one without at the part of the code). And both echo's result in a path starting with "F:". So my first reaction was freaky! After some frustrating hours I found the problem in the symlink I used. Summary: Possible solutions: |
| Comments |
| Comment by Marco Pivetta [ 23/Jan/13 ] |
|
Maarten de Keizer looks like the issue is still there in doctrine/annotations. Are you able to come up with a failing test case? |