Guía de Código
Evitar nombres complicados
Los nombres claros facilitan que los desarrolladores comprendan el código rápidamente. Un buen nombre debe describir su función y proporcionar contexto.
$currentDate = $moment->format('y-m-d');Usar notación CamelCase
Aplica la notación CamelCase para nombrar variables, clases, métodos y funciones.
$customerPhone = '1134971828';
public function calculateProductPrice(int $productId, int $quantity)
{
// lógica aquí
}Evitar la sentencia else y anidaciones profundas
Las sentencias else pueden complicar la lectura del código, especialmente si la condición if es extensa. Minimiza los niveles de anidación para mantener el código limpio y fácil de seguir.
if (!$product->hasStock()) {
return false;
}
// código...Declaración de tipos en parámetros y retornos
A partir de PHP 7, es posible definir tipos tanto para los parámetros como para los valores de retorno en funciones y métodos, lo que mejora la robustez del código.
function sum(int $val1, int $val2): int
{
return $val1 + $val2;
}Evitar valores mágicos
Los "valores mágicos" son constantes usadas directamente en el código, lo que puede generar duplicación y errores. Centraliza estos valores en constantes.
Mal:
class Payment
{
public function isPending()
{
if ($this->status === "pending")
{
// lógica aquí
}
}
}Bien:
class Payment
{
const STATUS_PENDING = 'pending';
public function isPending()
{
if ($this->status === self::STATUS_PENDING)
{
// lógica aquí
}
}
}Centralizar valores evita tener que modificarlos en múltiples lugares.
Validación de Datos
Centraliza la validación con Form Requests para mantener los controladores limpios.
Ejemplo de Form Request:
class StoreCompanyRequest extends FormRequest {
public function rules() {
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', Rule::unique('companies')],
];
}
}Uso en el controlador:
public function store(StoreCompanyRequest $request) {
Company::create($request->validated());
}Uso de Eloquent API Resources
Utiliza Eloquent API Resources para transformar y formatear las respuestas de los modelos:
return new CompanyResource($company);Definición del Resource:
/** @mixin Company */
class CompanyResource extends JsonResource {
public function toArray($request) {
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}Valores nulos y tipos de unión
Siempre que sea posible, usa la notación corta para tipos anulables en lugar de usar una unión con null.
Bien:
public ?string $variable;Mal:
public string | null $variable;Tipos de retorno void
Si un método no devuelve ningún valor, indica que retorna void para dejar clara la intención.
public function scopeArchived(Builder $query): void
{
$query->...
}Promoción de propiedades en el constructor
Si todas las propiedades pueden ser promovidas en el constructor, utiliza constructor property promotion y mantén cada propiedad en una línea separada para mejorar la legibilidad.
Bien:
class MyClass {
public function __construct(
protected string $firstArgument,
protected string $secondArgument,
) {}
}Mal:
class MyClass {
protected string $secondArgument;
public function __construct(protected string $firstArgument, string $secondArgument)
{
$this->secondArgument = $secondArgument;
}
}Configuración
- Los archivos de configuración deben usar kebab-case. Ejemplo:
pdf-generator.php. - Las claves de configuración deben seguir la notación snake_case.
// config/pdf-generator.php
return [
'chrome_path' => env('CHROME_PATH'),
];Evita el uso del helper env fuera de los archivos de configuración. Usa valores env dentro de archivos de configuración.
Bien:
// Añadiendo credenciales a `config/services.php`
return [
'ses' => [
'key' => env('SES_AWS_ACCESS_KEY_ID'),
'secret' => env('SES_AWS_SECRET_ACCESS_KEY'),
'region' => env('SES_AWS_DEFAULT_REGION', 'us-east-1'),
],
];Comandos Artisan
Los nombres de los comandos Artisan deben seguir la convención kebab-case.
Bien:
php artisan delete-old-recordsMal:
php artisan deleteOldRecordsLos comandos deben proporcionar feedback al usuario. El método handle debe al menos mostrar un comentario indicando que todo salió bien.
// en un Command
public function handle()
{
// realizar tarea
$this->comment('¡Todo bien!');
}Si el comando procesa ítems, proporciona salida en cada iteración para que se pueda rastrear el progreso, y al final ofrece un resumen.
public function handle()
{
$this->comment("Comenzando el procesamiento de ítems...");
$items->each(function(Item $item) {
$this->info("Procesando ítem id `{$item->id}`...");
$this->processItem($item);
});
$this->comment("Se procesaron {$items->count()} ítems.");
}Rutas API
Sigue estas convenciones al definir rutas para APIs:
- Usa la forma plural del nombre del recurso. Ejemplo:
errors. - Usa kebab-case para los nombres de recursos. Ejemplo:
error-occurrences. - Limita el anidamiento profundo para evitar complejidad innecesaria.
Mal:
/projects/1/errors/1/error-occurrences/1Bien:
/error-occurrences/1En ciertos casos, el anidamiento es necesario y proporciona un contexto útil, como cuando accedes a todas las ocurrencias de un error.
/errors/1/occurrencesForm Request
En los FormRequest no hace falta la función de authorize
public function authorize(): bool
{
return true;
}