Doctrine 2 Cache
Gisteren begon ik het Doctrine 2 framework een beetje te ontdekken en toen kwam ik er tot mijn verbazing achter dat wordt verwacht dat cache wordt gebruikt, maar slechts APC, Memcache en XCache backends worden meegegeven, geen filecache. Deze wou ik dus zelf maken, en om het makkelijk te maken wou ik dat met een wrapper om Zend_Cache_Backend_File doen.
Hierbij stuitte ik echter op wat problemen: Zend_Cache_Backend_File escaped de id's niet, en met de namespace separator die doctrine in de id's stopt, krijg je problemen: de save werkt niet. Dit probeerde ik op te lossen door het id te encoden, ik dacht dat deze toch niet meer wordt teruggegeven aan Doctrine en er dus geen problemen zouden voordoen. Wanneer ik dit echter doe, door bijvoorbeeld het id te hashen of de backslash te vervangen, dat maakt niet uit, krijg ik de volgende, nogal onverwachte foutmelding:
Let op: De eerste keer gaat alles ok, en wordt de cache opgeslagen, de tweede keer gaat het bij het laden fout.
Notice: Trying to get property of non-object in C:\Program Files\Zend\Apache2\htdocs\doctrine\Doctrine\ORM\UnitOfWork.php on line 1210
Fatal error: Call to a member function isPostInsertGenerator() on a non-object in C:\Program Files\Zend\Apache2\htdocs\doctrine\Doctrine\ORM\UnitOfWork.php on line 1211
Het vreemde is, dat wanneer ik het id niet encode en het saven niet werkt (Zend_Cache_Backend_File negeert de fout stilletjes) hij gewoon steeds opnieuw saved en dus geen foutmelding geeft. Wanneer ik mijn cache voor de dummy ArrayCache van Doctrine vervang, gaat alles goed. Wanneer ik Doctrine's APC Cache gebruik gaat alles goed en wanneer ik Zend's APC cache gebruik met mijn wrapper gaat ook alles goed. Het moet dus bij het coderen van het id liggen.
Hier de wrapper, met log functie:
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
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
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
<?php
use Doctrine\Common\Cache\AbstractCache;
class ZendCache extends AbstractCache
{
protected $backend;
protected $log = array();
private function _log($action, array $params = array())
{
$this->log[] = array(
'action' => $action,
'params' => $params
);
}
public function getLogs()
{
return $this->log;
}
public function __construct(\Zend_Cache_Backend_ExtendedInterface $backend)
{
$this->backend = $backend;
}
/**
* {@inheritdoc}
*/
public function getIds()
{
$this->_log('getIds', array('result'=>$this->backend->getIds()));
return $this->backend->getIds();
}
/**
* {@inheritdoc}
*/
protected function _doFetch($id)
{
$this->_log('fetch',
array(
'id'=>$this->_encodeId($id),
'result'=>$this->backend->load($this->_encodeId($id))
)
);
return $this->backend->load($this->_encodeId($id));
}
/**
* {@inheritdoc}
*/
protected function _doContains($id)
{
$this->_log('contains',
array(
'id' => $this->_encodeId($id),
'result' => $this->backend->test($id)
)
);
return $this->backend->test($this->_encodeId($id));
}
/**
* {@inheritdoc}
*/
protected function _doSave($id, $data, $lifeTime = null)
{
$return = $this->backend->save($data, $this->_encodeId($id), array(), $lifeTime);
$this->_log('save',
array(
'id' => $this->_encodeId($id),
'data' => $data,
'lifeTime' =>$lifeTime,
'return' => $return,
)
);
return $return;
}
/**
* {@inheritdoc}
*/
protected function _doDelete($id)
{
$this->_log('delete', array('id' => $id));
return $this->backend->remove($this->_encodeId($id));
}
protected function _encodeId($id)
{
return str_replace('\\', '.', $id);
}
}
?>
use Doctrine\Common\Cache\AbstractCache;
class ZendCache extends AbstractCache
{
protected $backend;
protected $log = array();
private function _log($action, array $params = array())
{
$this->log[] = array(
'action' => $action,
'params' => $params
);
}
public function getLogs()
{
return $this->log;
}
public function __construct(\Zend_Cache_Backend_ExtendedInterface $backend)
{
$this->backend = $backend;
}
/**
* {@inheritdoc}
*/
public function getIds()
{
$this->_log('getIds', array('result'=>$this->backend->getIds()));
return $this->backend->getIds();
}
/**
* {@inheritdoc}
*/
protected function _doFetch($id)
{
$this->_log('fetch',
array(
'id'=>$this->_encodeId($id),
'result'=>$this->backend->load($this->_encodeId($id))
)
);
return $this->backend->load($this->_encodeId($id));
}
/**
* {@inheritdoc}
*/
protected function _doContains($id)
{
$this->_log('contains',
array(
'id' => $this->_encodeId($id),
'result' => $this->backend->test($id)
)
);
return $this->backend->test($this->_encodeId($id));
}
/**
* {@inheritdoc}
*/
protected function _doSave($id, $data, $lifeTime = null)
{
$return = $this->backend->save($data, $this->_encodeId($id), array(), $lifeTime);
$this->_log('save',
array(
'id' => $this->_encodeId($id),
'data' => $data,
'lifeTime' =>$lifeTime,
'return' => $return,
)
);
return $return;
}
/**
* {@inheritdoc}
*/
protected function _doDelete($id)
{
$this->_log('delete', array('id' => $id));
return $this->backend->remove($this->_encodeId($id));
}
protected function _encodeId($id)
{
return str_replace('\\', '.', $id);
}
}
?>
Dank voor het meedenken
Gewijzigd op 29/06/2010 10:12:46 door Pim -
Iemand hier enig verstand van?
Kan je $data bij backend->save en na backend->load vergelijken? Zitten daar verschillen in?
Het vreemde is echter dat wanneer ik de APC cache van Zend in mijn wrapper stop, het wel werkt... Maar ik zal de in en output vergelijken als ik weer bij mijn thuiscomputer kan.
Juist en daarom vermoed ik dat de fout in Backend_File zelf zit.