Having $_POST data within a PHP Class - php

I developed a habit of working like this in PHP and I was wondering if it is a correct way to work or not.
Basically, whenever I have a form, I would post the data to a 'handler' file which does a couple of basic checks (in certain cases) then creates an instance of the class.
The class __construct automatically calls a function within the class and begins validating the post data and redirects the user accordingly, along with a $_GET data to display a success message.
I'm aware this is the Post-Redirect-Get pattern, yet, my curiosity is: is it okay to redirect to a file and create the class instance within there, or is it okay if you post the data directly to the class file ?

Related

Bootstrap, MVC, Ajax, Smarty Php

Okay, I'm learning all about MVC, Bootstrap, Ajax and Smarty and I understand the basic principles of MVC. I am having one major issue however and I just cannot wrap my head around it, no matter how much I try and no matter how much reading I do.
At it's very core the thing I cannot seem to get my head around is how to pass variables from view to controller from controller to view.
If I want to assign a variable, I can simply $view->assign('variableName', 'variableValue') No issues there, then in the view if I want to call it, it's as simple as $variableName and it's in the view.
My issue is, I want to be able to minipulate data, for example let's say I want to have a list of items, numbers for the example, a list of 1-10, the user chooses 6, I want a way to be able to "POST" that back to the controller without actually having use POST/GET, I want to be able to essentially let it call an Ajax to send the users selection but I do not know the best way to do so.
If I was doing this without MVC, or Smarty it would be as simple as form, action post, I know that but unfortunately that isnt something I can use in this instance.
Any help you can offer would be appreciated.
I will begin with the normal workflow, e.g. without the MVC approach.
Let's say, in a certain moment you are seeing a web page in the browser and let's call it MAIN PAGE.
When you are submitting a form from main page without using ajax,
the whole page refreshes, no matter if the form action points to the
main page or to another one.
When you are submitting values using an ajax call (as part of the
main page code), then the main page will not be reloaded. E.g. an
ajax call targets ANOTHER PAGE to fetch some data in some format
(html, json, etc) and prints the data on screen, in a specified
container inside the main page.
Now, let's see what happens in a web MVC architecture.
You must understand, that an MVC application consists of only one page: index.php. This page serves as the MAIN PAGE, but ALSO as the ANOTHER PAGE, targeted when using ajax calls. The index.php page is therefore processed each time when you are sending a request to the web server - be it through manually changing the url in the address bar of the browser, through posting a html form, or through starting an ajax script.
All other components of the MVC structure (classes, template files, etc) are serving only one purpose: to build the structure of the index.php page - as main page or as ajax response page.
So, in principle, in the index.php page you'll have something like this:
Read the URL, e.g the url components: controller name, action name, action parameters (HTTP GET query string). For this you can use an instance of a Router class.
Create an object of type Request, passing and saving the url components into it. Here are read and saved the other server request variables too, e.g. HTTP POST, HTTP cookies, etc.
Create an instance of the View class.
Based on the url's controller name instantiate the corresponding Controller class, passing the Request object and the View instance to it. Here you'd give the model layer constructs (like a model factory object) as constructor parameter(s) too.
Based on the url's action name call the corresponding controller method, e.g. the controller "action". Exactly here, inside the controller action, are taking place the processing of the server request variables (saved in the Request object), the loading of the template files and their rendering, including transferring the processed server request variables into them.
In the last step, the rendered template files will be directly printed or further passed to an object of type Response, which in turn prints them.
In the end, you'll have a fully "constructed" index.php page, which will be either printed on screen by the browser (if index.php has the role of a main page) or processed by the browser as the result of an ajax request.
Note that I used the description of the steps found in the classical MVC approach. There are also other... types of this concept, best presented in Architecture more suitable for web apps than MVC?
Other very good resources:
MVC for advanced PHP developers (contains a list of great resources)
How should a model be structured in MVC?
Understanding MVC Views in PHP
Understanding MVC
MVC (Model-View-Controller) in PHP tutorial (Part I...IV)
Model-View-Confusion (Part I+II)
James Mallison - Dependency Injection and Dependency Inversion in PHP
Good luck.

PHP MVC Form Submission

I have a question related to form submission done in PHP application that's built in MVC architecture (self-written framework).
All examples that I've seen so far (including existing back-end frameworks) work this way that once form for adding record to database is submitted then certain method of controller is executed [say i.e. addRecord()], which triggers method of appropriate model. If everything goes OK then record is added and controller's method [addRecord() in this example] renders view of "index" page that displays table with records from database.
What I would like to achieve is to render view with form used to add records (the same that I used to add first record) instead of "index". Obviously I can do it easily by just rendering appropriate view from addRecord() (view with the form).
But the tricky point is when you check url you'll see the following:
The first time you enter it will be i.e.
http://project_name/my_controller/create
Once first form was submietted and you return to the view from addRecord() method then url will be:
http://project_name/my_controller/addRecord
What I would like to see is return to the original url, that is http://project_name/my_controller/create
Not sure if this is clear?
PS. Of course I could use AJAX call for form submission (that way I will stay at the same page) but perhaps it's possible to achieve the same without AJAX.
Thanks in advance,
On the controller you will want to submit to the addRecord route and do the processing. Have a check to make sure it was successful and on successful submission you can redirect back to the create route.
It is hard to give an example since you are using a custom made framework. I use slim which has a redirect method for a route. If what you have made does not have something like that then using should do the trick.
header('Location: '.$createUrl);
die(); //or exit

Proper way to pre-fill form after server-side validation failure, involving two separate php files

A very basic question. I have a form in one file form.php, I post it to another file processForm.php which does the server-side validation and processing. I am not using any framework.
Now, in case of form validation failure, I need to display the form again with all the values prefilled, without using a javascript history.back() from the processForm.php. What is the clean and proper way to do this so that I have all the posted values available again in form.php and can prefill them?
This is easy if the form submission happens to the same page, but this is how I got this and I cannot make the submission into the same page. So what would you do? Store the values in session? Curl post? Send the values using GET to form.php?
Why or why not? Please mention pros and cons.
Go read up on the MVC pattern.
You can't implement an interactive program without implementing a model, a view and a controller - the point is that your code should be structured to implement each of the three concerns as a single entity, be that as functions (or function trees), classes (or class trees) or files. And the three components within the pattern should be structurally grouped.
So if you want to the user to arrive at (say) second page after successfully filling in a form at first page, but to stay on first page when the form fails the validation, then a simple way to implement this would be to have first page implement the model view and controller, i.e. to both populate/generate the form and be the target for the form. Then if it receives a valid request sent from the form, send a redirect to second page.
This avoids the need for each page to load and process the MVC code for the preceding page as well as the current one - although that approach reduces the number of round trips to the browser which can help with performance.
NB using POST does not preclude the use of variables in the URL - indeed, I recommend using GET variables to indicate the data you wish to manipulate and POST variables to show how they should be manipulated.

Where to put PHP files for AJAX in MVC architecture?

I'm creating site using MVC architecture and get stunned when I came to AJAX. I create simple feedback form with AJAX. When user submit it there is called PHP file that inserts given values into the database using 'database' class.
Where to put that PHP file (so it would be somehow hierarchic)?
I tried to put it in /models/ajax/file.php, but it seems to me stupid and, of course, 'database' class wasn't found.
It's no different than how you do any other page of your site. That this page's output goes to an AJAX request instead of directly to a web browser is irrelevant. Its logic goes in the controller, the database code goes in the model layer, its response goes in a view.
You should call controller from AJAX request. And response will probably use different (for example JSON) view

Codeigniter application design

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.

Categories