Analiza tu código automáticamente con PHPSTAN

En proyectos de WordPress, mantener un código limpio y libre de errores es fundamental para garantizar la calidad, la seguridad y la escalabilidad. Herramientas como PHPStan (análisis estático) y PHPLint (validación de sintaxis) se integran fácilmente en tus procesos de testing automatizado, ayudándote a detectar problemas antes de que lleguen a producción.

En esta entrada aprenderás cómo añadir ambas herramientas en tu flujo de tests para WordPress paso a paso.


¿Por qué usar PHPStan?

  • PHPStan: analiza tu código sin ejecutarlo, detectando errores de tipos, llamadas a métodos inexistentes y malas prácticas.
  • Ambas herramientas mejoran la calidad del código y facilitan la colaboración en equipos de desarrollo WordPress.

Instalación con Composer

Asegúrate de tener instalado Composer en tu entorno de desarrollo. Luego añade las dependencias:

composer require --dev phpstan/phpstan wp-coding-standards/wpcs szepeviktor/phpstan-wordpress phpstan/extension-installer

Esto instalará ambas herramientas dentro de tu carpeta vendor/.


Configuración de PHPStan

  1. Crea el archivo phpstan.neon.dist en la raíz del proyecto (incluye WooCommerce):
parameters:
    level: 1
    paths:
        - includes
    bootstrapFiles:
        - tests/phpstan-bootstrap.php
    excludePaths:
        - vendor/
        - node_modules (?)

Ejemplo phpstan

<?php
/**
 * PHPStan Bootstrap File
 * 
 * This file defines constants and functions that PHPStan needs to understand
 * but are not available during static analysis.
 */

// Define plugin constants that are used throughout the codebase
if (!defined('CONHOLD_PLUGIN_URL')) {
    define('CONHOLD_PLUGIN_URL', 'http://localhost/wp-content/plugins/connect-ecommerce/');
}

if (!defined('CONHOLD_VERSION')) {
    define('CONHOLD_VERSION', '1.0.0');
}

if (!defined('CONHOLD_FILE')) {
    define('CONHOLD_FILE', __FILE__);
}

// Define WordPress constants that might be missing
if (!defined('DOING_AJAX')) {
    define('DOING_AJAX', false);
}

if (!defined('WP_DEBUG')) {
    define('WP_DEBUG', false);
}

if (!defined('ABSPATH')) {
    define('ABSPATH', '/path/to/wordpress/');
}

// Mock WordPress functions that PHPStan can't find
if (!function_exists('wp_doing_ajax')) {
    function wp_doing_ajax() {
        return defined('DOING_AJAX') && DOING_AJAX;
    }
}

if (!function_exists('CONHOLD_get_options')) {
    function CONHOLD_get_options() {
        return [];
    }
}


// Mock Action Scheduler function
if (!function_exists('as_schedule_recurring_action')) {
    function as_schedule_recurring_action($timestamp, $interval_in_seconds, $hook, $args = [], $group = '') {
        return true;
    }
}

// Mock WP_CLI class
if (!class_exists('WP_CLI')) {
	class WP_CLI {
			public static function line($message) {
					echo $message . "\n";
			}
			public static function add_command($command, $class) {
					return true;
			}
	}
}

Configura composer.json:

"scripts": {
	"format": "phpcbf --standard=phpcs.xml.dist",
	"lint": "phpcs --standard=phpcs.xml.dist",
	"phpstan": "phpstan analyse --memory-limit=2048M"
}
  1. Ejecuta el análisis:
composer phpstan

Configuración con WooCommerce

composer require --dev php-stubs/wordpress-stubs php-stubs/woocommerce-stubs

Y añadir el include en el archivo de configuración

parameters:
    bootstrapFiles:
        - vendor/php-stubs/wordpress-stubs/wordpress-stubs.php
        - vendor/php-stubs/woocommerce-stubs/woocommerce-stubs.php
        #- vendor/php-stubs/woocommerce-stubs/woocommerce-packages-stubs.php

Configuración de PHPLint

  1. Crea un archivo .phplint.yml:
path: .
jobs: 10
extensions:
  - php
  1. Ejecuta el análisis:
vendor/bin/phplint

Integración con PHPUnit y GitHub Actions

Puedes añadir ambos chequeos en tus pipelines de CI/CD para que cada commit o pull request pase por estas validaciones.

Y añadir el archivo con tus propias reglas de Coding Standards:

<?xml version="1.0"?>
<ruleset name="Coding Standards for Internal Scanner Tool">
	<description>Description of Plugin.</description>

	<exclude-pattern>*/vendor/*</exclude-pattern>
	<exclude-pattern>reports/*</exclude-pattern>
	<exclude-pattern>php/tests/*</exclude-pattern>
	<exclude-pattern>php/prt_phpunit/*</exclude-pattern>

	<arg value="ps"/>
	<arg name="extensions" value="php"/>

	<file>./plugin.php</file>
	<file>./includes</file>
	<file>./templates</file>

	<rule ref="WordPress">
		<exclude name="Universal.Arrays.DisallowShortArraySyntax"/>
		<exclude name="WordPress.DB" />
		<exclude name="WordPress.Files.FileName"/>
		<exclude name="WordPress.NamingConventions.ValidFunctionName" />
	</rule>

	<rule ref="WordPress.WP.I18n">
		<properties>
			<property name="text_domain" type="array" value="plugin-name" />
		</properties>
	</rule>

	<rule ref="WordPress.Utils.I18nTextDomainFixer">
		<properties>
			<property name="old_text_domain" type="array">
				<element value="" />
			</property>
			<property name="new_text_domain" value="plugin-name" />
		</properties>
	</rule>
</ruleset>

De este modo, al ejecutar composer format o composer lint, se correrán PHPUnit, PHPStan y PHPLint juntos.

Añadir en .github/workflows/php-lint.yml

name: PHP Code Linting

on:
  push:
    branches:
      - trunk
      - 'release/**'
    # Only run if PHP-related files changed.
    paths:
      - '.github/workflows/php-lint.yml'
      - '**.php'
      - 'phpcs.xml.dist'
      - 'composer.json'
      - 'composer.lock'
  pull_request:
    branches:
      - trunk
      - 'release/**'
      - 'feature/**'
    # Only run if PHP-related files changed.
    paths:
      - '.github/workflows/php-lint.yml'
      - '**.php'
      - 'phpcs.xml.dist'
      - 'composer.json'
      - 'composer.lock'
    types:
      - opened
      - reopened
      - synchronize

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/trunk' }}
jobs:
  php-lint:
    name: PHP
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v4

      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.0'

      - name: Validate Composer configuration
        run: composer validate

      - name: Install PHP dependencies
        uses: ramsey/composer-install@a2636af0004d1c0499ffca16ac0b4cc94df70565
        with:
          composer-options: '--prefer-dist'

      - name: PHP Lint
        run: composer lint

      - name: PHP PHPStan
        run: composer phpstan

Conclusión

Integrar PHPStan y PHPLint en tus TESTs de WordPress es una manera sencilla de elevar la calidad del desarrollo, detectar errores de forma temprana y mejorar la robustez de tus plugins y temas.

Si quieres llevar tu proyecto al siguiente nivel, empieza por añadir estas herramientas en tu flujo de trabajo. 🚀👉 ¿Quieres que te prepare este artículo en formato markdown completo y listo para publicar en WordPress (con encabezados h2, h3, bloques de código y enlaces a las herramientas), o prefieres que lo deje en texto plano para que lo adaptes tú?

Referencias:

Deja un comentario

ÚLTIMOS ARTÍCULOS

Cierre Ventana

Analiza tu código automáticamente con PHPSTAN

En proyectos de WordPress, mantener un código limpio y libre de errores es fundamental para garantizar la calidad,…

Cierre Ventana

Desarrolla y crea Test para que tus plugins no tengan errores

Este es el tutorial que vamos a tener en cuenta para la charla de la WordCamp Galicia 2025.…

Cierre Ventana

Un gran año en el equipo de plugins

En el Equipo de Plugins en WordPress ha sido un gran año, puedes ver los números en resumen…

Logo David
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.Para más información consulta nuestra <a href="/politica-privacidad/">Política de Privacidad</a>