Skip to content

Contributor's Guide

codeguy edited this page Feb 11, 2012 · 12 revisions

Contributor's Guide

Table of Contents

Read the License

Slim is licensed under the MIT License. You can read the license here.

Back to Top

Read the RoadMap

The GiHub Wiki contains the Slim Framework documentation and road map. Refer to the Road Map for a glimpse into Slim's short term and long term future. Road Map items in the near future will be added to the GitHub issue tracker.

Visit the GitHub Wiki

Back to Top

Report and work on issues in the Issue Tracker

The GitHub issue tracker is the place to submit Slim Framework issues or comment on existing issues. All feature requests should be posted to http://help.slimframework.com instead. If your feature suggestions are substantial, please post your proposal to http://help.slimframework.com before writing and submitting code.

Visit the GitHub Issue Tracker

Back to Top

Learn PHPUnit

Slim development is backed by PHPUnit tests. For your code to be accepted into the Slim master repository, it must be tested and covered by PHPUnit tests.

Learn more about PHPUnit

Back to Top

Learn PHPDoc

Slim development is also actively documented. I use PHPDocumentor for inline code documentation. For your code to be accepted into the Slim master repository, it must be well documented using PHPDoc comments. I intend for Slim to be very well documented so that anyone can open the source code and find a friendly, easy to read explanation for every class, method, and variable.

Learn more about PHPDocumentor

Back to Top

Slim Framework Organization

www/
    .htaccess
    index.php
    Slim/
    templates/

The beauty of Slim is that it does not make any assumptions. You are free to re-arrange the default directory configuration as you need. The only requirements are:

  1. The index.php and .htaccess files both reside in the same directory. This directory will be the Slim application's root directory, and it must exist beneath (or itself be) the document root directory.
  2. All Slim class files are contained in the same directory. This enables the Slim Framework class loader to find the necessary class files.

.htaccess

The .htaccess file must exist in the same directory as index.php. This directory can be the document root directory, or a sub-directory of the document root directory. The .htaccess file is responsible for implementing a Front Controller pattern, directing all HTTP requests to the index.php file.

index.php

The index.php file is where the magic happens. This file contains your Slim application's routes and callbacks.

Slim/

The Slim/ directory contains all of the Slim Framework class files. If you move this directory elsewhere on your filesystem, ensure you keep the contents of this directory together. Do not add files to or remove files from this directory.

templates/

Slim's default View class uses PHP templates that reside in this directory. If you use a custom View class (e.g. for Twig or Smarty), then you will likely need to specify the templates and cache directory in your custom View class definition.

NOTE: If you use third-party libraries or code, you can place these files in a `lib/` or `vendor/` directory as you see fit.

Back to Top

Contributing to Slim

If you are submitting code for inclusion in the Slim Framework master repository, ensure you follow these guidelines. Each of these guidelines is explained in more detail below.

  1. Your code follows the code documentation guidelines, and all classes, methods, and variables are well documented with PHPDoc comments.
  2. Your code follows the code testing guidelines, has been thoroughly tested, and is submitted with successful PHPUnit tests.
  3. Your code adheres to the code style guidelines.
  4. Your code does not include third-party libraries.

NOTE: The Slim Framework master repository will never include third-party libraries. I want to keep the core framework as small and light-weight as possible. If your submitted code relies on third-party dependencies, you may want to re-think your code or talk with me about what you are trying to accomplish.

Back to Top

Code Documentation Guidelines

The Slim Framework uses PHPDocumentor for inline code documentation. Your submitted code should include thorough inline documentation for all variables, methods, and classes. Align PHPDocumentor tag values for readability. Additional PHPDocumentor tags may be used when appropriate.

If you submit new code that is entirely your own, please attribute your code with your name and website URL (optional) using the PHPDocumentor @author tag.

Class Documentation

Each class should have inline documentation that provides the class name, the class description, the class author, the class package, and the current Slim Framework version at which your code was added.

/**
 * MyClass
 *
 * A brief description of the class.
 *
 * @package     Slim
 * @author      Your Name <Your URL>
 * @since       1.6.0
 */
class MyClass {

}

Method Documentation

Each method should have inline documentation that provides the method name, the method description, the method parameters, the method return value, and any Exceptions that may be thrown.

/**
 * Method Name
 *
 * A brief description of the method
 *
 * @author      Your Name <Your URL>
 * @param       string $paramName
 * @return      string
 * @throws      Exception
 */
public methodName( $paramName ) {

}

Variable Documentation

Each class variable should have inline documentation that provides the data type of the variable. You may also provide a brief description of the variable if the purpose of the variable is not immediately evident.

/**
 * This is a brief description of this variable
 * @var int
 */
public $counter;

Back to Top

Code Testing Guidelines

All code must be submitted with passing PHPUnit tests and 100% coverage. The tests/ directory mirrors the Slim/ directory per PHPUnit recommendations. If you are modifying an existing class, append your new unit tests to the appropriate existing test file. If your code contains new classes, create a new test file in the tests/ directory where appropriate. Assuming PHPUnit is installed in your PATH, an example PHPUnit test looks like this:

<?php
class MyTest extends PHPUnit_Framework_TestCase {
    public function setUp() {}
    public function tearDown() {}
    public function testCase() {}
}
?>

Refer to the official PHPUnit documentation for more details.

Back to Top

Code Style Guidelines

File Formatting

PHP Code Demarcation

PHP code must always be delimited by the full-form, standard PHP tags. Only use the opening tag and omit the closing tag. This avoids potential issues should inadvertent whitespace be added after the closing PHP tag.

<?php
//Your code here

Indentation

Your code should be indented using four (4) spaces. Do not use the TAB character.

Line Endings

Line endings must end only with a line feed LF, as is customary for UNIX text files.

  1. Do not use carriage returns CR like Macintosh computers.
  2. Do not use the carriage return/linefeed combination like Windows computers.
  3. Lines should not contain trailing spaces.

Naming Conventions

Classes

Class names may only contain alphanumeric characters. Numbers are allowed but discouraged. If a class name is composed of more than one word, the first letter of each new word must be capitalized. Successive capitalized characters are not allowed. Class files that belong to the Slim Framework core should be placed in the Slim/ directory.

Filenames

For all other non-class files, only alphanumeric characters, underscores, and the dash character ("-") are allowed. Spaces are not allowed.

Any file that contains PHP code must end with a ".php" file extension. If a file contains a PHP class definition, the file must be named the same as the class. For example, if a file contains a class definition for class Book, the file should be named Book.php.

Functions and Methods

Function names must contain only alphanumeric characters. Underscores are not permitted. Numbers are permitted in function names, but are discouraged.

Function names must always start with a lowercase letter. When a function name consists of more than one word, the first letter of each new word must be capitalized. This is commonly referred to as the "camelCase" method.

Verbosity is encouraged. Function names should illustrate the purpose of the function to enhance self-documentation and understanding.

Functions in the global-scope are not allowed. If you have a function in global scope, wrap this function in a class and make it static.

Functions or variables declared static in a class generally should not be private, but instead protected. Use final if a function should not be extended.

Optional Parameters

Use null as the default value instead of false for situations like this:

public function foo( $required, $optional = null )

Only do so when $optional does not have or need a particular default value. However, if an optional parameter is boolean, and its logical default value should be true or false, then using true or false as the default value is acceptable.

Variables

Variable names may contain only alphanumeric characters. Underscores are not allowed. Numbers are allowed but are discouraged.

Like function names, variable names must always start with a lowercase letter and follow the "camelCase" capitalization convention.

Verbosity is encouraged. Variable names should always be as verbose as practical. Terse or short names like $i or $n are discouraged for anything other than very small loop contexts. If a loop contains more than 20 lines of code (or thereabouts), variables for such indices or counters should have longer, more descriptive names.

Constants

Constants may contain both alphanumeric characters and the underscore. Numbers are permitted in constant names.

Constant names must always have all letters capitalized.

To enhance readability, words in constant names must be separated by underscore characters.

Constants must be declared as class members by using the word const construct. Defining constants in global scope with define is permitted but discouraged.

Booleans and NULL Values

The Slim Framework uses lowercase for both boolean values and the null value.

Coding Style

String Demarcation

When a string is literal (contains no variable substitutions), the apostrophe or "single quote" must always be used to demarcate the string:

$foo = 'This is a literal string with single quotes';

When a literal string itself contains apostrophes, it is permitted to demarcate the string with quotation marks or "double quotes". The is especially encouraged for SQL statements.

$foo = "SELECT `id`, `name` FROM `people` WHERE `name`='Fred'";

This syntax is preferred over escaping apostrophes. Variable substitution is allowed using either of these forms:

$greeting = "Hello $name";

$greeting = "Hello {$name}";

This form is not allowed:

$greeting = "Hello ${name}";

String Concatenation

Strings may be concatenated using the "." operator. A space must always be added before and after the "." operator to improve readability.

$foo = 'This is a' . 'concatenated string';

When concatenating strings with the "." operator, it is allowed to break the statement into multiple lines to improve readability. In these cases, each successive line should be padded with whitespace such that the "." operator is aligned beneath the "=" operator:

$foo = 'This is the first line'
     . 'and the second line'
     . 'and the third line';

Arrays (Numerically-Indexed)

Negative numbers are not allowed as array indices. An indexed array may be started with any non-negative number, however this is discouraged and it is recommended that all arrays have a base index of 0.

When declaring indexed arrays with the array construct, a trailing space must be added after each comma delimiter to improve readability:

$sample = array(1, 2, 3, 'four', 'five');

Arrays (Associative)

When declaring associative arrays with the array construct, and if the array contains many elements, it is encouraged to break the array into multiple lines. In this case, each key/value pair should be on the same line, prepended with four spaces like this:

$sample = array(
              'one' => 1,
              'two' => 2,
              'three' => 3
          );

Class Declarations

Classes must be named by these conventions:

  1. The brace is always written on the same line as the class name.
  2. Every class must have a documentation block that conforms to the phpDocumentor standard.
  3. Any code within a class must be indented the standard indent of four spaces
  4. Only one class is allowed per file
  5. Placing additional code in a class file is allowed but discouraged.

This is an example of an acceptable class definition:

/**
 * My Class
 *
 * This is a description of the class
 *
 * @package Slim
 * @author  Josh Lockhart <http://www.github.com/codeguy>
 * @since   1.6.0
 */
class MyClass {
    //contents of class indented by four spaces
}

Class Member Variables

Member variables must be named following the variable naming conventions. Any variable declared in a class must be listed at the top of the class, prior to defining any functions.

The var construct is not allowed. Member variables always declare their visibility by using one of private, protected, or public constructs. Accessing member variables directly by making them public is allowed but discouraged.

Function and Method Declaration

Functions and methods must be named following the function and method naming conventions. Methods must always declare their visibility using one of private, protected, or public constructs. Following the the more common usage in the PHP community, static methods should declare their visibility first:

public static foo() { ... }

As with classes, the opening brace for a function or method is always written on the same line as the function or method name. There is no space between the function or method name and the opening parenthesis for the arguments. There is one space between the function or method arguments' closing parenthesis and the opening brace. This is an acceptable class method definition:

class MyClass {
    /**
     * Method Name
     *
     * This is a description of the method
     *
     * @param   string $one
     * @param   string $two
     * @return  void
     */
    public static function foo( $one, $two = null ) {
        //method contents
    }
}

A method or function's return value must not be enclosed in parentheses. This can hinder readability and may also break code if a function or method is later changed to return by reference.

function foo() {
    //RIGHT
    return 'bar';

    //WRONG
    return('bar');
}

Method and function argument type hinting is encouraged. But please keep your use of type hinting or exception throwing consistent when validating argument types.

Function and Method Usage

Function arguments are separated by a single trailing space after the comma delimiter. This is an example of an acceptable function call for a function that takes three arguments:

threeArguments(1, 2, 3);

For functions whose arguments permit arrays, the function call may include the array construct and can be split into multiple lines to improve readability. In these cases, the standard for writing arrays still apply:

threeArguments(array(1, 2, 3), 2, 3);

threeArguments(array(
                    'one' => 1,
                    'two' => 2,
                    'three' => 3,
               ), 2, 3);

IF / ELSE / ELSEIF

Control statements based on the if / else / elseif constructs must have a single space before the opening parenthesis of the conditional, and a single space between the closing parenthesis and opening brace.

Within the conditional statements between the parentheses, operators must be separated by spaces for readability. Inner parentheses are encouraged to improve logical grouping of larger conditionals.

The opening brace is written on the same line as the conditional statement. The closing brace is always written on its own line. Any content within the braces must be indented by four spaces.

if ( $a !== 2 ) {
    $a = 2;
}

For if statements that include elseif or else, the formatting should be as is in these examples:

if ( $a !== 2 ) {
    $a = 2;
} else {
    $a = 7;
}

if ( $a !== 2 ) {
    $a = 2;
} else if ( $a === 3 ) {
    $a = 4;
} else {
    $a = 7;
}

PHP does allow for these statements to be written without braces in some cases. However, please always use braces for if, elseif, or else statements.

Use of the elseif construct is allowed but discouraged in favor of else if.

Switch

Control statements written with the switch construct must have a single space before the opening parenthesis of the conditional statement, and also a single space between the closing parenthesis and the opening brace.

All content with the switch statement must be indented by four spaces. Content under each case statement must be indented with an four spaces.

switch ( $num ) {
    case 1:
        break;
    case 2:
        break;
    case 3:
        break;
    default:
        break;
}

The construct default may never be omitted from a switch statement.

NOTE: It is sometimes useful to write a case statement which falls through to the next case by not including a break; or return;. To distinguish these cases from bugs, such case statements must contain the comment "//break intentionally omitted".

Errors and Exceptions

The Slim Framework codebase must be E_STRICT compliant. Slim Framework code should not emit PHP warning (E_WARNING, E_USER_WARNING), notice (E_NOTICE, E_USER_NOTICE), or strict (E_STRICT) messages when error_reporting is set to E_ALL | E_STRICT.

See http://www.php.net/errorfunc for information on E_STRICT.

Slim Framework code should not emit PHP errors, if it is reasonably possible. Instead, throw meaningful exceptions that are constructed using the new construct like this:

public function foo() {
    throw new InvalidArgumentException('A meaningful message');
}

Best Practices

  1. Use the most specific Exception subclass that best describes the exception. This better communicates to the user what happened.
  2. Avoid catching the Exception base class. If a try block might encounter more than one type of exception, write a separate catch block for each specific exception.
  3. Don't silently suppress exceptions and allow execution to continue in an erroneous state. If you catch an exception, either correct the condition or throw a new exception.

Back to Top