Laravel - How to set HTTP response status code from Controller - php

I'm new to laravel and am successfully directing users tothe appropriate views from a controller, but in some instances I want to set an http status code, but it is always returning a response code of 200 no matter what I send.
Here is the code for my test controller function:
public function index()
{
$data=array();
return response()->view('layouts.default', $data, 201);
}
If I use the same code within a route, it will return the correct http status code as I see when I call the page with curl -I from the command line.
curl -I http://localhost/
Is there a reason why it doesn't work within a controller, but does within a route call?
I'm sure there is something I'm just misunderstanding as a newbie, but even the following code works in a route but not a controller:
public function index()
{
abort(404);
}
What am I doing wrong?

Solution
You could use what is mentioned here. You will need to return a response like this one:
public function index()
{
$data = ['your', 'data'];
return response()->view('layouts.default', $data)->setStatusCode(404);
} // ^^^^^^^^^^^^^^^^^^^
Notice the setStatusCode($integer) method.
Alternative
You could set an additional header when returning the view to specify additional data, as the documentation states:
Attaching Headers To Responses
Keep in mind that most response methods
are chainable, allowing for the fluent construction of response
instances. For example, you may use the header method to add a series
of headers to the response before sending it back to the user:
return response($content)
->header('Content-Type', $type)
->header('X-Header-One', 'Header Value')
->header('X-Header-Two', 'Header Value');

Related

CodeIgniter 4 redirect function not working

After logout, I tried to redirect for the home page. I tried to few ways, but not redirected.
class User extends BaseController
{
public function __construct()
{
helper('url');
}
for the logout function. I used three ways
redirect('/');
or
header("Location:".base_url());
or
route_to('/');
as per CI 4
use
return redirect()->to('url');
if you are using route then use
return redirect()->route('named_route');
I use this and it works
return redirect()->to(site_url());
In codeigniter 4 redirect()->to() returns a RedirectResponse object, which you need to return from your controller to do the redirect.
for ex.
class Home extends BaseController {
public function index() {
return redirect()->to('https://example.com');
}
}
I am new to CI4. In my case, I had to properly set $baseURL in App.php. For example, if the port is set incorrectly in your local development, it will just hang.
eg. public $baseURL = 'http://localhost:8888/';
Its worth saying that unlike the former CI3 redirect() function this one must be called from within a Controller. It won't work for example within a Library.
Update 2021
It is in fact possible to do this! Simply check that the returned response is an object and return it instead. So if a library returns a RedirectResponse, check it using the following code and return if applicable.
if (!empty($log) && is_object($log)){
return $log;
}
You could of course do get_class() to make sure the object is a type of RedirectResponse if there is any possibility of another object being returned.
If you using unnamed route:
$this->response->redirect(site_url('/user'));
'/user': It is my controller name. You can also used controller/function name.
Please look at the documentation
// Go back to the previous page
return redirect()->back();
// Go to specific URI
return redirect()->to('/admin');
// Go to a named route
return redirect()->route('named_route');
// Keep the old input values upon redirect so they can be used by the old() function
return redirect()->back()->withInput();
// Set a flash message
return redirect()->back()->with('foo', 'message');
// Copies all cookies from global response instance
return redirect()->back()->withCookies();
// Copies all headers from the global response instance
return redirect()->back()->withHeaders();
If you find:
{0, string} route cannot be found while reverse-routing
This error:
Please Go to system\HTTP\RedirectResponse Line no 91 :
Change:
throw HTTPException::forInvalidRedirectRoute($route);
To:
return $this->redirect(site_url('/Home'));
(dashboard after login)
The redirect statement in code igniter sends the user to the specified web page using a redirect header statement.
This statement resides in the URL helper which is loaded in the following way:
$this->load->helper('url');
The redirect function loads a local URI specified in the first parameter of the function call and built using the options specified in your config file.
The second parameter allows the developer to use different HTTP commands to perform the redirect "location" or "refresh".
According to the Code Igniter documentation: "Location is faster, but on Windows servers it can sometimes be a problem."
Example:
if ($user_logged_in === FALSE)
{
redirect('/account/login', 'refresh');
}
Original Answer: https://stackoverflow.com/a/725200/5700401

Laravel - check request method

I'm an iOS lead on an app and trying to fix some API bugs whilst our dev is 'unavailable'. I'm almost completely new to Laravel and trying to check what the request method is. I have followed some guidance from another question but have been unable to get it working:
public function defaults(Request $request, User $user){
$follow_ids = explode(',', env('FOLLOW_DEFAULTS'));
if ($request->isMethod('post')) {
return ['user' => $user];
}
$user->follows()->syncWithoutDetaching($follow_ids);
return ['user.follows' => $user->follows->toArray()];
}
Do you know where I might be going wrong here? Thanks in advance.
When the request is returned it always just seems to skip over and return ['user.follows' => $user->follows->toArray()]
$request should be an instance of Illuminate\Http\Request. This class extends Symfony's request (Symfony\Component\HttpFoundation\Request), which is actually where the isMethod() method is defined.
Basically, given the function definition as posted, it reads "if this is a POST request, just return the user data. if this is not a POST request (e.g. GET), update and return the relationship data."
So, if you send a POST request, you'll get the ['user' => $user] response. If you send any other request method (e.g. GET), you'll modify the follows relationship and get the ['user.follows' => $user->follows->toArray()] response.
To me, this seems backwards. I would think you'd want the POST request to update the data, and any other request (e.g. GET) to just return data.
If this is correct, you need to negate your isMethod check:
if (! $request->isMethod('post')) {
return ['user' => $user];
}
More appropriately you should define separate controller actions to handle POST vs GET requests, but that is outside the scope of this question, and probably more than you want to get into as a temporary maintainer.
It seems that the request is not a POST so the if check is never true. You could echo the method name like this:
$method = $request->method();
echo $method;
// or var_dump($method);

Getting values sent using post method in controller in magento 2 api

I can not get values sent from post method, using http request.
I am getting values using get method, but I need to get it using post method.
I am not using any view, I want to call http url, and send some data in my controller using post method.
This is how my controller looks like,
namespace Spaarg\eMenuApi\Controller\Index;
class Products extends \Magento\Framework\App\Action\Action
{
public function __construct(\Magento\Framework\App\Action\Context $context)
{
return parent::__construct($context);
}
public function execute()
{
//$token = $this->getRequest()->getPostValue();
$token = $this->getRequest()->getPost();
}
}
I am new to magento 2, and I don't understand what is the problem.
It will be great if someone can help.
It probably has to do with the Content-type of the http request, where Magento only understands Json and Xml (this is explained here). If you're using a different Content-type in the request or your data doesn't match the type declared in the header, then getPost() will not work.
As a fallback, you can always get all the POST data by using the following way:
public function execute()
{
$postData = file_get_contents("php://input");
}
Keep in mind that this will get the raw string, so you will likely need to process it accordingly before using it (for example with json_decode() or something like that).
For more information about this, check this SO question.

Slim PHP - Right way to use request and response objects

I'm new to Slim and PHP, but I'm trying to do a simple rest API with Slim. It's working, but I don't know if I'm doing it the right way and I cannot find another way to do it.
For example, I've a route like that:
$app->get('/contacts', '\Namespace\Class:method');
The method:
public function searchContacts($request, $response) {
return Contact::searchContacts($resquest, $response);
}
So, the unique way I found to access request and response from other classes is by passing the objects as params. Is it correct or is there a better (right) way to do it?
I think your way is not good.
Controller should process request and return response.
Your model(Contact) should'nt process requests. It should take needed params and return data.
Simple example:
public function searchContacts($request, $response)
{
// to example, you pass only name of contact
$results = Contact::searchContacts($request->get('contactName'));
$response->getBody()->write(json_encode($results));
return $response;
}
You don't need access to Request and Response objects from another classes. If it required, possible your architecture is wrong.
Good example from official site: http://www.slimframework.com/docs/tutorial/first-app.html#create-routes
the simplest way is to get the values from params and recieved the response in method.
$app->get('/contacts', function (Request $request, Response $response) {
$Contactname = $request->getAttribute('contact');
//You can put your search code here.
$response->getBody()->write("Contact name is, $name");
return $response;
});

Capture all informations passed to a view in Laravel

I want to capture every information passed to view using the afterFilter. So I need to know:
all variables
session flash
the action executed (last action)
the view called
This is because I need to check if the request is json or not for change the response.
Currently I use afterFilter like this:
public function __construct()
{
// Here's something that happens after the request
$this->afterFilter(function() {
});
}
What I want is: use the afterFilter method in BaseController to capture all events/actions and then decide if the request is json or not.
If you need more information, comment please.
And sorry for my english
Do you need to know if JSON or if AJAX? If AJAX then just use:
if (Request::ajax())
{
//
}
You may use Request::wantsJson() to determine if the request is asking for json in return using:
// In app/filters.php
App::after(function($request, $response)
{
if($request->wantsJson()) {
//...
}
});
In this case, Laravel (through Base/Symfony class) checks if the Accept header is set and if that is application/json.

Categories