Register page for website I've been working on a simple forum website as a toy project, to start learning PHP and SQL. I've implemented all of the functionality I want, but I thought I'd run the code by the Code Review community to see how I could improve it.



&lt;?php
session_start();
class database{
 protected static $connection;
 protected $state=0; //0 is fine, 1 is connection error, 2 is query error

 public function connect(){
  if(isset(self::$connection)){
   return self::$connection;
  }
  else{
   self::$connection=new mysqli('localhost','root','','mydummydatabase');
   if(self::$connection===false){
    $this -&gt; state=1;
    return false;
   }
   return self::$connection;
  }
 }
 public function query($query){
  $connection=$this -&gt; connect();
  $result=$connection -&gt; query($query);
  if($result===false){
   $this -&gt; state=2;
  }
  return $result;
 }
 public function sanitise($input){
  $connection=$this -&gt; connect();
  return "'".$connection -&gt; real_escape_string($input)."'";
 }
 public function get_first_row($result){
  if($result){
   return $result -&gt; fetch_assoc();

  }
  else{
   return false;
  }
 }
 public function state(){
  return $this-&gt;state;
 }

}
$db=new database();
$_SESSION['email-exists-in-database']=false;
$_SESSION['something-weird-happened']=false;
if(isset($_POST['email'])){
 $firstname=$db-&gt;sanitise($_POST['firstname']);
 $lastname=$db-&gt;sanitise($_POST['lastname']);
 $email=$db-&gt;sanitise($_POST['email']);
 $hash=password_hash($_POST['password'],PASSWORD_DEFAULT);
 $result=$db -&gt; query("SELECT `user-id` FROM `users` WHERE email=".$email);
 $record=$db-&gt;get_first_row($result);
 if($record!=false){
  $_SESSION['email-exists-in-database']=true;

 }
 else{
  $db -&gt; query("INSERT INTO `users` (firstname,lastname,email,passwordhash) VALUES (".$firstname.",".$lastname.",".$email.",'".$hash."')");

  if(!($db-&gt;state())){
   $result=$db -&gt; query("SELECT `user-id` FROM `users` WHERE email=".$email);
   $record=$db-&gt;get_first_row($result);
   $_SESSION['id']=$record['user-id'];
   header('Location: welcome.php');
   exit;
  }
  else{
   $_SESSION['something-weird-happened']=true;

  }
 }
}
?&gt;
&lt;html&gt;
&lt;head&gt;
&lt;link rel="stylesheet" media="screen" href="styles2.css"/&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div  class="input-form"&gt;
&lt;img src="account-logo.png" id="account-logo"&gt;
&lt;form action="&lt;?php echo $_SERVER['PHP_SELF'];?&gt;" method="post"&gt;
&lt;input type="text" maxlength="30" name="firstname" placeholder="First name"class="sign-in-box" required/&gt;
&lt;input type="text" maxlength="60" name="lastname" placeholder="Last name"class="sign-in-box" required/&gt;
&lt;input type="email" maxlength="100" name="email" placeholder="Email"class="sign-in-box" required/&gt;
&lt;input type="password" maxlength="200" name="password" placeholder="Password"class="sign-in-box" required/&gt;

&lt;input type="submit" name="Submit" value="Sign up"class="submit-button"/&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;?php
if($_SESSION['email-exists-in-database']){
 echo("&lt;div class='error-message'&gt;We already have an account associated with that email.&lt;/div&gt;");
}
if($_SESSION['something-weird-happened']){
 echo("&lt;div class='error-message'&gt;Something went wrong, please try again.&lt;/div&gt;");
}?&gt;
&lt;/body&gt;
&lt;/html&gt;




This is the Register page for the website. Some issues I'm concerned about are security, and good practice.

Any thoughts?
About your HTML

DOCTYPE

You are missing a DOCTYPE. You probably want to use

&lt;!DOCTYPE html&gt;


title element

The title element is a required element (in the very most cases). It has to be added to the head:

&lt;head&gt;
  &lt;title&gt;Register …&lt;/title&gt;
&lt;/head&gt;


alt attribute

The alt attribute is required for img elements.

If you account-logo.png is just decoration, the alt value should be empty:

&lt;img src="account-logo.png" id="account-logo" alt=""&gt;


label elements and placeholder attributes

You shouldn’t use the placeholder attribute to "label" input elements. Add label elements instead. 

If you want to use the placeholder attribute, it should show an example of what should be entered, or a description of the expected format. See placeholder definition in HTML 5.1.

&lt;label for="email"&gt;Email&lt;/label&gt;
&lt;input type="email" maxlength="100" name="email" id="email" placeholder="alice@example.com" class="sign-in-box" required /&gt;


Usability: maxlength

Do you really want a max length here? 

Because there are certainly names longer than 30/60 chars, and email addresses longer than 100 chars. Those users would have to abbreviate their names or use a different email address.

strong for warnings

You could make use of the strong element for the warnings/errors.

A heading

Your page has no headings. You’ll probably add site-wide stuff (like a header, navigation etc.) that contains headings, but even your form (i.e., this page’s main content) should get a heading.

meta-charset

Not required if you provide it via HTTP headers, but it’s typically a good idea to provide a meta-charset element in the head (as first element), e.g. if you use UTF-8:

&lt;head&gt;
  &lt;meta charset="utf-8" /&gt;
  &lt;!-- 'title' and 'link' follow here --&gt;
&lt;/head&gt;