If I want to create RESTful APIs, which one should I choose?
How do the URLs as index.php/id/1 work? I think it's a file path, not a URL.
If I want to get an image as abc.com/img/1.png, it may have conflicts with abc.com/img/{param}. How do I solve?
BTW, I use Laravel now.
Thanks so much.
The difference is in route model binding
https://laravel.com/docs/5.7/routing#route-model-binding
This allows you to get the model with the id that is passed into the route
So for example a route like this:
Route::get('users/{user}', 'UsersController#getUser');
Will allow you to do this in you method:
use App\User
public function getUser(User $user) {
return $user;
}
This means that you get the full record for the id that is in the route.
So your Questions:
1: I would use this for sending model id's
2: the variables in the route are passed in that order to the method allowing you to get access to them.
3: You will need to be careful with your routes as you can have conflicts. having said that Laravel does not use a traditional directory structure for storage. I believe that if you have a folder stucture of /public/img and that folder contains an img named 1.png it will get the image but I have not tested this.
Related
Am trying to use two different functions from one controller in a single page route
Route::get('/cart','App\Http\Controllers\Frontend\CartController#index');
Route::get('/cart','App\Http\Controllers\Frontend\CartController#alldata');
But the problem is the function alldata works where the function index doesn't
You can't have 2 GET routes with the same path.
Route::get('/cart','App\Http\Controllers\Frontend\CartController#index');
Route::get('/cart/all','App\Http\Controllers\Frontend\CartController#alldata');
The /cart route is overwritten by the alldata(). So the alldata() is calling instead of index().
kindly remove the alldata()'s route and pass the data from index().
Route::get('/cart','App\Http\Controllers\Frontend\CartController#index');
Route::get('/cart','App\Http\Controllers\Frontend\CartController#alldata');
Try to manipulate your logic in controller rather than in route file.
Use conditional in controller function.
I define route for update profile logic, when I used first logic It does not work but the use of second logic works fine. So I don't know what is the difference between those.
1. Route::post('/profile', 'ProfileController#update');
2. Route::post('/profile', 'ProfileController#update')->name('profile');
The only difference between them, the name,
so If you put in form action something like {{ route('profile') }} you mean: go to route that has name profile.
Read this for more details.
Routes with name eg Route::post('/profile', 'ProfileController#update')->name('profile');
can be accessed in blade using {{route('profile')}}
whereas the other one can only be accessed using url(). e.g
{{url('/profile')}}
The second one is a 'named route'. It allows you to reference your route by a name.
Laravel 5.7 Docs - Routing - Named Routes
Well the obvious difference is the added "->name('profile')" named route to your second line. You have tagged this post with laravel-5.7 so I have linked the documentation for this version: https://laravel.com/docs/5.7/routing#named-routes
It appears to me that perhaps you have some logic in the update function of your ProfileController like so:
if ($request->route()->named('profile')) {
//
}
Which would change the outcome of the request. Hope this helps, best regards.
I'm setting up a new route system.
Route::get('/{cat1Url}', 'CategoryController#showCat1')->name('showCat1');
Route::get('/{productUrl}', 'ProductController#showProduct')->name('showProduct');
My sef link is after "/"
But,
{{ route('showProduct',[$p->pr_url]) }}
This method not working with route name. Working only upside route.
I don't want use
"/cat/myVariable"
or
"/product/myVariable"
Can't I use route name to work this way?
What is the solution to this?
In this way, if you make a get request to /something the laravel you start from top of web.php file looking to a route that follows the pattern. Your both routes will follow that pattern, but the laravel will always, pass the first one to controller.
You have two options:
Put only one route, and inside the controller you switch to the appropriate function. But this isn't a great ideia, because this is the function of the Web.php.
Use the routes like the documentation recommend:
Route::get('/cat/{catId}', 'CategoryController#showCat')->name('showCat');
Route::get('/prod/{productId}', 'ProductController#showProduct')->name('showProduct');
and in Controller you make the appropriate handler of your Category or Product.
You will have to have a way to tell Laravel which url to be mapped to what otherwise it will always use the last defined route. So in your case calling /myVariable and /myVariable it will use the latest definition which is showProduct. The only other way is if you use regular expression to differentiate the variables. For example:
Route::get('/{cat1Url}', 'CategoryController#showCat1')
->name('showCat1')->where('cat1Url', 'cat-*');
Route::get('/{productUrl}', 'ProductController#showProduct')
->name('showProduct')->where('productUrl', 'prod-*');
This way your slugs need to start with what you define, but you cannot use just id as a numeric value for both.
is there a way to customize Laravel 5 resource URLs ?
For example, change user/1/edit to user/edit.
That's because I don't want anybody to see the id in the URL. I think it is database information and shouldn't be revealed.
The point is that I want to do this without changing my routes. On the other hands I want to do this by using resource routes I have and not by adding some new routes to them , as you know when you define a resource route in your project it automatically adds some predefined routes to the route table and you are forced to use them in the way they are. For example you have to send a GET request to user/{user} for showing the user. Now I want to have a URL like user/{username} for doing this without adding a new route, IS THAT EVEN POSSIBLE?
if there is a way for achieving this I appreciate it if you share it here.
Thanks a lot
Since in most cases id is an auto incremented value and guessable, better you can use any other unique column of users table here, e.g username and then using that column instead of id in resource controller. Suppose you've an unique username column in your table So, if you use that instead of id your call to user edit will be like:
{!! route('user.edit', $user->username) !!} // let's say username is shahrokhi
which is equivalent to
user/shahrokhi/edit
Now for example, in your resource controller to edit a user details code may be like:
public function edit($username)
{
$user = User::where('username', '=', $username)->firstOrFail();
// rest of your code goes here
}
And so on for other methods.
Say I have a controller, "Articles" but I want it to appear as a sub-folder (e.g. "blog/articles"), I can add a route like this:
$route['blog/articles'] = 'articles';
$route['blog/articles/(:any)'] = 'articles/$1';
This works fine, the only problem now is that example.com/articles and example.com/blog/articles both use the Articles controller and thus resolve to the same content. Is there a way to prevent this?
To add a little more clarity in case people aren't understanding:
In this example, I don't have a 'blog' controller, but I want 'articles' etc to appear to be in that subfolder (it's an organization thing).
I could have a blog controller with an 'articles' function, but I'm likely to have a bunch of 'subcontrollers' and want to separate the functionality (otherwise I could end up with 30+ functions for separate entities in the blog controller).
I want example.com/articles to return a 404 since that is not the correct URL, example.com/blog/articles is.
Shove this in your controller:
function __construct()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR show_404();
}
You can use subfolders in Codeigniter controllers, so in CI, the following directory structure works:
application/controllers/blog/articles.php and is then accessed at
http://example.com/blog/articles/*.
If, for some reason, you're set on routing instead of accessing the controllers in folders (you want to have a blog controller, for example, and don't want to route to it), you can do as suggested above and add the test for 'blog' to the constructor.
If you're in PHP5, you can use the constructor function like this:
function __construct()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR redirect('/blog/articles');
}
or, in PHP4, like this:
function Articles()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR redirect('/blog/articles');
}
I would suggest using redirect('blog/articles') instead of show_404(), though, so that you're directing users who hit /articles to the correct location, instead of just showing them a 404 page.
Routing there does not mean it will use a different controller, it just creates alias url segment to same controller. The way will be to create another controller if you are looking to use a different controller for those url segments.
If both /blog/ and /articles/ use the same controller, you can reroute one of them to a different one by just adding a new rule in your routes file.