Guidelines

1. PHP

Für PHP-Projekte sollte für die Verwaltung von Paketabhängigkeiten Composer verwendet werden.
Der gesamte Quellcode mit den dazugehörigen assets etc. sollten im Unterverzeichnis src/ liegen!

Tests sollten im Unterverzeichnis tests/ liegen!
Als Testing-Framework sollte entweder PHPUnit (nur Unit-Tests) oder Codeception (auch andere Testarten) verwendet werden.

1.1. Composer Initialisierung

composer init # in einem neuen PHP Projekt

Alle Fragen, die im folgenden nicht mit aufgeführt sind, können auf die default-Einstellungen gelassen werden.

Package name: locr/project-name
Package type: library oder project
License: proprietary
Would you like to define your dependencies (require) interactively [yes]?: no
Would you like to define your dev dependencies (require-dev) interactively [yes]?: no

1.2. PHP_CodeSniffer

PHP_CodeSniffer ist dafür da, um Verletzungen des Coding-Standards zu erkennen und ggf. zu korrigieren.
Zur Installation muss folgendes Kommando ausgeführt werden.

composer require --dev squizlabs/php_codesniffer

Als Basis-Konfiguration sollte folgende ./phpcs.xml verwendet werden.

<?xml version="1.0"?>
<ruleset
    name="locr GmbH Standard"
    xmlns="http://pmd.sf.net/ruleset/1.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="https://pmd.sf.net/ruleset/1.0.0 https://pmd.sf.net/ruleset_xml_schema.xsd"
    xsi:noNamespaceSchemaLocation="https://pmd.sf.net/ruleset_xml_schema.xsd">
    <description>A custom coding standard for locr GmbH projects!</description>
    <arg value="p"/>
    <arg name="extensions" value="php"/>
    <arg name="colors"/>
    <rule ref="PSR2.ControlStructures.SwitchDeclaration"/>
    <rule ref="PSR12"/>
    <rule ref="Squiz.NamingConventions.ValidVariableName.NotCamelCaps"/>
</ruleset>

Um das Testen der Regeln einfacher aufrufen zu können, sollte folgende Zeile in die composer.json Datei eingefügt werden.

{
    // ...
    "scripts": {
        // ...
        "phpcs": "./vendor/bin/phpcs ./src"
    }
}

Jetzt kann man mit:

composer phpcs

die Coding-Standards überprüfen.

1.3. PHPStan

PHPStan (PHP Static Analysis Tool) ist ein statisches Analyse Tool, um potentielle Fehler im PHP Code zu finden.
Zur Installation muss folgendes Kommando ausgeführt werden.

composer require --dev phpstan/phpstan

Als Basis-Konfiguration sollte folgende ./phpstan-8.1.neon verwendet werden.

parameters:
    phpVersion: 80100
    level: 9
    bootstrapFiles:
        - vendor/autoload.php
    paths:
        - src

In einem bestehenden/älteren PHP-Projekt kann man das level erstmal bis auf 1 runtersetzen und nach und nach höher stellen.

Um PHPStan einfacher aufrufen zu können, sollten folgende Zeilen in die composer.json Datei eingefügt werden.

{
    // ...
    "scripts": {
        // ...
        "phpstan": "@phpstan-8.1",
        "phpstan-8.1": "./vendor/bin/phpstan --configuration=phpstan-8.1.neon"
    }
}

Jetzt kann man mit:

composer phpstan

den Code analysieren lassen.

1.4. PHPUnit

PHPUnit (The PHP Testing Framework) ist für Unit-Tests geeignet.
Zur Installation muss folgendes Kommando ausgeführt werden.

composer require --dev phpunit/phpunit

Als Basis-Konfiguration sollte folgende ./phpunit.xml verwendet werden.

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd"
  bootstrap="vendor/autoload.php"
  executionOrder="depends,defects"
  displayDetailsOnTestsThatTriggerDeprecations="true"
  displayDetailsOnTestsThatTriggerErrors="true"
  displayDetailsOnTestsThatTriggerNotices="true"
  displayDetailsOnTestsThatTriggerWarnings="true"
  cacheDirectory=".phpunit.cache"
  requireCoverageMetadata="true"
  beStrictAboutOutputDuringTests="true"
  beStrictAboutCoverageMetadata="true">
  <testsuites>
    <testsuite name="default">
      <directory>tests</directory>
    </testsuite>
  </testsuites>
  <coverage>
    <report>
      <clover outputFile="test-results/phpunit.clover.xml"/>
      <html outputDirectory="test-results/html"/>
    </report>
  </coverage>
  <source>
    <include>
      <directory suffix=".php">src</directory>
    </include>
  </source>
</phpunit>

Tests sollten unter dem Verzeichnis tests/ abgelegt werden.
Eine einfache ExampleTest.php-Datei könnte wie folgt aussehen:

<?php

declare(strict_types=1);

namespace UnitTests;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;

use Locr\Example;

#[CoversClass(Example::class)]
final class ExampleTest extends TestCase
{
    public function testExample(): void
    {
        $this->assertEquals('OK', Example::getHttpStatusMessage(200));
    }
}

Um PHPUnit einfacher aufrufen zu können, sollte folgende Zeile in die composer.json Datei eingefügt werden.

{
    // ...
    "scripts": {
        // ...
        "test": "./vendor/bin/phpunit"
    }
}

Jetzt kann man mit:

composer test

den Code testen.

1.5. Codeception

Codeception ist ein Testing-Framework mit dem man nicht nur Unit-Tests, sondern auch Integrations-, API-, und Akzeptanz-Tests durchführen kann.

Zur Installation und Einrichtung von Codeception, bitte die Codeception-Seite konsultieren, da das den Rahmen dieser Dokumentation sprengen würde.

1.6. Code-Dokumentation

Dokumenation im Codes selbst sollte möglichst sparsam eingesetzt werden und nur dort, wo es nötig ist, um Unklarheiten oder schwer verständliche Code-Abschnitte zu erklären.

Davon abgesehen, können Methoden von Klassen mit Beispielen dokumentiert werden, um deren Verwendung zu verdeutlichen.
Beispiel:

<?php

declare(strict_types=1);

namespace Locr;

class Example
{
    /**
     * Diese Methode gibt die zu einem Status-Code zugehörige Status-Message zurück. \
     * Falls es den Code nicht gibt, kommt: 'Invalid' zurück.
     *
     * ```php
     * use Locr\Example;
     *
     * $code = 200;
     * $statusMessage = Example::getHttpStatusMessage($code);
     * print "{$code} {$statusMessage}"; // Ausgabe: 200 OK
     * ```
     */
    public static function getHttpStatusMessage(int $code): string
    {
        return match ($code) {
            200 => 'OK',
            400 => 'Bad Request',
            404 => 'Not Found',
            500 => 'Internal Server Error',
            default => 'Invalid'
        };
    }
}

Durch die IntelliSense Funktionen moderner Entwicklungsumgebungen sind diese Dokumentationen für Entwickler leichter zugänglich.