Подтвердить что ты не робот

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

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

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

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

Это проходит отлично. Далее в моем списке отправляется XML-данные с помощью POST. Поэтому для моего второго теста у меня есть:

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 не работал, я перешел с частью REST моего API, в которой используется JSON. Вот один из моих тестов:

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

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

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

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, добавляющая поля POST:

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!'. Большой! Но в моей базе данных теперь у меня пустая строка. Не хорошо. Он по-прежнему не видит содержание тела, а только заголовки.


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

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

  • Почему я не могу получить содержимое тела моего запроса?
  • Как получить содержимое тела моего запроса?
4b9b3361

Ответ 1

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

public function foo(Request $request){
    $bodyContent = $request->getContent();
}

Ответ 2

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

Из docs:

$this->call($method, $uri, $parameters, $files, $server, $content);

Ответ 3

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

Глядя на класс в редакции # 2, я бы сделал так:

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

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

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

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