My method within the controller can receive this:
domain.com/busqueda/anything
That will search within my database for'anything' and paginate the results, so if more than one then a 3rd value is needed:
domain.com/busqueda/anything/10
The '10' will be the offset.
Using a form with GEt method will result in:
domain.com?busqueda=anything
Which my controller won't accept. So i need to rewrite it to:
domain.com/busqueda/anything/
And be able as well to accept the offset value when typed or linked directly like:
domain.com/busqueda/anything/10
I'm pretty bad when htaccess comes. I have tried some rules but only worked with no 'offset'.
You can make another controller method for form, where you'll get GET parameter and make a redirect: redirect('busqueda/'.$this->input->get('busqueda'));
In case of having problems with routing:
In application/config/routes.php add:
$route['busqueda/(:any)/(:num)'] = 'busqueda_controller/busqueda_method/$1/$2';
$route['busqueda/(:any)'] = ''busqueda_controller/busqueda_method/$1';
In you busqueda_controller/busqueda_method just make:
$offset = false; //no offset
if(FALSE !== $this->uri->segment(3)) {
$offset = (int)$this->uri->segment(3); //I've used casting, because I don't know how CI does it. Maybe it's unnecessary here
}
Related
I have a bit of a complicated issue. I could use some help.
I have a form that is being handled by the following function:
$module = request('module');
$classe = request('classe');
$horaire = request('horaire');
$date = request('date');
$students = DB::select('SELECT * FROM `etudiants` WHERE etudiants.id_classe = '.$classe);
return view('g_absence.absence',['module'=> $module, 'classe'=>$classe,'horaire'=>$horaire,'date'=>$date,'students'=>$students]);
I take the values $module, $class, $horaire, $date and $students and need to use them inside a different view: g_absence.absence. This works fine and when the view is returned I have access to said variables.
The issue is, inside the g_absence.absence view, I have another form that also needs to be handled, and because the url remains the same even tho a different view is returned, I cant make two posts for the same path.
web.php:
Route::get('/testboy', [App\Http\Controllers\g_absence::class,'index'])->name('marquer');
Route::post('/testboy',[App\Http\Controllers\g_absence::class, 'marquer']);
Route::post('/testboy',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
The first line is the one that send to the form page just a simple
return view
The second one handle the form in that view
The third one, I want it to handle the form inside the
g_absence.absence view, but they share the same path.
Excuse me if I'm being unclear, I'm a bit of a beginner in Laravel
your problem is using the same route for different methods
basically the first route gets executed every time you use the '/testboy' action that is why your second function never get's called.
you can solve this issue by changing your urls for example:
Route::post('/testboy-marquer',[App\Http\Controllers\g_absence::class, 'marquer']);
Route::post('/testboy-ajoutabsence',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
Or you can use one function that's handle both with one url by pathing additional parameter to your url depending on your function call :
Route::post('/testboy?type=marquer',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
in your function check the type :
if(request('type') == 'marquer') {
execute marquer logic here...
} else {
execute absence logic here...
}
Using method and path with two functionalities is wrong, but if you want to somehow use both routes my same method and path which I don't recommend you must let the request to pass through like a middleware in your first block of code Instead of return a view.
Recommended way is to have 2 routes with different paths or at least one route with a parameter by which you can determine what code block must be executed.
I'm working on a project where I need to create clean URL for every products, see following pattern:-
example.com/Single_Product_Page
The original URL is example.com/browse/Single_Product_Page and I used following code:-
$route['(:any)'] = 'Products/browse/$1';
I've two page (1) example.com/Product
and (2) example.com/Products/Single_Product_Page
And it is working fine but now I'm unable to open Products page and when I tried to open it, It open Single_Product_Page
Please help me to solve this issue.
You need to update your routes similar to this example (which works OK on my site):
$route['products'] = 'controller/myfunction/argument';
$route['products/:any'] = 'controller/myfunction/another_argument/$1/1';
you can get more insight from the docs here
You can use a little hack to use just your controller name (and that's a must of course) but eliminate the need to write the method name and pass your parameters directly after the controller name so basically your url would look like this: http://localhost/controller/parameter and that would give you shorter urls as you intend but not an SEO friendly as you claimed.
You can use _remap in your controller and check if it matched a method process it normally or pass it to your index (which is your default method that's doesn't have to be written in your url) .. and now you won't need to use index in your url as you intended.
public function _remap($method)
{
if ($method === 'some_method_in_your_controller')
{
$this->$method();
}
else
{
$this->index($method);
}
}
Or you can depend on ajax for all of your crud operations and your url will be pretty much fixed all the time.
I have a route like this:
Route::get('demo/{system?}', 'MonitorController#demo');
I am using it like so because I would like my url to look like so:
mysite.com/demo/spain-system
Where spain-system will be the variable I need to get.
Right now, I'm getting it like this:
public function demo($systemName = null){
}
But I would like to be able to access to it as if it were a URL parameter with Input::get('system') so I can access to it from other methods or even from other controllers such as BaseController.php.
Is there any way to achieve this?
I've played around with Route::input('system') but then it doesn't work when I pass it as a get parameter (in other Ajax calls and so on)
Update
In PHP we can get URL params by using the $_GET function and laravel provides the function Input::get() to do so as well.
If there were no routes in laravel, I would make use of .htaccess rewrite rules to change this:
mysite.com/demo/?system=spain-system
To this:
mysite.com/demo/spain-system
And I could still retrieve the variable system as a GET parameter by using $_GET["system"].
That's kind of what I would expect of laravel, but it seems it is just treating it as the parameter of the demo method and not really as a URL variable.
Is there any way to keep treating it as a URL variable and at the same time use it in a pretty URL without the ?system= ?
So you actually just want to get an url like this? mysite.com/demo/spain-system instead of mysite.com/demo/?system=spain-system? Laravel provides that by default?
Look, When you want to get the router variable {system?} to be accesible you'll need to do this:
In your router:
Route::get('demo/{system}', 'MonitorController#demo');
Then you have an controller where this noods to stand in:
public function demo($system)
{
//your further system
//You are be able to access the $system variable
echo $system; //just to show the idea of it.
}
When you now go to to localhost/demo/a-system-name/, You'll see a blank page with a-system-name.
Hope this helps, because your question is abit unclear.
I am using codeigniter re-route to clean up some urls.
I am aware that I can do
$route['product/(:num)'] = "catalog/product_lookup_by_id/$1";
But in some cases I have to add some extra parameters to the redirect url so that I get them as a param to the method. for example
$route['product_unique_and_rare'] = "catalog/product_lookup_by_id/{HERE I WANT SOME ADDITIONAL EXTRA PARAM}";
How to do this so that I get the value in the param of the method rather than the value in uri->resegment
you can try this
$route['product_unique_and_rare/(:num)'] = "catalog/product_lookup_by_id/$1";
Get the param in product_lookup_id like this
function product_lookup_id($product_id){
/*$product_id will be the passed parameter*/
}
So, if someone goes for http://domain.com/product_unique_and_rare/23, $product_id will get the value 23.
You can hard-code the parameter too, but I believe you aren't looking for that.
I was browsing Symfony's website. I didn't really feel like I need all the functionality the framework offers, but I did like the routing part. It allows you to specify URL pattern like this
/some/path/{info}
Now for URL like www.somewebsite.com/app.php/some/path/ANYTHING it would allow you to send client a response specific for this URL. You could also use string ANYTHING and use it similar as GET parameter.
There is also option to hide app.php part of the URL which leaves us URL like www.somewebsite.com/some/path/ANYTHING.
My question is what's best approach to do this without a complex framework?
I have made my own mini-framework with the same routing syntax. Here's what I do:
Use MOD_REWRITE to store the parameters (like /some/path/{info}) in a $_GET variable I call params:
RewriteRule ^(.+)(\?.+)?$ index.php?params=$1 [L,QSA]
Parse the parameters and store them globally using this function:
public static function parseAndGetParams() {
// get the original query string
$params = !empty($_GET['params']) ? $_GET['params'] : false;
// if there are no params, set to false and return
if(empty($params)) {
return false;
}
// append '/' if none found
if(strrpos($params, '/') === false) $params .= '/';
$params = explode('/', $params);
// take out the empty element at the end
if(empty($params[count($params) - 1])) array_pop($params);
return $params;
}
Route to the proper page dynamically:
// get the base page string, must be done after params are parsed
public static function getCurPage() {
global $params;
// default is home
if(empty($params))
return self::PAGE_HOME;
// see if it is an ajax request
else if($params[0] == self::PAGE_AJAX)
return self::PAGE_AJAX;
// see if it is a multi param page, and if not, return error
else {
// store this, as we are going to use it in the loop condition
$numParams = count($params);
// initialize to full params array
$testParams = $params;
// $i = number of params to include in the current page name being checked, {1, .., n}
for($i = $numParams; $i > 0; $i--) {
// get test page name
$page = strtolower(implode('/', $testParams));
// if the page exists, return it
if(self::pageExists($page))
return $page;
// pop the last param off
array_pop($testParams);
}
// page DNE go to error page
return self::PAGE_ERROR;
}
}
The value here is that it looks for the most specific page to the least specific page. Also, workout outside of a framework gives you complete control so if there's a bug somewhere, you know you can fix it - you don't have to look up some weird workaround in your framework.
So now that $params is global, any page that uses a parameter simply calls $params[X] to work with it. Friendly URLs without a framework.
The way I add pages then is I put them into an array that is looked at in the pageExists($page) call.
For AJAX calls, I put in a special IF:
// if ajax, include it and finish
if($page == PageHelper::PAGE_AJAX) {
PageHelper::includeAjaxPage();
$db->disconnect();
exit;
}
And voila - your own micro routing framework.
I recommend this article http://net.tutsplus.com/tutorials/other/a-deeper-look-at-mod_rewrite-for-apache/ to understand url rewrite using apache mod_rewrite you do not need any framework just php. Also this is what in the depth any framework implements
The problem is that a routing is a complex thing in a framework.
Perhaps you take a look at Silex. Its a micro-framework based on the Symfony2 Components. Its not so big as Symfony2 but have some of the features.