I am managing to deploy a very simple implementation, containing a registration form and for demonstration purposes, I have chosen to use the MVC pattern.
My slight issue is that when I press the submit button, I want the submitted data to be handled by the suitable method of the controller.
For instance:
within the view part, I declare the form like this :
<form action="controller/validate" method="post"/>
I am assuming that this is a routing-related thing, but I am curious whether another way can be suggested.
--
Regards,
Theo
A router can be as simple as a switch statement instead of a full blown router for the small sites:
switch($_SERVER['REQUEST_URI']) {
case 'controller/validate':
$view = new \Views\User\Registration();
$controller = new \Controllers\UserRegistration($view);
$method = 'validate';
break;
default:
$view = new \Views\Error\NotFound();
$controller = new \Controllers\Error($view);
$method = 'notFound';
break;
}
echo $controller->$method();
Also note that instead of doing a relative URL based on the current path you often really want to do a relative URL to the document root:
<form action="/controller/validate" method="post"/>
Note the leading slash.
The above is just a simple (untested) example of semi pseudocode
Usually, you would make your controller accessible through a route (like POST /register). A controller action is assigned to this route in a bootstrap file. Some pseudo-code:
$framework->route('GET', '/register',
'RegistrationController::action_form');
$framework->route('POST', '/register',
'RegistrationController::action_submit');
Another aproach would be mapping routes directly to controllers (some frameworks do this, I believe Kohana is one of them) like this:
Route: /register/submit
Resolves to: RegisterContoller::action_submit()
Management of request method (GET, POST, PUT, DELETE in standard HTTP) happens in the action methods.
Related
I have two controllers Configure.php and Users.php. In my routes.cfg I have:
$route['default_controller'] = 'Users/login';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
$route['registration'] = 'registration';
$route['login'] = 'login';
$route['subit_backend']['GET']='subit_backend/register';
$route['save_userinput']='Users/save_userinput';
When a user brings up the website the following page comes up in the browser bar https://www.stantiation.com/sub_crud/Users/login/ which is perfect.
The problem is that if a user has forgotten their password I am having trouble routing them to method where they can create a new one. I have the user send an email to themselves where I have placed a "code" that will allow them to update their password. The email has a link to this form:
https://www.stantiation.com/sub_crud/Users/resetPassword?fp_code=492c8bbd3841xxx8201f3a01d77fd.
I also have a view file called view/Users/resetPassword.php which is form that allows the user to enter a new password. That pops up fine. This is the post method of the form.
When the user presses submit, I get https://www.stantiation.com/sub_crud/Users/save_userinput in the toolbar and a 404 error, because there is no save_userinput.php file. I am trying to get the save_userinput() method in the Users.php controller to run, not save_userinput.php in the view/Users/directory. I agree with the 404 because that file doesn't exist.
How can I specify in a form that I want the method in controller Users, not the file view/Users/save_userinput.php? That is why I put the last $route in but that doesn't seem to help.
It seems that you might be understanding the CodeIgniter URL scheme. Read about it HERE.
Basically, it boils down to http:doman.tld/controller/function[/var1 ...[/varN]]
So, after the domain you have multiple segments that are interpreted like so:
The first segment represents the controller that should be invoked.
The second segment represents the class function, or method, that should be called.
The third, and any additional segments, represent any variables that will be passed to the controller.
So the URL https://www.stantiation.com/sub_crud/Users/save_userinput would go to the controller Users (which appears to be in the folder of /application/controllers/sub_crud) and call the controller method save_userinput. It is not looking for a file named save_userinput.php.
The 404 could be because the controller is not in a sub-folder or because some other file the controller tries to load, i.e. a "view" file, cannot be found.
It's hard to offer better advice without seeing the html for the form and knowing exactly how you have your file layout structured.
(Side note: I avoid putting controllers in sub-folders because it messes with the URL "look" and IMO, in terms of "controllers", it's not that hard to track what-is-what.)
You really only need routes when you want to override CodeIgniter's segment-based approach to URLs. With that in mind, it appears (based on a general lack of understanding about your app) that the following "routes" don't make sense.
$route['registration'] = 'registration';
$route['login'] = 'login';
$route['subit_backend']['GET']='subit_backend/register';
$route['save_userinput']='Users/save_userinput';
i want to achieve url routing something like www.example.com/alicia
suppose alicia is not a class name or method name just something like passing data in url and with some class i want to access this and want to use it for further process.How i can use it ? Thanks in advance.
You can use Codeigniter's built-in routing, the file route.php is located in your config folder.
there you can add:
$route['alicia'] = 'welcome/index/something';
$route['alicia/:any'] = 'welcome/index/someotherthing/$1';
then in your controller, for example welcome you just create a function like:
public function index($page = null){
if($page=='something'){
// do what you need to do, for example load a view:
$this->load->view('allaboutalicia');
}
elseif ($page=='someotherthing'){
// here you can read in data from url (www.example.com/alicia/2017
$year=$this->uri->segment(2); // you need to load the helper url previously
}else{
// do some other stuff
}
}
documentation on routing and on urlhelper
edit after comment:
in case your uri segment is representing a variable, like a username, then you should use a uri scheme like www.example.com/user/alice and create your route like:
$route['user/:any'] = 'welcome/index/user';
then in your controller welcome
public function index($page=null){
if($page=='user'){
// do what you need to do with that user
$user=$this->uri->segment(2); // you need to load the helper url
}
else{
// exception
}
}
This could be tricky because you don't want to break any existing urls that already work.
If you are using Apache, you can set up a mod_rewrite rule that takes care to exclude each of your controllers that is NOT some name.
Alternatively, you could create a remap method in your base controller.
class Welcome extends CI_Controller
{
public function _remap($method)
{
echo "request for $method being handled by " . __METHOD__;
}
}
You could write logic in that method to examine the requested $method or perhaps look at $_SERVER["REQUEST_URI"] to decide what you want to do. This can be a bit tricky to sort out but is probably a good way to get started.
Another possibility, if you can think of some way to distinguish these urls from your other urls, would be to use the routing functionality of codeigniter and define a pattern matching rule in the routes.php file that points these names to some controller which handles them.
I believe that the default_controller will be a factor in this. Any controller/method situations that actually correspond to a controller::method class should be handled by that controller::method. Any that do not match will, I believe, be assigned to your default_controller:
$route['default_controller'] = 'welcome';
Can I get the controller action from given URL?
In my project, I will have different layout used for admin and normal users. i.e.
something.com/content/list - will show layout 1.
something.com/admin/content/list - will show layout 2.
(But these need to be generated by the same controller)
I have added filter to detect the pattern 'admin/*' for this purpose. Now I need to call the action required by the rest of the URL ('content/list' or anything that will appear there). Meaning, there could be anything after admin/ it could be foo/1/edit (in which case foo controller should be called) or it could be bar/1/edit (in which case bar controller should be called). That is why the controller name should be generated dynamically from the url that the filter captures,
So, I want to get the controller action from the URL (content/list) and then call that controller action from inside the filter.
Can this be done?
Thanks to everyone who participated.
I just found the solution to my problem in another thread. HERE
This is what I did.
if(Request::is('admin/*')) {
$my_route = str_replace(URL::to('admin'),"",Request::url());
$request = Request::create($my_route);
return Route::dispatch($request)->getContent();
}
I could not find these methods in the documentation. So I hope, this will help others too.
You can use Request::segment(index) to get part/segment of the url
// http://www.somedomain.com/somecontroller/someaction/param1/param2
$controller = Request::segment(1); // somecontroller
$action = Request::segment(2); // someaction
$param1 = Request::segment(3); // param1
$param2 = Request::segment(3); // param2
Use this in your controller function -
if (Request::is('admin/*'))
{
//layout for admin (layout 2)
}else{
//normal layout (layout 1)
}
You can use RESTful Controller
Route:controller('/', 'Namespace\yourController');
But the method have to be prefixed by HTTP verb and I am not sure whether it can contain more url segment, in your case, I suggest just use:
Route::group(array('prefix' => 'admin'), function()
{
//map certain path to certain controller, and just throw 404 if no matching route
//it's good practice
Route::('content/list', 'yourController#yourMethod');
});
I am new to laravel. My url for my only controller is
http://localhost/myapp/public/users
In the views for the form functions, I don't want to have to do an absolute path to the post function, e.g.
<form method='post' action='/myapp/public/user/update-user'>
I want to just set the users controller as the base url path so I can say in my form
<form method='post' action='/update-user'>
Is this possible?
Use URL::to()
or simply use laravel form
{{Form::open(array('url'=>'route_name'))}}
You can use URL::to() function.Laravel supports RESTful API or RESTful routing. So it is not a good idea to use routing like this.So use like,
In app/routes.php
// for view (GET)
Route::get('users', function(){
View::make('users');
});
Route::post('users', function(){
// do form validation and process here or call a function from controller
});
Then in your form use,
echo Form::open();
// form elements
echo Form::close();
Yes, it is possible, but it's a little complicated because laravel isn't really set up to support this.
You need to change the file vendor/laravel/framework/src/Illuminate/Http/Request.php, replacing the function root() with this:
public function root($domain = NULL)
{
return rtrim(($domain?:$this->getSchemeAndHttpHost()).$this->getBaseUrl(), '/');
}
And then in the getRootUrl($scheme, $root = null) method in the file vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php you need to change this line:
$root = $root ?: $this->request->root();
to this:
$root = $this->request->root($root);
That should allow laravel to automatically detect and handle subfolders correctly, so you will be able to use the standard URL methods.
First, you need to hide the /public/ part of your URL using the virtual host or the alias in your web server (apache or ...). The entry point (http://some.host/alias/ or http://some.virtual.host/) should lead directly to the public folder (i.e. /whatever/path/myapp/public/).
Second, using the routes, you can do the remaining easily. The route
Route::get('update_users', "UsersController#updateAction")
will redirect the http://whatever.host/update_users to the correct action without the need of the ugly format.
I have followed this nice video tutorial to create a mini MVC PHP framework.
As you can see, the guy creates an action called home() inside the Controller class to show the main page.
Now, I need to create another action called foobar() that shows another page, but how can i associated it to an url in a simple way?
This is usually done by routing. If the first part of the URL identifies the controller and the second the action, you extract those variables and route accordingly.
A very basic example:
$action = 'foobar';
$controllerName = 'whatever';
if(class_exists($controllerName)){
$controller = new $controllerName;
if(method_exists($controller, $action)){
$controller->$action();
}
}
Obviously, $action and $controllerName are obtained from the URL.
This code snippet tries to call the method 'foobar' inside a class named 'whatever'.