Developer Blog

Tipps und Tricks für Entwickler und IT-Interessierte

Recent Updates

Our latest news

PHP | Ökosystem

Inhaltsverzeichnis

PHPStan

Finds bugs in your code without writing tests. It’s open-source and free.

PHPMD: PHP Mess Detector

What PHPMD does is: It takes a given PHP source code base and look for several potential problems within that source. These problems can be things like:

  • Possible bugs
  • Suboptimal code
  • Overcomplicated expressions
  • Unused parameters, methods, properties

PHPMD is a mature project and provides a diverse set of pre defined rules (though may be not as many its Java brother PMD) to detect code smells and possible errors within the analyzed source code. Checkout the rules section to learn more about all implemented rules.

PHP CodeSniffer

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.

GrumPHP

Sick and tired of defending code quality over and over again? GrumPHP will do it for you! This composer plugin will register some git hooks in your package repository. When somebody commits changes, GrumPHP will run some tests on the committed code. If the tests fail, you won’t be able to commit your changes. This handy tool will not only improve your codebase, it will also teach your co-workers to write better code following the best practices you’ve determined as a team.

https://api-platform.com

Laravel | Arbeiten mit Swagger

Schritt 1: Erstellen Sie ein Laravel-Projekt

Wenn Sie noch kein Laravel-Projekt haben, erstellen Sie eines mit Composer. Öffnen Sie Ihr Terminal und führen Sie den folgenden Befehl aus:

composer create-project --prefer-dist laravel/laravel App

Ersetzen Sie your-api-project durch den gewünschten Projektnamen.

Schritt 2: Installieren Sie die Swagger-PHP-Bibliothek

Sie benötigen die Swagger-PHP-Bibliothek, um Swagger-Dokumentation zu generieren. Installieren Sie diese mit Composer:

composer require zircote/swagger-php

Schritt 3: Erstellen Sie API-Routen

In Laravel definieren Sie Ihre API-Routen in der Datei routes/api.php. Sie können Routen erstellen, wie Sie es normalerweise für Ihre API tun würden.

routes/api.php

use Illuminate\Support\Facades\Route;

Route::get('/users', 'UserController@index');
Route::post('/users', 'UserController@store');
Route::get('/users/{id}', 'UserController@show');

Schritt 4: Generieren Sie Swagger-Annotationen

In Ihren Controller-Methoden verwenden Sie Swagger-Annotationen, um Ihre API zu dokumentieren. Hier ist ein Beispiel, wie man eine Controller-Methode annotiert:

/**
 * @SWG\Get(
 *     path="/users",
 *     summary="Holt eine Liste von Benutzern",
 *     tags={"Users"},
 *     @SWG\Response(response=200, description="Erfolgreiche Operation"),
 *     @SWG\Response(response=400, description="Ungültige Anfrage")
 * )
 */
public function index()
{
    // Ihre API-Logik hier
}

Weitere Informationen zu Swagger-Annotationen finden Sie in der Swagger-PHP-Dokumentation.

Schritt 5: Generieren Sie Swagger-Dokumentation

Nachdem Sie Ihre Controller annotiert haben, müssen Sie die Swagger-Dokumentation generieren. Dies können Sie mit dem artisan Befehl tun, der vom darkaonline/l5-swagger Paket bereitgestellt wird.

Zuerst installieren Sie das Paket:

composer require darkaonline/l5-swagger

Veröffentlichen Sie nun die Swagger-Konfiguration:

php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"

Bearbeiten Sie die Datei config/l5-swagger.php, um die Swagger-Konfiguration nach Bedarf anzupassen.

Schritt 6: Generieren Sie Swagger-Dokumentation

Führen Sie den folgenden Befehl aus, um die Swagger-Dokumentation zu generieren:

php artisan l5-swagger:generate

Die Swagger UI ist verfügbar unter http://127.0.0.1:8000/api/documentation.

Schritt 7: Zugriff auf Swagger UI

Öffnen sie die Swagger UI URL in Ihrem Browser.

Laravel | Erstellen eines API Backend

Inhaltsverzeichnis

TL;DR

Der Code für die in diesem Post erstelle Anwendung liegt hier.

Notwendige Komponenten eines API Backend

Für die Umsetzung eines API Backend benötigen wir in unserer Laravel App mehrere Komponenten:

  • ein Model, das beschreibt, wir die Daten aussehen, die unsere API verwendet
  • ein Controller, der den Programmcode beinhaltet, m die einzelnen Aktionen (Create, Read, Update, Delete, ..) auszuführen
  • weitere Komponenten, um die Nutzung zu erleichern
    • ein Seeder um die Datenbank mit definierte Werten zu füllen
    • ein Migrationsskript, um die notwendigen Datenbankeinträge (Tabelle, Spalten) zu erstellen
    • Testskripte, um unseren Controller und weitere Kompoentne zu prüfen

Hinweis

Vorab ein Hinweis: jeder der nachfolgenden Kommandos erstellen Komponenten in Form von Dateien. Ein erneutes Erstellen wird fehlschlagen, da die entsprechende Datei schon vorhanden ist.

Um mit den verschiedenen Kommandos zu experimentieren, verwenden sie am besten eine Funktionalität von Git, die es ihnen ermöglicht de Status zurückzusetzen, also Dateien zu löschen.

Wenn Sie ein Kommando ausgeführt haben, dann sehen sie im Visual Studio die neu erstellen Dateien:

Selektieren sie die neu erstellten Dateien und wählen sie dann die Option Discard Changes:

Komponenten erstellen

Jede dieser Komponenten kann einzeln erstellt werden, z. B mit

❯ php artisan make:model Post
❯ php artisan make:controller PostController

Hierbei gilt es natürlich, die Abhängigkeiten zu berücksichtigen. Der Controller muss mit dem Model arbeiten und sollte daher die gleichen Felder und Feldnamen verwendet.

Einfacher ist es daher, das Laravel diese Abhängigkeiten kennt und entsprechend verwendet.

Bei der Erstellung des Models können wir auch einen dazu passenden Controller und weitere Komponenten erstellen:

❯ php artisan make:model Post --migration --controller --seed --api --requests --pest

   INFO  Model and test [app/Models/Post.php] created successfully.
   INFO  Migration [database/migrations/2024_04_19_073500_create_posts_table.php] created successfully.
   INFO  Seeder [database/seeders/PostSeeder.php] created successfully.
   INFO  Request [app/Http/Requests/StorePostRequest.php] created successfully.
   INFO  Request [app/Http/Requests/UpdatePostRequest.php] created successfully.
   INFO  Controller and test [app/Http/Controllers/PostController.php] created successfully.

Dies erstellt die Dateien

	app/Http/Controllers/PostController.php
	app/Http/Requests/
	app/Models/Post.php
	database/migrations/2024_04_19_073500_create_posts_table.php
	database/seeders/PostSeeder.php
	tests/Feature/Http/
	tests/Feature/Models/

Und um alle möglichen Komponenten zu erstellen, verwenden wir den nachfolgenden Befehl:

❯ php artisan make:model Post --all --pest

   INFO  Model and test [app/Models/Post.php] created successfully.
   INFO  Factory [database/factories/PostFactory.php] created successfully.
   INFO  Migration [database/migrations/2024_04_19_073800_create_posts_table.php] created successfully.
   INFO  Seeder [database/seeders/PostSeeder.php] created successfully.
   INFO  Request [app/Http/Requests/StorePostRequest.php] created successfully.
   INFO  Request [app/Http/Requests/UpdatePostRequest.php] created successfully.
   INFO  Controller and test [app/Http/Controllers/PostController.php] created successfully.
   INFO  Policy [app/Policies/PostPolicy.php] created successfully.

Dies erstellt die Dateien

	app/Http/Controllers/PostController.php
	app/Http/Requests/
	app/Models/Post.php
	app/Policies/PostPolicy.php
	database/factories/PostFactory.php
	database/migrations/2024_04_19_075242_create_posts_table.php
	database/seeders/PostSeeder.php
	tests/Feature/Http/
	tests/Feature/Models/

Jetzt aber genug der Einführung. Lassen Sie uns mit dem Erstellen des API Backend beginnen.

Sollten Sie Komponentne erstellen haben, dann löschen Sie diese wie beschrieben.

Einrichten der Starter-App

Erstellen der Starter App. In diesem Post beschreibe ich, wie sie eine Starter-App erstellen und die grundlegenden Anpassungen durchführen können.

Sie können die Starter App auch mit dem Laravel-Installer erstellen:

❯ laravel new App   --jet 
                   --api 
                   --database sqlite 
                   --stack livewire  
                   --teams 
                   --dark 
                   --verification 
                   --git 
                   --pest

Oder auch direkt mit dem dazugehörigen Repository starten:

❯ git clone https://github.com/r14r/Laravel_Tutorial_Erstellen-einer-Starter-App App
❯ cd App
❯ composer install
❯ npm install
❯ npm run build
❯ cp .env.example  .env
❯ php artisan migrate
❯ php artisan key:generate
❯ php artisan serve

Erstellen der erforderlichen Komponenten

❯ php artisan make:model Post --all --pest

   INFO  Model and test [app/Models/Post.php] created successfully.
   INFO  Factory [database/factories/PostFactory.php] created successfully.
   INFO  Migration [database/migrations/2024_04_19_075600_create_posts_table.php] created successfully.
   INFO  Seeder [database/seeders/PostSeeder.php] created successfully.
   INFO  Request [app/Http/Requests/StorePostRequest.php] created successfully.
   INFO  Request [app/Http/Requests/UpdatePostRequest.php] created successfully.
   INFO  Controller and test [app/Http/Controllers/PostController.php] created successfully.
   INFO  Policy [app/Policies/PostPolicy.php] created successfully.

Anpassen des Routing

Erweiteren Sie die Datei routes/api.php um den nachfolgenden Programmcode (Zeile 6 und 12-14):

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

use App\Http\Controllers\PostController;

Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');

Route::get('/post',         [PostController::class, 'index']);
Route::post('/post',        [PostController::class, 'store']);
Route::delete('/post/{id}', [PostController::class, 'destroy']);

Prüfen wir die von Laravel erkannten Routen:

Erster Test

Prüfen wir die bisherigen Schritte. Starten sie Laravel und öffnen sie einen Browser unter der Adresse http://127.0.0.1:8000/api/post

❯ php artisan serve

   INFO  Server running on [http://127.0.0.1:8000].

  Press Ctrl+C to stop the server

Sie sehen, das sie nichts sehen. Was zu erwarten war, da die API noch keine Daten hat und daher auch keine Daten liefern kann.

Datenbank

Tabelle erstellen

Erweitern wir als nächstes das Migrations-Skript, um die notwendige Tabelle zu erstellen und mit Werten zu füllen.

Die entsprechende Datei ist

database/migrations/2024_04_19_075600_create_posts_table.php 

Der genaue Name kann dabei bei Ihnen abweichen.

Passen sie die Funktion up() an:

public function up(): void
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

Die neuen Felder werden über eine Migration in der Datenbank erstellt:

❯ php artisan migrate

Wir kontrollieren, ob die Tabelle richtig erstellt wurde:

❯ php artisan db
SQLite version 3.37.0 2021-12-09 01:34:53
Enter ".help" for usage hints.
sqlite> PRAGMA table_info(posts);
0|id|INTEGER|1||1
1|title|varchar|1||0
2|content|TEXT|1||0
3|created_at|datetime|0||0
4|updated_at|datetime|0||0
sqlite> .quit

Tabelle füllen mit Hilfe eines Seeder

Erstellen Sie den Seeder, falls die Datei database/seeders/PostSeeder.php nicht vorhanden ist:

php artisan make:seeder PostSeeder

Ersetzen Sie den Inhalt mit dem nachfolgenden Programmcode:

<?php

namespace Database\Seeders;

use Illuminate\Support\Facades\DB;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class PostSeeder extends Seeder
{
    static $posts = [
        ['title' => 'Summer Health', 'content' => 'Stay hydrated!'],
        ['title' => 'Pasta Recipe',  'content' => 'Tomato base'],
        ['title' => 'Decor Ideas',   'content' => 'Go minimal'],
        ['title' => 'Python Tips',   'content' => 'Use lists']
    ];

    public function run(): void
    {
        foreach (self::$posts as $post) {
            DB::table('posts')->insert([
                'title' => $post['title'], 'content' => $post['content']
            ]);
        }
    }
}

Starten Sie den Seeder:

❯ php artisan db:seed --class PostSeeder

Hinweis: Sie können diesen Seeder auch die den generellen DatabaseSeeder mit aufnehmen, so das der Name des Seeders nicht mit angegeben werden muss.

Fügen die in der Datei database/seeders/DatabaseSeeder.php den nachfolgenden Programmcode hinzu:

$this->call([
    PostSeeder::class,
]);

Starten Sie den Seeder:

❯ php artisan db:seed

Bearbeiten der Komponenten

Model

Erweitern Sie die Datei app/Models/Post.php um die zusätzlichen Felder:

protected $fillable = ['title', 'content', 'created_at', 'updated_at'];

Testing

Für die Operationen GET (Einträge anzeigen), POST (neuen Eintrag erstellen) und DELETE (Eintrag löschen) stehen jeweils eigene URLs zur Verfügung. Am einfachsten ist der Test der URLs mit Postman.

Testen mit Postman

GET

http://127.0.0.1:8000/api/get

POST

http://127.0.0.1:8000/api/post

DELETE

http://127.0.0.1:8000/api/delete/6        

Testen mit curl in der Kommandozeile

GET

❯ curl http://127.0.0.1:8000/api/post
[{"id":1,"title":"Summer Health","content":"Stay hydrated!","created_at":null,"updated_at":null},{"id":2,"title":"Pasta Recipe","content":"Tomato base","created_at":null,"updated_at":null},{"id":3,"title":"Decor Ideas","content":"Go minimal","created_at":null,"updated_at":null},{"id":4,"title":"Python Tips","content":"Use lists","created_at":null,"updated_at":null}]

POST

❯ curl -X POST  http://127.0.0.1:8000/api/post -H "Content-Type: application/json" -d '{ "title": "Neuer Titel", "content": "Neuer Inhalt!" }'
{"title":"Neuer Titel","content":"Neuer Inhalt!","updated_at":"2024-04-19T15:48:22.000000Z","created_at":"2024-04-19T15:48:22.000000Z","id":6}

DELETE

❯ curl -X DELETE http://127.0.0.1:8000/api/post/6
{"message":"Post deleted"}