Die Anzeige der verschiedenen Bildgrößen in frühen Builds von Willow CMS war umständlich und repetitiv. In diesem Beitrag erzähle ich, wie ich mithilfe von PHP-Traits und magischen Methoden eine saubere, wartungsfreundliche Lösung für die URL-Generierung von Bildern erstellt habe.

PHP-Eigenschaften verstehen

Traits bieten einen Mechanismus zur Wiederverwendung von Code in Sprachen mit einfacher Vererbung wie PHP. Sie ermöglichen die Kapselung von Methoden, die in mehrere Klassen integriert werden sollen, und Klassen können mehrere Traits haben. Anstatt Code zu duplizieren oder komplexe Vererbungshierarchien zu erstellen, können wir mit Traits Funktionen bei Bedarf „einmischen“, indem wiruse Schlüsselwort. Dieser Ansatz hilft dabei, DRY-Prinzipien (Don't Repeat Yourself) einzuhalten.

Magische Methoden in PHP

Magische Methoden in PHP sind spezielle Methoden, die mit einem doppelten Unterstrich beginnen (__ ). Sie werden in bestimmten Situationen automatisch aufgerufen, sodass wir benutzerdefiniertes Verhalten für allgemeine Vorgänge definieren können. Wenn Sie beispielsweise versuchen, auf eine Eigenschaft zuzugreifen, auf die nicht direkt zugegriffen werden kann, ruft PHP die__get() magische Methode, wenn es Code gibt, der dieses Attribut „auf magische Weise“ zum Leben erweckt.

Einführung in ImageUrlTrait

DerImageUrlTrait kombiniert die Leistungsfähigkeit von Merkmalen und magischen Methoden, um die URL-Generierung von Bildern zu vereinfachen. Anstatt Methoden oder Attribute für jede Bildgröße (Mikro, winzig, klein, mittel, groß, extragroß, massiv) explizit zu definieren, übernimmt dieses Merkmal die URL-Generierung dynamisch basierend auf der gewünschten Größe. Das bedeutet, dass wir Bild-URLs für eine Klasse erhalten können, die das Merkmal mit$image->smallImageUrl oder$image->largeImageUrl ohne für jede Größe spezifische Methoden/Attribute zu schreiben.

Funktionsweise von ImageUrlTrait

Schauen Sie sich den Code mit Kommentaren an. Lassen Sie uns die Hauptkomponenten des Merkmals aufschlüsseln:

protected function _getImageUrl(): string
{
    return str_replace('webroot/', '', $this->dir . $this->image);
}

Mit dieser Methode können Sie die URL für die ursprüngliche Bilddatei mithilfe eines Attributs wie diesem abrufen:$image->imageUrl oder$user->imageUrl . Die Methode generiert die URL für das Originalbild, indem sie Verzeichnis und Dateinamen kombiniert und das Präfix „webroot/“ entfernt (da dasdir Die Spalte in der Datenbank enthält den relativen Verzeichnispfad des Dateisystems gemäß der Ordnerstruktur des CakePHP-Projekts).

public function &__get(string $attribute): mixed
{
    if (preg_match('/^(.+)ImageUrl$/', $attribute, $matches)) {
        $size = lcfirst($matches[1]);
        $imageSizes = SettingsManager::read('ImageSizes');
        if (isset($imageSizes[$size])) {
            $url = $this->getImageUrlBySize($size);

            return $url;
        }
    }
    return parent::__get($attribute);
}

Hier geschieht die Magie. Beim Zugriff auf eine Eigenschaft wie$iamge->smallImageUrl oder$image->massiveImageUrl , diese Methode:

  1. Überprüft, ob der Eigenschaftsname mit „ImageUrl“ endet, indem ein regulärer Ausdruck verwendet wird undpreg_match
  2. Extrahiert das Größenpräfix (z. B. „klein“) in$size
  3. Überprüft, ob die Größe in unserer Konfiguration vorhanden ist
  4. Ruft eine Methode im Merkmal auf, um die URL für die angegebene Größe abzurufen
  5. Gibt die URL zurück
  6. Wenn keine Übereinstimmung gefunden wird, ruft das übergeordnete__get() Methode (weil CakePHP auch magische Methoden verwendet und wir die Methodenaufrufkette nicht unterbrechen möchten)

Der alte Weg: Ausführlich und fehleranfällig

Vor der Implementierung des Merkmals war für die Anzeige von Bildern mit Vorschau ausführlicher Code erforderlich:

$this->Html->image(SettingsManager::read('ImageSizes.small', '200') . '/' . $user->picture, 
    ['pathPrefix' => 'files/Users/picture/', 
    'alt' => $user->alt_text, 
    'class' => 'img-thumbnail', 
    'width' => '50',
    'data-bs-toggle' => 'popover',
    'data-bs-trigger' => 'hover',
    'data-bs-html' => 'true',
    'data-bs-content' => $this->Html->image(SettingsManager::read('ImageSizes.large', '400') . '/' . $user->picture, 
        ['pathPrefix' => 'files/Users/picture/', 
        'alt' => $user->alt_text, 
        'class' => 'img-fluid', 
        'style' => 'max-width: 300px; max-height: 300px;'])
    ]) 

Pfui! Dieser Ansatz hatte mehrere Probleme:

  • Wiederholte Anrufe anSettingsManager::read() mit kniffliger Punktnotation zur Auswahl einer Bildgröße
  • Komplexe verschachtelte HTML-Hilfsaufrufe
  • Schwer lesbarer Code
  • Erhöhte Wahrscheinlichkeit von Tippfehlern in Größennamen oder Pfaden beim Kopieren/Einfügen in den Ansichten

Der neue Weg: Sauber und wartungsfreundlich

Jetzt mitImageUrlTrait und einem einfachen Element können wir viel saubereren Code schreiben:

    $this->element('image/icon', [
        'model' => $article, 
        'icon' => $article->smallImageUrl, 
        'preview' => $article->largeImageUrl
    ]); 

Die Vorteile liegen auf der Hand:

  • Besser lesbarer Code
  • Weniger Wiederholungen
  • Reduziertes Fehlerrisiko
  • Einheitliche Bildverarbeitung in der gesamten Anwendung
  • Einfaches Ändern der Bildgröße (wenn ich möchte, dass das Vorschaubild größer ist, mache ich einfach'preview' => $article->massiveImageUrl )

Schlagwörter

Umgestaltung Code KuchenPHP Codequalität Merkmale