Class: FileStore
- Package: saf.File
- Author: John Luxford <lux@simian.ca>
- Copyright: Copyright (C) 2001-2003, Simian Systems Inc.
- License: http://www.sitellite.org/index/license Simian Open Software License
- Version: 1.2, 2003-10-26, $Id: Store.php,v 1.3 2007/10/06 00:06:30 lux Exp $
- Access: public
FileStore implements a directory layout that allows for higher
performance filesystem access on very large document collections.
FileStore may optionally use a database table to maintain a list of
files in the repository, since an 'ls' command wouldn't be efficient.
However, the database table must be created beforehand in order to
be in sync with all of the files in the repository, since FileStore
will not synchronize existing files.
The schema for such a table is:
CREATE TABLE table_name (
filename char(255) not null unique primary key
);
To create a new FileStore table, copy this into the SQL Shell module,
change the name, and execute it. That's all there is to it.
New in 1.2:
- Added move() and copy() commands, for dealing with pre-existing files.
Usage Example
<?php
$fs = new FileStore ('cache');
$fname = 'some_file.txt';
$fdata = 'fake data...';
if (! $fs->exists ($fname)) {
if ($fs->write ($fname, $fdata)) {
// written
} else {
echo $fs->error; // failed
}
} else {
// file already exists, but we don't want to overwrite it
}
$fh = $fs->open ($fname);
if ($fh) {
// $fh is an ordinary file handler
$data = fread ($fh);
fclose ($fh);
}
if ($fs->remove ($fname)) {
// deleted
} else {
$fs->error; // delete failed
}
?>
Properties
$handle = ""
- Access: public
Contains the handle of the currently open directory.
$path = ''
- Access: public
The path to the root of the file store. Default
is empty.
$_ls = array ()
- Access: private
Contains the list of files retrived from the previous read_all()
method call.
$description = "Unknown Document Type"
- Access: public
The description of the file.
$icon = "pix/icons/unknown.gif"
- Access: public
An icon to help describe the file visually.
$type = "ascii"
- Access: public
Type can be either 'ascii', 'binary', or 'folder'. Sitellite
treats files differently depending on their type.
$name = ""
- Access: public
The file's name.
$extension = ""
- Access: public
The file's extension (ie. the extension of 'file.gif' is 'gif').
$absolute = ""
- Access: public
The absolute path to the file, including its name.
$filesize
- Access: public
The actual size of this file in bytes.
$size = ""
- Access: public
The size of the file in a formatted string.
$filemtime
- Access: public
The actual value returned by the filemtime() call on this file.
$last_modified = ""
- Access: public
The date and time the file was last modified, in a formatted string.
$gid
- Access: public
The group id of the file.
$uid
- Access: public
The user id of the file.
$perms
- Access: public
The octal permissions of the file.
$formatted_perms
- Access: public
The permissions of the file formatted by the formatPerms()
method.
$group = ''
- Access: public
The group name of the file. Not available if PHP is running
in safe_mode.
$owner = ''
- Access: public
The owner name of the file. Not available if PHP is running
in safe_mode.
$is_writeable = false
- Access: public
Determines whether or not this file is writeable by the
current script.
$is_dir = false
- Access: public
Determines whether or not this file is a directory.
$content = false
- Access: public
Stores the content of the file after a call to contents().
$depth = 2
- Access: public
The number of levels deep the directory structure
should be set. Defaults to 2, and past that is likely
very unnecessary. Consider: A depth of 2 creates 3844
directories and stores up to about 1.8 million files, and a
depth of 3 creates 238,328 directories and stores up to about
120 million files (theoretically).
$ignoreChars = 0
- Access: public
The number of characters to ignore at the beginning
of file names. Defaults to 0. This is useful when you have
a collection of files that all use the same naming prefix,
so that the files are still evenly distributed within the
file storage system.
$useMD5 = false
- Access: public
If the file names are all very similar, and
$ignoreChars won't solve this, then it may be useful
to set $useMD5 to true (defaults to false), which makes
FileStore take an MD5 string of the file name and stores
it as if it was named after the MD5 string. This
should produce a consistently random distribution of
files, but renders the file system unviewable (or at
least not easily interpreted) by other means.
$autoInit = false
- Access: public
$autoInit determines whether you want to create the
entire directory structure at once or to do so incrementally
as new files are stored. This comes down to whether you
care about the extra mkdir() calls on file creation, or
would rather call init() once at the beginning and have it
do its thing for 5-10 minutes. Defaults to false.
$dirMode = 0755
- Access: public
Sets the directory mode to use when calling mkdir()
within buildDirs() and initDir(). Default is 0755.
$writeMode = 'wb'
- Access: public
Sets the write mode to use in the put() method.
Default is 'wb'.
$readMode = 'rb'
- Access: public
Sets the write mode to use in the get() method.
Default is 'rb'.
$appendMode = 'ab'
- Access: public
Sets the write mode to use in the append() method.
Default is 'ab'.
$dbTable = false
- Access: public
If the $dbTable is set, FileStore will use the
specified database table to maintain a list of all of
the files in the repository, which can be retrieved
via the listAll() method. Note: The table must be created
prior to the storage repository containing any files,
as FileStore does not synchronize existing files. See
above for an example 'CREATE TABLE' SQL command.
$error
- Access: public
Contains the error message if one occurs within
FileStore.
Methods
FileStore ($path = '', $ignoreChars = 0)
- Access: public
Constructor method.
init ()
- Access: public
- Return: boolean
Initializes the storage location by ensuring that
the base directory exists and calls buildDirs() to ensure
that each level of directory is pre-created. This has
the benefit that $autoInit can be set to false, and
eliminates an extra mkdir() call or twoon the first request
to store a file, but has the drawback that the first time
it is called, it can take up to several minutes. init()
must be called manually if $autoInit is false.
buildDirs ($dir, $depth = 2)
- Access: public
- Return: boolean
Builds the recursive directory structure used by this
package, stopping at the depth specified (called usually by
init(), which uses the $depth property to determine this number).
The directory structure is a series of directories named 'a'
through 'z', 'A' through 'Z', and '0' through '9', defaulting
to two levels deep. At two levels this creates 3844 directories,
which if they each stored a maximum of 500 files, after which
point a degradation in filesystem performance would be noticed,
could potentially store about 1.8 million files. We recommend
against an increase in $depth, as one more level would bring
the number of directories to 238,328 (and the number of files
in theory to about 120 million, far larger than most web sites
should need).
initDir ($path, $dirs)
- Access: private
- Return: boolean
Initializes a single directory within the structure.
Used when the $autoInit property is set to true.
getPath ($file)
- Access: public
- Return: string
Gets the absolute path to the file requested.
exists ($file)
- Access: public
- Return: boolean
Determines whether a file exists within the storage
system or not.
open ($file, $mode)
- Access: public
- Return: file handler
Opens a file within the system for writing. Note
that this method does not synchronize a newly created file
with the $dbTable. For that, use the get() and remove()
methods.
get ($file, $length = false)
- Access: public
- Return: string
Reads from the specified file, either in entirety,
or to the specified length. Handles opening and closing
of the file automatically. Returns false on error.
put ($file, $data, $length = false)
- Access: public
- Return: integer
Writes to the specified file, either in entirety,
or to the specified length. Handles opening and closing
of the file automatically. Returns false on error, or
the number of bytes written on success.
append ($file, $data, $length = false)
- Access: public
- Return: integer
Writes to the end of the specified file. Can
be limited by the $length parameter. Handles opening and
closing of the file automatically. Returns false on error,
or the number of bytes written on success.
move ($file, $oldFile, $isUploaded = false)
- Access: public
- Return: boolean
Moves the specified $oldFile to the repository, under the name
provided in the $file parameter. If $isUploaded is true, then
it uses the move_uploaded_file() function instead of the
rename() function.
copy ($file, $oldFile)
- Access: public
- Return: boolean
Copies the specified $oldFile to the repository, under the name
provided in the $file parameter.
remove ($file)
- Access: public
- Return: boolean
Deletes a file from the storage system.
listAll ($prefix = '', $limit = 0, $offset = 0)
- Access: public
- Return: array
Searches for a list of files within the repository
database table, optionally beginning with the specified
prefix. Returns an array of objects each with one
property ($filename), or false on error. Also sets the
$error property with any database error message. An
optional $limit and $offset may be specified to allow
for the ability to page through the list of files.
countAll ($prefix = '')
- Access: public
- Return: integer
Returns the total number of documents in the
repository, as listed in the accompanying database
table. A $prefix is optional. Returns false and
sets $error on database error.
