66use Symfony \Component \Config \Loader \DelegatingLoader ;
77use Symfony \Component \Config \Loader \LoaderResolver ;
88use Symfony \Component \Config \Resource \SelfCheckingResourceChecker ;
9+ use Symfony \Component \Config \ResourceCheckerConfigCache ;
910use Symfony \Component \Config \ResourceCheckerConfigCacheFactory ;
11+ use Symfony \Component \Filesystem \Filesystem ;
1012use Symfony \Component \HttpFoundation \Request ;
1113use Symfony \Component \Routing \Loader \PhpFileLoader ;
1214use Symfony \Component \Routing \Loader \XmlFileLoader ;
@@ -30,6 +32,26 @@ class RoutesLoader
3032 */
3133 private $ router ;
3234
35+ /**
36+ * @var ResourceCheckerConfigCacheFactory $cacheFactory
37+ */
38+ private $ cacheFactory ;
39+
40+ /**
41+ * @var SelfCheckingResourceChecker $checker
42+ */
43+ private $ checker ;
44+
45+ /**
46+ * @var ResourceCheckerConfigCache $cacheFreshChecker
47+ */
48+ private $ cacheFreshChecker ;
49+
50+ /**
51+ * @var string|null $cacheDir Путь к кэшу. Null -> не кэшировать.
52+ */
53+ private $ cacheDir ;
54+
3355 /**
3456 * AgnosticRouteLoader constructor.
3557 *
@@ -42,6 +64,8 @@ public function __construct(
4264 ?string $ cacheDir = null ,
4365 bool $ debug = true
4466 ) {
67+ $ this ->cacheDir = $ cacheDir ;
68+
4569 $ resolver = new LoaderResolver (
4670 [
4771 new YamlFileLoader (new FileLocator ()),
@@ -55,8 +79,8 @@ public function __construct(
5579 $ requestContext = new RequestContext ();
5680 $ request = Request::createFromGlobals ();
5781
58- $ checker = new SelfCheckingResourceChecker ();
59- $ cacheFactory = new ResourceCheckerConfigCacheFactory ([$ checker ]);
82+ $ this -> checker = new SelfCheckingResourceChecker ();
83+ $ this -> cacheFactory = new ResourceCheckerConfigCacheFactory ([$ this -> checker ]);
6084
6185 $ this ->router = new Router (
6286 $ delegatingLoader ,
@@ -73,7 +97,12 @@ public function __construct(
7397 );
7498
7599 if ($ cacheDir ) {
76- $ this ->router ->setConfigCacheFactory ($ cacheFactory );
100+ $ this ->cacheFreshChecker = new ResourceCheckerConfigCache (
101+ $ this ->cacheDir . '/url_generating_routes.php ' ,
102+ [$ this ->checker ]
103+ );
104+
105+ $ this ->warmUpCache ();
77106 }
78107 }
79108
@@ -84,6 +113,61 @@ public function __construct(
84113 */
85114 public function getRoutes () : RouteCollection
86115 {
116+ if ($ this ->cacheDir ) {
117+ $ compiledRoutesFile = $ this ->cacheDir . '/route_collection.json ' ;
118+
119+ if ($ this ->cacheFreshChecker !== null
120+ &&
121+ $ this ->cacheFreshChecker ->isFresh ()
122+ &&
123+ @file_exists ($ compiledRoutesFile )) {
124+ $ collection = file_get_contents ($ compiledRoutesFile );
125+ if ($ collection ) {
126+ $ collection = unserialize ($ collection );
127+ return $ collection ;
128+ }
129+ }
130+ }
131+
87132 return $ this ->router ->getRouteCollection ();
88133 }
89- }
134+
135+ /**
136+ * Удалить кэш.
137+ *
138+ * @return void
139+ */
140+ public function purgeCache () : void
141+ {
142+ $ filesystem = new Filesystem ();
143+
144+ if (!$ filesystem ->exists ($ this ->cacheDir )) {
145+ return ;
146+ }
147+
148+ $ filesystem ->remove ($ this ->cacheDir );
149+ }
150+
151+ /**
152+ * Создать (если надо), кэш.
153+ *
154+ * @return void
155+ */
156+ private function warmUpCache () : void
157+ {
158+ $ this ->router ->setConfigCacheFactory ($ this ->cacheFactory );
159+
160+ if (!$ this ->cacheFreshChecker ->isFresh ()) {
161+ if (!@file_exists ($ this ->cacheDir )) {
162+ @mkdir ($ this ->cacheDir , 0777 );
163+ }
164+
165+ file_put_contents (
166+ $ this ->cacheDir . '/route_collection.json ' ,
167+ serialize ($ this ->router ->getRouteCollection ())
168+ );
169+ }
170+
171+ $ this ->router ->getGenerator (); // Трюк по созданию кэша.
172+ }
173+ }
0 commit comments