shordy: PDO und Sqlite - Aller Anfang ist schwer

Hallo, ich möchte nun kleine Datenbanken auf SQLite umstellen.

Dazu möchte ich PDO von php benutzen.

Ich finde leider kein schönes Einführungstutorial. Wäre über einen Link dankbar. Ich bin gerade hier:
http://www.php.net/manual/de/pdo.connections.php,
aber mir fehlt irgendwie der Gesamtüberblick.

Die Frage, die ich jetzt konkret habe, ist: wie kann ich mit $BLA = new PDO("sqlite: pfad"); verhindern, dass eine neue Datenbank angelegt, wenn sie nicht vorhanden ist. Ich möchte nicht ein file-exists davor bauen. Ich suche nach etwas wie: ist die Datenbank mit der SQLite-Struktur vorhanden, dann öffne sie, ansonsten gib eine Exception zurück, oder so.

Vielen Dank für diese Antwort.

Grüße

  1. Hi!

    Hallo, ich möchte nun kleine Datenbanken auf SQLite umstellen.
    Dazu möchte ich PDO von php benutzen.

    Damit begrenzt du (oder erweiterst) dich auf den Funktionsumfang von PDO. Eine Interoperabilitiät zu anderen DBMSen bekommt man damit aber kaum, weil jedes System immer noch seinen eigenen SQL-Dialekt spricht.

    Ich finde leider kein schönes Einführungstutorial. Wäre über einen Link dankbar. Ich bin gerade hier:
    http://www.php.net/manual/de/pdo.connections.php,
    aber mir fehlt irgendwie der Gesamtüberblick.

    Du kannst da nur das allgemeine PDO-Kapitel nehmen und diese kleine DBMS-spezifische Ergänzung, um den Umgang mit PDO zu lernen. Informationen zum SQLite-spezifischen SQL müsstest du in Richtung SQLite-Dokumentation/-Tutorial suchen.

    Die Frage, die ich jetzt konkret habe, ist: wie kann ich mit $BLA = new PDO("sqlite: pfad"); verhindern, dass eine neue Datenbank angelegt, wenn sie nicht vorhanden ist. Ich möchte nicht ein file-exists davor bauen. Ich suche nach etwas wie: ist die Datenbank mit der SQLite-Struktur vorhanden, dann öffne sie, ansonsten gib eine Exception zurück, oder so.

    Das geht meines Erachtens nur mit dem nativen Treiber, dessen Konstruktor kennt entsprechende Flags. Der PDO-Konstruktor kennt $driver_options, aber da im SQLite-Teil keine beschrieben sind, wird es keine geben, die man verwenden kann.

    Alternativ, ohne file_exists() zu verwenden, bleibt wohl nur, das Verzeichnis ohne Schreibrecht für den PHP-Prozess zu konfigurieren. Dann kann der darin keine Dateien anlegen, wohl aber vorhandene bearbeiten (wenn diese beschreibbar sind).

    Lo!

    1. Hallo und vielen vielen DAnk für die Antwort.

      Damit begrenzt du (oder erweiterst) dich auf den Funktionsumfang von PDO. Eine Interoperabilitiät zu anderen DBMSen bekommt man damit aber kaum, weil jedes System immer noch seinen eigenen SQL-Dialekt spricht.

      NAja, ich möchte diese Datenbanken in SQLite belassen, falls Du ein späteres Ändern zu z.B. MySQL meinst. Hätte mich auch mit zB adoDB beschäftig, was allerdings ein bisschen langsamer sein soll, weil eben nicht in php integriert, sondern aufgesetzt.

      Die Frage, die ich jetzt konkret habe, ist: wie kann ich mit $BLA = new PDO("sqlite: pfad"); verhindern, dass eine neue Datenbank angelegt, wenn sie nicht vorhanden ist. Ich möchte nicht ein file-exists davor bauen. Ich suche nach etwas wie: ist die Datenbank mit der SQLite-Struktur vorhanden, dann öffne sie, ansonsten gib eine Exception zurück, oder so.

      Das geht meines Erachtens nur mit dem nativen Treiber, dessen Konstruktor kennt entsprechende Flags. Der PDO-Konstruktor kennt $driver_options, aber da im SQLite-Teil keine beschrieben sind, wird es keine geben, die man verwenden kann.

      Alternativ, ohne file_exists() zu verwenden, bleibt wohl nur, das Verzeichnis ohne Schreibrecht für den PHP-Prozess zu konfigurieren. Dann kann der darin keine Dateien anlegen, wohl aber vorhandene bearbeiten (wenn diese beschreibbar sind).

      Schade. Das ist etwas unbefriedigend. Aber gut. Meinst Du mit nativer Variante die Funktion sqlite_open() und $error_message, die ich dann abfragen muss?

      Liebe Grüße

      Lo!

      1. Hi!

        NAja, ich möchte diese Datenbanken in SQLite belassen, falls Du ein späteres Ändern zu z.B. MySQL meinst.

        Was versprichst du dir von PDO, was dir die direkte(n) Schnittstelle(n) nicht bieten können?

        Hätte mich auch mit zB adoDB beschäftig, was allerdings ein bisschen langsamer sein soll, weil eben nicht in php integriert, sondern aufgesetzt.

        Das "bisschen" ist vermutlich messbar aber nicht weiter relevant, weil es im Grundrauschen untergehen wird. Wenn es dir um Geschwindigkeit geht, ist SQLite sicherlich auch nicht gerade ein Renner. Zudem wäre es eigenartig, wenn du deswegen zwar auf ADO verzichtest, dann aber nicht konsequent auch PDO weglässt.

        Das geht meines Erachtens nur mit dem nativen Treiber, dessen Konstruktor kennt entsprechende Flags.
        Schade. Das ist etwas unbefriedigend. Aber gut. Meinst Du mit nativer Variante die Funktion sqlite_open() und $error_message, die ich dann abfragen muss?

        Ich verlinkte ja darauf, allerdings auf die SQLite3-Version aus PHP5.3. sqlite_open() hat keine Option, das Anlegen der Datei zu unterdrücken.

        Lo!

        1. Was versprichst du dir von PDO, was dir die direkte(n) Schnittstelle(n) nicht bieten können?

          Habe Probleme gehabt, mit der direkten Schnittstelle (sprich $db = new SQLiteDatabase(); ) SQLite Datenbanken der Version 3 zu öffnen. Bitte verbessern, wenn SQLiteDatabase() nicht die direkte Variante bezeichnet oder ich komplett die Begriffe vertausche. Ich habe das bis jetzt so verstanden.

          Ich verlinkte ja darauf, allerdings auf die SQLite3-Version aus PHP5.3. sqlite_open() hat keine Option, das Anlegen der Datei zu unterdrücken.

          Sorry, dachte hinter dem Link befindet sich die Erklärung, was ein Konstruktor ist. Habe nicht nachgeschaut. Ich hoffe, ich verstehe gleich, wie man das anwenden kann. Muss jetzt erstmal löffeln gehen, Kantine macht gleich zu :)

          VIelen dank für deine Antwort. Hat mir jetzt schon sehr geholfen!

          Grüße

          1. Hi!

            Habe Probleme gehabt, mit der direkten Schnittstelle (sprich $db = new SQLiteDatabase(); ) SQLite Datenbanken der Version 3 zu öffnen.

            Das würde mich wundern, wenn in PHP kein SQLite3-Support drin ist, PDO aber mit solchen Dateien umgehen kann. Für Version 3 ist die Klasse SQLite3 vorgesehen. (Ich habe aber keine Erfahrung mit SQLite und der Kompatibilität zwischen den Versionen.)

            Lo!

            1. Das würde mich wundern, wenn in PHP kein SQLite3-Support drin ist, PDO aber mit solchen Dateien umgehen kann. Für Version 3 ist die Klasse SQLite3 vorgesehen. (Ich habe aber keine Erfahrung mit SQLite und der Kompatibilität zwischen den Versionen.)

              Super, vielen Dank. Die Klasse SQLite3 isses dann!

              Ich mache das jetzt so, dass ich eine eigene Klasse erstelle, welche die SQLite3 extended. Dann redifiniere ich __construct und mache es, wie ich möchte.

              Etwas auf dem Schlauch stand ich gestern, wie ich die drei Schalter anspreche. Ist ja im Manual mit INT angegeben. Ich erreiche jetzt, was ich möchte (Datenbank wird nicht erstellt, wenn nicht vorhanden). Aber ganz sicher, ob ich den Schalter richtig bediene,  bin ich mir nicht. Folgende Methode habe ich geschrieben:

                
              public function __construct($datapath) {  
                	  
                GLOBAL $Site;  
                try{  
                  parent::__construct($datapath, SQLITE3_OPEN_READWRITE);  
                } catch (Exception $e) {  
                  throw new Exception("Could not open user database!");  
                }  
              }
              

              Die exception wird neu geworden, damit ich einen eigenen Fehlertext bekomme und an mein Seitenobjekt gegeben. Das kann damit besser umgehen :) Die ganze Instanzierung steht also auch nochmal in einem try{}-Block.

              Vorschläge zu dem Schalter??

              Liebe Grüße

              1. Hi!

                Etwas auf dem Schlauch stand ich gestern, wie ich die drei Schalter anspreche. Ist ja im Manual mit INT angegeben. Ich erreiche jetzt, was ich möchte (Datenbank wird nicht erstellt, wenn nicht vorhanden). Aber ganz sicher, ob ich den Schalter richtig bediene,  bin ich mir nicht.

                Schau dir die Werte der Flags mal binär an, dann wirst du in der Regel immer nur ein gesetztes Bit und an unterschiedlichen Positionen finden. Mehrere Werte or-verknüpft setzen die jeweiligen Bits zusammen. Der entstehende Wert 3 wäre also eine Kombination aus Bit 0 und Bit 1

                } catch (Exception $e) {
                    throw new Exception("Could not open user database!");
                Die exception wird neu geworden, damit ich einen eigenen Fehlertext bekomme und an mein Seitenobjekt gegeben. Das kann damit besser umgehen :) Die ganze Instanzierung steht also auch nochmal in einem try{}-Block.

                Na dann würde ich aber eine selbst definierte Klasse nehmen, damit man auch gezielt auf die einzelnen Exceptions-Typen reagieren kann. Ansonsten ist mit einem anderen Text nicht wirklich was besser. Dass der Text so generisch verfasst ist, macht ihn auch weniger geeignet für eine genauere Fehlersuche. Dafür/Zudem würde ich die eigentliche Exception an der vorgesehenen (3.) Stelle als Parameter übergeben.

                Vorschläge zu dem Schalter??

                Passt so.

                Lo!