So konfigurieren und verwenden Sie PDO für den Datenbankzugriff unter Linux
- 3082
- 216
- Matteo Möllinger
Zielsetzung
Erfahren Sie, wie Sie PDO für den Datenbankzugriff konfigurieren und verwenden: Von Fehlermodi zum Abrufen von Methoden.
Anforderungen
- Ein Standardkenntnis von MySQL und
Mysql
Befehlszeile Client; - Mit den grundlegenden Konzepten der objektorientierten Programmierung vertraut sein
- Php> = 5.1
- Haben Sie eine funktionierende MySQL/Mariadb -Datenbank
Schwierigkeit
MITTEL
Konventionen
- # - Erfordert, dass gegebene Linux -Befehle entweder mit Root -Berechtigungen ausgeführt werden müssen
direkt als Stammbenutzer oder durch Verwendung vonsudo
Befehl - $ - Erfordert, dass die angegebenen Linux-Befehle als regelmäßiger nicht privilegierter Benutzer ausgeführt werden können
Einführung
PDO ist eine Abkürzung für PHP -Datenobjekte
: Es handelt sich um eine PHP -Erweiterung für die Interaktion mit Datenbanken durch die Verwendung von Objekten. Eine seiner Stärken liegt in der Tatsache, dass sie nicht streng mit einer bestimmten Datenbank verbunden ist: Die Schnittstelle bietet unter anderem eine gemeinsame Möglichkeit, auf verschiedene Umgebungen zuzugreifen:
- Mysql
- Sqlite
- PostgreSQL
- Microsoft SQL Server
Dieser Leitfaden zielt darauf ab, einen völlig vollständigen Überblick über PDO zu bieten, wobei der Leser Schritt für Schritt aus der Herstellung einer Verbindung zur Datenbank zur Auswahl des am besten geeigneten Abrufmodus führt.
Erstellen Sie eine Testdatenbank und Tabelle
Das erste, was wir tun werden, ist, eine Datenbank für dieses Tutorial zu erstellen:
Datenbank erstellen Solar_System; Gewähren Sie alle Privilegien für Solar_System.* Zu 'testuser'@'localhost' identifiziert durch 'testPassword';
Kopieren Wir haben dem Benutzer gewährt Testuser
alle Privilegien auf der Sonnensystem
Datenbank, verwendet Testpasswort
als Passwort. Erstellen wir nun eine Tabelle und füllen sie mit einigen Daten (keine astronomische Genauigkeit beabsichtigt):
Verwenden Sie Solar_System; Tischplaneten erstellen (id tinyint (1) Unsigned NOT NULL AUTO_INCREMENT, Primärschlüssel (ID), Name Varchar (10) NICHT NULL, COLOR VARCHAR (10) NICHT NULL); In Planeten (Name, Farbe) Werte einfügen ('Erde', 'blau'), ('Mars', 'rot'), ('Jupiter', 'seltsam');
Kopieren DSN: Datenquellenname
Jetzt, da wir eine Datenbank haben, müssen wir a definieren DSN
. DSN steht für Datenquellenname
, und es handelt sich im Grunde genommen um eine Reihe von Informationen, die zur Verbindung zur Datenbank erforderlich sind, die in Form einer Zeichenfolge dargestellt werden. Die Syntax kann je nach Datenbank, mit der Sie eine Verbindung herstellen möchten, unterschiedlich sein. Da wir jedoch mit MySQL/Mariadb interagieren, werden wir:
- Die Art des Treibers für die Verbindung zu verwenden
- Der Hostname des Computers, der die Datenbank hostet
- Der Port, der für die Verbindung verwendet wird (optional)
- Der Name der Datenbank
- Das Zeichen (optional)
Das Format der Zeichenfolge wäre in unserem Fall das folgende (wir werden sie in der speichern $ dsn
Variable):
$ dsn = "mysql: host = localhost; port = 3306; dbname = solar_system; charSet = utf8";
Kopieren Erstens haben wir das zur Verfügung gestellt Datenbankpräfix
. In diesem Fall haben wir verwendet, da wir eine Verbindung zu einer MySQL/MariADB Mysql
. Wir haben dann das Präfix vom Rest der Saite durch einen Dickdarm und jeden anderen Abschnitte durch ein Semikolon getrennt.
In den nächsten beiden Abschnitten haben wir die angegeben Hostname
der Maschine, auf der die Datenbank gehostet wird und die Hafen
Für die Verbindung verwenden. Wenn der letztere nicht bereitgestellt wird, wird der Standard verwendet, was in diesem Fall in diesem Fall ist 3306
. Sofort nachdem wir das zur Verfügung gestellt haben Name der Datenbank
, und danach die Charset
benutzen.
Erstellen des PDO -Objekts
Jetzt, wo unser DSN bereit ist, werden wir das bauen PDO -Objekt
. Der PDO -Konstruktor nimmt die DSN -Zeichenfolge als erster Parameter, den Namen des Benutzers in der Datenbank als zweiten Parameter, sein Passwort als dritter und optional als Array von Optionen als viertes an:
$ options = [pdo :: attr_errmode => pdo :: errmode_exception, pdo :: attr_default_fetch_mode => pdo :: fetch_assoc]; $ pdo = new pdo ($ dsn, 'testuser', 'testPassword', $ options);
Kopieren Die Optionen können jedoch auch nach dem Erstellen des Objekts über die angegeben werden SetAttribute ()
Methode:
$ pdo-> setAttribute (pdo :: attr_errmode, pdo :: errmode_exception);
Kopieren Festlegen von PDO -Verhalten auf Fehlern
Schauen wir uns einige der verfügbaren Optionen an Pdo :: attr_errmode
. Diese Option ist wirklich wichtig, da das PDO -Verhalten bei Fehlern definiert. Mögliche Optionen sind:
Pdo :: ermode_silent
Dies ist der Standardwert. PDO legt nur die Fehlercode und die Fehlermeldung fest. Sie können mit der Verwendung der abgerufen werden Fehlercode()
Und FehlerInfo ()
Methoden.
Pdo :: errmode_exception
Dies ist meiner Meinung nach die empfohlene. Mit dieser Option wird PDO zusätzlich zum Einstellen des Fehlercodes und der Info a PdoException
, die den Skriptfluss brechen und im Fall von besonders nützlich ist PDO -Transaktionen
(Wir werden sehen, welche Transaktionen später in diesem Tutorial liegen).
Pdo :: errmode_warning
Mit dieser Option setzt PDO den Fehlercode und die Info als indiziert fest Pdo :: ermode_silent
, wird aber auch a ausgeben a WARNUNG
, die den Fluss des Skripts nicht brechen wird.
Einstellung des Standard -Abrufmodus
Eine weitere wichtige Einstellung kann über den PDO :: default_fetch_mode angegeben werden. Konstante. Sie können die Standardfetch -Methode angeben, die beim Abrufen von Ergebnissen aus einer Abfrage verwendet werden soll. Dies sind die am häufigsten verwendeten Optionen:
Pdo :: fetch_both:
Dies ist der Standardwert. Damit wird das von einer Abfassungsabfrage abgerufene Ergebnis sowohl durch Integer als auch mit dem Spaltennamen indiziert. Wenn Sie diesen Abrufmodus beim Abrufen einer Zeile aus der Planets Tabelle anwenden, wird uns dieses Ergebnis vergeben:
$ STMT = $ PDO-> Abfrage ("aus Planeten auswählen"); $ results = $ stmt-> fetch (pdo :: fetch_both);
Kopieren Array ([ID] => 1 [0] => 1 [Name] => Erde [1] => Erde [Farbe] => Blau [2] => Blau)
Pdo :: fetch_assoc:
Mit dieser Option wird das Ergebnis in einem gespeichert Assoziatives Array
In welchem Schlüssel wird der Name der Spalte und jeder Wert der entsprechende Wert in einer Zeile:
$ STMT = $ PDO-> Abfrage ("aus Planeten auswählen"); $ results = $ stmt-> fetch (pdo :: fetch_assoc);
Kopieren Array ([ID] => 1 [Name] => Erde [Farbe] => Blau)
Pdo :: fetch_num
Dieser Abrufmodus gibt die abgerufene Zeile in a zurück 0-Indexed-Array:
Array ([0] => 1 [1] => Erde [2] => Blau)
Pdo :: fetch_column
Diese Abrufmethode ist nützlich, wenn Sie nur die Werte einer Spalte abrufen und alle Ergebnisse in einem einfachen, eindimensionalen Array zurückgeben. Zum Beispiel diese Abfrage:
$ STMT = $ PDO-> Abfrage ("Name aus Planeten auswählen");
Kopieren Würde dieses Ergebnis zurückgeben:
Array ([0] => Erde [1] => Mars [2] => Jupiter)
Pdo :: fetch_key_pair
Diese Abrufmethode ist nützlich, wenn Sie die Werte von nur 2 Spalten abrufen. Es wird die Ergebnisse in Form eines assoziativen Arrays zurückgeben, in dem die aus der Datenbank für die ersten angegebenen Spalte in der Abfrage abgerufenen Werte als Array -Tasten verwendet werden Array -Werte:
$ STMT = $ PDO-> Abfrage ("Name, Farbe aus Planeten auswählen"); $ result = $ stmt-> fetchall (pdo :: fetch_key_pair);
Kopieren Würde zurückkehren:
Array ([Erde] => blau [Mars] => Rot [Jupiter] => Seltsam)
Pdo :: fetch_object:
Bei Verwendung der Pdo :: fetch_object
konstant, an anonymer Objekt
wird für jede abgerufene Zeile erstellt. Die (öffentlichen) Eigenschaften werden nach den Spalten benannt, und die Abfrageergebnisse werden als ihre Werte verwendet. Wenn Sie diesen Abrufmodus auf dieselbe Abfrage oben anwenden, wird uns ein Ergebnis des Formulars zurückgegeben:
$ results = $ stmt-> fetch (pdo :: fetch_obj);
Kopieren STDCASS -Objekt ([Name] => Erde [Farbe] => Blau)
Pdo :: fetch_class:
Dieser Abrufmodus weist wie die oben genannten den Wert der Spalten den Eigenschaften eines Objekts zu. In diesem Fall sollten wir jedoch eine vorhandene Klasse angeben, mit der das Objekt erstellt werden sollte. Lassen Sie es uns demonstrieren, zuerst werden wir eine Klasse erstellen:
Klassenplanet privat $ name; private $ color; public function setName ($ planet_name) $ this-> name = $ planet_name; public function setColor ($ planet_color) $ this-> color = $ planet_color; public function getName () return $ this-> name; public function getColor () return $ this-> color;
Kopieren Bitte ignorieren Sie die Naivität des obigen Codes und beachten Sie nur, dass die Eigenschaften der Planetenklasse sind Privatgelände
Und die Klasse hat keinen Konstruktor. Versuchen wir nun, die Ergebnisse zu erzielen.
Beim Benutzen bringen()
mit Pdo :: fetch_class
Sie müssen die verwenden setfechmode ()
Methode im Anweisungsobjekt, bevor Sie versuchen, die Daten abzurufen, z. B.:
$ STMT = $ PDO-> Abfrage ("Name, Farbe aus Planeten auswählen"); $ stmt-> setfetchMode (pdo :: fetch_class, 'Planet');
Kopieren Wir haben die Fetch -Optionskonstante zur Verfügung gestellt Pdo :: fetch_class
Als erstes Argument der Methode setFetchMode () und als der Name der Klasse, mit der das Objekt (in diesem Fall 'Planet') als zweites erstellt werden sollte. Jetzt rennen wir:
$ planet = $ stmt-> fetch ();
Kopieren Ein Planetenobjekt sollte erstellt werden:
var_dump ($ planet);
Kopieren Planet -Objekt ([Name: Planet: privat] => Erde [Farbe: Planet: privat] => blau)
Beachten Sie, wie die aus der Abfrage resultierenden Werte den entsprechenden Eigenschaften des Objekts zugewiesen wurden, selbst wenn sie privat sind.
Zuweisen von Eigenschaften nach der Objektkonstruktion
Die Planet -Klasse hat keinen expliziten Konstruktor definiert, daher keine Probleme bei der Zuweisung der Eigenschaften. Aber was wäre, wenn die Klasse einen Konstruktor hätte, bei dem die Eigenschaft zugeordnet oder manipuliert wurde? Da die Werte zugewiesen werden, bevor der Konstruktor aufgerufen wird, wären sie überschrieben worden.
PDO hilft der Bereitstellung der Fetch_props_late
Konstante: Bei der Verwendung werden die Werte den Eigenschaften zugeordnet nach Das Objekt ist konstruiert. Zum Beispiel:
Klassenplanet privat $ name; private $ color; öffentliche Funktion __construct ($ name = mond, $ color = grau) $ this-> name = $ name; $ this-> color = $ color; public function setName ($ planet_name) $ this-> name = $ planet_name; public function setColor ($ planet_color) $ this-> color = $ planet_color; public function getName () return $ this-> name; public function getColor () return $ this-> color;
Kopieren Wir haben unsere Planetenklasse geändert und einen Konstruktor bereitgestellt, der zwei Argumente einnimmt: das erste ist Name
und der zweite ist Farbe
. Diese Argumente haben jeweils einen Standardwert von Mond
Und grau
: Dies bedeutet, dass, wenn keine Werte explizit bereitgestellt werden.
In diesem Fall, wenn wir nicht verwenden Fetch_props_late
, Unabhängig von den aus der Datenbank abgerufenen Werten haben die Eigenschaften immer die Standardwerte, da sie überschrieben werden, wenn das Objekt konstruiert ist. Überprüfen wir es. Zuerst führen wir die Frage aus:
$ stmt = $ pdo-> query ("Name auswählen, Farbe von Solar_System wobei Name = 'Earth'"); $ stmt-> setfetchMode (pdo :: fetch_class, 'Planet'); $ planet = $ stmt-> fetch ();
Kopieren Dann werfen wir die ab Planet
Objekt und überprüfen Sie, welche Werte seine Eigenschaften haben:
var_dump ($ planet); Objekt (Planet)#2 (2) ["Name": "Planet": privat] => String (4) "Mond" ["Farbe": "Planet": privat] => String (4) "Grau"
Kopieren Wie erwartet wurden die aus der Datenbank abgerufenen Werte von den Standardeinstellungen überschrieben. Jetzt zeigen wir, wie dieses Problem durch Verwendung gelöst werden kann Fetch_props_late
(Die Abfrage ist die gleiche wie oben):
$ stmt-> setfetchMode (pdo :: fetch_class | pdo :: fetch_props_late, 'Planet'); $ planet = $ stmt-> fetch (); var_dump ($ planet); Objekt (Planet)#4 (2) ["Name": "Planet": privat] => String (5) "Erde" ["Farbe": "Planet": privat] => String (4) "Blau"
Kopieren Endlich haben wir die gewünschten Ergebnisse erzielt. Aber was ist, wenn der Klassenkonstruktor keine Standardwerte hat und er bereitgestellt werden muss ? Einfach: Wir können die Konstruktorparameter in Form eines Arrays als drittes Argument nach dem Klassennamen in der Methode setfetchMode () angeben. Lassen Sie zum Beispiel den Konstruktor ändern:
Klassenplanet privat $ name; private $ color; öffentliche Funktion __construct ($ name, $ color) $ this-> name = $ name; $ this-> color = $ color; […]
Kopieren Die Konstruktorargumente sind jetzt obligatorisch, also würden wir laufen:
$ stmt-> setfetchMode (pdo :: fetch_class | pdo :: fetch_props_late, 'Planet', ['Moon', 'Gray']);
Kopieren In diesem Fall dienen die von uns bereitgestellten Parameter genau als Standardwerte, um das Objekt ohne Fehler zu initialisieren: Sie werden durch die aus der Datenbank abgerufenen Werte überschrieben.
Mehrere Objekte abrufen
Natürlich ist es möglich, mehrere Ergebnisse als Objekte zu erzielen, die entweder verwendet werden bringen()
Methode innerhalb einer Weile Schleife:
while ($ planet = $ stmt-> fetch ()) // Machen Sie Dinge mit den Ergebnissen
Kopieren oder durch das Abrufen aller Ergebnisse gleichzeitig. In diesem Fall, wie oben erwähnt, verwenden Sie die fetchall ()
Methode, Sie müssen den Fetch -Modus nicht angeben, bevor Sie die Methode selbst aufrufen, sondern im Moment, in dem Sie ihn nennen:
$ stmt-> fetchall (pdo :: fetch_class | pdo_fetch_props_late, 'Planet', ['Moon', 'Gray']);
Kopieren Pdo :: fetch_into
Mit dieser Fetch -Methode erstellt PDO kein neues Objekt, sondern aktualisiert die Eigenschaften eines vorhandenen, sondern nur, wenn sie es sind öffentlich
, oder wenn Sie die verwenden __Satz
Magische Methode im Objekt.
Vorbereitete gegen direkte Aussagen
PDO hat zwei Möglichkeiten, Abfragen auszuführen: Einer ist der direkte, einstufige Weg. Das andere, sicherere ist zu verwenden Vorbereitete Aussagen
.
Direkte Abfragen
Bei Verwendung direkter Abfragen haben Sie zwei Hauptmethoden: Anfrage()
Und exec ()
. Erstere Rendits Returns a Pdostatemnt
Objekt, mit dem Sie über die auf Ergebnisse zugreifen können bringen()
oder fetchall ()
Methoden: Sie verwenden es für eine Anweisung, die eine Tabelle nicht ändert, wie z WÄHLEN
.
Letzteres gibt stattdessen die Anzahl der Zeile zurück, die durch die Abfrage geändert wurden: Wir verwenden sie für Aussagen, die Zeilen wie EINFÜGUNG
, LÖSCHEN
oder AKTUALISIEREN
. Direkte Aussagen sind nur zu verwenden, wenn in der Abfrage keine Variablen enthalten sind und Sie absolut vertrauen, dass es sicher ist und ordnungsgemäß entkommen ist.
Vorbereitete Aussagen
PDO unterstützt auch zweistufige, vorbereitete Aussagen: Dies ist nützlich, wenn sie Variablen in der Abfrage verwenden, und es ist im Allgemeinen sicherer, weil die vorbereiten()
Die Methode führt die notwendige Flucht für uns durch. Mal sehen, wie Variablen verwendet werden. Stellen Sie sich vor, wir möchten die Eigenschaften eines Planetenobjekts in die einfügen Planeten
Tisch. Zuerst würden wir die Abfrage vorbereiten:
$ stmt = $ pdo-> vorbereiten ("In Planeten (Name, Farbe) Werte einfügen (?, ?) ");
Kopieren Wie bereits gesagt, würden wir zuerst die verwenden vorbereiten()
Methode, die die SQL -Abfrage als Argument nimmt und Platzhalter für die Variablen verwendet. Jetzt können Platzhalter von zwei Arten sein:
Positionsplatzhalter
Beim Benutzen ?
Positionsplatzhalter Wir können prägnanter Code erhalten, müssen jedoch die Werte in derselben Reihenfolge der Spaltennamen in einem Array als Argument an die angeben, die ersetzt werden sollen ausführen()
Methode:
$ stmt-> execute ([$ planet-> name, $ planet-> color]);
Kopieren Namens Platzhalter
Verwendung Namens Platzhalter
, Wir müssen keine bestimmte Reihenfolge respektieren, aber wir werden mehr ausführliche Code erstellen. Beim Ausführen der ausführen()
Methode, die wir die Werte in Form eines bereitstellen sollten Assoziatives Array
In welchem Schlüssel würde der Name des gebrauchten Platzhalters und der zugehörige Wert derjenige sein, der in der Abfrage ersetzt wird. Zum Beispiel würde die obige Abfrage:
$ stmt = $ pdo-> vorbereiten ("In Planeten (Name, Farbe) Werte einfügen (: Name,: Farbe)"); $ stmt-> execute (['name' => $ planet-> name, 'color' => $ planet-> color]);
Kopieren Die Vorbereitungs- und Ausführungsmethoden können sowohl bei Abfragen durchgeführt werden, die Daten aus der Datenbank ändern oder einfach abrufen. Im ersteren Fall verwenden wir die Abrufmethoden, die wir oben gesehen haben, um die Daten abzurufen. In letzteren können wir die Anzahl der betroffenen Zeilen mit der Verwendung der betroffenen Zeilen abrufen Reihenanzahl()
Methode.
Die Methoden BindValue () und BindParam ())
Um die Werte bereitzustellen, die in der Abfrage ersetzt werden sollen, können wir auch die verwenden bindValue ()
Und Bindparam ()
Methoden. Der erste bindet den Wert der Variablen, die dem zugehörigen Positions- oder Named -Platzhalter zur Verfügung gestellt wird, die bei der Vorbereitung der Abfrage verwendet werden. Verwenden des obigen Beispiels hätten wir es getan:
$ stmt-> bindValue ('name', $ planet-> name, pdo :: param_str);
Kopieren Wir binden den Wert von $ Planet-> Name
zum :Name
Platzhalter. Beachten Sie, dass wir sowohl BindValue () als auch BindParam () -Methoden als drittes Argument angeben können Typ
der Variablen unter Verwendung der zugehörigen PDO -Konstante in diesem Fall Pdo :: param_str
.
Verwendung Bindparam ()
, Stattdessen können wir die Variable an den verwandten Platzhalter binden, der bei der Vorbereitung der Abfrage verwendet wird. Beachten Sie, dass in diesem Fall die Variable an gebunden ist Referenz
, und sein Wert wird dem Platzhalter nur zum Zeitpunkt der ausführen()
Methode heißt es. Die Syntax ist die gleiche wie oben:
$ stmt-> bindparam ('name', $ planet-> name, pdo :: param_str)
Kopieren Wir haben die $ Planet-> Namensvariable an die gebunden :Name
Platzhalter, nicht sein aktueller Wert! Wie oben erwähnt, wird die Konvertierung genau dann durchgeführt, wenn die ausführen()
Die Methode wird aufgerufen, sodass der Platzhalter durch den Wert, den die Variable zu diesem Zeitpunkt hat.
PDO -Transaktionen
Transaktionen bieten eine Möglichkeit, die Konsistenz bei der Ausgabe mehrerer Abfragen beizubehalten. Alle Fragen werden in einer „Stapel“ durchgeführt und nur dann in die Datenbank verpflichtet, wenn alle erfolgreich sind. Transaktionen funktionieren nicht in allen Datenbanken und nicht für alle sql
Konstruktionen, weil einige von ihnen eingehen und implizite Commit (vollständige Liste hier) verursachen)
Stellen Sie sich mit einem extremen und seltsamen Beispiel vor, der Benutzer muss eine Liste von Planeten auswählen. Jedes Mal, wenn er eine neue Auswahl einreicht, möchten Sie, dass Sie die vorherige aus der Datenbank löschen, bevor er die neue einfügt. Was würde passieren, wenn die Löschung erfolgreich ist, aber nicht die Einfügung? Wir hätten einen Benutzer ohne Planeten! In der Regel werden Transaktionen implementiert:
$ pdo-> begintransaction (); Versuchen Sie $ stmt1 = $ pdo-> exec ("aus Planeten löschen"); $ stmt2 = $ pdo-> vorbereiten ("In Planeten (Name, Farbe) Werte einfügen (?, ?) "); foreach ($ planets as $ planet) $ stmt2-> execute ([$ planet-> getName (), $ planet-> getColor ()); $ pdo-> commit (); catch (catch () catch () PdoException $ e) $ pdo-> rollback ();
Kopieren Zuerst begintransaktion ()
Die Methode des PDO-Objekts deaktiviert die Abfrage automatisch und dann in einem Try-Catch-Block werden die Abfragen in der gewünschten Reihenfolge ausgeführt. An dieser Stelle wenn nein PdoException
wird erhoben, die Fragen werden mit dem begangen begehen()
Methode, ansonsten über die Rollback ()
Methode, die Transaktionen werden zurückgekehrt und automatisch wiederhergestellt.
Auf diese Weise wird es bei der Ausgabe mehrerer Fragen immer Konsistenz geben. Es ist ziemlich offensichtlich, dass Sie PDO -Transaktionen nur dann verwenden können, wenn die Pdo :: attr_errmode
ist eingestellt auf Pdo :: errmode_exception
.
Verwandte Linux -Tutorials:
- Dinge zu installieren auf Ubuntu 20.04
- So ändern Sie Mariadb -Benutzerkennwort
- So erstellen Sie einen Docker -basierten Lampenstapel mit Docker auf…
- Ampache Raspberry Pi Installation
- Eine Einführung in Linux -Automatisierung, Tools und Techniken
- OpenLiteSpeed WordPress Installation
- Dinge zu tun nach der Installation Ubuntu 20.04 fokale Fossa Linux
- Ubuntu 20.04 WordPress mit Apache -Installation
- Ubuntu 20.04: WordPress mit Nginx -Installation
- Installieren Sie MySQL auf Ubuntu 20.04 LTS Linux
- « So installieren Sie den Serviio Media Server auf Raspberry Pi
- So verwenden Sie GNU Stow, um Programme zu verwalten, die von Source und Dotfiles installiert sind »