Store Temperatures Water Bath

<?php

  error_reporting( -1 );
  ini_set( 'display_errors', 'On' );

  class Serial
  {
    private $fd;

    public function open( $port )
    {
      exec( 'mode ' . $port . ' baud=115200 data=8 stop=1 parity=n' );
      $this->fd = dio_open( $port, O_RDWR );
      return $this->fd;
    }

    public function close()
    {
      dio_close( $this->fd );
    }

    public function readline()
    {
      if( $this->fd )
      {
        $line = "";
        while( ($ch = dio_read( $this->fd, 1 )) != "\n" )
        {
          if( $ch != "\r" )
            $line .= $ch;
        }
        return $line;
      }
    }
  }

  class Temperature_Database
  {
    public $stmt;
    public $mysqli;

    public function __construct()
    {
      global $temperature;
      global $mean;
      global $std_dev;
      global $heater;
      global $integral;
      global $target;

      $db_name = "water_bath";

      //
      // This program can be called with optional arguments:
      //   --database=foo         the name of the database to use
      //   --new                  delete the old database first
      //

      $options = getopt( "", [ "database::", "new::" ] );

      $drop_it = FALSE;
      foreach( array_keys( $options ) as $key )
      {
        if( $key == "new" )
          $drop_it = TRUE;
        if( $key == "database" )
        {
          $db_name = $options[$key];
        }
      }

      print( "Using database $db_name\n" );

      //
      // Connect to the MySql server on localhost
      //
      $this->mysqli = new mysqli( 'localhost', 'root', '' )
        or die( 'Could not connect: ' . mysqli_error() );

      //
      // Optionally start a fresh database by dropping the old one
      //
      if( $drop_it )
      {
        print( "Droping database $db_name\n" );
        $this->mysqli->query( 'DROP DATABASE IF EXISTS ' . $db_name )
          or die( "Could not drop database $db_name: " . $this->mysqli->error  );
      }
        
      //
      // Create the database if it does not exist
      //
      $this->mysqli->query( 'CREATE DATABASE IF NOT EXISTS ' . $db_name )
        or die( "Could not create database $db_name: " . $this->mysqli->error  );

      //
      // Select the database
      //
      $this->mysqli->select_db( $db_name )
          or die( "Could not select database $db_name: " . $this->mysqli->error );

      if( $drop_it )
        $this->mysqli->query("DROP TABLE IF EXISTS temps");

      //
      // Create a table of data if this is a new database
      //
      $create_table = "CREATE TABLE IF NOT EXISTS temps ("
        . " id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,"
        . " temperature DOUBLE NOT NULL,"
        . " mean DOUBLE NOT NULL,"
        . " std_dev DOUBLE NOT NULL,"
        . " heater DOUBLE NOT NULL,"
        . " integral DOUBLE NOT NULL,"
        . " target DOUBLE NOT NULL,"
        . " reg_date TIMESTAMP )";

      $this->mysqli->query( $create_table )
        or die( 'Create table failed: ' . $this->mysqli->error );

      //
      // Prepare our insert query
      //
      $this->stmt = $this->mysqli->prepare(
        "INSERT INTO temps( temperature, mean, std_dev, heater, integral, target ) VALUES( ?, ?, ?, ?, ?, ? )" )
          or die( 'Prepare failed: ' . $this->mysqli->error );

      //
      // And bind it
      //
      $this->stmt->bind_param( "dddddd", $temperature, $mean, $std_dev, $heater, $integral, $target )
        or die( 'Bind_param failed: ' . $this->mysqli->error );
        
    }

    public function save_temp()
    {
      global $temperature;
      global $mean;
      global $std_dev;
      global $heater;
      global $integral;
      global $target;

      //
      // This will execute our previously prepared and bound insert query
      //
      $this->stmt->execute()
        or die( 'Insert failed: ' . $this->mysqli->error );

      print( $temperature . ", " . $mean . ", " . $std_dev . ", " . $heater . ", " . $integral . ", " . $target . PHP_EOL );
    }
  }

  $serial = new Serial();
  $db = new Temperature_Database();

  // if( $serial->open( "\\\\.\\COM8:" ) )
  if( $serial->open( "COM8:" ) )
  {
    for( ;; )
    {
      $data = $serial->readline();
      $pieces = explode( ",", $data );
      $temperature = $pieces[0];
      $mean = $pieces[1];
      $std_dev = $pieces[2];
      $heater = $pieces[3];
      $integral = $pieces[4];
      $target = $pieces[5];
      $db->save_temp();
    }
    $serial->close();
  } 
  else
    print( "Can't open COM8:" );
?>