Laravel-Modelle: Wo sind Modelleigenschaften?

Lesezeit: 10 Minuten

Benutzeravatar von dotNET
Punkt net

(Ich komme aus dem Visual Studio + Entity Framework-Hintergrund und versuche, gleichwertige Funktionen in Laravel + Eloquent zu finden.)

In EF und Visual Studio fügen wir unserer Anwendung ein neues Modell hinzu und teilen ihm einfach unsere vorhandene Datenbank mit. EF kann dann Modelle für meine Tabellen mit öffentlichen Eigenschaften für Spalten generieren. Dies gibt uns all diese IDE- und Compiler-Vorteile wie Intellisense, Rechtschreibfehlererkennung usw.

Ich habe kürzlich erklärt, dass ich VS Code, Laravel und Eloquent erkundet habe. Beim Durchgehen all dieser Tutorials und Artikel bin ich mir nicht sicher, wann und wie diese Eigenschaften in den Modellklassen generiert werden. Ich habe es versucht artisan make:model Befehl und es hat die Modellklasse generiert, aber es gibt keine Eigenschaften darin. So,

  1. Soll ich sie von Hand schreiben? (Wirklich?)
  2. Werden dies nur öffentliche Variablen oder Standardeigenschaften mit Getter/Setter sein (entschuldigen Sie meine .NET-Mentalität :))?
  3. Gibt es ein Tool/eine Erweiterung, die meine Datenbank untersuchen und Modelle mit Eigenschaften für ihre Spalten erstellen könnte?

Aktualisieren

An die Leute, die meine Frage beantwortet haben, vielen Dank. Außerdem waren einige der Kommentare, die ich gepostet habe, auf meine Unkenntnis über den (seltsamen IMO) Ansatz von PHP in Bezug auf den Mitgliederzugriff zurückzuführen; Ich habe gerade herausgefunden, dass PHP sich nicht über nicht vorhandene Klassenmitglieder beschwert und sie stattdessen spontan generiert (z $post->NonExistingMember = SomeValue läuft gut; dies würde nicht einmal in den meisten anderen Sprachen, die ich kenne, kompiliert werden). Große Überraschung für mich. Ich habe C++, VB, C#, Java und mehrere andere Sprachen verwendet und habe dieses Verhalten nirgendwo anders gesehen. Alle diese Sprachen würden sofort einen Kompilierungsfehler ausgeben, der besagt, dass Typ X kein Mitglied namens Y enthält. Ich kann nicht sehen, wie der unterschiedliche Ansatz von PHP mit OOP zusammenpasst.

Das eigentliche Problem, für das ich diese Frage gepostet habe, bleibt immer noch ungelöst. Obwohl ich verwenden kann Reliese / Laravel Um Modellklassen für meine Datenbank zu generieren, generiert das Tool immer noch keine Klassenmitglieder für Tabellenspalten, sodass ich keine Vorteile der automatischen Vervollständigung erhalte. Ich würde gerne von den Experten hören, ob das möglich ist (automatisch natürlich).

Aktualisierung 2

Jetzt, da ich die Laravel-Umgebung etwas besser verstehe, dachte ich, ich würde meine Erfahrungen teilen. Siehe meine Antwort unten.

  • Vielleicht könnte dir das helfen: stackoverflow.com/questions/30560485/…

    – Raffael

    8. August 2018 um 11:33 Uhr

  • Vielleicht kann das helfen: Laravel: Eloquent Erste Schritte. Aber im Grunde ja, Sie schreiben sie von Hand. Es sind Pakete verfügbar, die Modelle aus einer vorhandenen Datenbank generieren können

    – Brombeer

    8. August 2018 um 11:38 Uhr

  • @RafaelBoszko: Das trifft den Nagel auf den Kopf (das ist Nagelkopf :)). Danke schön.

    – Punkt net

    8. August 2018 um 11:43 Uhr

  • Haben Sie dies jemals so gelöst, dass Sie die Vorteile der automatischen Vervollständigung erhalten? Auch ich komme aus C# und bin es gewohnt, dass die Dinge etwas expliziter und nicht “automagisch” sind.

    – Louise Eggleton

    15. November 2019 um 12:49 Uhr

  • @LouiseEggleton: Ich habe mehr Zeit damit verbracht, mit Laravel zu arbeiten. Das grundlegende Problem (oder nennen Sie es Feature) besteht darin, dass eine Klasse zur Kompilierungszeit kein Mitglied enthalten muss, da es kein Element gibt Kompilierzeit sozusagen. PHP interpretiert den Code zur Laufzeit und generiert spontan Mitglieder. Eine Modellklasse erfordert also überhaupt keine Mitglieder. Dies unterscheidet sich stark von der C#-Welt, in der wir stark typisierte Modelle (Entity oder sogar DataSets) mit einer 1-1-Entsprechung zwischen Klasseneigenschaften und zugrunde liegenden Tabellenspalten haben. All dies bedeutet, dass es in VS Code keine automatische Vervollständigung geben wird Laravel.

    – Punkt net

    15. November 2019 um 17:24 Uhr

Benutzeravatar von dotNET
Punkt net

Nachdem ich nun einige Zeit mit Laravel, Eloquent und PHP im Allgemeinen verbracht habe, werde ich ein paar Dinge teilen in der Hoffnung, dass dies anderen Startern hilft.

PHP ist eine dynamische Sprache und ihr Code wird im laufenden Betrieb kompiliert (im Gegensatz zu C# und VB.NET). Ihre Modellklassen müssen Mitglieder nicht explizit definieren, damit sie zugänglich/zuweisbar sind, solange sie erweitert werden Model (eine eingebaute Klasse in Laravel Eloquent) können Sie nicht existierenden Mitgliedern Werte zuweisen, die denselben Namen wie die zugrunde liegende Datenbanktabellenspalte haben, und Eloquent speichert sie für Sie in der DB. Also zum Beispiel, wenn Sie eine posts Tabelle in Ihrer Datenbank, die eine Spalte mit dem Namen hat bodykönnen Sie den folgenden Code schreiben, um einen neuen Datensatz in Ihrer Datenbank zu erstellen:

$p = new Post;
$p->body = 'Some stuff';
$p->save();

Natürlich muss man eine Klasse haben Post in Ihrem Projekt, das von reicht Model Sie müssen jedoch kein Mitglied definieren body innerhalb dieser Klasse. Das mag für Leute aus der .NET-Welt seltsam klingen, aber so funktionieren dynamische Sprachen.

Für die automatische Generierung von Modellen enthält Laravel integrierte Befehle (php artisan make:model), die diese für Sie generieren können.

Verwenden Sie schließlich für Intellisense und Autocomplete dasselbe Tool, das von Laravel selbst verwendet wird, dh DocBlocks. Dies sind spezielle Kommentare in PHP, mit denen Sie Ihre Codeelemente dokumentieren können. Sie können also allen Ihren Modellklassen, die Eigenschaftsnamen und -typen enthalten, DocBlocks hinzufügen. Zum Glück für alle gibt es eine sehr nette Erweiterung in VS Code, die dies automatisch für Sie erledigen kann. Installieren Sie es mit dem folgenden Befehl:

composer require --dev barryvdh/laravel-ide-helper

Führen Sie nun den folgenden Befehl aus, um DocBlocks für alle Ihre Modellklassen zu generieren (natürlich sollten Sie Ihre Datenbank und Modelle bereits vorher generiert haben):

php artisan ide-helper:models --dir="app"

Die Erweiterung ruft die Struktur Ihrer Datenbank ab und injiziert DocBlocks in alle Ihre Modelle, die in etwa so aussehen:

/**
 * App\User
 *
 * @property int $id
 * @property string $name
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Exam whereUpdatedAt($value)
 * @mixin \Eloquent
 */
class User extends Model
{
}

VS Code zeigt Ihnen jetzt Tabellenfeldnamen in Modelleigenschaften an, wie hier (sehen Sie, wie Intellisense auftaucht name Mitglied aus unseren DocBlocks, während wir tippen na...):

Geben Sie hier die Bildbeschreibung ein Beachten Sie, dass ich auch Intelephense in meinem VS-Code installiert habe, obwohl ich nicht sicher bin, ob dies erforderlich ist, damit die Funktion zur automatischen Vervollständigung funktioniert.

Bearbeiten

Dynamische Eigenschaften sind in PHP 8.2 veraltet und ich höre, dass sie in PHP 9.0 ungültig werden, was bedeutet, dass Laravel-Modelle in zukünftigen Versionen nicht in der Lage sein sollten, diese magischen Dinge zu tun.

Ich bin kein PHP-Guru, aber ich habe gehört, dass wir nicht in Panik geraten müssen. Zwei Dinge: Erstens die Implementierung der Objekte __get Und __set wird weiterhin gut funktionieren. Zweitens Plus, das Sie (sie) auch verwenden können #[AllowDynamicProperties] auf Modellklassen, um dynamische Requisiten zuzulassen. Und schließlich können sie den Modellgenerator umschreiben, um Spaltennamen als Requisiten in der Modellklasse auszuspucken. Letzteres wird das Beste sein und PHP der Funktionsweise der C#-Welt einen Schritt näher bringen (genau dort, wo dieser Beitrag begonnen hat, lol).

  • Sie müssen die Eigenschaften nicht definieren, sondern Sie selbst darf nicht Eigenschaften definieren. Ihre Definition bricht mit den Annahmen von Eloquent. Dies ist eine Designentscheidung, die ich nicht verstehe, aber ärgerlicher ist, dass sie auf den Laravel-Dokumentationsseiten nicht erwähnt wird.

    – weit

    6. Oktober 2020 um 15:19 Uhr

  • Ich hatte dieses Rätsel, als ich von Symfony zu Laravel wechselte. Wie Sie selbst programmiere ich viele Sprachen und bevorzuge den strikten Typ, Sie können PHP strikt oder locker in 7+ codieren. In Symfony verwende ich Doktrin orm für die Datenbank, sie werden Entitäten anstelle von Modellen genannt, aber sie sind nur eine codierte Version Ihrer Tabelle und verwenden Repositories, um Abfragen durchzuführen. Sie deklarieren die Eigenschaften tatsächlich mit Gettern und Settern. Laravel verwendet magische Methoden, um die Eigenschaften zu erstellen, ich mag es nicht, aber ich mag Laravel im Allgemeinen, also lebe ich damit. Die Verwendung des Docblock-Ansatzes funktioniert jedoch gut, um ihn ein wenig auszugleichen

    – MMMWeirdo

    20. Januar 2022 um 20:07 Uhr


  • Nun, wie wäre es jetzt, wenn dynamische Eigenschaften in PHP 8.2 als veraltet gelten (php.net/releases/8.2/en.php#deprecate_dynamic_properties)? In der Laravel-Dokumentation konnte ich dazu nichts finden.

    – Boris N

    10. Februar um 0:37 Uhr


  • Modellattribute sind keine dynamischen Eigenschaften. Laravel verwendet die magischen Methoden __get und __set, um Datenbankspalten einer Eigenschaft zuzuordnen, die ein Array von Attributen ist.

    – Teilen

    23. Februar um 19:33 Uhr

Benutzeravatar des Holonauten
Holonaut

Ich verwende Anmerkungen, um alle Eigenschaften für die automatische Vervollständigung zu deklarieren (funktioniert in PHPStorm, bin mir bei anderen IDEs nicht sicher).

/**
 * @property $id
 * @property $microsoft_id
 * @property $name
 * @property $qualification
 * @property $company
 */
class ShopTenant extends Model
{
    public $connection = 'shop';
    public $table="tenants";
    protected $guarded = ['id'];
}

Sie können so etwas verwenden, um eine Liste aller Spalten einer Tabelle zu erhalten, und diese Liste dann in Ihre Anmerkungen einfügen/formatieren:

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'tenants';

Benutzeravatar von NicuVlad
NicuVlad

  1. Leider ja, Sie müssen sie von Hand schreiben, aber nur, wenn Sie den Wert dieser Eigenschaften aktualisieren müssen, überprüfen Sie Punkt 2 ($fillable array)
  2. Sie müssen die Eigenschaften deklarieren, die gefüllt werden können:

Zum Beispiel ein Modell namens Post für eine Datenbanktabelle “posts”, die 2 Spalten “title” und “body” hat:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{

 //not mandatory to declare the table name, Laravel will find it using reflection if you follow the naming standard
 protected $table="posts"; //not mandatory

 protected $fillable = ['title','body'];
}

Im Steuergerät:

$newPost = new Post;
$newPost->title="A new title";
$newPost->body = 'A new body';
$newPost->save(); //only at this point the db is modified

Oder Sie können sie ausblenden, wenn Sie die Eigenschaften in einem Array oder einer JSON-Antwort zurückgeben (in der Sammlung werden auch die ausgeblendeten angezeigt):

protected $hidden = [
 'title',
];

Sie können auch neue Eigenschaften in das Modell einfügen, indem Sie verwenden Accessoren

  1. Ich glaube nicht, Sie können einige Laravel VS Code-Plugins installieren, um Ihr Leben einfacher zu machen (z. B.: Blade-Snippets). Sie können dies überprüfen Dieser Artikel.

  • Danke. Können Sie Ihre Modellklassendefinition in die Antwort aufnehmen?

    – Punkt net

    8. August 2018 um 12:07 Uhr

  • Überprüfen Sie meine aktualisierte Antwort. Ich hoffe, Sie haben danach gefragt. Wenn Sie etwas anderes brauchen, kann ich meine Antwort aktualisieren.

    – NicuVlad

    8. August 2018 um 12:16 Uhr

  • Jetzt bist du nahe an dem, was ich verlange. Was ist $newPost->title im obigen Code? In Ihrer Klasse gibt es keine solche Eigenschaft oder öffentliche Variable. Selbst wenn dies der Fall wäre, wie würde diese Variable der zugrunde liegenden Tabellenspalte zugeordnet werden?

    – Punkt net

    8. August 2018 um 12:29 Uhr


  • Der Titel ist die „Titel“-Spalte aus Ihrer Datenbank. Wenn Sie einen Beitrag erstellen und einen „Titel“-Wert hinzufügen müssen, müssen Sie den Titel im „$fillable“-Array hinzufügen.

    – NicuVlad

    8. August 2018 um 12:33 Uhr

  • Standardmäßig müssen Sie wahrscheinlich auch eine „id“, „created_at“ und „updated_at“ von Laravel erstellen, aber in diesem Array müssen Sie nur die Eigenschaften deklarieren, die Sie ändern müssen.

    – NicuVlad

    8. August 2018 um 12:36 Uhr

Eigentlich müssen Sie die Eigenschaften nicht angeben. Es wird alles automatisch von Laravel erledigt. Wenn Sie ein Modell erstellen, verwendet Laravel den Plural (und es hat ein wirklich gutes System dafür: Post wird zu Posts, Aktivität wird zu Aktivitäten usw.) des Klassennamens, um auf die Tabelle zuzugreifen. Sie können also mit einem leeren Modell arbeiten, ohne die Eigenschaft $table oder $fillable/$guarded zu setzen.

// use only, if your table name differs from the models classname
$table="users_options"; // when you want to name your model 'Vote' but the table is called 'users_options' for instance.

// use fillable and guarded only to specify mass-assignment columns
$fillable = [whatever, ...];
$guarded = [whatever, ...];

Sie können jederzeit auf die Eigenschaften zugreifen:

class Post extends Model
{

}

// would do sth like this: select name from posts where id = 1;
// without specifying anything in the model
$name = Post::find(1)->name;

Sie müssen selbst hinzufügen. Zum Beispiel

$fillable = ['firstname', 'email','username'];
$guarded = ['price'];

  • Ich suche nach öffentlichen Eigenschaften für meine Spalten, damit ich Codezeitvorteile wie automatische Vervollständigung und Erkennung von Rechtschreibfehlern usw. erhalte.

    – Punkt net

    8. August 2018 um 17:48 Uhr

  • Ich suche nach öffentlichen Eigenschaften für meine Spalten, damit ich Codezeitvorteile wie automatische Vervollständigung und Erkennung von Rechtschreibfehlern usw. erhalte.

    – Punkt net

    8. August 2018 um 17:48 Uhr

1444620cookie-checkLaravel-Modelle: Wo sind Modelleigenschaften?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy