database-setup via php

Saitama, Tokyo at Sunrise, by Christoph Burmeister (own photo )

Saitama, Tokyo at Sunrise, by Christoph Burmeister (own photo )

For bigger application, you basically need a database-backend. Sure, you could install it everytime via phpmyadmin-console, but wouldn’t it be nice to have the ability to install the backend via the frontend? Just let the user input username and password for the dbms and the name of the database to use and all should go automatically. Of course we add some input-validation.

So let’s get started with the index.php, that simply instantiates the SetupController:

<?php
// Because legacy php "errors" (warnings, notices) are not automatically converted to exceptions.
// On need an "errors-to-exceptions" error handler to get the exceptions thrown.
set_error_handler( create_function('$severity, $message, $filename, $lineno', 'throw new ErrorException($message, 0, $severity, $filename, $lineno);') );
include 'setupController.php';
new SetupController(); ?>

the setupController.php with some input-validation

<?php
include 'setupModel.php';
class SetupController{
   public function __construct(){  $errorStyles = $this->hideErrors();
      if (empty($_POST)){
         include 'inputView.php';
      } else {
         if (!$this->isInputValid($_POST, $errorStyles)){
            include 'inputView.php';
         } else {
            $setupModel = new SetupModel($_POST['username'], $_POST['password'],$_POST['database']);
            $result;
            try{
               $setupModel->execute();
               $result = "Congratulations, all is fine.";
            } catch (Exception $e) {
               $result = "Sorry, an error occured: ".$e->getMessage();
            } 
            include 'finishView.php';
         }
      }
   }

   private function hideErrors(){
      return array( 'database' => 'visibility:hidden', 'username' => 'visibility:hidden', 'password' => 'visibility:hidden' );
   }

   private function isInputValid($dataArray, &$errorStyles){
      $valid = true;
      if (strlen($dataArray['database']) == 0) {
         $valid = false; $errorStyles['database'] = 'color:red';
      } if (strlen($dataArray['username']) == 0) {
         $valid = false; $errorStyles['username'] = 'color:red';
      } if (strlen($dataArray['password']) == 0) {
         $valid = false; $errorStyles['password'] = 'color:red';
      } return $valid;
   }
}
?>

At first call, the request let the Controller route to the inputView.php:

<html>
   <body>
      <form action="index.php" method="POST">
         <table>
            <tr>
               <td>database:</td>
               <td><input type="text" name="database" value="<?php if (isset($_POST['database']))echo $_POST['database'] ?>"/></td>
               <td><span style="<?php echo $errorStyles['database'] ?>">verify your input</span></td>
            </tr>
            <tr>
               <td>username:</td>
               <td><input type="text" name="username" value="<?php if (isset($_POST['username']))echo $_POST['username'] ?>"/></td>
               <td><span style="<?php echo $errorStyles['username'] ?>">verify your input</span></td>
            </tr>
            <tr>
               <td>password:</td>
               <td><input type="password" name="password" value="<?php if (isset($_POST['password']))echo $_POST['password'] ?>"/></td>
               <td><span style="<?php echo $errorStyles['password'] ?>">verify your input</span></td>
            </tr>
            <tr>
               <td colspan="3" ><input type="submit" value="next" /></td>
            </tr>
         </table>
      </form>
   </body>
</html>

The finishView.php is just a view, showing the result to the user:

<?php echo $result; ?>

So the Controller uses the SetupModel as the inner business-logic of the application:

<?php 
class SetupModel{
   private $database;
   private $username;
   private $password;
   private $db_connection;

  function __construct($username, $password, $database){
     $this->username = $username;
     $this->password = $password;
     $this->database = $database;
  }

  public function execute(){
     try {
        $this->createConnection();
        $this->createTables();
        $this->insertBaseData();
     } catch (Exception $e) {
        throw new Exception ($e->getMessage());
     }
  }

/**
 * exceptions are not thrown by mysql-extension, but because of using a error-to-exception-handler, we can catch the fault 🙂
 */
 private function createConnection(){
    $this->db_connection = mysql_connect ('localhost', $this->username, $this->password);
    mysql_select_db ($this->database);
 }

 private function createTables(){
    //mysql_query("XXX");
 }

 private function insertBaseData(){
    //mysql_query("XXX");
 }
}
?>

Note the first lines in index.php where we „transform“ all the old-style-php-errors (that come with mysql-extensions) into exceptions. That results in an exception, that is thrown by mysql_connect(), if an error occures. I should remember this when working with old-style-errors and the new php5-exceptions.