Estándar de codificación

Este documento describe las reglas y las recomendaciones para desarrollar Nette. Al contribuir código a Nette tiene que seguirlas. La forma más fácil de hacerlo es imitar el código existente. El objetivo es que todo el código parezca escrito por una sola persona.

El estándar de codificación de Nette se corresponde con PSR-12 Extended Coding Style con dos excepciones principales: usa tabuladores en lugar de espacios para la indentación y usa PascalCase para las constantes de clase.

Muchas de estas reglas las puede comprobar y corregir automáticamente la herramienta Nette Coding Standard, así que no tiene que revisarlas a mano.

Reglas generales

  • Cada archivo PHP tiene que contener declare(strict_types=1)
  • Para separar los métodos se usan dos líneas vacías, para mejorar la legibilidad
  • El motivo de usar el operador de silencio (@) tiene que estar documentado: @mkdir($dir); // @ - el directorio puede existir
  • Si se usa un operador de comparación con tipado débil (es decir, ==, !=, …), la intención tiene que estar documentada: // == para aceptar null
  • Puede escribir varias clases de excepción en un único archivo llamado exceptions.php, y varios enums en enums.php
  • En las interfaces no se indica la visibilidad de los métodos, porque siempre son públicos
  • Cada propiedad, valor de retorno y parámetro tiene que tener el tipo indicado. Al contrario, en las constantes finales nunca indicamos el tipo, porque es evidente
  • Para delimitar las cadenas hay que usar comillas simples, salvo cuando el propio literal contiene apóstrofos

Convenciones de nombres

Saltos de línea y llaves

El estándar de codificación de Nette se corresponde con PSR-12 (o PER Coding Style), pero lo precisa o lo modifica en algunos puntos:

  • Las funciones flecha se escriben sin espacio antes del paréntesis, es decir, fn($a) => $b
  • No hace falta una línea vacía entre los distintos tipos de sentencias de importación use
  • El tipo de retorno de una función o método y la llave de apertura están siempre en líneas separadas:
	public function find(
		string $dir,
		array $options,
	): array
	{
		// cuerpo del método
	}

La llave de apertura en una línea aparte es importante para separar visualmente la firma de la función o método de su cuerpo. Si la firma está en una línea, la separación es clara (imagen de la izquierda). Si está en varias líneas, en PSR la firma y el cuerpo se funden (en el centro), mientras que en el estándar de Nette siguen separados (a la derecha):

Bloques de documentación (phpDoc)

La regla principal: nunca duplique ninguna información de la firma, como el tipo de un parámetro o el tipo de retorno, sin aportar valor.

Bloque de documentación de la definición de una clase:

  • Empieza con una descripción de la clase
  • Le sigue una línea vacía
  • Le siguen las anotaciones @property (o @property-read, @property-write), una por línea. Sintaxis: anotación, espacio, tipo, espacio, $nombre
  • Le siguen las anotaciones @method, una por línea. Sintaxis: anotación, espacio, tipo de retorno, espacio, nombre(tipo $param, ...)
  • La anotación @author se omite. La autoría se conserva en el historial del código fuente
  • Se pueden usar las anotaciones @internal o @deprecated
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */

Un bloque de documentación de una propiedad que contiene solo la anotación @var debería estar en una sola línea:

/** @var string[] */
private array $name;

Bloque de documentación de la definición de un método:

  • Empieza con una descripción breve del método
  • Sin línea vacía
  • Anotaciones @param, una por línea
  • Anotación @return
  • Anotaciones @throws, una por línea
  • Se pueden usar las anotaciones @internal o @deprecated

A cada anotación le sigue un espacio, salvo a @param, a la que le siguen dos espacios para mejorar la legibilidad.

/**
 * Finds a file in directory.
 * @param  string[]  $options
 * @return string[]
 * @throws DirectoryNotFoundException
 */
public function find(string $dir, array $options): array

Funciones y constantes globales

Las funciones y las constantes globales se escriben sin barra invertida inicial, es decir, count($arr) y no \count($arr). En las funciones que PHP puede optimizar, añada use function al principio del archivo para que el compilador pueda traducirlas de forma más eficiente. Entre ellas están funciones como count, strlen, is_array, is_string, is_scalar, sprintf, etc. Las funciones se listan en una sola línea para mantener compacto el bloque de importaciones:

use Nette;
use function count, is_array, is_scalar, sprintf;

De vez en cuando importamos también constantes cuyo valor conocido puede ayudar al compilador:

use const PHP_OS_FAMILY;

Tabuladores en lugar de espacios

Los tabuladores tienen varias ventajas sobre los espacios:

  • El tamaño de la indentación se puede ajustar en los editores y en la web
  • No imponen al código la preferencia de tamaño de indentación del usuario, lo que hace el código más portable
  • Se pueden escribir con una sola pulsación (en cualquier sitio, no solo en los editores que convierten los tabuladores en espacios)
  • La indentación es su razón de ser
  • Respetan las necesidades de los colegas con discapacidad visual y ciegos

Al usar tabuladores en nuestros proyectos permitimos ajustar el ancho, algo que a la mayoría de la gente puede parecerle innecesario, pero que es esencial para las personas con discapacidad visual.

Para los programadores ciegos que usan líneas braille, cada espacio representa una celda braille. Así que si la indentación predeterminada es de 4 espacios, una indentación de tercer nivel desperdicia 12 valiosas celdas braille antes incluso de que empiece el código. En una línea de 40 celdas, la más habitual en los portátiles, eso es más de una cuarta parte de las celdas disponibles desperdiciadas sin aportar ninguna información.