This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
CodeIgniter Routing
What should be happening: user navigates to URI, routes.php grabs the State and sends it to the controller, the controller returns some info from a database query. Pretty basic stuff.
The problem: the URI isn't passing the variable to the controller. I'm being told
Missing argument 1 for States::state_summary
I can set a default for the function argument, ie. ($st='Alabama') and everything works smoothly.
I don't even see how this is possible. Maybe at least tell me what I need to test to track down the bug.
URI:
http://example.com/index.php/states/Alabama
routes.php:
$route['states/(.*)'] = "states/state_summary/$1";
States controller:
...
function state_summary($st)
{
// DB query
// Return data
}
...
I believe your route should be adjusted to this:
$route['states/(:any)'] = "states/state_summary/$1";
That worked for me.
I'm not sure if (.*) is valid as I've never seen it used.
Well, I never write the controller to have parameter, instead I use rsegment method:
...
function state_summary()
{
$st = trim($this->uri->rsegment(3));
// DB query
// Return data
}
...
With this, I have more control with the passed parameter. I can sanitize it using trim or intval, before pass it to model or library.
Also, there are some tweak in codeigniter core library about routing the url. See it in the file system/libraries/Router.php, the code inside function _parse_routes() around lines 278. It is how URI routing work in CI.
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 using this plugin to create slug-based URL's on a CakePHP 2 web application: https://github.com/josegonzalez/cakephp-dynamic-route
The documentation suggests that you would call a Cake controller like so:
posts/view?id=45
My URL's currently work as Cake's default behaviour. So using the example above posts/view/45 works but posts/view?id=45 does not.
When I call URL's as per the example I get a 404 error.
My functions are written like so (e.g. in PostsController.php):
public function view($id) {
// logic to load post by ID
// ...
}
There is almost no documentaiton for the above plugin. Has anyone used it or know where I'm going wrong? It seems you cannot pass a GET variable such as 'id' to the 'view' function, without re-factoring the code inside it to accept passed parameters?
The solution appears to be that some of the controller functions needed to be re-written to accept GET style parameters.
In the documentation a "spec" field looks like this:
posts/view?id=45
In a regular CakePHP application the route for that would be like this: posts/view/45
The plugin simply doesn't work if you put the second style of route (posts/view/45) into the "spec" field.
So the answer is the "spec" fields must be like so:
posts/view?id=45 and then your controller functions have to be re-written, e.g.
public function view($id) {
if (isset($this->request->params['id'])) {
$id = $this->request->params['id'];
}
}
Doing this means that it will work with a parameter (view?id=45) or a standard Cake call (view/45).
Please note this has nothing to do with the "slug" aspect of the plugin - the "slug" can be anything, as per the documentation examples: /why-isnt-this-pup-asleep or /manchester/cakephp-developers-dance-to-beyonce. The original question was asking if there was a way to map a "spec" given in the documentation to a Cake controller function without having to modify it like I have above. The answer seems to be no, you have to modify them!
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 trying to figure out how to access two (or more) parameters passed to a Laravel controller. I know how to create the route, and the URL is created correctly, but then I can only access the first passed parameter in my controller.
Route:
Route::get('managers/{id}/{parameter2}', array('as'=>'dosomething', 'uses'=> 'ManagersController#dosomething'));
where the first parameter is obviously the $id for managers, and the second parameters is to be processed by the controller.
View:
Do Something
generates the URL:
http://domain/managers/1/2
where 1 is easily accessed as the $id for managers, but when I try to access the 2nd parameter "2" using $parameter2, e.g. using a simple return: "id=$id and parameter2=$parameter2" statement, I get an "unidentified variable: $parameter2" error.
What am I doing wrong?
Is there a better way to pass multiple parameters? I'm especially asking the "better way?" question because what I want to do is use the 2nd parameter to change a value in a database table, and using a 'get' method, somebody could change the parameter value in the URL and therefore cause mischief. Must I use a 'post' method? I'd love to be able to use a link, since that works much better with the design of my application.
Thanks!
I was asked to include the controller, which I'm happy to do. Initially, just for testing, as I mentioned, my controller was a simple return to display the values of the two passed parameters. But here is what I want to be able to do, including the actual name of the function ("update_group" rather than "dosomething") --
ManagersController:
public function update_group($id)
{
DB::table('groups')->where('id','=',$parameter2)->update(array('manager_id'=>$id));
return Redirect::route('managers.show', array('id'=>$id));
}
The update table works perfectly if I replace $parameter2 with an actual value, so that syntax is fine. The issue is that Laravel says that $parameter2 is an undefined variable, despite the fact that the URL contains the value of $parameter2 as you can see above.
And since it occurs to me that the answer to this may involve adding a function to the Manager model, here is the current
Manager.php
class Manager extends Eloquent {
protected $table = 'managers'; ... (mutator and error functions)
}
Just change
public function update_group($id)
to
public function update_group($id, $parameter2)
All looks ok in your route. Seeing the controller code would help, but likely, you may not have a second parameter in your controller's dosomething() method.
public function dosomething($id, $parameter2){
var_dump($id).'<br />';
var_dump($paremter2);
}
If that isn't the case, you can try dumping it from the route's callback to further diagnose.
Route::get('managers/{id}/{parameter2}', function($id, $parameter2)
{
var_dump($id).'<br />';
var_dump($paremter2);
});
Depending on your use case, you can pass them in a query string like so: but it isn't really the 'best way', unless you're doing something like building an API that won't use the same variables in the same order all the time.
/managers?id=1¶mter2=secondParameter
var_dump(Request::query('id')).'<br />';
var_dump(Request::query('paramter2'));
So I have a page:
http://www.mysite.com/controller/function
The function is defined in the controller as:
function ()
{
//some stuff here
}
However it is possible to resolve the URL:
http://www.mysite.com/controller/function/blablabla
i.e. "blablabla" can be passed to the function and forms an additional URI segment, but still brings up the same page. I have the same issue with a number of controllers / functions - how do I prevent parameters being passed to the function (or appearing as a URI segment)?
I've been working with Codeigniter and PHP for around 6 months very part time, so forgive me if the answer is obvious but my searches haven't been fruitful on this.
My goal is optimised SEO - unsure whether better to redirect the page with the extra URI segment to the correct page or to the 404 page.
You can't prevent that without changing how CI handles URI parsing.
You could force a redirect like so:
function my_happy_function($redirect=null) {
if($redirect) {
redirect('/controller/my_happy_function/');
}
}
That would strip out any variables that are given in the URI, at the cost of a page redirect.
Sounds like you want a generic catch all for pages. You can do this using routes.
For example:
$route['my_happy_function(/:any)*'] = "my_happy_function";
then in your my_happy_function index method you check the URI segments there...
public function index()
{
$something = $this->uri->segment(1);
$something_else = $this->uri->segment(2);
// etc
}
this way all calls to my_happy_function get pushed to the index method...
wait, did I understand your question correctly? If I missed the point let me know and I can update.