Community Documentation

Object-oriented code

Last updated November 8, 2011. Created by Crell on October 19, 2009.
Edited by jhodgdon, flortjes, dww, jrchamp. Log in to edit this page.

Drupal follows common PHP conventions for object-oriented code, and established industry best practices. As always, though, there are Drupal-specific considerations.

Naming conventions

  1. Classes and Interfaces should use UpperCamel naming.
  2. Methods and class properties should use lowerCamel naming.
  3. Classes should not use underscores in class names unless absolutely necessary to derive names inherited class names dynamically. That is quite rare, especially as Drupal does not mandate a class-file naming match.
  4. Interfaces should always have the suffix "Interface".
  5. Protected or private properties and methods should not use an underscore prefix. Although common in the PHP 4 era, it is discouraged in PHP 5-specific code.

Examples:

<?php
interface FelineInterface {

  public function
meow();

  public function
eatLasagna($amount);

}

class
GarfieldTheCat implements FelineInterface {

  protected
$lasagnaEaten = 0;

  public function
meow() {
    return
t('Meow!');
  }

  public function
eatLasagna($amount) {
   
$this->lasagnaEaten += $amount;
  }
}
?>

Use of interfaces

The use of a separate Interface definition from an implementing class is strongly encouraged. It encourages separation of concerns and allows more flexibility in extending code later. It also makes the documentation easier to read as the documentation is neatly centralized in the interface. All interfaces should be fully documented according to established documentation standards.

If there is even a remote possibility of a class being swapped out for another implementation at some point in the future, split the method definitions off into a formal Interface. A class that is intended to be extended must always provide an Interface that other classes can implement rather than forcing them to extend the base class.

Visibility

All methods and properties of classes must specify their visibility: public, protected, or private. The PHP 4-style "var" declaration must not be used.

The use of public properties is strongly discouraged, as it allows for unwanted side effects. It also exposes implementation specific details, which in turn makes swapping out a class for another implementation (one of the key reasons to use objects) much harder. Properties should be considered internal to a class.

The use of private methods or properties is strongly discouraged. Private properties and methods may not be accessed or overridden by child classes, which limits the ability of other developers to extend a class to suit their needs.

Type hinting

PHP supports optional type specification for function and method parameters for classes and arrays. Although called "type hinting" it does make a type required, as passing an object that does not conform to that type will result in a fatal error.

  • DO specify a type when conformity to a specific interface is an assumption made by the function or method. Specifying the required interface makes debugging easier as passing in a bad value will give a more useful error message.
  • DO NOT specify a type for a class. If specifying a type, always specify an Interface. That allows other developers to provide their own implementations if necessary without modifying existing code.

Example:

<?php
// Wrong:
function make_cat_speak(GarfieldTheCat $cat) {
  print
$cat->meow();
}

// Correct:
function make_cat_speak(FelineInterface $cat) {
  print
$cat->meow();
}
?>

Instantiation

Creating classes directly is discouraged. Instead, use a factory function that creates the appropriate object and returns it. This provides two benefits:

  1. It provides a layer of indirection, as the function may be written to return a different object (with the same interface) in different circumstances as appropriate.
  2. PHP does not allow class constructors to be chained, but does allow the return value from a function or method to be chained.

Chaining

PHP allows objects returned from functions and methods to be "chained", that is, a method on the returned object may be called immediately, like so:

<?php
// Unchained version
$result = db_query("SELECT title FROM {node} WHERE nid = :nid", array(':nid' => 42));
$title = $result->fetchField();

// Chained version
$title = db_query("SELECT title FROM {node} WHERE nid = :nid", array(':nid' => 42))->fetchField();
?>

As a general rule, a method should return $this, and thus be chainable, in any case where there is no other logical return value. Common examples are those methods that set some state or property on the object. It is better in those cases to return $this rather than TRUE/FALSE or NULL.

Comments

file name

What should be the name of the file which contains only one single class?
Lets say we have an interface "FelineInterface" should I put in into a file FelineInterface .inc or
somethin like that ?Is there any rule for that ?

--
Regards,
Robert

DO NOT specify a type for a

DO NOT specify a type for a class. If specifying a type, always specify an Interface.

This should be removed; Type hint is a step towards type-safe code: it's better to have a crash where the error is instead of experiencing all sorts of warnings and unexpected behavior multiple layers lower or upper: it makes errors being evident and easier to find. Type hinting, whatever it is with array, interfaces or class names is always a good idea and should be advised to use everywhere it can.
PHP is not type safe per essence, but we can use type hinting to make some critical portions of code to be closer to type safe: it is a really bad advice to discourage people from using type hinting in general.

That allows other developers to provide their own implementations if necessary without modifying existing code.

That is under the assumption the original code is meant to be extended: this is not always the case. Plus it doesn't prevent people from extending by inheritance. Letting people pass anything wrong is making the whole framework fragile and unstable. If you want the code to be flexible and extensible, you have to design it for: type hinting has nothing to do with flexibility.

Pierre Rineau