Skip to content

Instantly share code, notes, and snippets.

@pmjones
Last active December 19, 2015 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmjones/5877934 to your computer and use it in GitHub Desktop.
Save pmjones/5877934 to your computer and use it in GitHub Desktop.
Brain dead variation.

PSR-T: Transformation Of Logical Paths To File System Paths

This document describes an algorithm to transform a logical resource path to a file system path. Among other things, the algorithm allows transformation of class paths and other logical resource paths to file paths.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

  1. Definitions

Logical Separator: A single character to delimit logical segments; for example, a slash, backslash, colon, etc.

Logical Segment: A string delimited by logical separators.

Logical Path: A string composed of logical segments and logical separators.

Logical Path Prefix: A logical path prefix is any series of contiguous characters the beginning of a logical path. For example, given a logical separator of : and a logical path of Foo:Bar:Baz, the valid logical path prefixes are F, Fo, Foo, Foo:, ..., Foo:Bar:Baz.

Logical Path Suffix: Given a logical path and a logical path prefix, the logical path suffix is the remainder of the logical path after the logical path prefix. For example, given a logical separator of :, a logical path of Foo:Bar:Baz:Qux, and a logical path prefix of Foo:Bar:, then Baz:Qux is the logical path suffix.

File System Path Prefix: A file system path in the file system associated with a logical path prefix.

  1. Specification

Given a logical path, a logical path prefix, a logical separator, and a file system path prefix, implementations MUST transform the logical path into a path that MAY exist in the file system.

  • If the logical path prefix is not valid for the logical path, the implementation MUST return false.

  • The implementation MUST replace the logical path prefix in the logical path with the file system path prefix.

  • The implementation MUST replace logical path separators in the logical path suffix with directory separators.

  • The implementation MUST return the transformed string.

  1. Example Implementation

The example implementation MUST NOT be regarded as part of the specification; it is an example only. Implementations MAY contain additional features and MAY differ in how they are implemented.

<?php
/**
 * Example implementation.
 * 
 * Note that this is only an example, and is not a specification in itself.
 * 
 * @param string $logical_path The logical path to transform.
 * @param string $logical_prefix The logical prefix associated with $fs_prefix.
 * @param string $logical_sep The logical separator in the logical path.
 * @param string $fs_prefix The file system path prefix for the transformation.
 * @return string The logical path transformed into a file path.
 */
function transform(
    $logical_path,
    $logical_prefix,
    $logical_sep,
    $fs_prefix
) {
    // make sure prefixes match exactly
    $len = strlen($logical_prefix);
    if (substr($logical_path, 0, $len) !== $logical_prefix) {
        return false;
    }
    
    // get the part after the prefix and transform it
    $logical_suffix = substr($logical_path, $len);
    return $fs_prefix
         . str_replace($logical_sep, DIRECTORY_SEPARATOR, $logical_suffix);
}
?>

Appendix A: Expected Inputs From Resource Locators

The specification is intentionally very loose in what it accepts, and does not attempt to normalize inputs. The benefit is that the transformation rules can be applied to almost any situation. The drawback is that minor differences in inputs can result in very different file system paths.

In order to standardize expectations for the resulting file system paths, resource locators that call the implementation code should pass inputs as follows:

  • The logical path MUST begin with a logical separator.

  • The logical path prefix MUST begin with a logical separator.

  • The file system prefix MUST end with a directory separator.

N.b.: Trailing logical separators in the logical path and the logical path prefix are significant.

An example follows.

<?php
// Find resources using a ":" separator.  Trailing logical separators are
// significant:
// 
// - Foo:Bar:Baz will be transformed into a path *without* a trailing
//   directory separator.
// 
// - Foo:Bar:Baz: will be transformed into a path *with* a trailing
//   directory separator.
function locate_resource($resource_name, $resource_prefix, $fs_prefix)
{
    // force a leading logical separator on the logical path
    $resource_name = ':' . ltrim($resource_name, ':');
    
    // force a leading logical separator on the logical path prefix
    $resource_prefix = ':' . ltrim($resource_prefix, ':');
    
    // force a trailing directory separator on the file system path prefix
    $fs_prefix = rtrim($fs_prefix, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
    
    // transform the logical path to a file system path
    $path = transform($resource_name, $resource_prefix, ':', $fs_prefix);
    
    // is it readable from the file system?
    if (is_readable($path)) {
        // return the transformed path
        return $path;
    }
    
    // the resource is not readable from the file system
    return false;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment