Как мне получить содержимое тела HTTP-запроса в Laravel?


Я создаю API с помощью Laravel 5 и тестирую его с помощью PHPUnit. Мне нужно протестировать устаревшую функциональность на совместимость, которая представляет собой сообщение XML. На данный момент мой первый тест выглядит так:

public function testPostMessages()
{
    $response = $this->call('POST', 'xml');

    $this->assertEquals(200, $response->getStatusCode());
}

Это проходит просто замечательно. Следующим в моем списке является фактическая отправка XML-данных вместе с СООБЩЕНИЕМ. Итак, для моего второго теста у меня есть:

public function testPostMessagesContent()
{
    $response = $this->call('POST', 'xml');

    $this->assertTrue(is_valid_xml($response->getContent()));
}

Этот тест не проходит. Однако я не отправляю свои XML-данные. Как мне отправить свой XML-файл?
Теперь, после этого мне нужно добавить в функциональность для получения содержимого из запроса. Я знаю, что есть объект Request, с которым я могу взаимодействовать, но я точно не знаю, какой метод его вызывать. Как мне получить свой XML-файл из моего контроллера?


Обновление #1

Тем временем мне удалось получить некоторые результаты. Мой текущий тест выглядит так:

public function testPostMessagesContent()
{
    $response = $this->call('POST', 'xml', array('key' => 'value'), array(), array(), array('content' => 'content'));
    $this->assertContains('~', $response->getContent());
}

У меня там есть только тильда, потому что я знаю, что она не будет совпадать, чтобы я мог видеть весь ответ. В XmlController.php Я имейте:

class XmlController extends Controller {
public function index(Request $request)
{
    return $request;
    }
}

Мой вывод из PHPUnit выглядит следующим образом:

1) XmlTest::testPostMessagesContent
Failed asserting that 'POST xml HTTP/1.1
Accept:          text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Language: en-us,en;q=0.5
Content-Type:    application/x-www-form-urlencoded
Host:            localhost
User-Agent:      Symfony/2.X
' contains "~".

Где мои параметры и мой контент? Я чувствую, что просто неправильно использую call().


Обновление #2

Я обновил свой контроллер, чтобы использовать Request:all() вот так:

class XmlController extends Controller
{
    public function index()
   {
        $content = Request::all();
        return $content;
    }
}

Это вернуло мою пару ключ-значение, но не содержимое.

1) XmlTest::testPostMessagesContent
Failed asserting that '{"key":"value"}' contains "~".

Пары ключ-значение хороши; это прогресс. Однако то, что мне действительно нужно, - это контент, так как я буду получать эти данные в контенте часть запроса. Если я использую Request::getContent(), я получаю обратно пустую строку. Вот мой вызов в тесте:

$response = $this->call('POST', 'xml', array('key' => 'value'), array(), array(), array('content' => 'content'));

Вот мои результаты теста:

1) XmlTest::testPostMessagesContent
Failed asserting that '' contains "~".

Обновление #3

Я вообще не могу получить тело содержимого HTTP-запроса. Поскольку XML не работал, я перешел к остальной части своего API, которая использует JSON. Вот один из моих тестов:

public function testPostMessagesContent()
{
    $response = $this->call('POST', 'messages', ['content' => 'content']);

    $this->assertEquals('saved!', $response->getContent());
}

Этот тест пройден. Если я использую curl, я также получаю успешный вызов:

curl -X POST -d "content=my_new_content" "http://localhost:8000/messages"

Это возвращает 'saved!' Это потрясающе, но если я попытаюсь использовать curl в отдельном PHP-скрипте (для имитации клиента), вот что будет возвращено:

Array ( [url] => http://localhost:8000/messages [content_type] => text/html; charset=UTF-8 [http_code] => 302 [header_size] => 603 [request_size] => 118 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.063977 [namelookup_time] => 0.000738 [connect_time] => 0.000866 [pretransfer_time] => 0.000943 [size_upload] => 12 [size_download] => 328 [speed_download] => 5126 [speed_upload] => 187 [download_content_length] => -1 [upload_content_length] => 12 [starttransfer_time] => 0.057606 [redirect_time] => 0 [certinfo] => Array ( ) [primary_ip] => ::1 [primary_port] => 8000 [local_ip] => ::1 [local_port] => 63248 [redirect_url] => http://localhost:8000 [request_header] => POST /messages HTTP/1.1 Host: localhost:8000 Accept: */* Content-type: text/xml Content-length: 12 ) Redirecting to http://localhost:8000. 

Это моя команда curl, добавляющая поля СООБЩЕНИЙ:

curl_setopt($ch, CURLOPT_POSTFIELDS, 'content=test');

Мне кажется, что в текст запроса добавляются поля POSTFIELDS. В этом случае у меня все та же проблема. Я не могу получить содержимое тела моих HTTP-заголовков. После того, как я прокомментировал свою проверку, я получаю:

Array ( [url] => http://localhost:8000/messages [content_type] => text/html; charset=UTF-8 [http_code] => 200 [header_size] => 565 [request_size] => 118 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.070225 [namelookup_time] => 0.000867 [connect_time] => 0.00099 [pretransfer_time] => 0.001141 [size_upload] => 12 [size_download] => 6 [speed_download] => 85 [speed_upload] => 170 [download_content_length] => -1 [upload_content_length] => 12 [starttransfer_time] => 0.065204 [redirect_time] => 0 [certinfo] => Array ( ) [primary_ip] => ::1 [primary_port] => 8000 [local_ip] => ::1 [local_port] => 63257 [redirect_url] => [request_header] => POST /messages HTTP/1.1 Host: localhost:8000 Accept: */* Content-type: text/xml Content-length: 12 ) saved!

Итак, у меня есть мое 'saved!' сообщение. Отлично! Но, в моем база данных теперь у меня есть пустая строка. Не очень хорошо. Он все еще не видит содержимое тела, только заголовки.


Критерии ответа

Я ищу ответы на эти вопросы:

  1. Почему я не могу получить основное содержание моего запроса?
  2. Как мне получить основное содержание моего запроса?
Author: beznez, 2015-02-11

3 answers

Внутренний контроллер вводит объект запроса. Поэтому, если вы хотите получить доступ к телу запроса внутри метода контроллера "foo", выполните следующие действия:

public function foo(Request $request){
    $bodyContent = $request->getContent();
}
 58
Author: gandra404, 2015-07-28 07:14:02

Вы можете передать данные в качестве третьего аргумента call(). Или, в зависимости от вашего API, возможно, вы захотите использовать шестой параметр.

Из документов :

$this->call($method, $uri, $parameters, $files, $server, $content);
 3
Author: Jason McCreary, 2015-02-11 16:23:02

Я не думаю, что вам нужны данные из вашего запроса , я думаю, вам нужны данные из вашего Ответа . Эти два понятия различны. Также вы должны правильно построить свой ответ в своем контроллере.

Глядя на класс в правке № 2, я бы сделал так, чтобы он выглядел так:

class XmlController extends Controller
{
    public function index()
    {
        $content = Request::all();
        return Response::json($content);
    }
}

Как только вы дойдете до этого, вы должны проверить содержание своего ответа в своем тестовом примере (при необходимости используйте print_r), вы должны увидеть данные внутри.

Дополнительная информация о Ответы Ларавеля здесь:

Http://laravel.com/docs/5.0/responses

 0
Author: delatbabel, 2015-02-18 15:29:24