1

I try to execute file_get_contents() on my own route used for AJAX mostly:

file_get_contents($this->router->generate('ajax_get_provinces', array('country' => $country->getName()), true));

I get an error:

Warning: file_get_contents(http://symfony.trainingexperience.org/ajax/get-provinces/Spain): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request

Action:

/**
 * GET method
 *
 * @Route("/ajax/get-provinces/{country}", name="ajax_get_provinces")
 *
 * @param $country
 * @param Request $request
 *
 * @return JsonResponse
 */
public function getProvinces($country, Request $request)
{
    $translator = $this->get('translator');

    if (!$request->isXmlHttpRequest()) {
        return new JsonResponse(array('message' => $translator->trans('ajax.access.error')), 400);
    }

    ...

    return new JsonResponse($provinces, 200);
}

2 Answers2

1

This is your problem i would say:

if (!$request->isXmlHttpRequest()) {
    return new JsonResponse(array('message' => $translator->trans('ajax.access.error')), 400);
}

file_get_contents does not set the required headers for the request to be identified as XmlHttpRequest (X-Requested-With)

/**
 * Returns true if the request is a XMLHttpRequest.
 *
 * It works if your JavaScript library sets an X-Requested-With HTTP header.
 * It is known to work with common JavaScript frameworks:
 *
 * @see http://en.wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript
 *
 * @return bool true if the request is an XMLHttpRequest, false otherwise
 */
public function isXmlHttpRequest()
{
    return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
}

Try executing your request through curl with the correct headers or remove the XMLHttpRequest check in your action.

Here you can read how to make the request through curl: PHP: Simulate XHR using cURL

Edit: To set the required header with file_get_contents you could try this

$options = array(
    'http' => array(
        'header'  =>  "Accept:application/json\r\n" .
                      "X-Requested-With:XMLHttpRequest\r\n",
        'method'  => 'GET'
    ),
);

$context = stream_context_create($options);

file_get_contents($this->router->generate('ajax_get_provinces', array('country' => $country->getName()), true, $context));

This could work if no other headers are missing.

Community
  • 1
  • 1
Joe
  • 2,356
  • 10
  • 15
  • This exactly was the problem, thanks a bunch! You are a genius –  Apr 28 '17 at 12:33
  • Glad i could help. If you want to keep using file_get_contents though take a look at http://php.net/manual/en/function.stream-context-create.php with this you can set headers and pass the resource as third parameter to file_get_contents. – Joe Apr 28 '17 at 12:37
  • Do you think it is passible to modify context and header for file_get_contents() seem like xml request? –  Apr 28 '17 at 12:44
  • @IgnasDamunskis i edited a small sample how to create a stream_context for file_get_contents and how it could look like. Also how you have to include it in your file_get_contents call. I don't know if this will be enough but you could give it a try. – Joe Apr 28 '17 at 12:53
0

I found this at file_get_contents throws 400 Bad Request error PHP

I quote: You might want to try using curl to retrieve the data instead of file_get_contents. curl has better support for error handling:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 
$this->router->generate('ajax_get_provinces', array('country' => $country->getName()), true)); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$output = curl_exec($ch);   

// convert response
$output = json_decode($output);

// handle error; error output
if(curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 200) {

  var_dump($output);
}

curl_close($ch);

This may give you a better idea why you're receiving the error. A common error is hitting the rate limit on your server.

Community
  • 1
  • 1
sietse85
  • 1,488
  • 1
  • 10
  • 26