Startseite
  • » Home
  • » Handbuch & FAQ
  • » Forum
  • » Übersetzungsserver
  • » Suche
Startseite › Forum › Drupalcenter.de › Allgemeines zu Drupal ›

Anfänger mit Drupal benötigt Hilfe bei einer SQL-Abfrage

Eingetragen von atomicx (5)
am 28.04.2008 - 00:08 Uhr in
  • Allgemeines zu Drupal
  • Drupal 6.x

Grüsse Euch

Mein Problem:

Unten im Footer möchte ich eine kleine Statistik über die Besucher meiner Seite machen und zwar mittels Block. Den PHP-Filter habe ich installiert. Nun ich schaffe das einfach nicht eine SQL-Abfrage zu machen in diesem Block. Es passiert einfach nichts! Die Datenbank und die Tabellen existieren, sonst sollte es auch funktionieren, habe es ohne Drupal getestet.

Hier der wichtige Teil:

.............VER['HTTP_REFERER'];

$sql='SELECT `ip` , `unixtime` FROM `counter`  WHERE `ip` LIKE \'' . $ip . '\'';
$erg=db_query($sql);
while($a=mysql_fetch_object($erg)){
    $ip=$a->ip;
    $unixtime1=$a->unixtime;
}
// Sicherheitssperre 2 Minuten für die selbe IP
$time=$unixtime-$unixtime1;
if($time>120){
    $sql1='INSERT INTO `counter`.`counter` (`id`, `ip`, `datum`, `unixtime`, `dns`, `browser`, `referer`) VALUES (NULL, \''. $ip . '\', \'' . $datum . '\', \'' . $unixtime . '\', \'' . $dns . '\', \'' . $browser . '\', \'' . $referer . '\');';
    $erg=db_query($sql1);
}........................

Wer noch etwas weiterlesen möchte:

Könntet ihr mir auch noch ein paar Linktipps geben, wo ich Beispiele sehe, bin euch sehr dankbar :)

Freundliche Grüsse aus der Schweiz.

‹ Problem mit Feeds - invalid rss feed content Neuinstall mit anschließenden Problemen ›
  • Anmelden oder Registrieren um Kommentare zu schreiben

Arbeiten mit der Datenbank

Eingetragen von UwBach (310)
am 28.04.2008 - 06:55 Uhr

schau mal ob dir das weiter hilft, ich hatte das mal für mich aufgeschrieben. Ich benutze hier eine eigene Funktion, denke aber das das für das Grundverständnis ausreichend ist ohne die vollständige Anwendung zu kennen. Versuche erst einmal die Ergebnisse auszulesen, entweder mit dem DEVEL-Modul oder mit einem einfachen drupal_set_message(). Kümmer dich dann darum wie du die Ergebnisse in den richtigen Block bekommst

Drupal ist in der Lage mit verschiedenen Datenbanken zu arbeiten. Die Auswahl wird in der Regel bei der Installation getroffen. Ferner ist Drupal in der Lage auch weitere Datenbanken (exterene Datenbanken) einzubinden.

Die Einbindung der Datenbank ist im Script ./sites/default/settings.php niedergelegt.

$db_url = 'mysql://username:password@localhost/databasename';
oder
$db_url = 'mysqli://username:password@localhost/databasename';
oder
$db_url = 'pgsql://username:password@localhost/databasename';

$db_prefix = '';

Mit dem Prefix $db_prefix = ''; kann ein Datenbank-Prefix, z. B. drupal_tablename, festgelegt werden. Diese Option ist immer dann zu empfehlen, wenn man nicht nur mit Standard-Modulen arbeiten möchte oder mehrere Distributionen in einer Datenbank laufen lassen möchte. Hierbei ist einzig zu beachten das die Table in den Querys entsprechend gekennzeichnet sind SELECT * FROM {table_name};. Durch den Einsatz der geschweiften Klammer kann Drupal die entsprechenden Table-Prefixe ersetzen und parst die Query zu SELECT * FROM prefix_table_name (Funktion db_prefix_tables($spl) in Script ./includes/database.inc). Sobald Module mit ander User geteilt werden soll muss man darauf achten, man weiß ja nicht wie der andere User die Datenbank anlegt.

Drupal stellt dann ein Reihe von Funktionen zur Verfügung mit denen die Datenbankoperationen ausgeführt werden können. Leider stehen nicht alle Funktionen aus dem PHP-Manual MySQL-Funktionen zur Verfügung. Diese können aber auch direkt aufgerufen werden, hier sollte man die Sicherheit der Abfragen beachten.

Hier die wichtigsten Funktionen für MySQL (aus dem Script ./includes/datase.mysql.inc):

db_query($query)
Die Grundfunktion der Query. Hier nutzt Drupal die "Prepared Statements"-Syntax, bei der die Query "nackt", d. h. ohne Daten, übergeben wird und die Daten erst nach Prüfung eingefügt werden (siehe Erklärung nächste Seite).
db_affected_rows()
Gibt die Anzahl der betroffenen Zeilen einer Query zurück (für UPDATE, INSERT und DELETE).
db_error()
Gibt die Fehlermeldung einer Anfrage zurück. Leider fehlt hier die Funktion mysql_errno().
db_escape_string($text)
Setzt vor bestimmten Zeichen ein "/".
db_fetch_array($result)
Liefert ein Array mit dem Ergebnis einer Zeile der Abfrage; nur für SELECT-Anweisungen.
db_fetch_objekt($result)
Liefert ein Objekt mit dem Ergebnis. db_fetch_object() ähnelt db_fetch_array(), mit einem Unterschied - ein Objekt wird zurück geliefert anstatt eines Arrays. Indirekt bedeutet dies, dass Sie die Daten nur mit ihren Feldnamen und nicht mit dem Offset ansprechen können (Nummern sind ungültige Namen für Eigenschaften).
db_next_id($name)
Da Drupal keine auto_increment in den Datenbanken verwendet, wird über die Funktion db_next_id($name) der nächste frei Key geholt. Normalerweise ist das der größte Key + 1. Drupal kann etwas durcheinanderkommen, wenn Schlüssel manuel in der Datenbank gelöscht werrden - also Vorsicht. Die Syntax ist einfach $name = {table_name}_gewünschteID, also z. B. die nächste freie UID $naechsterUser = db_next_id('{users}_uid');.
db_num_rows($result)
Anzahl der Treffer eines SELECTS.
db_table_exists($table)
Abfrage ob eine bestimmte Tabelle vorhanden ist.

Für MySQLI und PostgreSQL stehen ähnliche Scripte mit gleichen Funktionen unter ./includes/datase.mysqli.inc und ./includes/datase.pgsql.inc bereit.
Datenbankabfragen als Prepared Statements

Die Syntax ist eigentlich simpel; es wird eine normale Query formuliert und die Werte werden nur mit Platzhaltern versehen. Diese Platzhalter werden dann nach Prüfung durch die eigentliche Werte ersetzt.

$user->uid = 12;

$result = db_query('SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $user->uid);

Erstellt wird daraus die Query 'SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = 12'. Werden mehrere Platzhalter verwendet, müssen diese in der richtigen Reihenfolge angegeben werden. Gleiche Werte sind dabei auch mehrfach nazugeben.
Sieht einfach aus - aber warum der Aufwand? Ganz einfach: So können SQL-Injections verhindert werden und vorbereitete Statements können schneller reprudziert werden (werden schneller ausgeführt).

Wichtig ist dabei die korrekte Syntax der Daten anzugeben, d. h. wie sollen sie Daten geprüft werden. Es gibt fünf Datentypen die entsprechend geprüft werden können:

%s
Prüft ob es sich um einen STRING handelt.
%d
Prüft ob es sich um einen ITERGER handelt.
%f
Prüft ob es sich um einen FLOAT handelt.
%b
Prüft ob es sich um einen BINARAY DATA handelt. Diese dürfen nicht in '' gekapselt werden.
%%
Prüft ob es sich um einen LITERAL handelt.

Insbesondere bei Strings sollte man allerdings sehr vorsichtig sein und ggf. noch mal eine gesonderte Prüfung einbauen bevor man die Daten mit der Query weitergibt. Als kleines Beispiel für eine schlechte Passwort-Abfrage:

$user = 'wackelpudding' OR uid = 1; --';
$pass = 'abc';
SELECT uid FROM users WHERE name = '.$username.' AND pass = MD5('.$password.')

// daraus wird:
// SELECT uid FROM users WHERE name = "wackelpudding" or uid = 1
// Das Ergebnis ist immer die UID des 1 Drupal-User (Administator)

Um solche Injections abzuwähren reicht ein einfaches Ersetzen bestimmter Strings, in diesem Fall '--' um die Auskommentierung eines Teils der Query zu verhindern. Auch sollten Strings immer escape-ed werden bevor sie an die Datenbank weitergegeben werden (Funktion db_escape_string($text). An dieser Stelle soll das reichen, es soll ja keine Anleitung zum Hacken werden, aber das macht deutlich wie gefährlich bestimmte Abfragen sein können.
Ergebnisse aus der Datenbank auslesen

/**
* Prüft ob es einen Mitarbeiter mit der UID gibt
*
* @param User-ID des Drupal-System
* @return Array - 0 => 0 = user nicht registriert, 1 = User registriert
* 1 => Integer = Berechtigung des Users
*/
function check_ma($uid)
{
// Prüfen ob der User in der xyz-Datenbank registriert ist und holen der Berechtigung
$query = ' SELECT m.berechtigung, m.name FROM mitarbeiter AS m, abteilungzugehoerig AS a
WHERE m.uid = %d AND m.eintrittsDatum < now() AND (m.austrittsDatum >= now() OR m.austrittsDatum = "0000-00-00")
AND a.uid = %d AND a.active = 1';

$ergDB = db_query($query, $uid, $uid);

$anzahl_erg = db_num_rows($ergDB);

// Wenn kein Ergebniss gefunden wurde
if($anzahl_erg == 0)
return array(0 => 0, 1 => 0);
// Darf nicht passieren - dann ist etwas gewaltig schief gelaufen
elseif($anzahl_erg > 1)
{
drupal_set_message('Suchen Sie den Programmierer und erschlagen Sie ihn.');
return array(0 => 0, 1 => 0);
}
// holen der Ergebnisse
$erg = db_fetch_array($ergDB);

// Rückgabe wenn nichts gefunden wurde
return array(0 => 1, 1 => $erg['berechtigung']);
} // END check_ma()

  • Anmelden oder Registrieren um Kommentare zu schreiben

@atomicx

Eingetragen von netzkoop (1820)
am 28.04.2008 - 08:41 Uhr

Geht das?:

$erg = db_query('SELECT ip, unixtime FROM {counter} WHERE ip LIKE %s', $ip);

Zum weiterlesen:
http://www.drupalcenter.de/handbuch/6722

-----------
Luca Curella
Kooperative Netze - Berlin

  • Anmelden oder Registrieren um Kommentare zu schreiben

luzer schrieb Geht

Eingetragen von UwBach (310)
am 28.04.2008 - 09:06 Uhr
luzer schrieb

Geht das?:

$erg = db_query('SELECT ip, unixtime FROM {counter} WHERE ip LIKE %s', $ip);

Zum weiterlesen:
http://www.drupalcenter.de/handbuch/6722

Du solltest die Strings in Anführungszeichen setzen

$erg = db_query('SELECT ip, unixtime FROM {counter} WHERE ip LIKE "%s"', $ip);

ansonsten sieht das gut aus (ohne das getestet zu haben).

Gruß

UwBach

  • Anmelden oder Registrieren um Kommentare zu schreiben

Danke, an alle die so

Eingetragen von atomicx (5)
am 28.04.2008 - 13:47 Uhr

Danke, an alle die so schnell geantwortet haben, ich werde es heute nach der Arbeit gleich mal ausprobieren und euch das Ergebnis mitteilen.

Danke :)

Freundliche Grüsse aus der Schweiz, atomicx.

  • Anmelden oder Registrieren um Kommentare zu schreiben

Also ich bekomme immer noch

Eingetragen von atomicx (5)
am 28.04.2008 - 17:46 Uhr

Also ich bekomme immer noch nicht mein gewünschtes Resultat. Es passiert einfach nichts.

echo $erg; == Object id #16
echo 'true'; ==

$erg=db_query('SELECT ip, unixtime FROM {counter} WHERE ip LIKE "%s"', $ip);
echo $erg;
while($a=db_fetch_object($erg)){
    $ip=$a->ip;
    $unixtime1=$a->unixtime;
    echo 'true';
}

Ist es nicht irgendwie möglich einfach den Standart zu nehmen? Also normale Sql-Querys die man sich gewöhnt ist?

  • Anmelden oder Registrieren um Kommentare zu schreiben

Schon versucht, dich langsam

Eingetragen von netzkoop (1820)
am 28.04.2008 - 19:21 Uhr

Schon versucht, dich langsam vorwärts zu tasten?
Was ergibt:

<?php
$erg
= db_query('SELECT ip FROM {counter}');
while (
$a = db_fetch_object($erg)){
    print
$a->ip;
}
?>

um zu sehen ob du die Tabelle überhaupt ansprechen kannst.
Ist die eigentlich in der gleichen DB wie Drupal?

-----------
Luca Curella
Kooperative Netze - Berlin

  • Anmelden oder Registrieren um Kommentare zu schreiben

Eigentlich bin ich einer der

Eingetragen von atomicx (5)
am 28.04.2008 - 19:52 Uhr

Eigentlich bin ich einer der Schritt für Schritt arbeitet, was beim Programmieren nicht unklug ist, doch habe ich ja das Script schon getestet bevor ich es in Drupal eingesetzt habe, da funktionierte alles ganz gut.
Nun muss ich das anscheinend noch auf drupalisch Übersetzen, was mir etwas Schwierigkeiten macht, weil ich nicht genau weiss was Drupal noch alles daran ändert bis zum Ziel. Mein Ziel ist es ein Besuchercounter zu basteln der mit Local Shared Objects(Flashcookies) funktioniert und so die Cookies nicht einfach so gelöscht werden.

<?php
$erg
= db_query('SELECT ip FROM {counter}');
while (
$a = db_fetch_object($erg)){
    print
$a->ip;
}
?>

Dieser Code funktioniert wunderbar, alle meine Testeinträge von der Spalte "ip" werden aufgeführt.

Ja, diese Tabelle ist in der selben Datenbank wie den Rest von Drupal.

  • Anmelden oder Registrieren um Kommentare zu schreiben

Super jetzt funktioniert

Eingetragen von atomicx (5)
am 28.04.2008 - 21:03 Uhr

Super jetzt funktioniert alles, wie es sollte!

Ich danke euch allen ganz herzlich und wünsche euch noch eine schöne Zeit! Auf bald..

  • Anmelden oder Registrieren um Kommentare zu schreiben

Benutzeranmeldung

  • Registrieren
  • Neues Passwort anfordern

Aktive Forenthemen

  • Probleme beim Versand von Mails via Drupal 9
  • [gelöst]Hilfsprogramme
  • [gelöst] Drupal 9: Wie kommt der Inhalt eines selbst erstellten Feldes in page-title.html.twig
  • Daten werden bei Sortierung mehrfach ausgegeben
  • [gelöst] Sichtbarkeit von Seiten über Rollen steuern
  • [gelöst] Menüpunkte deaktivieren sich automatisch
  • Kartenansicht, Position des Users und Nodes anzeigen
  • Theme suggestion wird nicht verwendet
  • [gelöst]Pflichtfeld vom User deaktivieren lassen
  • Konto löschen, wie? (Drupalorg/Drupalcenter)
  • Layout-Builder hängt
  • Drupal 8/9 SEO-Beratung/Coaching
Weiter

Neue Kommentare

  • Na dann haste ja 24x7 Stunden
    vor 8 Stunden 8 Minuten
  • es sieht so aus als ob es ein
    vor 9 Stunden 57 Minuten
  • Da es auch mit neuer Drupal
    vor 10 Stunden 38 Minuten
  • Sorry für die späte
    vor 12 Stunden 15 Minuten
  • Hilfsprogramm
    vor 17 Stunden 11 Minuten
  • Regina, ganz herzlichen Dank
    vor 18 Stunden 33 Minuten
  • Was sind denn deine
    vor 1 Tag 14 Stunden
  • Zitat: Ich möchte ja die
    vor 2 Tagen 17 Stunden
  • Gelöst
    vor 2 Tagen 17 Stunden
  • Das hilft mir leider nicht.
    vor 2 Tagen 17 Stunden

Statistik

Beiträge im Forum: 246117
Registrierte User: 18885

Neue User:

  • Stine_64
  • uniquename
  • xapizm

» Alle User anzeigen

User nach Punkten sortiert:
wla9018
stBorchert6003
quiptime4972
Tobias Bähr4019
bv3917
ronald3832
md3717
Thoor3678
Alexander Langer3416
Exterior2903
» User nach Punkten
Zur Zeit sind 0 User und 2 Gäste online.

Hauptmenü

  • » Home
  • » Handbuch & FAQ
  • » Forum
  • » Übersetzungsserver
  • » Suche

Quicklinks I

  • Infos
  • Drupal Showcase
  • Installation
  • Update
  • Forum
  • Team
  • Verhaltensregeln

Quicklinks II

  • Drupal Jobs
  • FAQ
  • Drupal-Kochbuch
  • Best Practice - Drupal Sites - Guidelines
  • Drupal How To's

Quicklinks III

  • Tipps & Tricks
  • Drupal Theme System
  • Theme Handbuch
  • Leitfaden zur Entwicklung von Modulen

RSS & Twitter

  • Drupal Planet deutsch
  • RSS Feed News
  • RSS Feed Planet
  • Twitter Drupalcenter
Drupalcenter Team | Impressum & Datenschutz | Kontakt
Angetrieben von Drupal | Drupal is a registered trademark of Dries Buytaert.
Drupal Initiative - Drupal Association