6

I have a relatively simple script like the following:

<?php
$url = "localhost:2222/test.html";

echo "*** URL ***\n";
echo $url . "\n";
echo "***********\n";
echo "** whoami *\n";
echo exec('whoami');
echo "* Output **\n";

$ch = curl_init(); 

curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

$output = curl_exec($ch); 

curl_close($ch);

echo $output;

When I execute it on the command line, it works - I get the meager results from within test.html.

When I run this script by loading up the built-in PHP server and browsing to the script, it hangs. No output to the screen, nothing written to the logs.

I read that sometimes user permissions can get in the way, so I tried doing whoami to ensure that the user that ran the built-in PHP server is the same as the one who executed the script on the command line; which they are.

safe_mode is off, disable_functions is set to nothing. I can exec other commands successfully (like the whoami).

What else should I check for? Does the built-in PHP server count as someone other user when it fulfills a request perhaps?

Deltran
  • 115
  • 2
  • 9
  • It might be an issue with specifying the port in the URL. I have run in to that problem before. I fixed it by just removing the port form the url, not sure if that will work for you. – Dan Mar 20 '15 at 19:05
  • 2
    Is `localhost:2222` the same server that's running this script? I'm not very familiar with the built-in PHP dev server, but you may simply be running into a deadlock situation if that server is single-threaded. – deceze Mar 20 '15 at 19:11
  • @dan08 I can't get it to find the resource without the port number in the curl url. Launching the server without a port number doesn't seem possible. – Deltran Mar 20 '15 at 19:26
  • You need to specify the port with `curl_setopt ($ch, CURLOPT_PORT , 2222);` and not in the url – DarkBee Mar 20 '15 at 19:27
  • @deceze Apparently the built-in PHP dev server is single threaded - launched a second one running on port 3333 and it was able to curl the file! Thank you! – Deltran Mar 20 '15 at 19:27
  • @DarkBee the curlopt_port is a good catch, but even changing that isn't letting the request complete. – Deltran Mar 20 '15 at 19:32

3 Answers3

28

The PHP built-in development web server is a very simple single threaded test server. It cannot handle two requests at once. You're trying to retrieve a file from itself in a separate request, so you're running into a deadlock. The first request is waiting for the second to complete, but the second request cannot be handled while the first is still running.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 1
    Well played. I had the same issue myself, and was going nuts. – Manngo Jan 14 '17 at 11:08
  • 7
    I would like to add a bonus to this answer. If you wan't to keep going with the PHP's built-in server, you can create a new one on a different port `php -S 127.0.0.1:2223` and make the curl request to the new one's url. – muratgozel May 18 '18 at 15:03
  • Ran into this problem and ended up with a solution somewhat similar to @muratgozel. I'd have gotten back two days of my life if I'd found this post right off the bat. It's maddening when something like this fails silently without logging or throwing an error. – WiiBopp Apr 29 '20 at 17:31
1

Since PHP 7.4 the environment variable PHP_CLI_SERVER_WORKERS allows concurrent requests by spawning multiple PHP workers on the same port on the built-in web server. It is considered experimental, see the docs.

Using it, the PHP script can send requests to itself which is already being served, without halting.

PHP_CLI_SERVER_WORKERS=10 php -S ...

Works with Laravel as well:

PHP_CLI_SERVER_WORKERS=10 php artisan serve
Hossein
  • 4,097
  • 2
  • 24
  • 46
-7

I think problem in your $url. It may be look like this $url = "http://localhost:2222/test.html"; or $url = "http://localhost/test.html"; I think it's solve your problem. Thanks for your question. Best of luck.

Rz Rasel
  • 86
  • 6