I am building a simple user registration form using the MVC design pattern, in PHP.
Can someone please advise if I have selected the correct areas for code implementation, as after some fair amount of reading I understand people often interpret the docs in different ways.
I understand there may be no wright / wrong answer here, but am just trying to get some feedback on how the majority would implement it.
Many thanks.
Model
Function containing PDO mysql insert query
View
HTML form markup with PHP self action and controller include
Controller
Data validation and php include of model function
yup there are different approaches to MVC... your concepts look correct except for the view which should not contain the controller include. It is the controller that includes the model and view. Furthermore, i would have put validations in the model itself.
Model : validation functions(return true or false if error) and insert query
View : html form only with data passed from controller
Controller: main entry point/file (e.g. registration.php)
The controller is the entry point which is where you include your view and model.
Basically in the controller,
you check if form is submitted or not.
If not submitted, display the view (i.e. the form)
if data submitted, do validation using model's validation functions.
If validation ok, execute sql in your model and redirect to success page or display a success message.
If validation is not correct, display your view and fill in your form with the submitted data.
But as i said, there are different approaches to MVC; e.g. you can do all validations in the controller itself instead of the model like you proposed.
I'm writing a custom component for the Joomla CMS using the MVC pattern. I'm implementing a simple workflow, where I want the user to enter some data into a view, validate this data (on server side, this is not about client side/JavaScript validation) and redirect the user to another view, if the validation succeeded. If the data is invalid, the first view should be displayed again with the invalid fields marked.
Now I'm not sure, where to place the validation code: My first thought was to place it in the controller, since this one has to decide whether to redirect to the second view or not. But I found a couple of advices telling me not to place validation code in the controller.
Placing it into the model of the first view would also be an option. But since in Joomla there's a 1-to-1 relationship between model and view, I'm not sure if it's ok to only create a model class (because in case of successful validation, the first view is not shown again).
Is there any standard way to do this? Or is this kind of behaviour implemented in some standard component, so I could look for the source code? Any ideas (some pseudo-code would be nice and sufficient...)?
Thanks for any help!
In my projects, I put them in the Form model (using HTML_QuickForm2).
Semi code:
$form = new HTML_QuickForm2();
$form->addElement('text')->addRule('email');
if ($form->validate()) {
echo "all fine, storing in database";
} else {
//error, let's try it again
echo $form;
}
This way, you have all the rules and validations in your form object. Move the form initialization code into an own class extending HTML_QuickForm2, and you're set.
i have been doing simple MVC tutorials for a while and i get the concept. But i am wondering, when a form is displayed in a view, how is the form processed? A code to check for form submission must be present in the view file, which doesn't really fit because view should just be for displaying output.
So when you have a form in a view file of an MVC framework, where should the code to check for form submission be?
Of course this depends on the specific framework, but this is rather typical:
form data is posted to a controller (like all requests)
data validation rules are defined in the model
the controller runs the data through the model for validation
if successfully validated, the controller does whatever it's supposed to do
if data is invalid, the controller pushes error messages for invalid fields to the view
the view just displays the error messages
The form submission can be handle in controller. check this
The code to check for and validate the form submission should be in the controller or the model, depending upon the type of data received from the form and what you're doing with it. That's the point of MVC. View files should contain only the barest amount of logic necessary to display the page.
I think the most common approach would be the controller, since it is the controller that handles all input data (via $_POST, $_GET etc) and then ultimately decides which methods to call to handle that input, and which view to output.
I have a custom MVC application/framework where each action is a function inside of a controller class.
I have a signup action which renders a view with a form requesting user details. On submit it posts to a processSignup action that validates the data and either inserts the user into the database and redirects to a success page or needs to redisplay the original view/form with the errors.
The signup action runs several queries and hands off a variety of data to the view. E.g. it needs to get a list of available countries that the user can choose in a drop-down, retrieve a list of suggested usernames based on the name they entered on a previous form, and retrieve other data from a model.
I'm trying to find out how I can avoid repeating all these queries and the render of the view in my processSignup action in the event of an error. What's the standard way to handle these situations? The signup action receives POST data from a previous form so I can't have the signup form submit to itself and branch based on GET vs POST.
I could just call the signup function directly and have it receive an optional parameter to differentiate between normal requests and ones for invalid forms but that seems hackish. How do other frameworks handle this scenario? I'm using PHP but this is more of a high-level question than one specific to the language.
Avoiding duplicate code certainly isn't unique to MVC frameworks. The standard approach would be to simply create a private function that both signup and processSignup call before rendering the view. Something like:
private function setCommonVars()
{
// set country, username arrays, etc...
}
As far as rendering the signup view, the flexible thing about MVC is that you can reuse views. Your framework should have a way of explicitly choosing a view within a controller method (e.g., $this->view = 'signup'). That way, if an error occurs in processSignup, you can choose the signup view before rendering.
I have several questions regarding CI application design.
Q. When creating a new form and your using CI's form_helper I'm creating arrays in the controller and passing it to the view/form_input() method. Should I be doing this in the controller, the view, or a separate file?
Q. In my controller, I create a method for my form i.e., new_user() and in my view/form_open() I specify a different method in my controller to handle the action (i.e., add(), edit(), delete() ..etc) & that method handles the validation. This is the way that I perfer; however, I've had a lot of difficulty passing the data around if the validation fails. Any suggestions?
Q. I have an instance or two that when I perform form validation I need to validate against two $_POST variables. An example would be, on validation I need to query the database to determine if the entered business already exists (based off business name and zip code) then redirect back to the view and persist the post variables. So far I haven't been able to find a way to create a custom callback function to do this because you can only pass in one parameter. The only way that I've been able to get this to work is if validation passes, I then perform the database check and if the business exists I put the $_post in session/flashdata and use redirect to load the view again. The array that defines the form_input attributes calls set_value for that is where it pulls the flashdata for each record in the array.
$data['name'] = array(
'name' => 'name',
'id' => 'name',
'value' => set_value('name', $this->session->flashdata('name')),
'maxlength' => '200',
'size' => '79',
'class' => 'text'
I realize that this really comes down to preferences; however, I'm really wanting to gain some insight on what pitfalls I can expect and how others are designing their applications. I've downloaded sample applications and I've dome a good amount of searching but I really haven't found much discussion. Any suggestions are greatly appreciated.
Thank you!
I'll share my approach using CI
I create Controller as slim as possible. The controller main job will only get parameter through URI, _GET, and _POST. Then controller will pass required parameter to models, and get the result. After that, view file will be loaded and all variables required by the view will be passed.
All process logic, related with database, email sending, etc, is handled in the model. Model will get parameter, do query, process query result if needed, then return an array, resultset, boolean, or integer. Controller that get the returned value pass it directly to view, without reprocessing it.
In view, it will process the variable in order to displaying it. There will be loop to display list of data, get the column field from array then display it as a form default value, etc. View and model often developed in pair, because all needed field in view must be provided by the query in the Model.
The only 'fat' processing in Controller is the form_validation. I have answer it in your other question, how I wrote my form_validation rules and how to use it.
Below is my answers for your question above:
Q. When creating a new form and your
using CI's form_helper I'm creating
arrays in the controller and passing
it to the view/form_input() method.
Should I be doing this in the
controller, the view, or a separate
file?
I rarely using form_helper. This is because most of my view is came from fellow designer or provided by client as the HTML file. I only use form_dropdown because it's allow me to pass options as an array, instead of do foreach. For the other form element, I just use the one presented in the template file.
Q. In my controller, I create a method
for my form i.e., new_user() and in
my view/form_open() I specify a
different method in my controller to
handle the action (i.e., add(),
edit(), delete() ..etc) & that method
handles the validation. This is the
way that I perfer; however, I've had a
lot of difficulty passing the data
around if the validation fails. Any
suggestions?
When I create my application, I often only have 2 main methods in controller. admin is for displaying list and handle delete, and form to display and handle add and edit. Let me give example with a product module.
I will have product controller with these methods:
class Product extends MY_Controller {
function index()
{
//for front page, display list of product
}
function detail()
{
//for front page, display single product detail
//product id is passed as 3rd URI segment
$id = intval($this->uri->rsegment(3));
}
function admin()
{
//for admin, display product list
//receive id in _POST then do delete
//after delete, do redirect to self, best practise
}
function form()
{
//for admin, handle add and edit
$id = intval($this->uri->rsegment(3));
//if id given and product detail data can be loaded, then it in 'edit' mode
//else it in 'add' mode
//after validation success, and insert/update success, redirect to product/admin
}
}
Using this approach, I can avoid duplicate code and can maintain all code to always up to date. Almost all add & edit have same view and form field. In case add & edit form differ (such as edit user, do not allow changing username), by have $mode variable set to either add or edit, I can put simple if and display correct form, validation rules, and call appropriate model metods.
Q. I have an instance or two that when
I perform form validation I need to
validate against two $_POST variables.
An example would be, on validation I
need to query the database to
determine if the entered business
already exists (based off business
name and zip code) then redirect back
to the view and persist the post
variables. So far I haven't been able
to find a way to create a custom
callback function to do this because
you can only pass in one parameter.
The only way that I've been able to
get this to work is if validation
passes, I then perform the database
check and if the business exists I put
the $_post in session/flashdata and
use redirect to load the view again.
The array that defines the form_input
attributes calls set_value for that is
where it pulls the flashdata for each
record in the array.
You can create your own validation rules. To pass more than one parameter, you can open the file system/libraries/Form_validation.php then see the function matches($str, $field) code. Your callback can have more than 1 parameter, and function matches($str, $field) code will show you how to read and use the second parameter.
I hope this will help you in learning and using CI. Waiting great web application from you ;)
Q. When creating a new form and your using CI's form_helper I'm creating arrays in the controller and passing it to the view/form_input() method. Should I be doing this in the controller, the view, or a separate file?
A. Form_Helper should be always use in "view".
Q. In my controller, I create a method for my form i.e., new_user() and in my view/form_open() I specify a different method in my controller to handle the action (i.e., add(), edit(), delete() ..etc) & that method handles the validation. This is the way that I perfer; however, I've had a lot of difficulty passing the data around if the validation fails. Any suggestions?
A. My way is direct add/edit() to a save();, in save() method I do if else for both cases.
Q. I have an instance or two that when I perform form validation I need to validate against two $_POST variables. An example would be, on validation I need to query the database to determine if the entered business already exists (based off business name and zip code) then redirect back to the view and persist the post variables. So far I haven't been able to find a way to create a custom callback function to do this because you can only pass in one parameter. The only way that I've been able to get this to work is if validation passes, I then perform the database check and if the business exists I put the $_post in session/flashdata and use redirect to load the view again. The array that defines the form_input attributes calls set_value for that is where it pulls the flashdata for each record in the array.
A. I recommend u use $this->input->post instant of using $_POST, because CI will help u filter XSS if u enable it.
PHP didn't support is_POST like .NET, what I do is use a textbox as reference
if(isset($_POST('txt_Name')))
{
}
**or**
if($this->input->post('txt_Name'))
{
}
Hope my answer able to help you.