From d349d3fee02191e59a0a7ba04a94a2e522be0cf8 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 29 Oct 2014 03:58:21 +0100 Subject: [PATCH] added ContainerLoader: humble replacement for ContainerFactory --- src/DI/ContainerFactory.php | 3 +- src/DI/ContainerLoader.php | 104 ++++++++++++++++++++++++++++ tests/DI/ContainerLoader.basic.phpt | 23 ++++++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/DI/ContainerLoader.php create mode 100644 tests/DI/ContainerLoader.basic.phpt diff --git a/src/DI/ContainerFactory.php b/src/DI/ContainerFactory.php index 3ade498ff..5fc12bde9 100644 --- a/src/DI/ContainerFactory.php +++ b/src/DI/ContainerFactory.php @@ -14,6 +14,7 @@ * DI container generator. * * @author David Grudl + * @deprecated */ class ContainerFactory extends Nette\Object { @@ -122,7 +123,7 @@ private function loadClass() flock($handle, LOCK_SH); foreach ((array) @unserialize(file_get_contents("$file.meta")) as $f => $time) { // @ - file may not exist if (@filemtime($f) !== $time) { // @ - stat may fail - unlink($file); + @unlink($file); // @ - file may not exist break; } } diff --git a/src/DI/ContainerLoader.php b/src/DI/ContainerLoader.php new file mode 100644 index 000000000..4226ab304 --- /dev/null +++ b/src/DI/ContainerLoader.php @@ -0,0 +1,104 @@ +tempDirectory = $tempDirectory; + $this->autoRebuild = $autoRebuild; + } + + + /** + * @param mixed + * @param callable function(string $class): [code, files] + * @return string + */ + public function load($key, $generator) + { + $class = $this->getClassName($key); + if (!class_exists($class)) { + $this->loadFile($class, $generator); + } + return $class; + } + + + /** + * @return string + */ + public function getClassName($key) + { + return 'Container_' . substr(md5(serialize($key)), 0, 10); + } + + + /** + * @return void + */ + private function loadFile($class, $generator) + { + $file = "$this->tempDirectory/$class.php"; + if (!$this->autoRebuild && (@include $file) !== FALSE) { // @ - file may not exist + return; + } + + if (!is_dir($this->tempDirectory)) { + @mkdir($this->tempDirectory); // @ - directory may already exist + } + $handle = fopen("$file.tmp", 'c+'); + if (!$handle) { + throw new Nette\IOException("Unable to open or create file '$file.tmp'."); + } + + if ($this->autoRebuild) { + flock($handle, LOCK_SH); + foreach ((array) @unserialize(file_get_contents("$file.meta")) as $f => $time) { // @ - file may not exist + if (@filemtime($f) !== $time) { // @ - stat may fail + unlink($file); + break; + } + } + } + + if (!is_file($file)) { + flock($handle, LOCK_EX); + if (!is_file($file)) { + list($code, $dependencies) = call_user_func($generator, $class); + if (!file_put_contents($file, "getClassName($key); +Assert::match('Container%[\w]+%', $className); + +$container = $cache->load($key, function($class) { + return array("class $class {}", array()); +}); +Assert::type($className, new $container);