I have been reading up on DDD a lot over the last few days and could not find one solid example of how someone would go about simply registering a user on their site so after lots of reading I have stuck this together and I would like your feedback on it because I am sure it is far from perfect, it might even be completely wrong but here it goes:
RegisterController
$userMapper = $this->dataMapperFactory->build('user');
if($userMapper->fetchByUsername($username) !== NULL) {
// Error: The chosen username already exists
}
else {
if($userMapper->fetchByEmail($email) !== NULL) {
// Error: The email address already exists
}
else {
$userDO = $this->domainObjectFactory->build('user');
// Set the properties of the $userDO object here with the ones
// from the registration form
// Insert the new user into the database
$userMapper->save($userDO);
}
}
I have done all the form validation with my own FormValidation class so when I add the properties to the $userDO object they are all 100% ready to be inserted into the database (correct length, type, format, ranges etc) so how does the code look to you?
I think I am on the right track and I would really appreciate any tips on how to improve my code.
Also, the way I am checking if the username they chose has already been taken, is there a better way to do that? Instead of having to create an object each time to check? Like the old way I used to do it with a simple:
SELECt COUNT(*) FROM users WHERE username = 'john'
Thanks.
Some theory-related "blah":
As you might be aware, the core concept of MVC and MVC-inspired design patterns is the SoC. It dictates that you divide these patterns in to major layers: presentation layer and domain model layer.
In this case it is significant, because you current structure of controller contains application logic (the interaction domain logic entities and storage abstractions), whereas a controller should be only responsible for altering state of model layer (and sometimes - the current view) based on user input.
You end up violating bot the above mentioned SoC and also SRP.
Note: in context of web based MVC variations the "user" is a web browser, not the person sitting behind it.
Instead you should encapsulate the application logic in services (as #Gordon mentioned). In a fully realized model layer the different services become something like a public-ish API through which the presentation layer interacts with model.
Though, unlink Gordon, I would recommend your service to be a bit broader. In case of user registration, I would make it a part of CommunityService or maybe MembershipService. A structure that handles all the aspects of the user account management as far as the model layer is concerned.
The code bits:
One way for using in controller would look something like:
public function postUser( $request )
{
$community = $this->serviceFactory->build('Community');
$community->addUser( $request->getParameter('username'),
$request->getParameter('password'),
$request->getParameter('repeated_password'),
$request->getParameter('email') );
}
While this is a valid way, you might already notice an possible problem. Even when user registration need only the minimum of data, the amount of parameters that you end up passing to the service makes it hard to use.
Passing the $request on to service is not a valid improvement. You would just end up violating Law of Demeter. Instead i would recommend something like:
$keys = ['username', 'password', 'repeated_password', 'email'];
$community->addUser( $request->getParameters( $keys ) );
Where the getParameters() method is implemented similar to:
public function getParameters( $keys )
{
$response = [];
foreach( $keys as $parameter )
{
$response[ $parameter ] = $this->getParameter( $parameter );
}
return $response;
}
Domain logic and validation
You mentioned, that some FormValidation class, that you are using to make sure, that your instance of User domain object receives proper values. Actually the data validation is one of the domain object's responsibilities. You still might use a separate validation class, to avoid code duplication, but that would be a dependency, which is injected by domain object's factory to share between instances.
Note: in my personal experience, the duplication for validation is quite rare for anything but the null-checks. Each of complicated validation rule-sets are targeted at fields of one specific domain object. That, in my opinion, makes a validation class quite redundant ... unless you expect to share same validation class between multiple projects.
The code-flow usually is such that, when you need to store the data from domain object, you check if it has not acquired an error state, and if there is an error, you actually dump it in session, for a retrieval after redirect.
if ( $user->isValid() )
{
$sqlMapper->store( $user );
}
else
{
$sessionMapper->storeUser();
}
In this use-case pre-validated input ends up actually being harmful.
All of the code in my project is procedural. It isn't using any framework, or any MVC structure. Most of the PHP is form handlers with some logic. So lots of code like this:
<?php
require "headerFile.php";
$user = array(); // filled with user data
if (isset($_POST['submitButton'])) {
if (isset($_POST['money'])) {
if (is_numeric($_POST['money'])) { // I don't actually validate numbers this way
if ($_POST['money'] <= $user['money']) {
$query = mysql_query("SELECT * FROM someTable WHERE id={$user['id']}");
if($result = mysql_fetch_array($query)) {
if ($someOtherCheck == $user['someOtherData']) {
/*
* run some queries, give user some item
*
*/
} else {
echo "This isn't right.";
}
} else {
echo "You don't have a row in some table!";
}
} else {
echo "You don't have that much money!";
}
} else {
echo "Enter a valid number";
}
} else {
echo "Enter how much you want to wager.";
}
}
// some hard coded form goes here
require "footerFile.php";
?>
There are over a hundred of these forms and nested if handlers, some that are similar with more/fewer conditions.
I want to start using OOP and I've been reading up on design patterns but I can't seem to find anything that applicable to my project.
I'm adding loads of new blocks of code similar to the block above, I don't want to copy and paste and just change a couple of bits here and there, what are my options?
First off, if you are ever copying and pasting code that should be a BIG RED FLAG. This should be a warning that instead of copying and pasting, you need to write a generalized function that can be used.
Secondly, it's really time to stop using mysql_query-like functions. Even the PHP page says use of those functions is discouraged. I would start moving your SQL over to PDO which is more OO-like.
When I inherited an application that looked the code you posted, I wrote a blog post about the steps I took to start getting a handle on things. It may also be helpful to you - http://mattmccormick.ca/2011/10/13/how-to-refactor-a-php-application/
OOP is not always about application. It is about readability and structure. Honestly, how readable is the code you have posted here? There are a ton of things happening and it would take you 10 minutes to decipher them all. However, if you break it down into classes with class functions you would be able to glance at things and know what is going on.
OOP does not do a ton for php all the time, but its something you want to do for almost all other non-static load languages. With the added benefit that if you have more than one programmer on a project you can both read the code. Comments are you friend.
You're best option is to use functions with returns. Return the value and then the function does whatever it needs to do with it. I personally would do something like
$class->check
if error
$this->error_handler
and the function error handler does whatever you want it to do with the error, if its die or echo then do that, but you build the error handler, so if you ever want to change it, you chance it in one place instead of 20.
Even without bringing in OOP, you could do wonders for structuring your code to be readable. There's no need to nest your conditionals if they're not dependent on each other.
$form_is_valid = true;
if (!isset($_POST['submitButton'])) {
echo "This isn't right.";
$form_is_valid = false;
}
if (!isset($_POST['money'])) {
echo "Enter how much you want to wager.";
$form_is_valid = false;
} elseif (!is_numeric($_POST['money'])) {
echo "Enter a valid number";
$form_is_valid = false;
} elseif (!$_POST['money'] <= $user['money']) {
echo "You don't have that much money!";
$form_is_valid = false;
}
if ($form_is_valid) {
do_stuff_here();
}
Regarding Frameworks
A decent framework will help you on your way to organizing code better trough separation of concerns, but does not necessarily enforce best practices. Subjectively, I say it takes hands-on experience and making lots of mistakes before best practices are ingrained in your head.
Try to think of a framework as a delivery mechanism only. Optimally, your code is not tied to any one framework. This generally means using components to handle different aspects of your application such as routing, validation, config, events, dependencies, etc.
Regarding OOP
Something I feel you should start with would be the SOLID principle. This will help you, although not guarantee, avoid making mistakes that cost you a lot of time down the road.
Foremost, your objects should only have a single responsibility. e.g. a Product object should not be responsible for acting as a data store, persisting itself, handling an order, etc etc.
Also another biggy would be dependency injection. This is huge for unit testing your classes (which you should get in the habit of doing). In a nutshell, do not construct dependency within a class. Construct it beforehand and pass it in through either a constructor argument or a setter method.
The process of architecting an application merits having its own books, so I'm not going to attempt writing it all here. If you follow the SOLID principle though, you will be well on your way to being a better developer.
Regarding your code above
That kind of nesting is generally a smell, and I can see why you are asking the question...
Step 1 would be to separate the validation in to its own service. Thinking of this in a MVC sense, at the least, your controller would only have [pseudocode] if ($form->isValid()) { do something }. This alone eliminates the bulk of spaghetti you have.
I want to start using OOP and I've been reading up on design patterns but I can't seem to find anything that applicable to my project.
You don't have to start with patterns yet .. understand the basics and you can progress form there ..
This is a basic example
if (isset($_POST['submitButton'])) {
$db = new \mysqli("localhost", "user", "pass", "db");
$user = new User("Juddling Stack", 123456);
$user->setMoney(500.01);
$player = new PlayerRegister($db, $user);
if (! isset($_POST['money']) || ! is_numeric($_POST['money']))
$player->addError("Enter Valid Wager Money");
if ($_POST['money'] <= $user['money']) {
$player->addError("You don't have that much money!");
}
try {
$player->doSQL();
} catch ( BaseException $e ) {
foreach ( $e->getError() as $error ) {
echo $error, " <br />";
}
}
}
Classes Used
It looks like your code is combining certain components of both the model and view layers. You're running queries against a database, and in the same place, you're including hard coded forms. So, a good place for you to start would be to split these tasks up into two separate classes. For example, write a class to connect to your database and run queries against it, and another class to actually serve your content.
My advice on Design patterns is to not get too bogged down in the details. Instead, try to understand why certain patterns are so helpful, and what problems they are trying to solve. A lot of beginners get too bogged down in the how , and they end up wasting so much time learning the nuances of a framework when a simple solution would have sufficed.
Finally, as you read through your code, keep an eye out for things that could potentially be structured into a class. Also, remember that specialization is key, and by building classes that are very specialized in what they do, you are building modular components that could potentially be used in other projects,
Let's start by stating the problem you are having which is not not using OOP, but called programming-overhead or in programmer terms spaghetti-code.
If you experience a lot of overhead, meaning time wasted writing almost the exact same line of code, where only it's content is different, but the functionality is the same. Then start slicing every peace of code that's the same from it's function, but differentiate its content.
You stated there is more to be copied pasted, and even more complex, I'll just do the form validation part (something I called stage 1), which is just one simple example of how to apply logic that does all the work for you by feeding input it expects. One example might be more elegant than others.
all code below is not tested
An example for locating code of equal functionality.
// functionality on checking values is the same, but it's content is not
if (isset($_POST['submitButton'])) {
if (isset($_POST['money'])) {
if (is_numeric($_POST['money'])) {
and
// though every decision made by its content is only being produced once ..
} else
echo "You don't have that much money!";
} else
echo "Enter a valid number";
} else
echo "Enter how much you want to wager.";
Now the trick is to find a solution to logically solve this. PHP is full of build-in functions, but first grasp the idea on how to solve it. An example would be to have each key, like submitButton, money have a value that would equal to not exists if not set/present, let's say null. Second, you are comparing values with a key supplied by the $_POST, so no matter what.. your $_POST array is the decision maker.
A keen example can be seen on how the jQuery library has been build using the $.extend() method to apply default values to keys, so that a key always has a value and always a decision to make by not checking first if it exists. But so can PHP.
Let's default the values.
$_POST = array_merge(array(
'submitButton' => null,
'money' => 0,
'etc' => '...'
, $_POST);
Building a function to validate this array is a lot easier now, because you can always depend on a value being present.
You stated you have many more forms that need validation, a function that would validate certain fields would be next to figure out.
A formal representation of a valid or invalid form could be an array, e.g.
$valid_form = array(
'submitButton' => array('not_null'),
'money' => array('not_null','int'),
'etc' => '...'
);
A function to validate would be
function validateForm($values, $valid) {
// error array to be returned
$error = array();
// let's iterate over each value, remember we defaulted the $_POST array with
// all the fields it can have, so all fields should be iterated apon.
foreach($values as $key => $value) {
if(array_key_exist($key, $valid)) {
// logic content can be used by different functions, switch
// used here for simplicity
foreach($valid[$key] as $validation) {
switch($validation) {
case 'not_null':
if(is_null($value)) {
$error[] = "error logic";
continue; // skip rest
}
break;
case 'etc':
$error[] = "..";
break;
}
}
}
}
return $error ? $error : true; // true being valid
}
The error handling can be done in a lot of ways, just one simple example (depends on how extensive this project is going to be), you could bind the error content to the validation key, e.g.
$vfe = $valid_form_errors = array( // $vfe for simlicity's sake
'__no_error' => 'no error present for "%key%" validation',
'not_null' => '%key% should not be null',
'int' => '%key% expects to be an integer'
);
$valid_form = array(
'submitButton' => array('not_null'),
'money' => array('not_null','int'),
'etc' => '...'
);
A function to create a formal error message
function error_msg($key, $validation) {
global $vfe;
// error exists?
$eE = array_key_exists($validation,$vfe);
return str_replace('%key%', $eE?$key:$validation, $vfe[$eE?$validation:'__no_error']);
}
And in the simple switch, the error logic is
foreach($valid[$key] as $validation) {
switch($validation) {
case 'not_null':
if(is_null($value))
$error[] = error_msg($key, $validation);
break;
case 'etc':
$error[] = "..";
break;
}
}
So how would your code look like using a different logic?
// first stage ..
$form_valid = validateForm($_POST, $valid_form);
if ($form_valid === true) {
// second stage, same logic be applied as with validateForm, etc.
if($_POST['money'] <= $user['money']) {
$query = mysql_query("SELECT * FROM someTable WHERE id={$user['id']}");
if($result = mysql_fetch_array($query)) {
// third stage, same logic can be applied here..
if ($someOtherCheck == $user['someOtherData']) {
} else {
echo "This isn't right.";
}
} else {
echo "You don't have a row in some table!";
}
}
else {
$errors = $form_valid;
// error handling here
print_r($errors);
}
It all comes to how specific you can define values being expected. You can extend every function to more specific, like binding the errors to a form key so you can specifically target that input at a later stage. They key thing is to erase all possible duplication where a function might do all this for you by simply asking him to compare values you expect, and let him tell which value there actually are.
I wonder what would be the professional way to handle insert/delete requests of a website?
Right now, what I have is I inserted two <input type = "hidden"/> on each form where one hidden's value correspond to a function it needs and the other is the parameter of this function. So when the form submits, I have a post.php file that handles ALL insert/delete requests that simply invokes the value of the hiddens via call_user_func() in PHP. Like so:
<input name = "arg" value = "{$id}" type = "hidden"/>
<input name = "call" value = "delete_member" type = "hidden"/>
call_user_func($_POST['call'], $_POST['arg']);
I'm having doubts on how sensible this solution is because I found out that the hiddens aren't actually hidden in the source on the client-side.
My first solution was to basically have a lot of conditionals checking for which function to invoke but I really hated that a lot so I changed it with this solution.
I wonder what are the better ways I can do this, or maybe how the professionals do it? Handling insert/delete queries.
I would consider this a very bad way to call actions from the client side.
For one this data is put into the HTML which will always be viewable and editable by the client. As such this means you cannot trust the data you receive from the client and as such you cannot trust the function they are calling.
Another point to re-inforce my previous idea. You say you run validation to make sure it is a function and all that, but you have a problem. Closures return true on these functions (since they are functions and methods and they exist). So a user can put a anon function as the value of your hiden field and actually run whatever they want on your server.
As others say I would recommend looking into MVC. Look into how Yii/CodeIgniter/Zend/Lithium/Kohana/etc do this and how they route.
An example of how routing for actions such as deletion is done by my favourite framework, Yii:
class UserController extends CController{
public function actionDelete($id = null){
if($id===null){ return false; }
}
}
Then the form/link calls /user/delete?id=2 which makes index.php route to the userController and use the actionDelete function inside the user controller, running it's code. Of course this is a very simplified version and it gets a lot more complex to stop vulnerabilities.
You may also wish to look into CSRF validation.
The most common way is to just call a function that takes care of one form at the time like this example for submitting a blog message:
blog.php
if(isset($_POST['submit'])) {
save_message();
} else {
display_form();
}
function display_form()
{
?>
<form action="blog.php"> etc etc....
<?php
}
function save_message()
{
//security checks and inserts etc
$_SESSION['message'] = 'Form saved succesfully';
header('location: blog_overview.php');
}
This is according to me a practish, but you might want to checkout frameworks like Codeigniter and Kohana since the above code is functional (and to me outdated). Read some tutorials about OOP (Object Oriented Programming) and MVC (Model View Controller). It might seem alot of work, but if you really want it to do it right it is worth the time and effort.
I have been doing some reading about many different things lately to improve my coding quality.
I am wondering if it is a good practice to post form to the same page often I used this type of snippet in my current applications.
public function addAction(){
$form = new Application_Form_Add();
$this->view->form = $form;
if(!$this->_request->isPost() && $form->isValid($this->_request->getParams())){
$mapper = new Application_Model_ModelMapper();
$model = new Application_Model_Model($form->getValues());
if(!$mapper->save($model)){
$this->view->messages('an error occurred etc ... ');
return;
}
$this->_helper->redirector->gotoRoute(array('id' => $model->id), 'model_view');
}
}
so my add action presents the form on GET request and process it on POST request.
I came around this article of Matthew Weier O'Phinney, I think everyone can agree he is one of the PHP gurus of the moment. In his example, he make two differents action one to show the form, one to process it. So if the form doesn't validate he plays with $this->render to re render the form view.
Is it a bad practice to submit form to same page and if yes why?
For the purpose of code readability and maintainability, two different controller actions - despite them associated with the same form - are better separated as two functions/scripts.
Imagine what it would be like if all CRUD operations were combined in a single function/script. That will be messy.
I don't think it's bad.
No matter we do this with same page and different page.
Both ways are correct at their places.
using singe page is a sort and sweet way and using 2 pages gives our code a managed way.
In my opinion both are equall.
In my oppinion I prefer to use one action for it. This keeps all the stuff together. O'Phinney's controller could loo like this:
addAction (uses saveAction to save)
editAction (uses saveAction to save)
saveAction (does not render itself)
Having one method for all controller save/edit logic is the only reason (assumption!) to make it and extra action. Cool, keeps everything in one place. But: this required both, edit and add, to have exactly the same logic. As soon as there is any if/else like
public function saveAction()
{
if($action == 'edit)
{
// edit logic
} else if($action == 'add')
{
// add logic
}
}
to have a different logic depending on the action, this totally exploits the idea of one action. So if you know that the logic is always the same and is very unlikly to change, this is the way to save you lot's of coding work :).
On the other hand, if your add/edit logic are a bit different, I'd keep all logic together that belongs together:
addAction (prints form and saves on POST)
editAction (prints form and saves on POST)
This might look like code-duplication (and maybe is), but then, my edit/add actions have about 3-6 lines of code. But as soon as the logic of either changes, you really know the place.
So this is a personally oppinion, I'd stick with seperated actions as soon as stuff becomes more complex.
(As a note: to logic I'm refering to controller logic, all data-logic should be in the model anyway)
I have only recently started web programming and I am pretty much amazed that although I am using a validation library, I still get 20-30 lines of code for validation alone, not counting error messages and callback functions. I am using the Kohana MVC framework and I was wondering if there was any way I can shorten my validation codes. I tried to think of the following
putting validation codes in my model (which is quite had for a noob like me).
creating a really small library to validate entries(something that hooks to the validation class, thus allowing me to call the library for repetitive procedures like user registration, editing and stuff)
Or are there any better and more efficient ways?
I would highly recommend working on including the validation in the model. Once you are able to do one, any others you create will be much easier. Plus if you have multiple controllers trying to save that data, you will not need to recode the validation. The Kohana docs contain some examples for integrating the validation library and ORM, you should start there.
I use Zend_Validate with Zend_Forms for validation in which the validation code is in the forms init method. All I have to do is pass an array of validators for each element and than run ..
$form->isValid($data);
...outside of the form to validate the data.
The validation array is easily more than 30 lines because I seperate each array entry with a newline. But i guess you will have that if you defining fine grained validation rules for each element right.
And its really easy to define new Validators in Zend.
edit: i discovered a framework that extends the Zend Framework which allows domain objects to contain its own validation. Its called Xyster framework but I could not get it to work on the first try so I haven't tried after that.
Here's my strategy for dealing with validation code. I suppose by 'validation library', you mean those which just make sure an email is an email, telephone numbers are numerical, and are not business rules in nature.
The idea is to have each business rule code as a functor - if it is PHP, you can get by just using a string to define the function; for other languages, you may have to use the strategy pattern. Define an interface for the functor (not necessary for PHP) and dump it into an array.
Run through the array which will return success, error and an error-code to a buffer. At the end, examine the error buffer and determine which validation has failed. Use it to customise the view.
Here's an example
$checkUniqueUserName = new CheckUniqueUserName();
$checkEmailNotUsed = new EmailNotUsed();
$validator = array();
$validator[$checkUniqueUserName->name()] = $checkUniqueUserName;
$validator[$checkEmailNotUsed->name()] = $checkEmailNotUsed;
$results = array();
foreach ($validator as $v)
{
$result[$v->getValidatorName()] = $v->execute($userInfo);
}
class CheckUniqueUserName()
{
public function execute($userInfo)
{
// SQL blah blah blah
if ($bNameUnique)
return array ('success' => 1)
else
return array ('success' => 0, 'error' => "$name is in used", 'error_code' => 'duplicate_name);
}
}
At the end, you will have a results array, each filled with a validation process, and you know which has failed, and which has not. This can then be passed to the client-side for further processing, like highlighting the failed fields. The error_code an be used to look up the proper error message and formatting applied to it.
I am not really sure about what you mean by call-backs though.