Schlagwort-Archive: Laravel

LAMP Stack für Laravel auf WSL installieren

Für Windows existieren eine Vielzahl von LAMP Applikationen wie Laragon oder XAMPP. Allerdings sind einige nützliche Pakete, die man zu Laravel hinzufügen kann, nicht mit Windows kompatibel. Auch Funktionen wie der Scheduler oder Queue Workers können nur über Umwege getestet werden. Anstelle für jeden Entwickler bei jedem Projekt Server zu erstellen und echte Domains darauf umzuleiten, haben wir hier eine detaillierte Anleitung erstellt, mit der man auf dem Windows Subsystem for Linux eine vollwertige Entwicklungsumgebung erstellen kann.

Auch erstellt haben wir ein Shell Script, welches die komplette Verwaltung übernimmt:

  • Starten/Stoppen/Neustarten des LAMP Stacks
  • Anzeigen aller vHosts/Ordner
  • Erstellung neuer Projekte mit Option für Laravel
  • Erstellung einer neuen Datenbank mit Benutzer und Passwort und automatischem Ausfüllen der .env.
  • Erstellung von Self Signed Certificates

Updates

Vorbereitung in Windows

Damit wir innerhalb von Windows auf die im WSL gehosteten Seiten zugreifen können, müssen wir jedes Mal einen neuen Eintrag in der Host Datei hinterlegen. Damit das automatisch durch unser Script übernommen werden kann, verwenden wir gsudo. Um gsudo zu installieren, öffnen wir PowerShell als Administrator und verwenden diesen Befehl:

PowerShell -Command "Set-ExecutionPolicy RemoteSigned -scope Process; iwr -useb https://raw.githubusercontent.com/gerardog/gsudo/master/installgsudo.ps1 | iex"

Als nächstes loggen wir uns im Windows Store ein und installieren Ubuntu. Wir verwenden die neueste Version (Ubuntu 22.04 LTS).

Grundinstallation

Nach erfolgreicher Installation von Ubuntu wechseln wir auf den root Benutzer.

sudo su

Damit wir ungestraft sudo verwenden können ohne ständig das Passwort eintippen zu müssen, fügen wir mit visudo am Ende der sudoers Datei eine Ausnahme für unseren Account hinzu (billinger mit dem eigenen Accountnamen austauschen).

billinger ALL=(ALL) NOPASSWD:ALL

PHP Repository hinzufügen:

add-apt-repository ppa:ondrej/php

Update, Upgrade und Installation von Apache, MySQL und PHP. Da bei älteren Laravel Versionen PHP 8 nicht funktioniert, installieren wir gleich PHP 7.4 und 8.1 gleichzeitig. Je nachdem welche Version später notwendig ist, kann diese einfach gewechselt werden.

apt-get update && apt-get upgrade -y 
apt install -y apache2 mysql-server unzip php8.1-{fpm,gd,mysql,curl,xml,zip,intl,mbstring,bz2,ldap,apcu,bcmath,gmp,imagick,igbinary,redis,smbclient,cli,common,opcache,readline,imagick,redis}  php7.4-{fpm,gd,mysql,curl,xml,zip,intl,mbstring,bz2,ldap,apcu,bcmath,gmp,imagick,igbinary,redis,smbclient,cli,common,opcache,readline,imagick,redis} 

Damit der mysql Benutzer auch ein Home Verzeichnis hat und nicht bei jedem Neustart einen Fehler ausgibt:

usermod -d /var/lib/mysql/ mysql

Apache Konfiguration

Diverse notwendige Apache Module werden aktiviert und anschließend PHP FPM 8.1 umgestellt. Auf dem gleichen Weg kann auch PHP 7.4 aktiviert werden.

a2enmod rewrite ssl vhost_alias authz_groupfile headers cache expires actions alias proxy_fcgi proxy proxy_html proxy_http xml2enc mpm_event http2
a2enconf php8.1-fpm
echo "Protocols h2 http/1.1" >> /etc/apache2/apache2.conf

PHP Konfiguration

Optimierung der Konfiguration:

sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/pm.max_children =.*/pm.max_children = 240/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/pm.start_servers =.*/pm.start_servers = 30/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/pm.min_spare_servers =.*/pm.min_spare_servers = 10/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/pm.max_spare_servers =.*/pm.max_spare_servers = 200/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests =.*/pm.max_requests = 1000/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/allow_url_fopen =.*/allow_url_fopen = 1/" /etc/php/8.1/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/8.1/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/8.1/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/8.1/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/8.1/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/8.1/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/8.1/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 1024M/" /etc/php/8.1/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/8.1/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/8.1/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/8.1/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/8.1/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/8.1/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/8.1/fpm/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=16/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/8.1/fpm/php.ini
sed -i "s|;emergency_restart_threshold.*|emergency_restart_threshold = 10|g" /etc/php/8.1/fpm/php-fpm.conf
sed -i "s|;emergency_restart_interval.*|emergency_restart_interval = 1m|g" /etc/php/8.1/fpm/php-fpm.conf
sed -i "s|;process_control_timeout.*|process_control_timeout = 10|g" /etc/php/8.1/fpm/php-fpm.conf
sed -i '$aapc.enable_cli=1' /etc/php/8.1/mods-available/apcu.ini
sed -i "s/rights=\"none\" pattern=\"PS\"/rights=\"read|write\" pattern=\"PS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"EPS\"/rights=\"read|write\" pattern=\"EPS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"PDF\"/rights=\"read|write\" pattern=\"PDF\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"XPS\"/rights=\"read|write\" pattern=\"XPS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/pm.max_children =.*/pm.max_children = 240/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/pm.start_servers =.*/pm.start_servers = 30/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/pm.min_spare_servers =.*/pm.min_spare_servers = 10/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/pm.max_spare_servers =.*/pm.max_spare_servers = 200/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests =.*/pm.max_requests = 1000/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/allow_url_fopen =.*/allow_url_fopen = 1/" /etc/php/7.4/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.4/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/7.4/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.4/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.4/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.4/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.4/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 1024M/" /etc/php/7.4/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.4/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/7.4/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.4/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.4/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.4/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.4/fpm/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=16/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/7.4/fpm/php.ini
sed -i "s|;emergency_restart_threshold.*|emergency_restart_threshold = 10|g" /etc/php/7.4/fpm/php-fpm.conf
sed -i "s|;emergency_restart_interval.*|emergency_restart_interval = 1m|g" /etc/php/7.4/fpm/php-fpm.conf
sed -i "s|;process_control_timeout.*|process_control_timeout = 10|g" /etc/php/7.4/fpm/php-fpm.conf
sed -i '$aapc.enable_cli=1' /etc/php/7.4/mods-available/apcu.ini
sed -i "s/rights=\"none\" pattern=\"PS\"/rights=\"read|write\" pattern=\"PS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"EPS\"/rights=\"read|write\" pattern=\"EPS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"PDF\"/rights=\"read|write\" pattern=\"PDF\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"XPS\"/rights=\"read|write\" pattern=\"XPS\"/" /etc/ImageMagick-6/policy.xml

Erweiterung der php.ini mit einer custom.ini und Erstellung von symbolischen Links:

#### /etc/php/custom.ini

max_execution_time = 2400
max_input_time = 900
post_max_size = 800M
memory_limit = 4048M
upload_max_filesize = 800M
max_input_vars = 100000
max_file_uploads = 5000
realpath_cache_size = 4M
date.timezone = 'Europe/Berlin'
display_errors = On
error_log = /var/log/php-error.log
error_reporting = E_ALL
phar.readonly = 0

opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=32531
opcache.save_comments=1
opcache.fast_shutdown=0
opcache.max_file_size=0
opcache.validate_timestamps=1
opcache.revalidate_freq=2
ln -s /etc/php/custom.ini /etc/php/7.4/fpm/conf.d/custom.ini
ln -s /etc/php/custom.ini /etc/php/8.1/fpm/conf.d/custom.ini
ln -s /etc/php/custom.ini /etc/php/7.4/cli/conf.d/custom.ini
ln -s /etc/php/custom.ini /etc/php/8.1/cli/conf.d/custom.ini

Composer Installation

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
mv composer.phar /usr/local/bin/composer
echo "export COMPOSER_ALLOW_SUPERUSER=1" >> ~/.bashrc

NVM und NPM Installation

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
source ~/.bashrc
nvm install node
npm set unsafe-perm true
n=$(which node);n=${n%/bin/node}; chmod -R 755 $n/bin/*; sudo cp -r $n/{bin,lib,share} /usr/local

lamp Script hinterlegen

visudo ausführen und in der Zeile Details secure_path= /opt/lamp hinzufügen

mkdir /opt/lamp
cd /opt/lamp
wget https://admin-code.de/downloads/lamp
chmod +x lamp
echo "export PATH='$PATH:/opt/lamp'" >> ~/.bashrc
source ~/.bashrc

Rechte in /var/www anpassen

(billinger mit dem eigenen Accountnamen austauschen)

chown -R www-data:www-data /var/www
chmod 00755 /var
chmod 00755 /var/www
find /var/www -type d -exec chmod 00755 {} \;
find /var/www -type f -exec chmod 00644 {} \;
usermod -a -G www-data billinger

Mögliche Script Schalter

Ausführen kann man das Script mit dem Befehl „lamp“. Danach kommen die weiteren Keywords. Die Befehle „start“, „stop“, „restart“, „status“ beziehen sich auf die Services. Mit „list“ kann man kontrollieren, welche Konfigurationen in Apache vorhanden sind und welche Ordner in /var/www stehen. Mit „add Projektname“ und „remove Projektname“ können Projekte hinzugefügt und gelöscht werden (beim Löschen wird nur die Apache Konfiguration gelöscht. Die Daten bleiben weiterhin vorhanden).

Die Hilfe kann über „lamp help“ angezeigt werden.

Script ausführen

Da es ein paar Funktionen gibt die ohne https nicht funktionieren, erstellen wir für alle neuen Projekte automatisch Zertifikate. Da es sich hier allerdings um lokale Domainnamen handelt, können hier keine „echten“ Zertifikate wie von Let’s Encrypt verwendet werden. Eine Certificate Authority kann die Validität unserer Entwicklungsseiten nicht verifizieren. Deswegen werden wir unsere eigene Certificate Authority erstellen.

Wir verwenden hierfür dev-certificates von Ben Morel (https://github.com/BenMorel).

Unser lamp Script prüft automatisch, ob das Zertifikat schon existiert und erstellt es gegebenenfalls neu. Damit der Browser dieses auch verwendet, muss es hinterlegt werden.

Bei der Erstellung eines neuen Projektes kann zwischen Laravel und nicht Laravel entschieden werden. Ebenfalls ist es möglich, ein zuvor gepulltes Projekt in die vHosts mit einzufügen. Dabei sollte man die Frage ob Laravel installiert werden soll, ablehnen. Eine neue Datenbank kann trotzdem automatisch generiert und in die .env geschrieben werden.

Ebenfalls ist es möglich, „normale“ Projekte mit oder ohne Datenbank zu erstellen. Diese bekommen dann, um zu verifizieren dass die Installation funktioniert hat, eine Standard HTML Seite.

Unter den allgemeinen Informationen im Script kann die Variable TLD mit einer gewünschten TLD definiert werden. Moderne Browser werden beim aufrufen wie my-project.local direkt die Suchmaschine verwenden. Wer nicht jedes erste Mal https:// schreiben möchte, kann hier eine reguläre TLD wie .de oder .com verwenden. Besser wären allerdings die neuen TLDs wie .fun, .xyz, oder thematisch passend .test.

Autostart LAMP Stack

Da Apache und MySQL nicht Teil unseres Windows Betriebssystems sind, steht uns der LAMP Stack erst zur Verfügung, wenn Ubuntu gestartet wird und wir dort die Services entweder automatisch oder manuell über „lamp start“ ausführen. Damit dies automatisiert passiert, öffnen wir einmal regulär Ubuntu und notieren uns via Task Manager den genauen Pfad.

"C:\Program Files\WindowsApps\CanonicalGroupLimited.Ubuntu22.04LTS_2204.0.10.0_x64__79rhkp1fndgsc\ubuntu2204.exe"

Als nächstes öffnen wir mit WIN + R den Ausführen Dialog und öffnen den Autostart Ordner von Windows.

shell:startup

In diesem Ordner erstellen wir nun eine neue Batch Datei in der wir unsere WSL Befehle hinterlegen. Die Batch Datei wird bei jedem Systemstart automatisch ausgeführt.

@echo off 
wsl sudo bash /opt/lamp/lamp start

Visual Studio Code mit WSL Verbinden

Sobald WSL auf dem Gerät installiert ist, sollte sich Visual Studio Code automatisch beim Start melden und das Plugin „Remote – WSL“ vorschlagen, nun dieses installieren und in der .bashrc den Pfad für Visual Studio hinterlegen. Danach kann in WSL mit dem Befehl „code /path/to/open“ das gewünschte Verzeichnis geöffnet werden.

export PATH=$PATH:"/mnt/c/Users/BILLINGER/AppData/Local/Programs/Microsoft VS Code/bin"

Abschließend nochmal das .bashrc File mit source .bashrc laden.

Sollten Sie noch Fragen haben oder eine Beratung wünschen, können Sie gerne mit uns Kontakt aufnehmen oder unsere Webseite besuchen.

Gerne können Sie hier auch weitere Artikel zum Thema Laravel lesen. Andere Sysadmin Blogartikel finden Sie auf unserem Hauptblog.

Laravel mit InfluxDB Verbinden

Laravel kommt mit vielen Providern für Datenbank Verbindungen. Allerdings gibt es eine Vielzahl von Datenbanken, die nur über Umwegen von Laravel angesprochen werden können. Wie das Ganze mit InfluxDB funktioniert, erfahren Sie in diesem Beitrag.

Als erstes fügen wir das Paket mit Composer zu unserem Laravel Projekt hinzu:

composer require tray-labs/laravel-influxdb

In die .env müssen die Verbindungsinformationen hinterlegt werden:

INFLUXDB_HOST=localhost
INFLUXDB_PORT=8086
INFLUXDB_USER=some_user
INFLUXDB_PASSWORD=some_password
INFLUXDB_SSL=false
INFLUXDB_VERIFYSSL=false
INFLUXDB_TIMEOUT=0
INFLUXDB_DBNAME=some_database
INFLUXDB_UDP_ENABLED=false # Activate UDP
INFLUXDB_UDP_PORT=4444 # Port for UDP

Abschließend führen wir diesen Befehl im Terminal aus:

php artisan vendor:publish

Im Controller, in dem wir auf InfluxDB zugreifen möchten, können wir jetzt den Provider angeben und die Datenbankabfragen durchführen.

Wie das Ganze in der Influx Cloud DB aussieht, haben wir uns auch angeschaut und werden auf den nächsten Blog Beitrag verlinken, sobald dieser erscheint.

Sollten Sie noch Fragen haben oder eine Beratung wünschen, können Sie gerne mit uns Kontakt aufnehmen oder unsere Webseite besuchen.

Gerne können Sie hier auch andere Artikel zum Thema Laravel anschauen.

Laravel Notifications per Mail versenden

Mit Laravel kann man Benutzern direkt Notifications per E-Mail senden. Wie das funktioniert, erfahren Sie in diesem Artikel.

Zum Thema Laravel Notifications haben wir auch einen Artikel zu Notifications in Rocket.Chat versenden veröffentlicht, diesen können Sie hier finden.

Mailtrap & SMTP Konfiguration

Zum Testen verwenden wir mailtrap.io. Wie der Name es schon suggeriert werden alle Mails direkt abgefangen. Diese werden dann in einem Postfach gebündelt angezeigt.

Innerhalb des Postfaches gehen wir auf SMTP Settings und wählen im Dropdown direkt Laravel aus. Die richtigen Einstellungen werden angezeigt und können in die .env eingetragen werden.

Erstellung Notification & Controller

php artisan make:notification AlarmNotification
php artisan make:controller NotificationController

Im NotificationController erstellen wir eine Test Funktion und inkludieren die AlarmNotification, damit wir diese auch ansprechen können.

<?php

namespace App\Http\Controllers;

use App\Notifications\AlarmNotification;

class NotificationController extends Controller
{
    public function test()
    {
        // testing notification
    }
}

In der Test Funktion erstellen wir uns die NotificationData, die wir versenden möchten.

$notificationData = [
    'message' => 'Test Notification',
    'actionLink' => 'https://admin-code.de'
    'actionText' => 'Click here'
];

Damit wir die Notification versenden können, benötigen wir noch einen Zielbenutzer. Über „notify“ können wir ihm dann die Notification mit notificationData schicken.

$user = User::first();

$user->notify(new AlarmNotification($notificationData));

Damit das auch funktioniert, müssen innerhalb des User Models Notifications erlaubt sein.
Dies sollte standartmäßig bereits der Fall sein – trotzdem sollte folgendes kontrolliert werden:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
use Illuminate\Database\Eloquent\SoftDeletes;



class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

An diesem Punkt können wir die Notification bereits testen.

// api.php

use App\Http\Controllers\NotificationController;

Route::get('notification-test', [NotificationController::class, 'test']);

Über Postman können wir nun die API aufrufen und etwaige Fehler analysieren.

Möglicher Fehler beim Versenden der Mail:

stream_socket_client(): php_network_getaddresses: getaddrinfo for mailhog failed: No such host is known.

Lösung:

php artisan cache:clear
php artisan config:clear

Konfiguration der Notification

Am Anfang der Notification Class deklarieren wir die notificationData als private.

class AlarmNotification extends Notification
{
    use Queueable;
    private $notificationData;

Und schreiben diese mit in den Constructor

public function __construct($notificationData)
    {
        $this->notificationData = $notificationData;
    }

Nun können wir die Informationen, die wir im Controller an die Notification weitergegeben haben hier auch verwenden. In der toMail Funktion wird der Text der Mail definiert.

public function toMail($notifiable)
    {
        return (new MailMessage)
	    ->line($this->notificationData['message'])
	    ->action(
	        $this->notificationData['actionText'],
	        $this->notificationData['actionLink']
	    )
    }

Aussehen der Laravel Notification ändern

Die Templates, die von Laravel verwendet werden, um Notifications zu versenden, können mit diesen beiden Commands in den resources Ordner verschoben und anschließen bearbeitet werden:

php artisan vendor:publish --tag=laravel-mail
php artisan vendor:publish --tag=laravel-notifications

Nun können wir zum Beispiel das Logo im Header der Notification verändern:

Dazu einfach in der resources/views/vendor/mail/html/header.blade.php den Link austauschen. Dabei nicht vergessen, in der CSS Datei die Breiten- und Höhenangaben zu bearbeiten.

Weitere Informationen und Meta Daten in Laravel Notification

Neben Linien und einem Action Button kann man noch weitere Infos and die Notification weitergeben.

->level()

Verändert Farben des Action Buttons und Anrede wenn keine gesetzt ist

->subject()

Betreff der E-Mail

->from()

Absender der E-Mail

->replyTo()

E-Mail Adresse für Antworten

->priority()

Priorität der E-Mail, 1-5, 1 ist das höchste

->greeting()

Anrede

->line()

Text in der Mail, kann auch mehrmals per For-Loop verwendet werden

->salutation()

Gruß zum Abschied

Mehr Methoden können Sie in der offiziellen Dokumentation nachschlagen.

Sollten Sie noch Fragen haben oder eine Beratung wünschen, können Sie gerne mit uns Kontakt aufnehmen oder unsere Webseite besuchen.

Gerne können Sie hier auch andere Artikel zum Thema Laravel anschauen.

Laravel Scheduler

Mit Hilfe des Schedulers können Tasks gezielt geplant und unabhängig von Benutzeraktivitäten innerhalb von Laravel ausgeführt werden. Wie der Scheduler verwendet wird, erfahren Sie in diesem Artikel.

Grundsätzlich werden bei Laravel Funktionen nur ausgeführt, wenn Benutzer diese auslösen. Wenn wir allerdings Tasks haben, die regelmäßig zu bestimmten Zeiten ausgeführt werden, müssen wir den Scheduler verwenden.

Die Grundfunktion hinter dem Scheduler ist ein Cronjob, der jede einzelne Minute ausgeführt wird. Der Cronjob ruf dann wiederum über Artisan den Scheduler auf.

Editierung des Crontabs

sudo su
crontab -e

Der Crontab wird standartmäßig mit dem Endgegner vi geöffnet. Mit der Bild-runter Taste gehen wir hier zur letzten Zeile, drücken i für insert und fügen die folgende Zeile ein.

* * * * * /usr/bin/php7.4 /var/www/insight/artisan schedule:run > /dev/null 2>&1

(Die Pfade für die PHP-Executeable und Artisan müssen natürlich angepasst werden)

Erstellung der Commands

Zum ausführen der Einzelnen Tasks werden Commands verwendet. Diese können wie gewohnt mit Artisan erstellt werden.

php artisan make:command <command:name>

Der neue Command kann im Ordner /app/Console/Commands gefunden werden.

Wichtig hierbei ist die Signatur des Commands (im Bild Zeile 24). Diese wird verwendet, um den Command über den Scheduler oder die Konsole aufzurufen.

Was genau der Command ausführen soll, wird in der handle() Funktion definiert. Kleinere Funktionen können direkt innerhalb des Commandos definiert werden. Dazu kann man wie im Screenshot regulär Models und Helpers importieren und verwenden. Bei umfangreicheren Abläufen oder benötigten Hilfsfunktionen sollte man die Funktionalität direkt in den dazugehörigen Controller auslagern:

Auch für das Debuggen ist es hilfreich, die Funktionen im Controller zu haben, um diese dann per API via Postman zu testen. Der direkte Aufruf der Commands führt zu keinen Fehlermeldungen in der Console.

Konfiguration Scheduler

Die Konfigurationsdatei des Schedulers ist unter app/Console/Kernel.php zu finden. Hier müssen die Commands hinterlegt werden, um sie dann auszuführen:

In der Funktion schedule können wir anschließen unsere Commands mit Häufigkeit der Aufrufe hinterlegen:

Schedules können in den Unterschiedlichsten Konstellationen getriggert werden, eine Umfangreiche Liste der Modifiers kann in der offiziellen Dokumentation gefunden werden.

Sollten Sie noch Fragen haben oder eine Beratung wünschen, können Sie gerne mit uns Kontakt aufnehmen oder unsere Webseite besuchen.

Gerne können Sie hier auch andere Artikel zum Thema Laravel anschauen.

Laravel Notifications an Rocket.Chat versenden

Laravel Notifications können standardmäßig per E-Mail, SMS (über Drittanbieter) und Slack versendet werden. Mit Hilfe des Community Projektes Laravel Notification Channels lassen sich Notifications auch an andere Dienste schicken.

In diesem Artikel zeigen wir Ihnen, wie Rocket.Chat angesprochen werden kann.

Setup

Der Rocket.Chat Notification Channel wird mit Composer installiert:

composer require laravel-notification-channels/rocket-chat

Vorab müssen wir innerhalb von Rocket.Chat einen neuen Channel und eine Integration erstellen:

Wichtig: Der Rocket.Chat Token wird erst nach dem ersten Speichern generiert.

In die .env werden die URL des Rocket.Chat Servers, das Token aus dem letzten Screenshot, und der Name des Zielchannels hinterlegt:

ROCKETCHAT_URL="https://chat.admin-box.de/"
ROCKETCHAT_TOKEN="*******"
ROCKETCHAT_CHANNEL="insight"

In der Datei config/services.php wird der neue Rocket.Chat Service hinterlegt:

'rocketchat' => [
    'url' => env('ROCKETCHAT_URL'),
    'token' => env('ROCKETCHAT_TOKEN'),
    'channel' => env('ROCKETCHAT_CHANNEL'),
],

Eine neue Notification wird erstellt:

php artisan make:notification TestNotification

Zum Steuern der Notification wird ein neuer Controller erstellt (optional):

php artisan make:controller NotificationController

Controller Konfiguration

Im Controller, den wir verwenden möchten, um die Notification auszuführen, fügen wir die Notification hinzu

use App\Notifications\TestNotification;

und können sie danach auch schon in einer Beispielfunktion verwenden

public function testNotification()
{
    $user = Auth::user();
    $notificationData = [
        'body' => 'Testbenachrichtigung von ' . $user->name,
        'url' => 'https://portal.admin-insight.de'
    ];>

    Notification::route('', '')
        ->notify(newTestNotification($notificationData));
}

Da wir hier keine Nachrichten direkt an einzelne Benutzer versenden, die in unserer Laravel Installation hinterlegt sind, sondern hart auf einen Rocket.Chat Server und einen Channel gehen, können wir mit Notification::route(“, “) die Notification triggern. Bei anderen Formen der Notification, wie E-Mail, wird die Notification mit Hilfe des User Models aufgerufen, und die verknüpfte E-Mail-Adresse wird automatisch zur Zieladresse.

$user->notify(new TestNotification($notificationData)));

Notification Konfiguration

Innerhalb der Notification werden die folgenden Klassen hinzugefügt

use NotificationChannels\RocketChat\RocketChatMessage;
use NotificationChannels\RocketChat\RocketChatAttachment;
use NotificationChannels\RocketChat\RocketChatWebhookChannel;

Auf RocketChatAttachment kann verzichtet werden, sollte man grundsätzlich keine Anhänge versenden.

class TestNotification extends Notification
{
    use Queueable;
    private $notificationData; // 

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($notificationData)
    {
        $this->notificationData = $notificationData;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return [ 
            RocketChatWebhookChannel::class
        ];
    }

Die Variable $notificationData wird im Constructor bespielt und kann dann später in der Nachricht verwendet werden

    public function toRocketChat($notifiable): RocketChatMessage
    {

        return RocketChatMessage::create()
          ->content($this->notificationData['body'] . ' [Hier klicken](' . $this->notificationData['url'] . ')' );
    }

In der toRocketChat Funktion wird nun die Nachricht erstellt und losgeschickt

Neben content() gibt es noch weitere nützliche Methoden:

->alias('')

Ändert den Namen des Absenders (der originale Name wird dahinter noch gezeigt)

->emoji('')

Tauscht das Profilbild des Absenders mit einem der Rocket.Chat Emojis (Bspw. :radioactive:)

->avatar('')

Tauscht das Profilbild des Absenders mit einem im Internet gespeichertem Bild

->attachment() und attachments()

Hier können Bilder/Videos/Sounds als Anhang der Nachricht hinzugefügt werden

Beispielhaftes Attachment:

->attachment(
    RocketChatAttachment::create()
        ->imageUrl('https://domain.tld/image.jpg')
        ->color('blue') 
        ->text('attachmentText'
);

Anhänge haben ebenfalls eine Vielzahl von möglichen Methoden. Zeitstempel, Farben, Thumbnails, und vieles mehr. Mehr Methoden können Sie in der offiziellen Dokumentation nachschlagen.

Sollten Sie noch Fragen haben oder eine Beratung wünschen, können Sie gerne mit uns Kontakt aufnehmen oder unsere Webseite besuchen.

Gerne können Sie hier auch andere Artikel zum Thema Laravel anschauen.

Laravel CRUD

CRUD steht für: create, read, update und delete.

Laravel implementiert die REST Architektur (Representational State Transfer). Vereinfach gesagt bedeutet dies, dass die Anforderungen an eine Ressource über die Route bzw. den URL abgebildet werden.

Wir wollen unsere BeispielApp ein wenig „aufbohren“, damit wir nicht nur Artikel anzeigen können (read), sondern sie auch erzeugen (create), aktualisieren (update) und löschen können (delete).

Wir löschen nun den BlogController in unserem Projekt und speichern uns vorher den Code aus der index Action weg. Wir erzeugen ihn noch mal, diesmal aber mit dem Schalter: -r

php artisan make:controller BlogController -r

Wenn wir uns nun den Controller anschauen, stellen wir fest, dass die CRUD Methoden bzw. Actions schon generiert wurden.

  • Action: index – liefert eine Liste der Ressource
  • Action: create – liefert eine View bzw. Form zur Erfassung einer neuen Ressource
  • Action: store – speichert die Ressource
  • Action: show – liefert eine bestimmte Ressource
  • Action: edit – liefert eine View bzw. Form zur Bearbeitung einer Ressource
  • Action: update – speichert eine bearbeitete Ressource
  • Action: delete – löscht eine bestimmte Ressource

Wir fügen nun wieder den Code aus der index Action ein.

Wir möchten nun als nächstes, dass wir einen bestimmten Artikel in einer View angezeigt bekommen.

Für die Verarbeitung verantwortlich ist die Action show des Blog Controllers.

Zunächst definieren wir die Route:

Die Route in der routes/web.php:

Route::get('/blogs/{id}', [BlogController::class, 'show']);

Wir tragen temporär diesen Code in die show Action ein:

die('BlogController - showAction'); exit;

Die Route funktioniert also. Die geschweiften Klammern in der Route definieren also Parameter. Wir übergeben in diesem Fall die id des Artikel der Blog Tabelle.

Die Methode show des Blog Controllers:

Wir legen eine neue View an: blog.blade.php und fügen folgenden Code ein:

Der Aufruf im Browser:

Der Aufruf: /blogs/1 ruft also die Action show des Block Controllers auf. So ist es ja auch in der Route definiert.

Die Methode: show empfängt den Parameter id beim Aufruf.

Über das Blog Modell setzen wir eine sql-ähnliche Abfrage ab und erhalten so ein Blog Model, dass wir der View übergeben können.

Wir kümmern uns nun um das Anlegen eines neuene Blog Eintrags. Zunächst die Route in routes/web.php:

Route::get('/create', [BlogController::class, 'create']);

Die create Action des Blog Controllers:

Die Action: create gibt eine View: create zurück. Diese erstellen wir jetzt und fügen ein Formular ein:

Nun setzen wir die Route in der routes/web.php. Da wir Formulardaten an den Server senden wollen, benutzen wir diesmal die Methode: POST anstatt GET

Die Route ist identisch mit der für die index.blade.php. Nur eben diesmal als POST Request

Die zuständige Action ist: store.

Wenn wir nun /create aufrufen und einen neuen Artikel eintragen:

Wenn wir nun absenden, bekommen wir folgende Seite zu sehen:

Laravel erwartet einen Key oder Hash, der auf dem Server verglichen wird. Diese sogenannte Token wurde nämlich beim create Request erzeugt und ins HTML eingebettet.

Damit verhindert oder erschwert Laravel sogenannte CSRF Attacken.

Wir fügen nun folgendes ein in die create.blade.php:

Wir wollen nun erst einmal pürfen, ob das Problem dadurch gelöst wurde und damit der Request im Blog Controller bzw. der Store Action ankommt. Wir fügen diesen Code in die Store Action ein:

die('store action'); exit;

Wenn das Formular abgeschickt wurde, sollte der Browser so aussehen:

Nur der Vollständigkeit halber: Durch den Zusatz: @csrf im Formular wird ein Token erzeugt, dass dann beim POST mitgesendet und von Laravel auf Gleichheit überprüft wird.

Die Ausgabe in den Dev-Tools des Browsers:

Mit anderen Worten: Nur, wenn das Token, welches bei create mitgesendet wurde, identisch ist mit dem, welches beim Speicher POST mitgesendet wird, akzeptiert Laravel den Request.

Schlussendlich wollen wir natürlich den neuen Blog Eintrag auch in der Datenbank speichern. Wir programmieren in der Store Action:

Laravel übergibt ein Request Objekt. Wir lesen den Wert von blog aus, speichern ihn und erzeugen ein neues Blog Objekt. Dann setzen wir den Wert bzw. content und speichern das Model.

Am Schluss programmieren wir noch einen Redirekt auf die Übersichtsseite.

Der neue Blog Eintrag ist nun im Browser zu sehen:

Wir wollen nun einen bestimmten Blog Eintrag auch editieren und die Änderungen speichern. Wie gehabt, wir definieren die dafür zuständige Route in der routes/web.php und programmieren eine Controller Action.

Route::get('/blogs/{id}/edit', [BlogController::class, 'edit']);

Die Edit Action:

Kurze Erläuterung zu dem auskommentierten Code: Blog::find($id) funktioniert zwar, aber anders als bei der Where Abfrage, wird, falls die ID in der Datenbank nicht gefunden wird, keine 404 Page generiert. Es würde null zurückgegeben und so an die View übergeben. Der Zugriff in der View würde dann erst eine Exception auslösen.

Fehlt noch die View: edit.blade.php

Das war’s mit unserem Laravel-Tutorial. Wenn Sie noch Fragen haben oder Hilfe benötigen, können Sie sich sehr gerne mit uns in Verbindung setzen.

Hier geht es zum vorherigen Teil: Laravel Layout

Besuchen Sie auch gerne unsere Webseite: admin-code.de

Laravel Layout

Bisher haben wir nur eine View blogs.blade.php

Wahrscheinlich wird es aber mehrere Webseiten geben, die zur Website gehören. Jedes Template beinhaltet den kompletten HTML Code.

Oft ist nun aber so, dass beispielsweise der Header und/oder Footer immer derselbe ist. Trotzdem wird in jedem Template der Code wiederholt. Dies ist nicht nur redundanter Code, sondern es ist auch mühselig, alle Templates anzupassen, wenn sich mal etwas ändert, z.B. am Header oder Footer.

Erfreulicherweise bieter uns Laravel hier eine Lösung an, Layout Files

Die Idee ist, sich wiederholende Teile der HTML Seite in das Layout File zu schreiben. Die einzelnen Seiten fügen dann nur noch ihren speziellen Content ein.

Damit das Sinn macht, fügen wir als erstes ein zweites Template hinzu: about.blade.php

Wir könnten nun einen AboutController hinzufügen. Wir entscheiden uns aber dafür, einen InfoController anzulegen, der über verschiedene Actions solche Seiten wie about, impressum, contact usw. abwickelt.

Wir setzen die Route:

Die Route /about definiert also den InfoController und die Action showAbout.

Der Aufruf im Browser sollte zu diesem Ergebnis führen:

Wir möchten nun eine horizontale Navigation auf all unseren Seiten haben. Anstatt nun den Code auf jeder Seite einzufügen, legen wir ein Layout File an:

Wie man sieht, stellt das Layout-Template das Html Grundgerüst zur Verfügung und die Navigation.

Genau das brauchen wir auf jeder Seite. Den speziellen Seiten-Content stellen dann die einzelnen Seiten zur Verfügung.

Wir beginnen mit der index.blade.php. Wir löschen den Inhalt und fügen diesen Code ein:

Mittels @extends(‚layout‘) erbt unser Template den Code vom layout.blade.php Template.

Man kann nun verschiedene sogenannte sections definieren, deren Inhalt dann layout.blade.php ergänzt. In diesem Fall eben das H1 Tag.

Wenn wir nun die Startseite aufrufen, sehen wir erst einmal nur das layout Grundgerüst. Wir müssen im Layout Template noch die Sections rendern:

Wenn irgendeine Seite von Layout erbt, bedeutet dies auch, dass Layout Zugriff auf die Sections hat.

Im Layout File wird dann an beliebiger Stelle, also dort, wo der Inhalt der Section erscheinen soll, mittels @yield(‚NameDerSection‘) ebendieser Inhalt der jeweiligen Section hineingerendert.

Dementsprechend sieht dann die Ausgabe im Browser aus:

Nun bearbeiten wir die about.blade.php

Die Ausgabe dann entsprechend. Durch den Mechanismus der Vererbung sparen wir also Code und gestalten den Aufbau unserer Seiten modular.

Wir müssen noch die blog.blade.php bearbeiten. Sie sollte danach so aussehen:

Wir fügen nun in die layout.blade.php noch den Artikel Link ein, der auf die Route/blogs zeigt und passen das CSS ein wenig an, damit die Formatierung nur zieht bei unserer Navigation:

Der Aufruf im Browser:

Hier geht es zum vorherigen Teil: Laravel Datenbank

Hier geht es zum letzten Teil: Laravel CRUD

Besuchen Sie auch gerne unsere Webseite: admin-code.de

Laravel Datenbank

Wir verwenden in unserem Tutorial eine MySQL Datenbank.

Wir loggen uns als root auf dem Datenbank-Server ein.

mysql -u root -p

root hat in unserem Fall kein Passwort, also die Passwortabfrage einfach mit Enter quittieren.

Im Mysql Prompt folgendes eingeben.

CREATE USER 'laravel'@'localhost' IDENTIFIED BY 'admin';

Wir geben dem User laravel Berechtigungen für die Databank laravel. 

GRANT ALL PRIVILEGES ON laravel.* TO 'laravel'@'localhost';

Dann noch.

FLUSH PRIVILEGES;

Wir loggen uns als root aus.

quit;

 Wir melden uns als User laravel an.

mysql -u laravel -p

Wir sind nun als der User laravel eingeloggt und erzeugen die Datenbank laravel.

create database laravel;

Wir loggen uns wieder aus.  

quit;

Wir haben damit die Vorbereitungen abgeschlossen.

Im Document Root liegt eine verstecktes File .env

Wir konfigurieren den MySQL Zugang.

Die Konfigurationsdatei .env wird übrigens vom File config/database verarbeitet.

Mittels des CLI Tools artisan erzeugen wir ein Model (Wir befinden uns im Document Root). 

php artisan make:model Blog

Das Model Blog wurde nun im Verzeichnis app/Models erzeugt. Generierte Einträge entfernen wir erst einmal.

Wiederum mittels artisan erzeugen wir eine sogenannte Migration. Dies generiert uns eine Art SQL Script.

php artisan make:migration create_blog_table

Wie man sieht, wird unter database/migrations ein entsprechendes Script bzw. Klasse angelegt.

In der up() Methode werden schon 2 Felder definiert: id und timestamp. Wird das Script ausgeführt, wird die Tabelle Blog erzeugt.

Außerdem werden die Felder in der up() Methode in der Datenbank angelegt.

Die übrigen Scripte legt Laravel übrigens bei der Generierung des Projekts an. Wen sie nicht stören, lässt sie einfach drin. Somit wäre beispielsweise schon mal die Programmierung eines Logins bzw. einer User-Verwaltung schneller möglich.

Wir ersetzen noch Felder in der Datenbank bzw. modifizieren sie. Wir brauchen erst einmal nur ein Feld: content

Die Ausführung des Scripts bzw. die Migration wird angestoßen. 

php artisan migrate

Falls das folgenden Fehler erzeugt:

Eine Codezeile unter Providers/AppServiceProvider in der Methode boot() löst das Problem

Die Datenbank sollte nun so aussehen:

Wir wollen nun mitels des Tools: artisan tinker (im Terminal – im Document Root) 2 Datensätze in der Datenbank anlegen.

php artisan tinker

$blog = new App\Models\Blog

$blog->content = 'Mein erster Blogeintrag'

$blog->save()

Das dürfte zu folgendem Fehler führen:

Wir müssen dem Model noch mitteilen, zu welcher Tabelle es gehört:

Mit ctrl + c oder durch Eingabe des Befehls exit loggt man sich aus tinker aus.

Danach noch mal ausführen: in tinker einloggen, Model erzeugen, Eigenschaft setzen und speichern.

Unser Eintrag taucht dann auch erwartungsgemäß in der Datenbank auf:

Wir legen noch einen zweiten Datensatz an mit dem Content: Mein zweiter Blogeintrag.

Nun, wir möchten, dass die Route bzw. Adresse: http:/meineDomain/blogs uns die Einträge auf einer Webseite ausgibt.

Ein Controller soll für diese Route zuständig sein. 

php artisan make:controller BlogController

Wir fügen eine Action bzw. Methode index() ein.

Wir setzen die Route:

Wie gesagt, das Model ist sowohl für die Business Logik zuständig, als auch für den Datenbankzugriff

Dementsprechend besorgen wir uns im Controller die gewünschten Daten über das Blog Model:

Nicht vergessen: use App\Models\Blog; einfügen, sonst weiß Laravel nichts anzufangen.

Blog::all();

Wir brauchen noch die View. Diese legen wir an unter bzw. als resources/blogs.blade.php

Nun übergeben wir im Controller der View die Variable $blogs, also den Result aus der Datenbank:

Da unsere Abfrage alle Datensätze besorgt, ist die Rückgabe eine Collection. Wir müssen also in der View diese durchschleifen.

Die Template Engine Blade stellt uns dafür die Syntax bereit. Variablen werden immer in doppelte geschweifte Klammern gesetzt. Wir brauchen zusätzlich aber auch noch die Schleifen-Syntax:

Das Template bzw. Blade kann also durch diese Syntax auf die vorher im Controller übergebene Variable zugreifen und sie ausgeben bzw. verarbeiten.

Das Ergbnis im Browser sollte nun so aussehen:

Hier geht es weiter: Laravel Layout

Hier geht es zum vorherigen Teil: Laravel Beispielapp

Besuchen Sie auch gerne unsere Webseite: admin-code.de

Laravel Beispielapp

Wir programmieren eine Blog App.

Wir erzeugen mittels des CLI-Tools Artisan einen IndexController.

php artisan make:controller IndexController

Wir programmieren eine Methode, eine sogenannte Action, in den Controller

Nun passen wir die Definition der Route an.

Wir geben also als 2. Parameter den Controller und die Action an.

Die Syntax ::class löst übrigens den voll qualifizierten Namen auf – inkl. Namespace

Nun sollte das Ergebnis im Browser so aussehen.

Soweit klappt das also schon mal. Nun die View.

Laravel verwendet standardmäßig die Template-Engine Blade.
Der Konvention entsprechend erzeugen wir also unter resources/views ein File index.blade.php

Wir ändern die Index Action im Controller und lassen die View zurückgeben.

Nun sollte das Ergebnis im Browser so aussehen.

Wir haben nun also die Route gesetzt, verwenden einen Controller und geben eine neu erzeugte View zurück.

Hier geht es weiter: Laravel Datenbank

Hier geht es zum vorherigen Teil: Laravel Routing

Besuchen Sie auch gerne unsere Webseite: admin-code.de

Laravel Routing

Eine Route ist die angeforderte Ressource bzw. der URL.

Die Routen werden definiert in dem File routes/web.php.

Wie man sieht, wird hier eine Get-Route definiert.

  • Dabei bedeutet: „/“, dass die Domain angesteuert wird bzw. die index.html oder index.php.
  • Eine anonyme Funktion gibt dann die View zurück. Der Name der View, in diesem Fall: welcome, wird als Parameter mitgegeben.
  • Die View wird dann anhand des Namens unter resources/views gefunden

Dass die Route direkt die View zurückgibt, ist zwar technisch möglich, aber eher unüblich.

In der Beispielanwendung verwenden wir dann auch Routen, die mit Controllern zusammenarbeiten.

Hier geht es weiter: Laravel Beispielapp

Hier geht es zum vorherigen Teil: Laravel MVC

Besuchen Sie auch gerne unsere Webseite: admin-code.de