I'm writing a routing system that may or may not be part of a public API later for a personal project. A main part of the routing system is a response object for the user to send headers, status code, and the body of the response that is sent from the server.
I've created a response class that I think covers everything the user would want to do with the response (it could use a few more "convenience" functions however). I wanted to post it here to make sure my code is clean, and that I didn't miss anything that the end user might want to do.
An instance of the request class is provided to the user when a request is made to a specified URL (see my last code review)
I present my response class:
class Response {
private $headers = array();
private $code = 200;
private $body = '';
private $sent = false;
private $log;
public function __construct() {
$this->log = Logger::getLogger(get_class($this));
}
public function headers ($headers) { // Add some headers to the headers array
$this->headers = array_merge($this->headers, $headers);
return $this;
}
public function header ($key, $value) { // set a single header in the headers array
$this->headers[$key] = $value;
return $this;
}
public function code ($code) { // Set the status code
$this->code = $code;
return $this;
}
public function status ($code) { // Alternate method for setting the status code
return $this->code($code);;
}
public function json($str) { // respond with json, set the body text and set the content-type header
$this->header('Content-Type', 'application/json');
if(is_array($str)) { // handle either raw JSON text, or php arrays
$this->body = json_encode($str);
} else {
$this->body = $str;
}
return $this;
}
public function html ($str){ // respond with HTML
$this->header('Content-Type', 'text/html');
$this->body = $str;
return $this;
}
public function form ($str) { // Respond with form data
$this->header('Content-Type', 'application/x-www-form-urlencoded');
// TODO: Allow the user to user an array
$this->body = $str;
return $this;
}
public function render ($file){ // Render an HTML file from the templates folder
//TODO: Restrict to templates folder open
//TODO: Add server-side rendering code
$this->body = file_get_contents($file);
return $this;
}
public function sent() { // Check if the request has been sent
return $this->sent;
}
public function send () { // send the request
if($this->sent()){
$log->error('Attempted to call send on a sent response!');
exit('Attempted to call send on a sent response!');
}
// Log the request for debugging
$this->log->info($this->headers);
$this->log->info('HTTP Responce Code: ' . $this->code);
$this->log->info($this->body);
// Set the headers
foreach($this->headers as $key => $value) {
header($key .': ' . $value);
}
// Set the status code
http_response_code($this->code);
// Send out the body
echo $this->body;
// Set the sent variable
$this->sent = true;
}
}
EDIT:
The idea with the short and clear function names that all return $this
is to be able to have clear and simple chainable responses. (e.g $res->code(200)->json(... Json...);
)