Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitedf1bf7

Browse files
committed
Create OpCache adapter to use OPCache in recent versions of PHP
1 parent1ceb61e commitedf1bf7

File tree

3 files changed

+360
-0
lines changed

3 files changed

+360
-0
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Cache\Adapter;
13+
14+
useSymfony\Component\Cache\Exception\InvalidArgumentException;
15+
16+
/**
17+
* Adapter building static PHP files that will be cached by OPCache.
18+
* This Adapter is in read-only if you use AdapterInterface methods.
19+
* You can use the method "warmUp" to build the cache file.
20+
*
21+
* @author Titouan Galopin <galopintitouan@gmail.com>
22+
*/
23+
class OpCacheAdapterextends AbstractAdapter
24+
{
25+
private$file;
26+
private$storeSerialized;
27+
private$loaded;
28+
private$values;
29+
30+
publicfunction__construct($file,$namespace ='',$defaultLifetime =0,$storeSerialized =true)
31+
{
32+
parent::__construct($namespace,$defaultLifetime);
33+
34+
$directory =dirname($file);
35+
36+
if (!file_exists($directory)) {
37+
@mkdir($directory,0777,true);
38+
}
39+
40+
if (!file_exists($directory)) {
41+
thrownewInvalidArgumentException(sprintf(
42+
'Cache directory does not exist and cannot be created (%s)',
43+
$directory
44+
));
45+
}
46+
47+
if (!is_writable($directory)) {
48+
thrownewInvalidArgumentException(sprintf('Cache directory is not writable (%s)',$directory));
49+
}
50+
51+
$this->file =$file;
52+
$this->storeSerialized =$storeSerialized;
53+
$this->loaded =false;
54+
$this->values = [];
55+
}
56+
57+
publicfunctionwarmUp(array$values = [])
58+
{
59+
// On PHP 5.6, OPcache is able to keep statically declared arrays in shared memory,
60+
// but only up to 32767 elements (See https://bugs.php.net/68057).
61+
// On PHP 7.0+, all static arrays are kept in shared memory, statically declared or not.
62+
$static =count($values) >32767 ?'' :'static';
63+
64+
if ($this->storeSerialized) {
65+
foreach ($valuesas$id =>$value) {
66+
$values[$id] =serialize($value);
67+
}
68+
}
69+
70+
$exported =var_export($values,true);
71+
72+
$dump =<<<EOF
73+
<?php
74+
75+
/**
76+
* This file has been auto-generated
77+
* by the Symfony Cache Component.
78+
*/
79+
80+
$static\$staticArray =$exported;
81+
82+
\$array =&\$staticArray;
83+
unset(\$staticArray);
84+
85+
return\$array;
86+
EOF;
87+
88+
file_put_contents($this->file,$dump);
89+
90+
$this->loaded =false;
91+
$this->loadFile();
92+
}
93+
94+
/**
95+
* {@inheritdoc}
96+
*/
97+
protectedfunctiondoFetch(array$ids)
98+
{
99+
$this->loadFile();
100+
101+
$values = [];
102+
103+
foreach ($idsas$id) {
104+
if (!$this->doHave($id)) {
105+
continue;
106+
}
107+
108+
if ($this->storeSerialized) {
109+
$values[$id] =unserialize($this->values[$id]);
110+
}else {
111+
$values[$id] =$this->values[$id];
112+
}
113+
}
114+
115+
return$values;
116+
}
117+
118+
/**
119+
* {@inheritdoc}
120+
*/
121+
protectedfunctiondoHave($id)
122+
{
123+
$this->loadFile();
124+
125+
returnisset($this->values[$id]);
126+
}
127+
128+
/**
129+
* {@inheritdoc}
130+
*/
131+
protectedfunctiondoClear($namespace)
132+
{
133+
// This Adapter is read-only
134+
returnfalse;
135+
}
136+
137+
/**
138+
* {@inheritdoc}
139+
*/
140+
protectedfunctiondoDelete(array$ids)
141+
{
142+
// This Adapter is read-only
143+
returnfalse;
144+
}
145+
146+
/**
147+
* {@inheritdoc}
148+
*/
149+
protectedfunctiondoSave(array$values,$lifetime)
150+
{
151+
// This Adapter is read-only
152+
returnfalse;
153+
}
154+
155+
/**
156+
* Load the cache file.
157+
*/
158+
privatefunctionloadFile()
159+
{
160+
if ($this->loaded) {
161+
return;
162+
}
163+
164+
$this->loaded =true;
165+
166+
if (!file_exists($this->file)) {
167+
$this->values = [];
168+
return;
169+
}
170+
171+
$this->values =require$this->file;
172+
}
173+
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Cache\Tests\Adapter;
13+
14+
useCache\IntegrationTests\CachePoolTest;
15+
usePsr\Cache\CacheItemInterface;
16+
useSymfony\Component\Cache\Adapter\OpCacheAdapter;
17+
18+
/**
19+
* @group time-sensitive
20+
*/
21+
class OpCacheNotSerializedAdapterTestextends CachePoolTest
22+
{
23+
private$filename;
24+
25+
protected$skippedTests =array(
26+
'testBasicUsage' =>'OpCacheAdpater is read-only.',
27+
'testClear' =>'OpCacheAdpater is read-only.',
28+
'testClearWithDeferredItems' =>'OpCacheAdpater is read-only.',
29+
'testDeleteItem' =>'OpCacheAdpater is read-only.',
30+
'testSave' =>'OpCacheAdpater is read-only.',
31+
'testSaveExpired' =>'OpCacheAdpater is read-only.',
32+
'testSaveWithoutExpire' =>'OpCacheAdpater is read-only.',
33+
'testDeferredSave' =>'OpCacheAdpater is read-only.',
34+
'testDeferredSaveWithoutCommit' =>'OpCacheAdpater is read-only.',
35+
'testDeleteItems' =>'OpCacheAdpater is read-only.',
36+
'testDeleteDeferredItem' =>'OpCacheAdpater is read-only.',
37+
'testCommit' =>'OpCacheAdpater is read-only.',
38+
'testSaveDeferredWhenChangingValues' =>'OpCacheAdpater is read-only.',
39+
'testSaveDeferredOverwrite' =>'OpCacheAdpater is read-only.',
40+
'testSavingObject' =>'OpCacheAdpater is read-only.',
41+
42+
'testDataTypeObject' =>'OpCacheAdpater without serialization does not support objects.',
43+
44+
'testExpiresAt' =>'OpCacheAdpater does not support expiration.',
45+
'testExpiresAtWithNull' =>'OpCacheAdpater does not support expiration.',
46+
'testExpiresAfterWithNull' =>'OpCacheAdpater does not support expiration.',
47+
'testDeferredExpired' =>'OpCacheAdpater does not support expiration.',
48+
'testExpiration' =>'OpCacheAdpater does not support expiration.',
49+
50+
// todo
51+
'testIsHit' =>'OpCacheAdpater is read-only.',
52+
'testIsHitDeferred' =>'OpCacheAdpater is read-only.',
53+
'testDataTypeString' =>'OpCacheAdpater is read-only.',
54+
'testDataTypeInteger' =>'OpCacheAdpater is read-only.',
55+
'testDataTypeNull' =>'OpCacheAdpater is read-only.',
56+
'testDataTypeFloat' =>'OpCacheAdpater is read-only.',
57+
'testDataTypeBoolean' =>'OpCacheAdpater is read-only.',
58+
'testDataTypeArray' =>'OpCacheAdpater is read-only.',
59+
);
60+
61+
publicfunctioncreateCachePool()
62+
{
63+
$this->filename =sys_get_temp_dir() .'/symfony-cache/OpCache/not_serialized.php';
64+
65+
returnnewOpCacheAdapter($this->filename,'',0,false);
66+
}
67+
68+
publicfunctiontestWarmUp()
69+
{
70+
$values = [
71+
'string' =>'string',
72+
'integer' =>42,
73+
'null' =>null,
74+
'float' =>42.42,
75+
'boolean' =>true,
76+
'array_simple' => ['foo','bar' ],
77+
'array_associative' => ['foo' =>'bar','foo2' =>'bar2' ],
78+
];
79+
80+
$adapter =$this->createCachePool();
81+
$adapter->warmUp($values);
82+
83+
$this->assertEquals(
84+
file_get_contents(__DIR__ .'/../Fixtures/OpCache/not_serialized.php'),
85+
file_get_contents($this->filename),
86+
'Warm up should create a PHP file that OPCache can load in memory'
87+
);
88+
}
89+
90+
publicfunctiontestGetItem()
91+
{
92+
$adapter =$this->createCachePool();
93+
$adapter->warmUp(['key' =>'value' ]);
94+
95+
// get existing item
96+
$item =$adapter->getItem('key');
97+
$this->assertEquals('value',$item->get(),'A stored item must be returned from cached.');
98+
$this->assertEquals('key',$item->getKey(),'Cache key can not change.');
99+
100+
// get non-existent item
101+
$item =$adapter->getItem('key2');
102+
$this->assertFalse($item->isHit());
103+
$this->assertNull($item->get(),"Item's value must be null when isHit is false.");
104+
}
105+
106+
publicfunctiontestGetItems()
107+
{
108+
$adapter =$this->createCachePool();
109+
$adapter->warmUp(['foo' =>'foo','bar' =>'bar','baz' =>'baz' ]);
110+
111+
$keys = ['foo','bar','baz','biz'];
112+
113+
/** @type CacheItemInterface[] $items */
114+
$items =$adapter->getItems($keys);
115+
$count =0;
116+
117+
foreach ($itemsas$key =>$item) {
118+
$itemKey =$item->getKey();
119+
120+
$this->assertEquals($itemKey,$key,'Keys must be preserved when fetching multiple items');
121+
$this->assertEquals($key !=='biz',$item->isHit());
122+
$this->assertTrue(in_array($key,$keys),'Cache key can not change.');
123+
124+
// Remove $key for $keys
125+
foreach ($keysas$k =>$v) {
126+
if ($v ===$key) {
127+
unset($keys[$k]);
128+
}
129+
}
130+
131+
$count++;
132+
}
133+
134+
$this->assertSame(4,$count);
135+
}
136+
137+
publicfunctiontestHasItem()
138+
{
139+
$adapter =$this->createCachePool();
140+
$adapter->warmUp(['key' =>'foo' ]);
141+
142+
// has existing item
143+
$this->assertTrue($adapter->hasItem('key'));
144+
145+
// has non-existent item
146+
$this->assertFalse($adapter->hasItem('key2'));
147+
}
148+
149+
publicfunctiontestKeyLength()
150+
{
151+
$key ='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.';
152+
153+
$adapter =$this->createCachePool();
154+
$adapter->warmUp([$key =>'value' ]);
155+
156+
$this->assertTrue($adapter->hasItem($key),'The implementation does not support a valid cache key');
157+
}
158+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/**
4+
* This file has been auto-generated
5+
* by the Symfony Cache Component.
6+
*/
7+
8+
static$staticArray =array (
9+
'string' =>'string',
10+
'integer' =>42,
11+
'null' =>NULL,
12+
'float' =>42.420000000000002,
13+
'boolean' =>true,
14+
'array_simple' =>
15+
array (
16+
0 =>'foo',
17+
1 =>'bar',
18+
),
19+
'array_associative' =>
20+
array (
21+
'foo' =>'bar',
22+
'foo2' =>'bar2',
23+
),
24+
);
25+
26+
$array =&$staticArray;
27+
unset($staticArray);
28+
29+
return$array;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp