PageRenderTime 71ms CodeModel.GetById 41ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/symfony/2.0.0pr2/src/vendor/symfony/src/Symfony/Foundation/Kernel.php

https://github.com/ad2joe/php-framework-benchmarks
PHP | 448 lines | 291 code | 74 blank | 83 comment | 27 complexity | 8f9cc511b554b9c3aa5345c52362a6d9 MD5 | raw file
  1. <?php
  2. namespace Symfony\Foundation;
  3. use Symfony\Components\DependencyInjection\ContainerInterface;
  4. use Symfony\Components\DependencyInjection\Builder;
  5. use Symfony\Components\DependencyInjection\BuilderConfiguration;
  6. use Symfony\Components\DependencyInjection\Dumper\PhpDumper;
  7. use Symfony\Components\DependencyInjection\FileResource;
  8. use Symfony\Components\HttpKernel\Request;
  9. use Symfony\Components\HttpKernel\HttpKernelInterface;
  10. /*
  11. * This file is part of the Symfony package.
  12. *
  13. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  14. *
  15. * For the full copyright and license information, please view the LICENSE
  16. * file that was distributed with this source code.
  17. */
  18. /**
  19. * The Kernel is the heart of the Symfony system. It manages an environment
  20. * that can host bundles.
  21. *
  22. * @package Symfony
  23. * @subpackage Foundation
  24. * @author Fabien Potencier <fabien.potencier@symfony-project.org>
  25. */
  26. abstract class Kernel implements HttpKernelInterface, \Serializable
  27. {
  28. protected $bundles;
  29. protected $bundleDirs;
  30. protected $container;
  31. protected $rootDir;
  32. protected $environment;
  33. protected $debug;
  34. protected $booted;
  35. protected $name;
  36. protected $startTime;
  37. protected $request;
  38. const VERSION = '2.0.0-DEV';
  39. /**
  40. * Constructor.
  41. *
  42. * @param string $environment The environment
  43. * @param Boolean $debug Whether to enable debugging or not
  44. */
  45. public function __construct($environment, $debug)
  46. {
  47. $this->environment = $environment;
  48. $this->debug = (Boolean) $debug;
  49. $this->booted = false;
  50. $this->rootDir = realpath($this->registerRootDir());
  51. $this->name = basename($this->rootDir);
  52. if ($this->debug) {
  53. ini_set('display_errors', 1);
  54. error_reporting(-1);
  55. $this->startTime = microtime(true);
  56. } else {
  57. ini_set('display_errors', 0);
  58. }
  59. }
  60. public function __clone()
  61. {
  62. if ($this->debug) {
  63. $this->startTime = microtime(true);
  64. }
  65. $this->booted = false;
  66. $this->container = null;
  67. $this->request = null;
  68. }
  69. abstract public function registerRootDir();
  70. abstract public function registerBundles();
  71. abstract public function registerBundleDirs();
  72. abstract public function registerContainerConfiguration();
  73. abstract public function registerRoutes();
  74. /**
  75. * Checks whether the current kernel has been booted or not.
  76. *
  77. * @return boolean $booted
  78. */
  79. public function isBooted()
  80. {
  81. return $this->booted;
  82. }
  83. /**
  84. * Boots the current kernel.
  85. *
  86. * This method boots the bundles, which MUST set
  87. * the DI container.
  88. *
  89. * @return Kernel The current Kernel instance
  90. *
  91. * @throws \LogicException When the Kernel is already booted
  92. */
  93. public function boot()
  94. {
  95. if (true === $this->booted) {
  96. throw new \LogicException('The kernel is already booted.');
  97. }
  98. require_once __DIR__.'/bootstrap.php';
  99. $this->bundles = $this->registerBundles();
  100. $this->bundleDirs = $this->registerBundleDirs();
  101. // initialize the container
  102. $this->container = $this->initializeContainer();
  103. $this->container->setService('kernel', $this);
  104. // boot bundles
  105. foreach ($this->bundles as $bundle) {
  106. $bundle->boot($this->container);
  107. }
  108. $this->booted = true;
  109. return $this;
  110. }
  111. /**
  112. * Shutdowns the kernel.
  113. *
  114. * This method is mainly useful when doing functional testing.
  115. */
  116. public function shutdown()
  117. {
  118. $this->booted = false;
  119. foreach ($this->bundles as $bundle) {
  120. $bundle->shutdown($this->container);
  121. }
  122. $this->container = null;
  123. }
  124. /**
  125. * Reboots the kernel.
  126. *
  127. * This method is mainly useful when doing functional testing.
  128. *
  129. * It is a shortcut for the call to shutdown() and boot().
  130. */
  131. public function reboot()
  132. {
  133. $this->shutdown();
  134. $this->boot();
  135. }
  136. /**
  137. * Gets the Request instance associated with the master request.
  138. *
  139. * @return Request A Request instance
  140. */
  141. public function getRequest()
  142. {
  143. return $this->request;
  144. }
  145. /**
  146. * Handles a request to convert it to a response by calling the HttpKernel service.
  147. *
  148. * @param Request $request A Request instance
  149. * @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
  150. * @param Boolean $raw Whether to catch exceptions or not
  151. *
  152. * @return Response $response A Response instance
  153. */
  154. public function handle(Request $request = null, $type = HttpKernelInterface::MASTER_REQUEST, $raw = false)
  155. {
  156. if (false === $this->booted) {
  157. $this->boot();
  158. }
  159. if (null === $request) {
  160. $request = $this->container->getRequestService();
  161. }
  162. if (HttpKernelInterface::MASTER_REQUEST === $type) {
  163. $this->request = $request;
  164. }
  165. $this->container->setService('request', $request);
  166. $response = $this->container->getHttpKernelService()->handle($request, $type, $raw);
  167. $this->container->setService('request', $this->request);
  168. return $response;
  169. }
  170. /**
  171. * Gets the directories where bundles can be stored.
  172. *
  173. * @return array An array of directories where bundles can be stored
  174. */
  175. public function getBundleDirs()
  176. {
  177. return $this->bundleDirs;
  178. }
  179. /**
  180. * Gets the registered bundle names.
  181. *
  182. * @return array An array of registered bundle names
  183. */
  184. public function getBundles()
  185. {
  186. return $this->bundles;
  187. }
  188. public function getName()
  189. {
  190. return $this->name;
  191. }
  192. public function getSafeName()
  193. {
  194. return preg_replace('/[^a-zA-Z0-9_]+/', '', $this->name);
  195. }
  196. public function getEnvironment()
  197. {
  198. return $this->environment;
  199. }
  200. public function isDebug()
  201. {
  202. return $this->debug;
  203. }
  204. public function getRootDir()
  205. {
  206. return $this->rootDir;
  207. }
  208. public function getContainer()
  209. {
  210. return $this->container;
  211. }
  212. public function getStartTime()
  213. {
  214. return $this->debug ? $this->startTime : -INF;
  215. }
  216. public function getCacheDir()
  217. {
  218. return $this->rootDir.'/cache/'.$this->environment;
  219. }
  220. public function getLogDir()
  221. {
  222. return $this->rootDir.'/logs';
  223. }
  224. protected function initializeContainer()
  225. {
  226. $class = $this->getSafeName().ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';
  227. $location = $this->getCacheDir().'/'.$class;
  228. $reload = $this->debug ? $this->needsReload($class, $location) : false;
  229. if ($reload || !file_exists($location.'.php')) {
  230. $this->buildContainer($class, $location.'.php');
  231. }
  232. require_once $location.'.php';
  233. return new $class();
  234. }
  235. public function getKernelParameters()
  236. {
  237. $bundles = array();
  238. foreach ($this->bundles as $bundle) {
  239. $bundles[] = get_class($bundle);
  240. }
  241. return array_merge(
  242. array(
  243. 'kernel.root_dir' => $this->rootDir,
  244. 'kernel.environment' => $this->environment,
  245. 'kernel.debug' => $this->debug,
  246. 'kernel.name' => $this->name,
  247. 'kernel.cache_dir' => $this->getCacheDir(),
  248. 'kernel.logs_dir' => $this->getLogDir(),
  249. 'kernel.bundle_dirs' => $this->bundleDirs,
  250. 'kernel.bundles' => $bundles,
  251. 'kernel.charset' => 'UTF-8',
  252. ),
  253. $this->getEnvParameters()
  254. );
  255. }
  256. protected function getEnvParameters()
  257. {
  258. $parameters = array();
  259. foreach ($_SERVER as $key => $value) {
  260. if ('SYMFONY__' === substr($key, 0, 9)) {
  261. $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value;
  262. }
  263. }
  264. return $parameters;
  265. }
  266. protected function needsReload($class, $location)
  267. {
  268. if (!file_exists($location.'.meta') || !file_exists($location.'.php')) {
  269. return true;
  270. }
  271. $meta = unserialize(file_get_contents($location.'.meta'));
  272. $time = filemtime($location.'.php');
  273. foreach ($meta as $resource) {
  274. if (!$resource->isUptodate($time)) {
  275. return true;
  276. }
  277. }
  278. return false;
  279. }
  280. protected function buildContainer($class, $file)
  281. {
  282. $container = new Builder($this->getKernelParameters());
  283. $configuration = new BuilderConfiguration();
  284. foreach ($this->bundles as $bundle) {
  285. $configuration->merge($bundle->buildContainer($container));
  286. }
  287. $configuration->merge($this->registerContainerConfiguration());
  288. $container->merge($configuration);
  289. $this->optimizeContainer($container);
  290. foreach (array('cache', 'logs') as $name) {
  291. $dir = $container->getParameter(sprintf('kernel.%s_dir', $name));
  292. if (!is_dir($dir)) {
  293. if (false === @mkdir($dir, 0777, true)) {
  294. die(sprintf('Unable to create the %s directory (%s)', $name, dirname($dir)));
  295. }
  296. } elseif (!is_writable($dir)) {
  297. die(sprintf('Unable to write in the %s directory (%s)', $name, $dir));
  298. }
  299. }
  300. // cache the container
  301. $dumper = new PhpDumper($container);
  302. $content = $dumper->dump(array('class' => $class));
  303. if (!$this->debug) {
  304. $content = self::stripComments($content);
  305. }
  306. $this->writeCacheFile($file, $content);
  307. if ($this->debug) {
  308. // add the Kernel class hierarchy as resources
  309. $parent = new \ReflectionObject($this);
  310. $configuration->addResource(new FileResource($parent->getFileName()));
  311. while ($parent = $parent->getParentClass()) {
  312. $configuration->addResource(new FileResource($parent->getFileName()));
  313. }
  314. // save the resources
  315. $this->writeCacheFile($this->getCacheDir().'/'.$class.'.meta', serialize($configuration->getResources()));
  316. }
  317. }
  318. public function optimizeContainer(Builder $container)
  319. {
  320. // replace all classes with the real value
  321. foreach ($container->getDefinitions() as $definition) {
  322. if (false !== strpos($class = $definition->getClass(), '%')) {
  323. $definition->setClass(Builder::resolveValue($class, $container->getParameters()));
  324. }
  325. }
  326. }
  327. static public function stripComments($source)
  328. {
  329. if (!function_exists('token_get_all')) {
  330. return $source;
  331. }
  332. $ignore = array(T_COMMENT => true, T_DOC_COMMENT => true);
  333. $output = '';
  334. foreach (token_get_all($source) as $token) {
  335. // array
  336. if (isset($token[1])) {
  337. // no action on comments
  338. if (!isset($ignore[$token[0]])) {
  339. // anything else -> output "as is"
  340. $output .= $token[1];
  341. }
  342. } else {
  343. // simple 1-character token
  344. $output .= $token;
  345. }
  346. }
  347. return $output;
  348. }
  349. protected function writeCacheFile($file, $content)
  350. {
  351. $tmpFile = tempnam(dirname($file), basename($file));
  352. if (!$fp = @fopen($tmpFile, 'wb')) {
  353. die(sprintf('Failed to write cache file "%s".', $tmpFile));
  354. }
  355. @fwrite($fp, $content);
  356. @fclose($fp);
  357. if ($content != file_get_contents($tmpFile)) {
  358. die(sprintf('Failed to write cache file "%s" (cache corrupted).', $tmpFile));
  359. }
  360. if (!@rename($tmpFile, $file)) {
  361. throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
  362. }
  363. chmod($file, 0644);
  364. }
  365. public function serialize()
  366. {
  367. return serialize(array($this->environment, $this->debug));
  368. }
  369. public function unserialize($data)
  370. {
  371. list($environment, $debug) = unserialize($data);
  372. $this->__construct($environment, $debug);
  373. }
  374. }