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 12namespace Symfony\Bundle\WebServerBundle; 13 14/** 15 * @author Fabien Potencier <fabien@symfony.com> 16 */ 17class WebServerConfig 18{ 19 private $hostname; 20 private $port; 21 private $documentRoot; 22 private $env; 23 private $router; 24 25 public function __construct($documentRoot, $env, $address = null, $router = null) 26 { 27 if (!is_dir($documentRoot)) { 28 throw new \InvalidArgumentException(sprintf('The document root directory "%s" does not exist.', $documentRoot)); 29 } 30 31 if (null === $file = $this->findFrontController($documentRoot, $env)) { 32 throw new \InvalidArgumentException(sprintf('Unable to find the front controller under "%s" (none of these files exist: "%s").', $documentRoot, implode('", "', $this->getFrontControllerFileNames($env)))); 33 } 34 35 $_ENV['APP_FRONT_CONTROLLER'] = $file; 36 37 $this->documentRoot = $documentRoot; 38 $this->env = $env; 39 40 if (null !== $router) { 41 $absoluteRouterPath = realpath($router); 42 43 if (false === $absoluteRouterPath) { 44 throw new \InvalidArgumentException(sprintf('Router script "%s" does not exist.', $router)); 45 } 46 47 $this->router = $absoluteRouterPath; 48 } else { 49 $this->router = __DIR__.'/Resources/router.php'; 50 } 51 52 if (null === $address) { 53 $this->hostname = '127.0.0.1'; 54 $this->port = $this->findBestPort(); 55 } elseif (false !== $pos = strrpos($address, ':')) { 56 $this->hostname = substr($address, 0, $pos); 57 if ('*' === $this->hostname) { 58 $this->hostname = '0.0.0.0'; 59 } 60 $this->port = substr($address, $pos + 1); 61 } elseif (ctype_digit($address)) { 62 $this->hostname = '127.0.0.1'; 63 $this->port = $address; 64 } else { 65 $this->hostname = $address; 66 $this->port = $this->findBestPort(); 67 } 68 69 if (!ctype_digit($this->port)) { 70 throw new \InvalidArgumentException(sprintf('Port "%s" is not valid.', $this->port)); 71 } 72 } 73 74 public function getDocumentRoot() 75 { 76 return $this->documentRoot; 77 } 78 79 public function getEnv() 80 { 81 return $this->env; 82 } 83 84 public function getRouter() 85 { 86 return $this->router; 87 } 88 89 public function getHostname() 90 { 91 return $this->hostname; 92 } 93 94 public function getPort() 95 { 96 return $this->port; 97 } 98 99 public function getAddress() 100 { 101 return $this->hostname.':'.$this->port; 102 } 103 104 /** 105 * @param string $documentRoot 106 * @param string $env 107 * 108 * @return string|null 109 */ 110 private function findFrontController($documentRoot, $env) 111 { 112 $fileNames = $this->getFrontControllerFileNames($env); 113 114 foreach ($fileNames as $fileName) { 115 if (file_exists($documentRoot.'/'.$fileName)) { 116 return $fileName; 117 } 118 } 119 120 return null; 121 } 122 123 /** 124 * @param string $env 125 * 126 * @return array 127 */ 128 private function getFrontControllerFileNames($env) 129 { 130 return ['app_'.$env.'.php', 'app.php', 'index_'.$env.'.php', 'index.php']; 131 } 132 133 /** 134 * @return int 135 */ 136 private function findBestPort() 137 { 138 $port = 8000; 139 while (false !== $fp = @fsockopen($this->hostname, $port, $errno, $errstr, 1)) { 140 fclose($fp); 141 if ($port++ >= 8100) { 142 throw new \RuntimeException('Unable to find a port available to run the web server.'); 143 } 144 } 145 146 return $port; 147 } 148} 149