title: Simple Factory Pattern Demo
body: <p>I am trying to create a simple factory pattern demo in PHP. I am not sure if my codes are the best practice. It seems that I have some duplicated codes but I am not sure how to improve it. Basically, I want to create 3 types of accounts (basic, premium and vip). Please advise. Thanks a lot.</p>
  
  <p>abstract class</p>
  
  <pre><code>abstract class User {
  
      function __construct() {
          $this-&gt;db= new Database('mysql','localhost','mvcdb','root','');
      }
  
      abstract function checkUser();
  
      function showAccountCredit(){
          return $this-&gt;credits;
      }
      function getUserName(){
          return $this-&gt;username;
      }
  
  
  }
  </code></pre>
  
  <p>I have 3 different user account types:</p>
  
  <p>Basic Account</p>
  
  <pre><code>class BasicUser extends User {
  
      function __construct($username) {
          parent::__construct();
          $this-&gt;username=$username;
          $this-&gt;credit='10';
          $this-&gt;accountType='Basic Account';
  
          $data=$this-&gt;checkUser();
  
          if(!empty($data)){
              echo 'The username: '.$this-&gt;username.' already exists&lt;br&gt;';
              return false;
          }
  
          $array=array('username'=&gt;$this-&gt;username, 'password'=&gt;'password','credit'=&gt; $this-&gt;credit,'accountType'=&gt;$this-&gt;accountType);
          $this-&gt;db-&gt;insert('user',$array);
  
      }
  
  
       function checkUser(){
  
          $array=array(':username'=&gt;$this-&gt;username);
          $results=$this-&gt;db-&gt;select('SELECT * FROM USER WHERE username=:username',$array);
          if(!empty($results)){
          $this-&gt;credit=$results[0]['credit'];
          $this-&gt;accountType=$results[0]['accountType'];
          }
  
          return $results;
  
      }
  
      function showAccountCredit() {
          echo 'Username: '.$this-&gt;username.'&lt;br&gt;';
          echo 'Account Credit: '.$this-&gt;credit.'&lt;br&gt;';
          echo 'Account Type: '.$this-&gt;accountType;
      }
  
  }
  </code></pre>
  
  <p>Premium Account</p>
  
  <pre><code>class PremiumUser extends User {
  
      function __construct($username) {
          parent::__construct();
          $this-&gt;username=$username;
          $this-&gt;credit='100';
          $this-&gt;accountType='Premium Account';
  
          $data=$this-&gt;checkUser();
  
          if(!empty($data)){
              echo 'The username: '.$this-&gt;username.' already exists&lt;br&gt;';
              return false;
          }
  
          $array=array('username'=&gt;$this-&gt;username, 'password'=&gt;'password','credit'=&gt; $this-                   &gt;credit,'accountType'=&gt;$this-&gt;accountType);
          $this-&gt;db-&gt;insert('user',$array);
  
      }
  
  
       function checkUser(){
  
          $array=array(':username'=&gt;$this-&gt;username);
          $results=$this-&gt;db-&gt;select('SELECT * FROM USER WHERE username=:username',$array);
          if(!empty($results)){
          $this-&gt;credit=$results[0]['credit'];
          $this-&gt;accountType=$results[0]['accountType'];
          }
  
          return $results;
  
      }
  
      function showAccountCredit() {
          echo 'Username: '.$this-&gt;username.'&lt;br&gt;';
          echo 'Account Credit: '.$this-&gt;credit.'&lt;br&gt;';
          echo 'Account Type: '.$this-&gt;accountType.'&lt;br&gt;';
      }
  
  }
  </code></pre>
  
  <p>VIP account:</p>
  
  <pre><code>class VipUser extends User {
  
      function __construct($username) {
          parent::__construct();
          $this-&gt;username=$username;
          $this-&gt;credit='1000';
          $this-&gt;accountType='VIP Account';
  
          $data=$this-&gt;checkUser();
  
          if(!empty($data)){
              echo 'The username: '.$this-&gt;username.' already exists&lt;br&gt;';
              return false;
          }
  
          $array=array('username'=&gt;$this-&gt;username, 'password'=&gt;'password','credit'=&gt; $this-&gt;credit,'accountType'=&gt;$this-&gt;accountType);
          $this-&gt;db-&gt;insert('user',$array);
  
      }
  
  
       function checkUser(){
  
          $array=array(':username'=&gt;$this-&gt;username);
          $results=$this-&gt;db-&gt;select('SELECT * FROM USER WHERE username=:username',$array);
          if(!empty($results)){
          $this-&gt;credit=$results[0]['credit'];
          $this-&gt;accountType=$results[0]['accountType'];
          }
  
          return $results;
  
      }
  
      function showAccountCredit() {
          echo 'Username: '.$this-&gt;username.'&lt;br&gt;';
          echo 'Account Credit: '.$this-&gt;credit.'&lt;br&gt;';
          echo 'Account Type: '.$this-&gt;accountType;
      }
  
  }
  </code></pre>
  
  <p>UserFactory class</p>
  
  <pre><code>class UserFactory {
  
      static function create($username,$accountType){
  
          $accountType = strtolower($accountType);
  
          switch($accountType){
          case 'basic': return new BasicUser($username);
          case 'premium':return new PremiumUser($username);
          case 'vip': return new VipUser($username);
          default :return new BasicUser($username);
          }
      }
  </code></pre>
  
  <p>index.php</p>
  
  <pre><code>$user1= UserFactory::create('Jerry', 'Vip');
  $user1-&gt;showAccountCredit();
  
  
  $user2= UserFactory::create('Bob', 'Basic');
  $user2-&gt;showAccountCredit();
  
  
  $user3= UserFactory::create('Betty', 'premium');
  $user3-&gt;showAccountCredit();
  </code></pre>