Frantisek
Frantisek

Reputation: 7693

How to combine "add" and "edit" forms into 1 "script"?

I've always found myself creating two separate php files/scripts for adding a certain data and editing this data. These files weren't that much different, so I figured there should be a way how to make them into one file.

Here I'll present a very simple example to illustrate my point:

add.php:

<?php

$title = $_POST['title']; // ignore the unescaped data, this is a simple example
$text = $_POST['text'];
mysqli_query($connection,
   "INSERT INTO `articles` (`title`, `text`) VALUES ('$title', '$text')");

echo'
<form>
   <input type="text" name="title" value="'.$_POST['title'].'" />
   <input type="text" name="text" value="'.$_POST['text'].'" />
   <input type="submit" value="Add" />
</form>
';

?>

edit.php:

<?php

$id = $_GET['id'];
$title = $_POST['title']; // ignore the unescaped data, this is a simple example
$text = $_POST['text'];
// save data
mysqli_query($connection,
   "UPDATE `articles` SET `title` = '$title', `text` = '$text'
    WHERE `id` = $id");

// get current data
$q = mysqli_query($connection,"SELECT * FROM `articles` WHERE `id` = $id");
$d = mysqli_fetch_array($q);
$title = $d['title'];
$text = $d['text'];

echo'
<form>
   <input type="text" name="title" value="'.$title.'" />
   <input type="text" name="text" value="'.$text.'" />
   <input type="submit" value="Add" />
</form>
';

?>

As you can see, the add and edit forms/codes are very similar, except that:

Can these two somehow be merged into one file/code, so that if I want to add/change the form values, I don't need to edit two files separately, but will change the form only once?

Upvotes: 3

Views: 2501

Answers (4)

Satevis
Satevis

Reputation: 1348

You can use a INSERT ON DUPLICATE KEY UPDATE which roughly gave you :

<?php
$id = $_GET['id'];
$title = $text = '';

if ($_POST)
{
    $title = $_POST['title'];
    $text = $_POST['text'];
    // save data
    $query = "INSERT INTO `articles` (`id`, `title`, `text`)
              VALUES ('$id', '$title', '$text')
              ON DUPLICATE KEYS UPDATE title = title, text = text"
    mysqli_query($connection, $query);

}
else if ($id)
{
    // get current data
    $q = mysqli_query($connection, "SELECT * FROM `articles` WHERE `id` = $id");
    $d = mysqli_fetch_array($q);
    $title = $d['title'];
    $text = $d['text'];
}

echo '
<form>
   <input type="text" name="title" value="'.$title.'" />
   <input type="text" name="text" value="'.$text.'" />
   <input type="submit" value="Add" />
</form>';
  • If it's a POST and no $id present : a new row is inserted just like an INSERT.
  • If it's a POST and an $id is present : if $id already exist in the table than the row is updated otherwise it's an INSERT.
  • If you only have an $id : show the form with existing data in it.
  • If it's not a POST and $id isn't populated : show an empty form.

Upvotes: 3

Vyktor
Vyktor

Reputation: 21007

Here's an idea how it should look like using OOP (in my opinion).

Let's assume you have some class that represents form element called FormElement.

Then you have some generic form that should support what? Let's assume MVC:

  • displaying itself
  • adding elements
  • setting default values
  • parsing request values
  • getting values
  • validating values

So you'll build yourself an interface like

interface IForm {
    public function Display();
    public function AddElement( FormElement $element);
    public function SetValues( array);
    public function FetchPostValues();
    public function GetValues();
    public function Validate();
}

Then, what's common for both those forms (let's say that you want to prohibit change of email)? Everything except FetchPostValues()

So you'll build a class with one pure virtual method which will do everything that is similar:

abstract class FormArticle implements IForm {
    // All methods implemented except FetchPostValues
    abstract public function FetchPostValues();
}

And then just build two small classes that will define how to fetch post data:

class FormArticleEdit extends FormArticle {
    public function FetchPostValues(){
        if( isset( $_POST['email'])){
            throw new Exception('What are you trying to achieve?');
        }
        // ...
    }
}

And one more tip (two actually):

  • Implement abstract class like FormAbstract that will provide all generic methods like AddElement(), Display(). This will save you copying of those general methods every time, but will still provide you with ability to start from scratch (when using database or so directly to cache items).
  • Rather use framework that already has model for reusing forms (Zend is my personal favorite).

Upvotes: 0

I tend to make an interface for inserting and updating data which has only one method for inserting and updating. The key point for that to work is the user form that is being submitted must contain the id of the row being updated.

public method save( Object obj )
    if obj.id is in database
        query = "update table set attrA = obj.a, attrB = obj.b where id=obj.id" 
    else if obj.id < 1 
        query = "insert into table  (a,b,c) values (obj.a,obj.b,obj.c)"

This implies that when you create a new object to be submitted, it must have id initialized to 0 or -1 (1 is the first key row for a table with int primary keys). Likewise, a form in a html file must have an <input type=hidden value=row.id name=DBID> that is populated either with a default value (null, 0, -1) or a valid id of the object being edited.

Essentially this means that the user may update arbitrary rows in the table, but granted they have authenticated themselves, this should not be a problem. Also, it is usually enough to know that the id > 0 to to an INSERT, and UPDATE otherwise. It is not necessary to verify that the id being submitted is in the database table, because when you insert you do not set the id, but rather let the DB auto-increment the primary key.

update wow so many silly typos after only 3 beers. I hope this is readable

Upvotes: 1

Havelock
Havelock

Reputation: 6966

You could use a combination of GET and POST parameters do achieve what you want. Use the GET parameters to distinguish between edit and add, i.e. /post?action=add or /post?action=edit. Based on the value of $_GET['action'] you'd know whether to render an empty form to add a post or to populate the form in with data from the DB. Then you could have a hidden field in your form, which you'd fill in with the value of $_GET['action'] and so you'd be able to know whether to INSERT or UPDATE when processing the form after submitting it.

It might be worth though to start using some framework, i.e. CakePHP, CodeIgniter, Zend Framework, etc.

Upvotes: 1

Related Questions