Home arrow MySQL arrow Creating User Models in PHP and MySQL

Creating User Models in PHP and MySQL

In this fourth part of a programming tutorial series, you will learn how to create a user model in PHP and MySQL using segregated interfaces.

TABLE OF CONTENTS:
  1. Creating User Models in PHP and MySQL
  2. Building MySQL Abstraction Classes
  3. Building the User Model
By: Alejandro Gervasio
Rating: starstarstarstarstar / 1
June 21, 2011

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

While the name "segregated interface" may sound like a difficult to grasp concept, and while it is closely related to the most complex facets of object-oriented programming, the truth is that a segregated interface is nothing but a regular interface, which defines a contract that provides its implementers with the exact functionality that they require to perform a set of specific tasks. 

These elements play a great role in the definition of classes that have a narrowed, well-defined range of responsibilities, even when using a weakly-typed language such as PHP. Add to this the benefits of dependency injection, and you’ll start seeing segregated interfaces as a blessing, rather than a waste of time (and code).

In previous parts of this series I developed a couple of basic – yet functional - libraries which made use of some segregated interfaces to easily switch over different implementations at runtime (also known as Polymorphism). If you missed those parts or need a refresher, you can find them here:

The usage of segregated interfaces isn’t limited to creating a few standalone libraries; you can also use them to develop a model class, which perform typical CRUD operations in a MySQL table containing data, as I will be demonstrating in this article. 

Before you move on and begin reading, a word of warning is in order here: to keep the whole example short and easy to follow, the model will be closely tied to the underlying storage (a MySQL database). In fact, I’m not a big fan of this approach, so if you want to create a clean domain model, the example can be easily amended by delegating the CRUD methods to a simple data mapper.

Caching model data: a quick look at the previous cache back-ends

Since I want to provide this sample user model with the ability to cache data that has been previously collected through its finders, I’m going to use a slightly modified version of the cache back-ends developed in the preceding tutorial.

As you may recall, these back-ends implemented a segregated interface called “CacheableInterface”, whose modified definition now looks like this:

(CacheableInterface.php)

<?php

interface CacheableInterface
{
    public function set($key, $data);
   
    public function get($key);
   
    public function delete($key);
   
    public function exists($key);
   
    public function clear();    
}


As you can see, the only difference between the old version of the above interface and this enhanced one is that it now declares a new “clear()” method, which will be implemented by the back-ends for clearing their respective caches.

Having said that, here’re the first class that implements the interface in question:

(ApcCache.php)

<?php

class ApcCache implements CacheableInterface
{
    /**
     * Save data to the cache
     */
    public function set($key, $data)
    {
        if (!apc_store(strtolower($key), $data)) {
            throw new ApcCacheException('Error saving data with the key ' . $key . ' to the APC cache.');
        }
        return $this;
    }
   
    /**
     * Get the specified data from the cache
     */
    public function get($key)
    {
        if ($this->exists($key)) {
            if (!$data = apc_fetch(strtolower($key))) {
                throw new ApcCacheException('Error fetching data with the key ' . $key . ' from the APC cache.');
            }
            return $data;
        }
        return null;
    }
   
    /**
     * Delete the specified data from the cache
     */
    public function delete($key)
    {
        if ($this->exists($key)) {
            if (!apc_delete(strtolower($key))) {
                throw new ApcCacheException('Error deleting data with the key ' . $key . ' from the APC cache.');
            }
            return true;
        }
        return false;
    }
   
    /**
     * Check if the specified cache key exists
     */
    public function exists($key)
    {
        return (boolean) apc_exists(strtolower($key));
    }
   
    /**
     * Clear the cache
     */
    public function clear($cacheType = 'user')
    {
        return apc_clear_cache($cacheType);
    }       
}




(ApcCacheException.php)

<?php

class ApcCacheException extends Exception{}


Considering that the “ApcCache” class was already discussed in depth, I’m not going to waste your valuable time explaining what it does. So, move on and look at second cache back-end, which caches data using the file system. Here it is:

(FileCache.php)

<?php

class FileCache implements CacheableInterface
{
    protected $_cacheDir = 'cache';
   
    /**
     * Constructor
     */
    public function __construct($cacheDir = '')
    {
        if ($cacheDir !== '') {
            if (!is_dir($cacheDir)) {
                throw new FileCacheException('The specified cache directory is invalid.');
            }
            $this->_cacheDir = $cacheDir;
        }
    }
   
    /**
     * Save data to the specified cache file
     */
    public function set($key, $data)
    {
        $cacheFile = $this->getCacheFile($key);
        if (!file_put_contents($cacheFile, serialize($data))) {
            throw new FileCacheException('Error saving data with the key ' . $key . ' to the cache file.');
        }
        return $this;
    }
   
    /**
     * Get data from the specified cache file
     */
    public function get($key)
    {
        if ($this->exists($key)) {
            $cacheFile = $this->getCacheFile($key);
            if (!$data = unserialize(file_get_contents($cacheFile))) {
                throw new FileCacheException('Error reading data with the key ' . $key . ' from the cache file.');
            }
            return $data;
        }
        return null;
    }
   
    /**
     * Delete the specified cache file
     */
    public function delete($key)
    {
        if ($this->exists($key)) {
            $cacheFile = $this->getCacheFile($key);
            if (!unlink($cacheFile)) {
                throw new FileCacheException('Error deleting the file cache with key ' . $key);
            }
            return true;
        }
        return false;
    }
   
    /**
     * Check if the specified cache file exists
     */
    public function exists($key)
    {
        $cacheFile = $this->getCacheFile($key);
        return file_exists($cacheFile);
    }
   
    /**
     * Remove all the cache files
     */
    public function clear()
    {
        $cacheFiles = $this->_cacheDir . DIRECTORY_SEPARATOR . '*.cache';
        array_map('unlink', glob($cacheFiles));
    }
     
    /**
     * Get the specified cache file
     */
    protected function getCacheFile($key)
    {
        return $this->_cacheDir . DIRECTORY_SEPARATOR . strtolower($key) . '.cache';
    }     
}



(FileCacheException.php)

<?php

class FileCacheException extends Exception{}

Again, the inner workings of the “FileCache” class should be pretty familiar to you, as this cache backend was also covered in detail in the previous installment of the series. However, it’s important to note that at this point I managed to create an extendable caching system, which will be used later on by the aforementioned user model.

But I’m getting ahead of myself, since it’s necessary to provide the model with the ability to access the underlying storage mechanism in the first place. Not surprisingly, this will be achieved via a simple MySQL abstraction class, which will make use of a segregated interface as well.    



 
 
>>> More MySQL Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

MYSQL ARTICLES

- Oracle Unveils MySQL 5.6
- MySQL Vulnerabilities Threaten Databases
- MySQL Cloud Options Expand with Google Cloud...
- MySQL 5.6 Prepped to Handle Demanding Web Use
- ScaleBase Service Virtualizes MySQL Databases
- Oracle Unveils MySQL Conversion Tools
- Akiban Opens Database Software for MySQL Use...
- Oracle Fixes MySQL Bug
- MySQL Databases Vulnerable to Password Hack
- MySQL: Overview of the ALTER TABLE Statement
- MySQL: How to Use the GRANT Statement
- MySQL: Creating, Listing, and Removing Datab...
- MySQL: Create, Show, and Describe Database T...
- MySQL Data and Table Types
- McAfee Releases Audit Plugin for MySQL Users

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: