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

Commitb31562d

Browse files
[Form][EventDispatcher] Fix VarDumper usage related to perf regression
1 parent84229f8 commitb31562d

File tree

7 files changed

+249
-244
lines changed

7 files changed

+249
-244
lines changed

‎src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php‎

Lines changed: 15 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
useSymfony\Component\EventDispatcher\EventSubscriberInterface;
1616
useSymfony\Component\EventDispatcher\Event;
1717
useSymfony\Component\Stopwatch\Stopwatch;
18-
useSymfony\Component\VarDumper\Caster\ClassStub;
19-
useSymfony\Component\VarDumper\Cloner\VarCloner;
2018
usePsr\Log\LoggerInterface;
2119

2220
/**
@@ -34,7 +32,6 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
3432
private$called;
3533
private$dispatcher;
3634
private$wrappedListeners;
37-
private$cloner;
3835

3936
/**
4037
* Constructor.
@@ -50,9 +47,6 @@ public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $sto
5047
$this->logger =$logger;
5148
$this->called =array();
5249
$this->wrappedListeners =array();
53-
if (class_exists(ClassStub::class)) {
54-
$this->cloner =newVarCloner();
55-
}
5650
}
5751

5852
/**
@@ -159,8 +153,7 @@ public function getCalledListeners()
159153
$called =array();
160154
foreach ($this->calledas$eventName =>$listeners) {
161155
foreach ($listenersas$listener) {
162-
$info =$this->getListenerInfo($listener->getWrappedListener(),$eventName);
163-
$called[$eventName.'.'.$info['pretty']] =$info;
156+
$called[$eventName.'.'.$listener->getPretty()] =$listener->getInfo($eventName);
164157
}
165158
}
166159

@@ -198,8 +191,10 @@ public function getNotCalledListeners()
198191
}
199192

200193
if (!$called) {
201-
$info =$this->getListenerInfo($listener,$eventName);
202-
$notCalled[$eventName.'.'.$info['pretty']] =$info;
194+
if (!$listenerinstanceof WrappedListener) {
195+
$listener =newWrappedListener($listener,null,$this->stopwatch,$this);
196+
}
197+
$notCalled[$eventName.'.'.$listener->getPretty()] =$listener->getInfo($eventName);
203198
}
204199
}
205200
}
@@ -245,12 +240,11 @@ protected function postDispatch($eventName, Event $event)
245240
privatefunctionpreProcess($eventName)
246241
{
247242
foreach ($this->dispatcher->getListeners($eventName)as$listener) {
248-
$info =$this->getListenerInfo($listener,$eventName);
249-
$name =isset($info['class']) ?$info['class'] :$info['type'];
250-
$wrappedListener =newWrappedListener($listener,$name,$this->stopwatch,$this);
243+
$priority =$this->getListenerPriority($eventName,$listener);
244+
$wrappedListener =newWrappedListener($listener,null,$this->stopwatch,$this);
251245
$this->wrappedListeners[$eventName][] =$wrappedListener;
252246
$this->dispatcher->removeListener($eventName,$listener);
253-
$this->dispatcher->addListener($eventName,$wrappedListener,$info['priority']);
247+
$this->dispatcher->addListener($eventName,$wrappedListener,$priority);
254248
}
255249
}
256250

@@ -267,10 +261,13 @@ private function postProcess($eventName)
267261
$this->dispatcher->removeListener($eventName,$listener);
268262
$this->dispatcher->addListener($eventName,$listener->getWrappedListener(),$priority);
269263

270-
$info =$this->getListenerInfo($listener->getWrappedListener(),$eventName);
264+
if (null !==$this->logger) {
265+
$context =array('event' =>$eventName,'listener' =>$listener->getPretty());
266+
}
267+
271268
if ($listener->wasCalled()) {
272269
if (null !==$this->logger) {
273-
$this->logger->debug('Notified event "{event}" to listener "{listener}".',array('event' =>$eventName,'listener' =>$info['pretty']));
270+
$this->logger->debug('Notified event "{event}" to listener "{listener}".',$context);
274271
}
275272

276273
if (!isset($this->called[$eventName])) {
@@ -281,83 +278,19 @@ private function postProcess($eventName)
281278
}
282279

283280
if (null !==$this->logger &&$skipped) {
284-
$this->logger->debug('Listener "{listener}" was not called for event "{event}".',array('listener' =>$info['pretty'],'event' =>$eventName));
281+
$this->logger->debug('Listener "{listener}" was not called for event "{event}".',$context);
285282
}
286283

287284
if ($listener->stoppedPropagation()) {
288285
if (null !==$this->logger) {
289-
$this->logger->debug('Listener "{listener}" stopped propagation of the event "{event}".',array('listener' =>$info['pretty'],'event' =>$eventName));
286+
$this->logger->debug('Listener "{listener}" stopped propagation of the event "{event}".',$context);
290287
}
291288

292289
$skipped =true;
293290
}
294291
}
295292
}
296293

297-
/**
298-
* Returns information about the listener.
299-
*
300-
* @param object $listener The listener
301-
* @param string $eventName The event name
302-
*
303-
* @return array Information about the listener
304-
*/
305-
privatefunctiongetListenerInfo($listener,$eventName)
306-
{
307-
$info =array(
308-
'event' =>$eventName,
309-
'priority' =>$this->getListenerPriority($eventName,$listener),
310-
);
311-
if ($listenerinstanceof \Closure) {
312-
$info +=array(
313-
'type' =>'Closure',
314-
'pretty' =>'closure',
315-
);
316-
}elseif (is_string($listener)) {
317-
try {
318-
$r =new \ReflectionFunction($listener);
319-
$file =$r->getFileName();
320-
$line =$r->getStartLine();
321-
}catch (\ReflectionException$e) {
322-
$file =null;
323-
$line =null;
324-
}
325-
$info +=array(
326-
'type' =>'Function',
327-
'function' =>$listener,
328-
'file' =>$file,
329-
'line' =>$line,
330-
'pretty' =>$listener,
331-
);
332-
}elseif (is_array($listener) || (is_object($listener) &&is_callable($listener))) {
333-
if (!is_array($listener)) {
334-
$listener =array($listener,'__invoke');
335-
}
336-
$class =is_object($listener[0]) ?get_class($listener[0]) :$listener[0];
337-
try {
338-
$r =new \ReflectionMethod($class,$listener[1]);
339-
$file =$r->getFileName();
340-
$line =$r->getStartLine();
341-
}catch (\ReflectionException$e) {
342-
$file =null;
343-
$line =null;
344-
}
345-
$info +=array(
346-
'type' =>'Method',
347-
'class' =>$class,
348-
'method' =>$listener[1],
349-
'file' =>$file,
350-
'line' =>$line,
351-
'pretty' =>$class.'::'.$listener[1],
352-
);
353-
}
354-
if (null !==$this->cloner) {
355-
$info['data'] =$this->cloner->cloneVar(array(newClassStub($info['pretty'].'()',$listener)))->seek(0);
356-
}
357-
358-
return$info;
359-
}
360-
361294
privatefunctionsortListenersByPriority($a,$b)
362295
{
363296
if (is_int($a['priority']) && !is_int($b['priority'])) {

‎src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
useSymfony\Component\Stopwatch\Stopwatch;
1515
useSymfony\Component\EventDispatcher\Event;
1616
useSymfony\Component\EventDispatcher\EventDispatcherInterface;
17+
useSymfony\Component\VarDumper\Caster\ClassStub;
18+
useSymfony\Component\VarDumper\Cloner\VarCloner;
1719

1820
/**
1921
* @author Fabien Potencier <fabien@symfony.com>
@@ -26,6 +28,10 @@ class WrappedListener
2628
private$stoppedPropagation;
2729
private$stopwatch;
2830
private$dispatcher;
31+
private$pretty;
32+
private$data;
33+
34+
privatestatic$cloner;
2935

3036
publicfunction__construct($listener,$name,Stopwatch$stopwatch,EventDispatcherInterface$dispatcher =null)
3137
{
@@ -35,6 +41,26 @@ public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatc
3541
$this->dispatcher =$dispatcher;
3642
$this->called =false;
3743
$this->stoppedPropagation =false;
44+
45+
if (is_array($listener)) {
46+
$this->name =is_object($listener[0]) ?get_class($listener[0]) :$listener[0];
47+
$this->pretty =$this->name.'::'.$listener[1];
48+
}elseif ($listenerinstanceof \Closure) {
49+
$this->pretty =$this->name ='closure';
50+
}elseif (is_string($listener)) {
51+
$this->pretty =$this->name =$listener;
52+
}else {
53+
$this->name =get_class($listener);
54+
$this->pretty =$this->name.'::__invoke';
55+
}
56+
57+
if (null !==$name) {
58+
$this->name =$name;
59+
}
60+
61+
if (null ===self::$cloner) {
62+
self::$cloner =class_exists(ClassStub::class) ?newVarCloner() :false;
63+
}
3864
}
3965

4066
publicfunctiongetWrappedListener()
@@ -52,6 +78,25 @@ public function stoppedPropagation()
5278
return$this->stoppedPropagation;
5379
}
5480

81+
publicfunctiongetPretty()
82+
{
83+
return$this->pretty;
84+
}
85+
86+
publicfunctiongetInfo($eventName)
87+
{
88+
if (null ===$this->data) {
89+
$this->data =false !==self::$cloner ?self::$cloner->cloneVar(array(newClassStub($this->pretty.'()',$this->listener)))->seek(0) :$this->pretty;
90+
}
91+
92+
returnarray(
93+
'event' =>$eventName,
94+
'priority' =>null !==$this->dispatcher ?$this->dispatcher->getListenerPriority($eventName,$this->listener) :null,
95+
'pretty' =>$this->pretty,
96+
'data' =>$this->data,
97+
);
98+
}
99+
55100
publicfunction__invoke(Event$event,$eventName,EventDispatcherInterface$dispatcher)
56101
{
57102
$this->called =true;

‎src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,17 @@ public function testGetCalledListeners()
9696
$tdispatcher->addListener('foo',$listener =function () {});
9797

9898
$listeners =$tdispatcher->getNotCalledListeners();
99+
$this->assertArrayHasKey('data',$listeners['foo.closure']);
99100
unset($listeners['foo.closure']['data']);
100101
$this->assertEquals(array(),$tdispatcher->getCalledListeners());
101-
$this->assertEquals(array('foo.closure' =>array('event' =>'foo','type' =>'Closure','pretty' =>'closure','priority' =>0)),$listeners);
102+
$this->assertEquals(array('foo.closure' =>array('event' =>'foo','pretty' =>'closure','priority' =>0)),$listeners);
102103

103104
$tdispatcher->dispatch('foo');
104105

105106
$listeners =$tdispatcher->getCalledListeners();
107+
$this->assertArrayHasKey('data',$listeners['foo.closure']);
106108
unset($listeners['foo.closure']['data']);
107-
$this->assertEquals(array('foo.closure' =>array('event' =>'foo','type' =>'Closure','pretty' =>'closure','priority' =>null)),$listeners);
109+
$this->assertEquals(array('foo.closure' =>array('event' =>'foo','pretty' =>'closure','priority' =>null)),$listeners);
108110
$this->assertEquals(array(),$tdispatcher->getNotCalledListeners());
109111
}
110112

‎src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php‎

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
useSymfony\Component\HttpFoundation\Request;
1717
useSymfony\Component\HttpFoundation\Response;
1818
useSymfony\Component\HttpKernel\DataCollector\DataCollector;
19+
useSymfony\Component\HttpKernel\DataCollector\Util\ValueExporter;
20+
useSymfony\Component\VarDumper\Caster\Caster;
21+
useSymfony\Component\VarDumper\Caster\ClassStub;
22+
useSymfony\Component\VarDumper\Caster\StubCaster;
23+
useSymfony\Component\VarDumper\Cloner\Data;
24+
useSymfony\Component\VarDumper\Cloner\Stub;
25+
useSymfony\Component\VarDumper\Cloner\VarCloner;
1926

2027
/**
2128
* Data collector for {@link FormInterface} instances.
@@ -63,6 +70,16 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
6370
*/
6471
private$formsByView;
6572

73+
/**
74+
* @var ValueExporter
75+
*/
76+
private$valueExporter;
77+
78+
/**
79+
* @var ClonerInterface
80+
*/
81+
private$cloner;
82+
6683
publicfunction__construct(FormDataExtractorInterface$dataExtractor)
6784
{
6885
$this->dataExtractor =$dataExtractor;
@@ -221,6 +238,85 @@ public function getData()
221238
return$this->data;
222239
}
223240

241+
publicfunctionserialize()
242+
{
243+
$cloneVar =array($this,'cloneVar');
244+
245+
foreach ($this->data['forms_by_hash']as &$form) {
246+
if ($form['type_class']instanceof Data) {
247+
continue;
248+
}
249+
$form['view_vars'] =array_map($cloneVar,$form['view_vars']);
250+
$form['type_class'] =$cloneVar(newClassStub($form['type_class']));
251+
$form['synchronized'] =$cloneVar($form['synchronized']);
252+
$form['passed_options'] =array_map($cloneVar,$form['passed_options']);
253+
$form['resolved_options'] =array_map($cloneVar,$form['resolved_options']);
254+
$form['default_data'] =array_map($cloneVar,$form['default_data']);
255+
$form['submitted_data'] =array_map($cloneVar,$form['submitted_data']);
256+
257+
if (!empty($form['errors'])) {
258+
foreach ($form['errors']as$i =>$error) {
259+
if (!empty($error['trace'])) {
260+
$form['errors'][$i]['trace'] =array_map($cloneVar,$error['trace']);
261+
}
262+
}
263+
}
264+
}
265+
266+
returnserialize($this->data);
267+
}
268+
269+
/**
270+
* {@inheritdoc}
271+
*/
272+
protectedfunctioncloneVar($var)
273+
{
274+
if (null ===$this->cloner) {
275+
if (class_exists(ClassStub::class)) {
276+
$this->cloner =newVarCloner();
277+
$this->cloner->setMaxItems(50);
278+
$this->cloner->addCasters(array(
279+
Stub::class =>function (Stub$v,array$a,Stub$s,$isNested) {
280+
return$isNested ?$a : StubCaster::castStub($v,$a,$s,true);
281+
},
282+
\Exception::class =>function (\Exception$e,array$a,Stub$s) {
283+
if (isset($a[$k ="\0Exception\0previous"])) {
284+
unset($a[$k]);
285+
++$s->cut;
286+
}
287+
288+
return$a;
289+
},
290+
FormInterface::class =>function (FormInterface$f,array$a) {
291+
returnarray(
292+
Caster::PREFIX_VIRTUAL.'name' =>$f->getName(),
293+
Caster::PREFIX_VIRTUAL.'type_class' =>newClassStub(get_class($f->getConfig()->getType()->getInnerType())),
294+
);
295+
},
296+
ConstraintViolationInterface::class =>function (ConstraintViolationInterface$v,array$a) {
297+
returnarray(
298+
Caster::PREFIX_VIRTUAL.'root' =>$v->getRoot(),
299+
Caster::PREFIX_VIRTUAL.'path' =>$v->getPropertyPath(),
300+
Caster::PREFIX_VIRTUAL.'value' =>$v->getInvalidValue(),
301+
);
302+
},
303+
));
304+
}else {
305+
@trigger_error(sprintf('Using the %s() method without the VarDumper component is deprecated since version 3.2 and won\'t be supported in 4.0. Install symfony/var-dumper version 3.2 or above.',__METHOD__),E_USER_DEPRECATED);
306+
$this->cloner =false;
307+
}
308+
}
309+
if (false ===$this->cloner) {
310+
if (null ===$this->valueExporter) {
311+
$this->valueExporter =newValueExporter();
312+
}
313+
314+
return$this->valueExporter->exportValue($var);
315+
}
316+
317+
return$this->cloner->cloneVar($var);
318+
}
319+
224320
privatefunctionrecursiveBuildPreliminaryFormTree(FormInterface$form, &$output,array &$outputByHash)
225321
{
226322
$hash =spl_object_hash($form);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp