PHP model for automatic SQL and form creation

After using Django and it’s hibernate-like Object-Relational Model (ORM) for a month or so, I decided to try how I could create a similar model mechanism using PHP. Here’s an example which I wanted to keep just under 100 lines for light reading. This example code demonstrates how to:

  • Easily create a structure with various types of fields (though currently it only supports CharField)
  • Generate SQL code for table creation
  • Generate a HTML form for editing the information

When you run the example, it will output the following (note the intentional error in the SQL statement syntax):

CREATE TABLE `person` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` VARCHAR(40),
`address` VARCHAR(40),
`phone` VARCHAR(15),
);

<form action=’.’ method=’POST’>
<table>
<tr><th>Name</th><td></td></tr>
<tr><th>Address</th><td></td></tr>
<tr><th>Phone</th><td></td></tr>
</table>
</form>

The code itself is here for you to use in any way you please, as long as you don’t hold me accountable for the results:

download code
run code



<?php

class Field
{
    var $size;
    var $label;
    var $editor;
    var $value;

    function __construct($size = 80, $label = '')
    {
        $this->size = $size;
        $this->label = $label;
    }
}

class CharField extends Field
{
    function __construct($size = 80, $label = '')
    {
        $this->editor = 'input type="text"';
        parent::__construct($size, $label);
    }

    function get_db_type()
    {
        return 'VARCHAR('.$this->size.')';
    }
}

class Model
{
    function get_name()
    {
        return get_class($this);
    }

    function make_create_sql()
    {
        $str = '';
        echo "nCREATE TABLE `",strtolower($this->get_name()),"` (n";
        echo "   `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,n";

        foreach ( get_class_vars($this->get_name()) as $x => $y)
        {
            echo '   `',$x,'` ',$this->$x->get_db_type(),",n";
        }

        echo ");nn";
    }

    function make_form()
    {
        foreach ( get_class_vars($this->get_name()) as $x => $y)
        {
            echo $this->$x->label,': <',$this->$x->editor,' name="',$x,"\">n";
        }
    }

    function make_form_table()
    {
        echo "  <table class=\"mytable\">n";
        foreach ( get_class_vars($this->get_name()) as $x => $y)
        {
            echo '    <tr><th>',$this->$x->label,'</th><td><',
                $this->$x->editor,' name="',$x,'" value="'.$this->$x->value.
                "\"></td></tr>n";
        }
        echo "  </table>n";
    }
}

class Person extends Model
{
    var $name, $address, $phone;

    function __construct()
    {
        $this->name = new CharField(40, 'Name');
        $this->address = new CharField(40, 'Address');
        $this->phone = new CharField(15, 'Phone');
    }
}

$j = new Person();

$j->name->value = "Erkki Tapola";

$j->make_create_sql();

echo "<form action='.' method='POST'>n";
$j->make_form_table();
echo "</form>n";

?>


You can easily add more field types according to the example CharField. Other features also available in Django, but this example doesn’t (yet) implement:

  • Query mechanisms to abstract SQL SELECT.
  • Persistence; save mechanisms to abstract UPDATE and INSERT.
  • Database table relation, fetch rows based on foreign keys and many-to-many relations

In addition, what I would like to see in Django:

  • Methods to update the current database schema with the added and modified field information. (Note: Check out Django-evolution, which is doing exactly this, and it even maintains a history of modifications.

Such a functionality would be safe for added columns and even column truncation and removal, as long as you indicate that this is actually your intent.

Leave a Reply

You must be logged in to post a comment.