PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php

https://gitlab.com/mohamedchiheb.bida/workshopFOS
PHP | 220 lines | 156 code | 27 blank | 37 comment | 11 complexity | 7cecece3baa391d5570c0a0c63f61913 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\FrameworkBundle\Command;
  11. use Symfony\Component\Console\Input\InputArgument;
  12. use Symfony\Component\Console\Input\InputInterface;
  13. use Symfony\Component\Console\Input\InputOption;
  14. use Symfony\Component\Console\Output\OutputInterface;
  15. use Symfony\Component\Process\PhpExecutableFinder;
  16. use Symfony\Component\Process\Process;
  17. /**
  18. * Runs PHP's built-in web server in a background process.
  19. *
  20. * @author Christian Flothmann <christian.flothmann@xabbuh.de>
  21. */
  22. class ServerStartCommand extends ServerCommand
  23. {
  24. /**
  25. * {@inheritdoc}
  26. */
  27. protected function configure()
  28. {
  29. $this
  30. ->setDefinition(array(
  31. new InputArgument('address', InputArgument::OPTIONAL, 'Address:port', '127.0.0.1:8000'),
  32. new InputOption('docroot', 'd', InputOption::VALUE_REQUIRED, 'Document root', null),
  33. new InputOption('router', 'r', InputOption::VALUE_REQUIRED, 'Path to custom router script'),
  34. ))
  35. ->setName('server:start')
  36. ->setDescription('Starts PHP built-in web server in the background')
  37. ->setHelp(<<<EOF
  38. The <info>%command.name%</info> runs PHP's built-in web server:
  39. <info>php %command.full_name%</info>
  40. To change the default bind address and the default port use the <info>address</info> argument:
  41. <info>php %command.full_name% 127.0.0.1:8080</info>
  42. To change the default document root directory use the <info>--docroot</info> option:
  43. <info>php %command.full_name% --docroot=htdocs/</info>
  44. If you have a custom document root directory layout, you can specify your own
  45. router script using the <info>--router</info> option:
  46. <info>php %command.full_name% --router=app/config/router.php</info>
  47. Specifying a router script is required when the used environment is not <comment>"dev"</comment> or
  48. <comment>"prod"</comment>.
  49. See also: http://www.php.net/manual/en/features.commandline.webserver.php
  50. EOF
  51. )
  52. ;
  53. }
  54. /**
  55. * {@inheritdoc}
  56. */
  57. protected function execute(InputInterface $input, OutputInterface $output)
  58. {
  59. if (!extension_loaded('pcntl')) {
  60. $output->writeln('<error>This command needs the pcntl extension to run.</error>');
  61. $output->writeln('You can either install it or use the <info>server:run</info> command instead to run the built-in web server.');
  62. return 1;
  63. }
  64. $documentRoot = $input->getOption('docroot');
  65. if (null === $documentRoot) {
  66. $documentRoot = $this->getContainer()->getParameter('kernel.root_dir').'/../web';
  67. }
  68. if (!is_dir($documentRoot)) {
  69. $output->writeln(sprintf('<error>The given document root directory "%s" does not exist</error>', $documentRoot));
  70. return 1;
  71. }
  72. $env = $this->getContainer()->getParameter('kernel.environment');
  73. if (false === $router = $this->determineRouterScript($input->getOption('router'), $env, $output)) {
  74. return 1;
  75. }
  76. $address = $input->getArgument('address');
  77. if (false === strpos($address, ':')) {
  78. $output->writeln('The address has to be of the form <comment>bind-address:port</comment>.');
  79. return 1;
  80. }
  81. if ($this->isOtherServerProcessRunning($address)) {
  82. $output->writeln(sprintf('<error>A process is already listening on http://%s.</error>', $address));
  83. return 1;
  84. }
  85. if ('prod' === $env) {
  86. $output->writeln('<error>Running PHP built-in server in production environment is NOT recommended!</error>');
  87. }
  88. $pid = pcntl_fork();
  89. if ($pid < 0) {
  90. $output->writeln('<error>Unable to start the server process</error>');
  91. return 1;
  92. }
  93. if ($pid > 0) {
  94. $output->writeln(sprintf('<info>Web server listening on http://%s</info>', $address));
  95. return;
  96. }
  97. if (posix_setsid() < 0) {
  98. $output->writeln('<error>Unable to set the child process as session leader</error>');
  99. return 1;
  100. }
  101. if (null === $process = $this->createServerProcess($output, $address, $documentRoot, $router)) {
  102. return 1;
  103. }
  104. $process->disableOutput();
  105. $process->start();
  106. $lockFile = $this->getLockFile($address);
  107. touch($lockFile);
  108. if (!$process->isRunning()) {
  109. $output->writeln('<error>Unable to start the server process</error>');
  110. unlink($lockFile);
  111. return 1;
  112. }
  113. // stop the web server when the lock file is removed
  114. while ($process->isRunning()) {
  115. if (!file_exists($lockFile)) {
  116. $process->stop();
  117. }
  118. sleep(1);
  119. }
  120. }
  121. /**
  122. * Determine the absolute file path for the router script, using the environment to choose a standard script
  123. * if no custom router script is specified.
  124. *
  125. * @param string|null $router File path of the custom router script, if set by the user; otherwise null
  126. * @param string $env The application environment
  127. * @param OutputInterface $output An OutputInterface instance
  128. *
  129. * @return string|bool The absolute file path of the router script, or false on failure
  130. */
  131. private function determineRouterScript($router, $env, OutputInterface $output)
  132. {
  133. if (null === $router) {
  134. $router = $this
  135. ->getContainer()
  136. ->get('kernel')
  137. ->locateResource(sprintf('@FrameworkBundle/Resources/config/router_%s.php', $env))
  138. ;
  139. }
  140. if (false === $path = realpath($router)) {
  141. $output->writeln(sprintf('<error>The given router script "%s" does not exist</error>', $router));
  142. return false;
  143. }
  144. return $path;
  145. }
  146. /**
  147. * Creates a process to start PHP's built-in web server.
  148. *
  149. * @param OutputInterface $output A OutputInterface instance
  150. * @param string $address IP address and port to listen to
  151. * @param string $documentRoot The application's document root
  152. * @param string $router The router filename
  153. *
  154. * @return Process The process
  155. */
  156. private function createServerProcess(OutputInterface $output, $address, $documentRoot, $router)
  157. {
  158. $finder = new PhpExecutableFinder();
  159. if (false === $binary = $finder->find()) {
  160. $output->writeln('<error>Unable to find PHP binary to start server</error>');
  161. return;
  162. }
  163. $script = implode(' ', array_map(array('Symfony\Component\Process\ProcessUtils', 'escapeArgument'), array(
  164. $binary,
  165. '-S',
  166. $address,
  167. $router,
  168. )));
  169. return new Process('exec '.$script, $documentRoot, null, null, null);
  170. }
  171. }