Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DonSchoeman's avatar

Custom HTTP response codes and status text.

I am trying to return custom HTTP response codes and status text for my REST API. To do this I thought it might be best to extend Illuminate\Http\Response with my own Response and then add the additional response codes and status text I require, for example:

<?php

namespace App\Http;

use Illuminate\Http\Response as BaseResponse;

class Response extends BaseResponse
{
    const HTTP_TOKEN_REQUIRED = 499;

    public static $statusTexts = [
        499 => 'Token Required'
    ];

    /**
     * Constructor.
     *
     * @param mixed $content The response content, see setContent()
     * @param int   $status  The response status code
     * @param array $headers An array of response headers
     *
     * @throws \InvalidArgumentException When the HTTP status code is not valid
     */
    public function __construct($content = '', $status = 200, $headers = array())
    {
        $this::$statusTexts = parent::$statusTexts + $this::$statusTexts;

        parent::__construct($content, $status, $headers);
    }
}

and then to obviously replace the Facade config in app.php to use my own, e.g.:

'Response'   => App\Http\Response::class

However, how do I now get the response() helper function to make an instance of my class instead of the default and is this even the right way to approach the problem in the first place?

0 likes
4 replies
DonSchoeman's avatar

Since my post was made I noticed that I'm setting the Response facade to point directly to my Response class which is obviously not correct since my Response class isn't in fact a Facade, so I changed it back to the default Response Facade.

I am now trying to implement a replacement response() function in my own autoloader.php with which I intend to return an instance of my own Response class but I have yet to figure out how I am going to do that as I don't know how to get the ResponseFactory contract to "know" about my Response class. I'm obviously missing something still...

DonSchoeman's avatar
DonSchoeman
OP
Best Answer
Level 3

Ok, I finally did it and here is how the future reader (you) can do it too. Since nobody responded to my original request I'm assuming it might be the only way to do it for now:

  1. Edit bootstrap/autoload.php and add the following:
require __DIR__.'/../app/Http/helpers.php';  // Add this line
require __DIR__.'/../vendor/autoload.php';
  1. Create a new file called: app/Http/helpers.php and add the following code:
<?php

/**
 * We supply our own instance of the response in order to load
 * our own response class when the response() helper is called.
 *
 * @param  string $content
 * @param  int    $status
 * @param  array  $headers
 *
 * @return \App\Http\JsonResponse
 */
function response($content = '', $status = 200, array $headers = [])
{
    $factory = app('App\Http\ResponseFactory');

    if (func_num_args() === 0) {
        return $factory;
    }

    return $factory->make($content, $status, $headers);
}

The above code basically declares the response() function so that when laravel's own helpers are created directly afterwards it will not declare a new one but use ours instead.

  1. Create a new file called: app/Http/ResponseFactory.php and add the following code:
<?php

namespace App\Http;

use JsonSerializable;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Routing\ResponseFactory as BaseFactory;

class ResponseFactory extends BaseFactory
{
    /**
     * Return a new JSON response from the application.
     *
     * @param  string|array  $data
     * @param  int  $status
     * @param  array  $headers
     * @param  int  $options
     * @return \App\Http\JsonResponse
     */
    public function json($data = [], $status = 200, array $headers = [], $options = 0)
    {
        if ($data instanceof Arrayable && ! $data instanceof JsonSerializable) {
            $data = $data->toArray();
        }

        return new JsonResponse($data, $status, $headers, $options);
    }
}

Here we declare our own factory that will return our own JsonResponse instance when used. The JsonResponse class is created next...

  1. Create a new file called: app/Http/JsonResponse.php and add the following code:
<?php

namespace App\Http;

use Illuminate\Http\JsonResponse as BaseResponse;

class JsonResponse extends BaseResponse
{
    const HTTP_AUTHENTICATION_TIMEOUT = 419;
    const HTTP_USER_NOT_FOUND = 425;
    const HTTP_TOKEN_INVALID = 498;
    const HTTP_TOKEN_REQUIRED = 499;

    public static $statusTexts = [
        419 => 'Authentication Timeout',
        425 => 'User Not Found',
        498 => 'Token Invalid',
        499 => 'Token Required'
    ];

    /**
     * Sets the response status code.
     *
     * @param int   $code HTTP status code
     * @param mixed $text HTTP status text
     *
     * If the status text is null it will be automatically populated for the known
     * status codes and left empty otherwise.
     *
     * @return Response
     *
     * @throws \InvalidArgumentException When the HTTP status code is not valid
     */
    public function setStatusCode($code, $text = null)
    {
        $this->statusCode = $code = (int) $code;
        if ($this->isInvalid()) {
            throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
        }

        if (null === $text) {
            if (isset(self::$statusTexts[$code])) {
                $this->statusText = self::$statusTexts[$code];
            } else if (isset(parent::$statusTexts[$code])) {
                $this->statusText = parent::$statusTexts[$code];
            } else {
                $this->statusText = 'Unknown Status';
            }
            return $this;
        }

        if (false === $text) {
            $this->statusText = '';
            return $this;
        }

        $this->statusText = $text;

        return $this;
    }
}

This file overrides the Illuminate\Http\JsonResponse class which in turn overrides the Symfony\Component\HttpFoundation\JsonResponse class. We need to append our own response codes and status texts here, as an example I have added code 499 Token Required and a few others but you can add more or replace them. We then have to also override the setStatusCode() method so that we can check our own array as well as that of the parent class.

  1. Finally, to return a JSON response with you own new code you can do the following in your controller:
return response()->json(['foo' => 'bar'], 499);

I hope this helps anyone in the same situation as I am.

2 likes
DonSchoeman's avatar

Please note that I made some changes to my own correct answer in the JsonResponse class and to copy and paste that source code instead of the source code from the "correct answer".

1 like
ather's avatar

Hi @donschoeman Could you please update this info for Laravel 6? Seems like there is no longer a bootstrap/autload.php file anymore in L6.

Thanks.

Please or to participate in this conversation.