How to pass route parameters to webcontroller in Laravel? - php

I've read from the Laravel manual that I can do this:
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
I've also read that you can pass the route directly to webcontroller:
Route::get('user', 'WebController#profile');
But what I can't find is how to pass the variable id to the webcontroller.
Route::get('user/{id}', 'WebController#profile');
// how so that the function profile at WebController receive the id?
I feel that this is a very basic thing to do, but I can't find it. I'm new to Laravel, so I don't know the keyword for search this. Please help. Thanks.

You can simply write up within your controller
public function profile($id){
//Here $id is having the value that you were passing
}

Related

How can I pass part of an url to my controller in Laravel

I'm making a registration form where after filling in a form, users get an email with all the info they've submitted including a link where they can edit their registration. Example url: localhost/registrationapp/edit/{id}
I've been trying to pass part of the url to a controller, this is my route:
Route::get('/edit/{id}', [RegistrationappController::class, 'edit'])->with('id', $id);
And I got this function in my controller:
public function edit($id)
{
return 123;
$registration= Registrationapp::find($id);
return view('edit')->with('registration, $registration);
}
The return 123 part is just added to see if I can even get to the controller, but it doesn't reach the controller. Instead I'm getting this error when I go to a url (for example localhost/registrationapp/edit/5):
Undefined variable $id
Is there any way to do what I'm trying to do? Any help would be greatly appreciated.
Just remove ->with('id', $id);
Note : if you are using url : localhost/registrationapp/edit/{id} , make sure to include registrationapp in route :
Route::get('registrationapp/edit/{id}', [RegistrationappController::class, 'edit']);
I reckon you need to have your route just as Route::get('/registrationapp/edit/{id}', [TestController::class, 'edit']);.
Please feel free to look at my laravel 7 snippet here, https://phpsandbox.io/n/73314638-5fvdc. It demonstrates below:
Route::get('/registrationapp/edit/{id}', [TestController::class, 'edit']);
Note, I borrowed the default welcome.blade.php file, and updated the default / route in web.php.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function edit($id)
{
return view('welcome', ['id' => $id]);
}
}
Edit: You're right in your comment reply from accepted answer, I missed a prefix to your example URL you shared, apologies about that. I've updated my answer here.

how to get name from url dynamically

How to get a part of the url?
query to be made:
$name = 'LeSant'; // (from url dinamic) //
$event = Dias::where('name', $name)->first();
How can I get name from the url? /event/LeSant
It depends on how you are declared this route. You can specify model parameter and with laravel route binding you can inject model in your controller method https://laravel.com/docs/9.x/routing#customizing-the-key
In routes/web.php:
Route::get('/events/{event:name}', [EventController::class, 'show']);
And in EventController controller you can use something like that:
public function show(Event $event)
{
// do something with $event
}
Or if it not suits to you can get last element from request()->segments()
Multiple ways to do that. You can use request helper for it. Below two ways with requesthelper:
request()->segment(count(request()->segments()))
last(request()->segments())

Bind posted data to a model in Laravel 5.4

I have seen other topics regarding this issue, didn't work out.
So in Laravel 5.4 Route Model Binding, we can bind a route to a model like:
define the route in web.php:
web.php:
Route::get('/users/{user}', UsersController#show);
UsersController#show:
public function show(User $user){
// now we already have access to $user because of route model binding
// so we don't need to use User::find($user), we just return it:
return view(users.show, compact('user'));
}
The above code will work just fine, so in our controller we can return the $user without finding the user, we already have it.
but imagine this:
web.php:
Route::patch('/users/archive', UsersController#archive);
EDITED: now the above line makes a patch route and we don't have {user} in the route url, the user id is being posted via the form.
UsersController#archive:
public function archive(Request $request, User $user){
// how can I access the $user here without using User::find($user);
// I get to this action via a form which is posting `user` as a value like `5`
dd($request->user); // this now echo `5`
// I can do:
// $user = User::find($request->user);
// and it works, but is there a way to not repeat it every time in every action
}
What I have tried:
in RouteServiceProvider::boot() I have:
Route::model('user', 'App\User');
The above is what i have found in Google, but not working.
I would appreciate any kind of help.
EDIT:
It seems it's not called Route Model Binding anymore since we don't have the {user} in the route and that's because my code is not working, the user variable is being posted to the controller and it's only accessible via $request->user.
this is route model binding:
Route::patch('users/{user}/archive', UsersController#archive);
this is not:
Route::patch('users/archive', UsersController#archive);
since we don't have {user} and it's being posted via the form and could be accessed only via $request->user.
(please correct me if I am wrong about the definition of route model binding)
SO:
what I want to achieve in a nutshell: in every request being sent to my UsersController, if I am sending user variable as a post variable, it must be bounded to User::findOrFail($request->user) and then $user must be available in my controller actions.
I want to achieve this because in every action I am repeating myself doing User::findOrFail($request->user) and I don't want to do that, so I want to check in every request if I have a variable name like a model name, they should be bounded.
There's no need to bind explicitly to the User class, so Route::model('user', 'App\User'); should be removed; type-hinting should be enough instead.
public function archive(Request $request, User $user) { ... }
should be working, just make sure you are importing the right User class at the top of the file (use App\User;).
Then the model is in your $user variable (method argument), try dd($user).
It's clear now that since the {user} variable is not in the URI, this is not a route model binding issue. You just want the User instance injected as a parameter based on the contents of the request.
$this->app->bind(User::class, function () {
$user_id = request('user') ?: request()->route('user');
return User::findOrFail($user_id);
});
You could add that to the register method in the AppServiceProvider (or any other registered provider) to have the model injected. I leave it to you to generalize this to other model classes.
You don't even need (Request $request) in your controller.
If you correctly imported User class, as alepeino said, you can access all user values from Model with this syntax $user-><value> for example:
public function archive(User $user) {
$userId = $user->id;
}
According to update.
If you use POST request, you can access it's data with such code request()->get('<variable you send as parameter>')
For example:
public function archive() {
$userId = request()->get('user');
$userInfo = User::find($userId);
//Or as you said
$user = User::findOrFail(request()->get('user'));
}
Can you try this;
public function archive(Request $request, $u = User::find($user){
//now variable $u should point to the user with id from url
}

How does Routing work in PHP laravel?

I have just started playing with Laravel framework and I have seen this :
Route::get('foo', function () {
return 'Hello World';
});
Can some one please explain what is this ? I mean over all I know what is get . but why do we put 'foo' and then the closure we put ?
Also where am I really getting the information from ?
First we declare the Facade of the Route, think like a shortcut to use the Route class.
After that, we choose the method of the route, it could be:
Route::get($uri, $callback); //get
Route::post($uri, $callback); //post
Route::put($uri, $callback); //put
Route::patch($uri, $callback); //patch
Route::delete($uri, $callback); //delete
Now you choose the url of the page, for example:
If you digit in the browser:
www.foobar.com/user/profile
Laravel will search for the route with the user/profile parameter, like that:
Route::get('user/profile', function () {
return 'Hello World';
});
You can pass variables too,
Route::get('user/{id}', function () {
return 'Hello World';
});
After that, you choose the callback method, in other words, what is gonna happen when the laravel enter in the route.
In your example, you have the function example, just returning a simple "hello world".
The best pratice here is to create a controller
php artisan make:controller FoobarController --resource
And referece to any method of your controller
Route::get('user/profile', 'FoobarController#index');
Now, when the laravel find the route, it's going to redirect to the index method of the Foobar controller, and there, you define your logic
public function index() {
return view('welcome');
}
Firsty, read the documentation, it's super easy, even for the begginers.
Step by step:
get is the HTTP method you use on this particular route. The other most often used is POST, but there are more of them.
foo is the route, in that case will be: www.example.com\foo. You can put any name as you want and need.
As a second parameter to a Route facade you put closure/name of the controller/view you want to handle endpoint, e.g.
Route::get('foo', 'SomeController#method');
Route::get('foo', function(){
return view('some.view');
};
There are lot more options in routing and they are not difficult to understand, just have a look on documentation or some video tutorials.

Proper way to pass a hard-coded value from route to controller (Laravel)?

I have a PagesController with one action: view.
This action accepts a page argument.
What I want to achieve:
Have a routes example.com/about and example.com/foobar.
When one of this routes is triggered, pass a value predefined in routes file to PagesController#view.
In my routes file:
Route::get('about', function () {
return App::make('App\Http\Controllers\PagesController')->view('about');
})->name('aboutPage');
Route::get('foobar', function () {
return App::make('App\Http\Controllers\PagesController')->view('foobar');
})->name('foobarPage');
It works as expected, but I want to know is there a better and more proper way to achieve the same functionality?
Pass your pages as route parameter:
Route::get('{page}', 'PagesController#view');
//controller
public function view($page)
{
//$page is your value passed by route;
return view($page);
}
So you just want an argument to your action. You can use optional parameters if that argument can be empty. You can read more about it here.
Route::get('{argument?}', 'PagesController#view')->name('page');
And in your PagesController:
public function view($argument = 'default') {
// Your logic
}
The accepted answer is what you want based on what you are doing.
If you really wanted a hardcoded value you can use the 'actions' array part of the route if you wanted.
Route::get('something', ['uses' => 'Controller#page', 'page' => 'something']);
public function page(Request $request)
{
$page = $request->route()->getAction()['page'];
...
}
asklagbox - blog - random tips and tricks
If you don't need the names of the routes like in your example
->name('foobarPage');
you can use something like this
Route::get('{page_name}','PagesController#view')->where('page_name', '(about)|(foobar)');
This will accept only the values passed in the regular expression for the page_name parameter. Other routes will throw a 404 error. I should mention that this technique seems to be valid for applications with one level of url nesting only and should NOT be used as a pattern.
From what I can see above if all you are doing is showing the correct view I would go for
Route::get('{page}', function($page)
{
if (view()->exists($page)) {
return view($page);
}
return abort(404);
});
This prevents you even needing a method in your controller.

Categories