slimphp / Slim

Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.
http://slimframework.com
MIT License
11.94k stars 1.95k forks source link

it keeps content type text/html #1535

Closed Serhioromano closed 8 years ago

Serhioromano commented 8 years ago

I do not know why. I do like this.

$content_type = 'application/json;charset=utf-8';
$response->withStatus(200)
    ->withHeader('Content-type', $content_type)
    ->write($data);

But in all my HTTP clients and tester I see that I have

Request

POST http://api.***.com/app/modules/lang
Content-Type: application/json
{"tag":"en-GB","module":"acl"}

Response

200 OK
Date:  Sat, 10 Oct 2015 21:50:14 GMT
Server:  Apache/2.4.16 (Unix) PHP/5.5.18
x-powered-by:  PHP/5.5.18
Access-Control-Allow-Origin:  *
Access-Control-Allow-Credentials:  true
Access-Control-Max-Age:  86400
Access-Control-Allow-Methods:  GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers:  Content-Type, Authorization
Content-Length:  64
Keep-Alive:  timeout=5, max=100
Connection:  Keep-Alive
Content-Type:  text/html

It always gives Content-Type: text/html no matter what I do. I even tried PHP header() function. What could be the reason?

Everything works, it is just my clients do not automatically process body as JSON and no auto format.

dopesong commented 8 years ago

Have you tried: withJson method? What you get with it?

https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Response.php#L285

Serhioromano commented 8 years ago

Still the same.

akrabat commented 8 years ago

where is this code?

silentworks commented 8 years ago

@Serhioromano are you sure you are returning the correct response object, remember PSR7 response object is immutable. Try the following below:

$app->get('/', function ($request, $response) {
    $data = [
        ['name' => 'Tester'],
        ['name' => 'Tester 1'],
    ];
    return $response->withJson($data);
});
Serhioromano commented 8 years ago

Very simple. This is my whole file as it is now.

<?php
define('_API', 1);

$loader = require '../vendor/autoload.php';
$app    = new \Slim\App();

use App\Lib\Language;
use App\Lib\Util;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$app->map(['POST'], '/{module}/{group}/{action}[/{id}]',
    function (ServerRequestInterface $request, ResponseInterface $response, $params) use ($app)
    {
        /**
         * @var $module string
         * @var $group  string
         * @var $action string
         * @var $id     string
         */
        extract($params);

        try
        {
            $body = $request->getParsedBody();
            if($body === NULL)
            {
                throw new \Exception("Cannot get Params");
            }

            Language::init($module, $body);

            $data = Util::apiExecute($request, $response, $app, $params, TRUE, $body);

            $content_type = 'text/html;charset=utf-8';

            if(is_array($data) || is_object($data) || $data == '1')
            {
                $content_type = 'application/json;charset=utf-8';
                $data         = json_encode(array(
                    'error'  => FALSE,
                    'result' => $data
                ));
            }

            $response->withStatus(200)
                ->withHeader('Content-type', $content_type)
                ->write($data);
        }
        catch(Exception $e)
        {
            $data = json_encode(array(
                'error'   => TRUE,
                'code'    => $e->getCode(),
                'message' => 'Error: ' . $e->getMessage(),
                'module'  => $module,
                'group'   => $group,
                'file'    => $e->getFile(),
                'line'    => $e->getLine(),
                //'trace'   => $e->getTrace(),
                'action'  => $action
            ));

            $response->withStatus(200)
                ->withHeader('Content-type', 'application/json;charset=utf-8')
                ->write($data);
        }
    });

$app->run();

And I did try withJson instead of

$response->withStatus(200)
    ->withHeader('Content-type', $content_type)
    ->write($data);

By the way @silentworks if I try your example it does work fine. I do not understand what is the difference.

akrabat commented 8 years ago

You need to return the $response from your closure.

Serhioromano commented 8 years ago

Hey!! Yes it works now. Although strange that it doe snot work like this

$response->withStatus(200)
    ->withHeader('Content-type', $content_type)
    ->write($data);
return $response;

But it works like this

return $response->withStatus(200)
    ->withHeader('Content-type', $content_type)
    ->write($data);
akrabat commented 8 years ago

For the first example, you need to reassign to $response as its immutable:

$response = $response->withStatus(200) ->withHeader('Content-type', $content_type) ->write($data); return $response;

zmip commented 8 years ago

FWIW, the withJSON helper function that was added to Slim 3 can only return application/json which causes problems in certain versions of MSIE when it is a response after an upload (IE will just download the JSON as a file, go figure...). So being able to set the Content-Type as an option would be a nice addition.

EwertonDutra commented 6 years ago

I have this problem too. Does not work: "return $ response-> withJson ('Erro na remoção', 400);"

It only works like this: "return $ response              -> withStatus (400)              -> withHeader ("Content-Type", "application / json; charset = utf-8")              -> write ('Erro na remoção'); "

ujikstark commented 2 years ago

i solved this with this one $response->getBody()->write(json_encode($tickets)); return $response->withAddedHeader('Content-Type', 'application/json');