Location: PHPKode > scripts > IPC Shared Memory > ipc-shared-memory/File.php
<?php
// +----------------------------------------------------------------------+
// | File based shared memory class for PHP5.                             |
// | Copyright (C) 2005 Craig Manley                                      |
// +----------------------------------------------------------------------+
// | This library is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU Lesser General Public License as       |
// | published by the Free Software Foundation; either version 2.1 of the |
// | License, or (at your option) any later version.                      |
// |                                                                      |
// | This library is distributed in the hope that it will be useful, but  |
// | WITHOUT ANY WARRANTY; without even the implied warranty of           |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU     |
// | Lesser General Public License for more details.                      |
// |                                                                      |
// | You should have received a copy of the GNU Lesser General Public     |
// | License along with this library; if not, write to the Free Software  |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  |
// | USA                                                                  |
// |                                                                      |
// | LGPL license URL: http://opensource.org/licenses/lgpl-license.php    |
// +----------------------------------------------------------------------+
// | Author: Craig Manley                                                 |
// +----------------------------------------------------------------------+
//
// $Id: File.php,v 1.2 2005/01/09 22:39:54 cmanley Exp $
//



/**
 * @author    Craig Manley
 * @copyright Copyright © 2005, Craig Manley. All rights reserved.
 * @package   IPC_SharedMem
 * @version   $Revision: 1.2 $
 */


/**
 * @ignore Require interface class.
 */
require_once(dirname(__FILE__) . '/../SharedMem.php');


/**
 * File based shared memory class.
 * Makes use of the regular file functions (fopen(), flock(), etc.) to use a file
 * for shared memory. This is great if you're using Linux or a similar operating
 * system that supports "tmpfs" and you have one of those available because it that
 * case this class will be using real RAM memory with regular file functions.
 *
 * This is how to configure tmpfs on a per user basis in Linux:
 * <pre>
 *  Get root to do this:
 *  mkdir /home/myname/tmpfs
 *  chown myname:mygroup /home/myname/tmpfs
 *  ... and place this in a script executed at boot time:
 *  mount -t tmpfs /mnt/tmpfs /home/myuser/tmpfs
 * </pre>
 *
 * @package  IPC_SharedMem
 * @see      http://www.php.net/manual/en/function.flock.php
 */
class IPC_SharedMem_File implements IPC_ISharedMem {

  // Private members
  private $file          = null;
  private $option_perms  = null;
  private $option_create = true;
  private $option_remove = false;
  private $handle        = null; // only set if in transaction mode.


  /**
   * Constructor.
   *
   * If the file with the name passed in the 1st parameter does not exist,
   * then it will be created automatically when needed.
   *
   * The following options can be set in the 2nd parameter:
   * <ul>
   *  <li>perms  - the octal shared memory permissions.</li>
   *  <li>create - boolean, create the shared memory if it does not exist, default true.</li>
   *  <li>remove - boolean, delete the shared memory when this object is destroyed, default false.</li>
   * </ul>
   *
   * @param string $file the name of the file to use as shared memory.
   * @param array $options associative array of options.
   * @return object
   */
  public function __construct($file, $options = null) {
    $this->file = $file;
    // Set options
    if (isset($options)) {
      if (isset($options['perms'])) {
        $this->option_perms = $options['perms'];
      }
      if (isset($options['create'])) {
        $this->option_create = $options['create'];
      }
      if (isset($options['remove'])) {
        $this->option_remove = $options['remove'];
      }
    }
    if (is_null($this->option_perms)) {
      $this->option_perms = 0666 & ~umask();
    }
  }


  /**
   * Destructor. Removes the shared memory file if the 'remove' option is true.
   */
  public function __destruct() {
    if (isset($this->handle)) {
      $this->transaction_finish();
    }
    if ($this->option_remove) {
      @unlink($this->file);
    }
  }


  /**
   * Opens the file and returns the file handle on success, else it throws an exception.
   *
   * @return resource
   */
  protected function _open() {
    $mode = $this->option_create ? 'a+' : 'r+';
    // r+ : Open for reading and writing; place the file pointer at the beginning of the file.
    // a+ : Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
    $file = $this->file;
    $mask = 0666 & ~$this->option_perms;
    $old_mask = umask($mask);
    $result = fopen($this->file, $mode);
    umask($old_mask);
    if (!$result) {
      throw new Exception("fopen(\"$file\", \"$mode\") failed.");
    }
    return $result;
  }


  /**
   * Opens the file and locks it exclusively so that you can safely read
   * and write to it in one blocking transaction.
   *
   * @return boolean
   */
  public function transaction_start() {
    if (!isset($this->handle)) {
      $this->handle = $this->_open();
      return flock($this->handle, LOCK_EX); // exclusive lock
    }
    return false;
  }


  /**
   * Releases the file lock and closes the file.
   *
   * @return boolean
   */
  public function transaction_finish() {
    if (isset($this->handle)) {
      $h = $this->handle;
      $this->handle = null;
      flock($h, LOCK_UN);
      return fclose($h);
    }
    return false;
  }


  /**
   * Returns all data from the shared memory.
   * If this is called while not in transaction mode, then a
   * read only transaction is automatically used within this call.
   *
   * @return string
   */
  public function fetch() {
    $h = null;
    if (isset($this->handle)) {
      $h = $this->handle;
    }
    else {
      $h = $this->_open();
      flock($h, LOCK_SH); // shared lock for reading
    }
    fseek($h,0);
    $result = '';
    while (!feof($h)) {
      $result .= fread($h, 8192);
    }
    if (is_null($this->handle)) {
      flock($h, LOCK_UN);
      fclose($h);
    }
    return $result;
  }


  /**
   * Writes the given string to the shared memory.
   * If this is called while not in transaction mode, then an
   * exclusive transaction is automatically used within this call.
   * Returns the number of bytes written.
   *
   * @param string $value
   * @return integer
   */
  public function store($value) {
    $h = null;
    if (isset($this->handle)) {
      $h = $this->handle;
    }
    else {
      $h = $this->_open();
      flock($h, LOCK_EX); // exclusive lock for writing
    }
    if ($this->option_create) { // mode == 'a+'
      ftruncate($h,0);
    }
    $result = fwrite($h, $value);
    if (is_null($this->handle)) {
      flock($h, LOCK_UN);
      fclose($h);
    }
  }

}


?>
Return current item: IPC Shared Memory