Laravel Route Controller with Forced Parameter - php

So i have checked out
PHP - Routing with Parameters in Laravel
and
Laravel 4 mandatory parameters error
However using what is said - I cannot seem to make a simple routing possible unless im not understanding how filter/get/parameters works.
So what I would like to do is have a route a URL of /display/2
where display is an action and the 2 is an id but I would like to restrict it to numbers only.
I thought
Route::get('displayproduct/(:num)','SiteController#display');
Route::get('/', 'SiteController#index');
class SiteController extends BaseController {
public function index()
{
return "i'm with index";
}
public function display($id)
{
return $id;
}
}
The problem is that it throws a 404
if i use
Route::get('displayproduct/{id}','SiteController#display');
it will pass the parameter however the URL can be display/ABC and it will pass the parameter.
I would like to restrict it to numbers only.
I also don't want it to be restful because index I would ideally would like to mix this controller with different actions.

Assuming you're using Laravel 4 you can't use (:num), you need to use a regular expression to filter.
Route::get('displayproduct/{id}','SiteController#display')->where('id', '[0-9]+');

You may also define global route patterns
Route::pattern('id', '\d+');
How/When this is helpful?
Suppose you have multiple Routes that require a parameter (lets say id):
Route::get('displayproduct/{id}','SiteController#display');
Route::get('editproduct/{id}','SiteController#edit');
And you know that in all cases an id has to be a digit(s).
Then simply setting a constrain on ALL id parameter across all routes is possible using Route patterns
Route::pattern('id', '\d+');
Doing the above will make sure that all Routes that accept id as a parameter will apply the constrain that id needs to be a digit(s).

Related

Mapping route to another route in Laravel

I am developing an application in the Laravel 5.2 which must have a friendly URL-s. This is not problem with the regular way, where the {slug} wildcard is handled by a controller but I want to make it in a different way.
For now I have only two controllers:
ProductsController#show to show details product
CategoriesController#show to show selected category with listing products which are assigned to it
And routes:
Route::get('product/{product}', 'ProductsCategory#show')->name('product.show');
Route::get('category/{category}', 'CategoriesController#show')->name('category.show');
So when I want to echo a just use route('product.show', compact('product'))
Nothing special until I want to handle different URL-s which are fetched from a database. I thought it will be possible to make an another routes which are assigned to existing and when I use a route(...) helper it will be handled automatically. But it is not. So for example I have a new URL:
domain.com/new-url-for-product.html
so by route it should be assigned to the regular 'product.show' route with some ID, which is handled by route model binder for {product} wildcard. The same for route(..) helper it should print friendly URL-s.
I don't know if my strategy is good. How do you handle with the similar problems?
of course route will handle this automatically. have a look into this. I am just giving you example, you have to set this code as per your need.
route('product.show', 'product'=>'new-url-for-product.html');
will generate this
domain.com/new-url-for-product.html
route('product.show', 'product'=>'new-url2-for-product.html');
will generate this URL
domain.com/new-url2-for-product.html
and so on, and then you have to handle all this in your controller method.
eg: your controller method for this route is ProductsCategory#show which is
public function show($product){
if($product == 'new-url-for-product.html'){
//perform this
}
if($product == 'new-url2-for-product.html'){
//perform this
}
}
this just an example, you have to map this according to your need
Edited Here is the example I tested it
Route::get('/product/{product}.html', ['as'=>'product.show', 'uses'=>'ProductsCategory#show']);

Using a different controller for GET and POST in Laravel but using the same name

I am writing route and controller rules for a web application. In a number of rules, a problem has emerged, which is that I need to match both GET and POST verbs, and send them to the controller, but different methods.
I considered using Route::controller('tracking', 'TrackingController') for this, but then it requires different names for each internal route, whereas I want to specify one name for both. Besides, I've read nothing but negativity regarding the usage, suggesting that it is not a good idea.
Here's what I have currently:
Route::match(['get', 'post'], '/tracking', [
'as' => 'tracking',
'uses' => 'TrackingController#index'
]);
While implementing this, I have discovered that I need to have two controller methods, index and track. How can I efficiently route GET to index and POST to track, while maintaining the same controller (TrackingController) and the same name (tracking)?
I considered using two separate routes, e.g. Route::get and Route::post, but that doesn't feel very eloquent.
you can use easily Route Controller,like this
Route::controller('tracking', 'TrackingController')
In here if you wanna use same method for both get and post,just use any prefix in method,like
//for both get and post
public function anyUrl();
//only get
public function getUrl();
//only post
public function postUrl();
Or use
Route::any('/url', function () {
return 'Hello World';
});

How to route the URI with parameters to a method in codeigniter?

I don't know much about the routing concept in codeigniter, I want to pass many parameters to a single method as explained in this http://www.codeigniter.com/userguide2/general/controllers.html tutorial page.
In the url I have this
http://localhost/code_igniter/products/display/2/3/4
In my routes.php I have written
$route['products/display/(:any)'] = 'Products_controller/display';
What I thought is it will pass all the parameters (here 2/3/4) to the method 'display' automatically but I am getting 404 page not found error.
In general I want to achieve something like, if the URI is controller/method I want to route to someother_controller/its_method and pass the parameters if any to that method. How can I do it?
In CI 3.x the (:any) parameter matches only a single URI segment. So for example:
$route['method/(:any)/(:any)'] = 'controller/method/$1/$2';
will match exactly two segments and pass them appropriately. If you want to match 1 or 2 you can do this (in order):
$route['method/(:any)/(:any)'] = 'controller/method/$1/$2';
$route['method/(:any)'] = 'controller/method/$1';
You can pass multiple segments with the (.+) parameter like this:
$route['method/(.+)'] = 'controller/method/$1';
In that case the $1 will contain everything past method/. In general I think its discouraged to use this since you should know what is being passed and handle it appropriately but there are times (.+) comes in handy. For example if you don't know how many parameters are being passed this will allow you to capture all of them. Also remember, you can set default parameters in your methods like this:
public function method($param=''){}
So that if nothing is passed, you still have a valid value.
You can also pass to your index method like this:
$route['method/(:any)/(:any)'] = 'controller/method/index/$1/$2';
$route['method/(:any)'] = 'controller/method/index/$1';
Obviously these are just examples. You can also include folders and more complex routing but that should get you started.
On codeigniter 3
Make sure your controller has first letter upper case on file name and class name
application > controllers > Products_controller.php
<?php
class Products_controller extends CI_Controller {
public function index() {
}
public function display() {
}
}
On Routes
$route['products/display'] = 'products_controller/display';
$route['products/display/(:any)'] = 'products_controller/display/$1';
$route['products/display/(:any)/(:any)'] = 'products_controller/display/$1/$2';
$route['products/display/(:any)/(:any)/(:any)'] = 'products_controller/display/$1/$2/3';
Docs For Codeigniter 3 and 2
http://www.codeigniter.com/docs
Maintain your routing rules like this
$route['products/display/(:any)/(:any)/(:any)'] = 'Products_controller/display/$2/$3/$4';
Please check this link Codeigniter URI Routing
In CodeIgniter 4
Consider Product Controller with Show Method with id as Parameter
http://www.example.com
/product/1
ROUTE Definition Should be
$routes->get("product/(:any)", "Com\Atoconn\Product::show/$1");

Laravel RESTful resource route adds percentages to URI

I have a user RESTful resource route in my Laravel App.
Route::resource('backbone.users', 'backbone\UserController');
for the the CRUD operations.
Unfortunately, I get following URIs:
I get {backbone} in the URI that results in %backbone% in the browser but
I want the URL like dev.domain/backbone/users NOT dev.domain/backbone/%backbone%/users
I would need to redirect like:
return Redirect::intended('backbone/{backbone}/users');
How come?
It's hard to tell by the screenshot (or maybe my eyes aren't great) but it looks like backbone/{backbone}/users. If this is the case, that's intended, the {} are indicating that it can take a variable in this position.
So it might be return Redirect::intended('background/1/users');
The controller method to go with it, in this case index of UserController will receive that variable as its argument.
This is normal for Laravel. The {} in your routes list represent url variables.
Take this route for example:
/users/{user}/edit
To use this route you would navigate to
/users/1/edit
Assuming you have your controller method setup similar to:
public function edit($userId)
{
}
The $userId variable would contain '1' from the url. Definitely checkout the docs for more on Laravel routing

PHP Laravel extending resource routing

Laravel routing functionality allows you to name a resource and name a controller to go with it. I am new to Laravel and would like to know if anyone knows how to extend the resources method in the route class provided.
Basically say I have: (which works fine)
/invoices
But say I want:
/invoices/status/unpaid
How is this achievable?
To see the basics of what I am doing check:
http://laravel.com/docs/controllers#resource-controllers
Resource controllers tie you into a specific URLs, such as:
GET|POST /invoices
GET|PUT /invoices/{$id}
GET /invoices/create
and so on as documented.
Since, by convention, GET /invoices is used to list all invoices, you may want to add some filtering on that:
/invoices?status=unpaid - which you can then use in code
<?php
class InvoiceController extends BaseController {
public function index()
{
$status = Input::get('status');
// Continue with logic, pagination, etc
}
}
If you don't want to use filtering via a query string, in your case, you may be able to do something like:
// routes.php
Route::group(array('prefix' => 'invoice'), function()
{
Route::get('status/unpaid', 'InvoiceController#filter');
});
Route::resource('invoice', 'InvoiceController');
That might work as the order routes are created matter. The first route that matches will be the one used to fulfill the request.

Categories