php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger

PHP Einsteiger PHP Problemlösungen für Spracheinsteiger
Archive: 2004, 2004/2, 2005, 2005/2, 2006, 2007, 2008, 2009, 2010,

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 13.02.2012, 19:48  
Neuer Benutzer
 
Registriert seit: 13.02.2012
Beiträge: 15
PHP-Kenntnisse:
Anfänger
sNaiK274 befindet sich auf einem aufstrebenden Ast
Standard [Erledigt] MySQLi Count Abfrage

Hey zusammen,

ich hab gerade einen alten Skript von mir rausgekramt und wollte diesen auf den neusten Stand bringen. Nach den ersten paar Zeilen kam natürlich auch eine Datenbankabfrage, die ich von MySQL auf MySQLi umstellen will.

Der Connect zur Datenbank steht, das war kein Problem.

Nun bin ich an einem Punkt, bei dem ich eine Eingabe (E-Mail Adresse) mit der DB abgleiche um herauszufinden, ob der Eintrag bereits existiert.

Jetzt habe ich 2, bzw. eigentlich 3 verschiedene Lösungsansätze, die auch alle funktionieren und mir das richtige Ergebnis (nach mehreren Test) liefern. Ausgabe jeweils per var_dump();


Variante 1: Prepared mit affected_rows (Variante 2: oder num_rows)

PHP-Code:
$sql 'SELECT
              COUNT(EMail)
            FROM
              Benutzer
            WHERE
              EMail = ?'
;
    
// Abfrage wird vorbereitet
    
$abfrage $db->prepare($sql);
    
// Fehlende Variablen zuweisen
    
$abfrage->bind_param('s',$email);
    
// Abfrage wird ausgeführt
    
$abfrage->execute();
    
// Ergebnisse werden gespeichert
    
$abfrage->store_result();
    
// Wenn ein Eintrag existiert -> E-Mail Adresse bereits hinterlegt -> Fehler
    
if($abfrage->affected_rows>0)    // Bzw. if($abfrage->num_rows>0)
    
$fehler[] = "Die eingegebene E-Mail Adresse existiert bereits und kann nicht verwendet werden"

Variante 3: Query mit num_rows

PHP-Code:
$sql 'SELECT
              EMail
            FROM
              Benutzer
            WHERE
              EMail = "'
.$email.'"';
    
// Query ausführen
    
$abfrage $db->query$sql );
    
// Wenn ein Eintrag existiert -> E-Mail Adresse bereits hinterlegt -> Fehler
    
if($abfrage->num_rows>0
    
$fehler[] = "Die eingegebene E-Mail Adresse existiert bereits und kann nicht verwendet werden"

Eine 4. Variante gibt es nicht (Variante 3 mit affected_rows). Dort erscheint folgender Hinweis:
Notice: Undefined property: mysqli_result::$affected_rows... Wobei var_dump() auch hier das richtige Ergebnis liefert.


Welche der 3 Varianten ist die "beste" (über das Wort brauchen wir nicht streiten ^^). Mir geht es um puncto Sicherheit, Übersichtlichkeit und Schnelligkeit. Schnelligkeit aber eher weniger. Ich glaube kaum, dass man bei einer der 3 Varianten einen Unterschied empfindet.

Von der Sicherheit her würde ich zu Variante 1 oder 2 tendieren, wegen den Prepared Statments. Von der Übersicht eher zu 3, weil weniger Code.

Laut Manual sollte affected_rows bei INSERT, UPDATE und DELETE benutzt werden, scheint aber auch bei SELECT zu funktionieren. Für SELECT bietet sich daher eher num_rows an.


Alles in allem tendiere ich derzeit zu Variante 2 (Prepared mit num_rows).

Sehen das andere genauso?

Gruß Steffen
sNaiK274 ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 13.02.2012, 19:52  
meikel
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von sNaiK274 Beitrag anzeigen
Laut Manual sollte affected_rows bei INSERT, UPDATE und DELETE benutzt werden, scheint aber auch bei SELECT zu funktionieren.
Das wäre ein Bug.

Zitat:
Alles in allem tendiere ich derzeit zu Variante 2 (Prepared mit num_rows).
Wäre auch richtig. Allerdings weiß ich nicht, was sich bei Dir hinter $db angesiedelt hat.
  Mit Zitat antworten
Alt 13.02.2012, 20:09  
Neuer Benutzer
 
Registriert seit: 13.02.2012
Beiträge: 15
PHP-Kenntnisse:
Anfänger
sNaiK274 befindet sich auf einem aufstrebenden Ast
Standard

Danke schonmal für die Antwort.

Zitat:
Zitat von meikel Beitrag anzeigen
Wäre auch richtig. Allerdings weiß ich nicht, was sich bei Dir hinter $db angesiedelt hat.
Naja, eigentlich nichts wildes. Ein Standard-Script zum Verbinden mit einer Datenbank und Fehlerausgabe.

PHP-Code:
<?
/* Mit Hilfe dieser Datei wird die Verbindung zur Datenbank hergestellt */

$dbhost="xxx";     // Datenbank-Host
$dbname="xxx";  // Datenbank-Name
$dbuser="xxx";        // Datenbank-Benutzer
$dbpass="xxx";  // Datenbank-Passwort

// Verbinden mit MySQLi
$db = @new mysqli($dbhost$dbuser$dbpass$dbname);

// Fehlerausgabe bei gescheiterter Verbindung
if ($db->connect_errno)
{
    echo 
'Es konnte keine Datenbankverbindung hergestellt werden!<br />';
    echo 
'Folgender Fehler ist aufgetreten: (' $db->connect_errno ') ' $db->connect_error;
    exit;
}
?>
Aber auch dafür nehme ich gerne Verbesserungsvorschläge an

Gruß Steffen
sNaiK274 ist offline   Mit Zitat antworten
Alt 13.02.2012, 20:23  
meikel
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von sNaiK274 Beitrag anzeigen
Aber auch dafür nehme ich gerne Verbesserungsvorschläge an
Ist schön kurz und müßte funktionieren. Könntest ja auch die mysqli Klasse ableiten:
PHP-Code:
<?php

class db extends mysqli {

  public function 
__construct(){
    
$acc getSqlAccount();
    
parent::__construct($acc['host'], ...);
# usw.
  
}
}
?>
Und falls Du mal auf PDO umsteigen solltest:

PHP-Code:
<?php
class db extends pdo {
# etwas anderer constructor -> DSN methode
}
  Mit Zitat antworten
Alt 13.02.2012, 20:43  
Neuer Benutzer
 
Registriert seit: 13.02.2012
Beiträge: 15
PHP-Kenntnisse:
Anfänger
sNaiK274 befindet sich auf einem aufstrebenden Ast
Standard

Danke für den Vorschlag, aber mit Klassen steh ich derzeit noch auf absolutem Kriegsfuß. Deinen Code versteh ich leider absolut gar nicht

Müsste mich vorher grundlegend damit befassen und einige Tutorials lesen, ansonsten bau ich dadurch mehr Fehler ein, als das die Sache sich für mich erstmal lohnen würde.

Solange mein Code sicher ist, funktioniert und eine einigermaßen gute Performance an den Tag legt bin ich erstmal zufrieden

Könnte überflüssig sein, habe aber in die SQL-Anweisung noch ein LIMIT 1 eingesetzt. Sollte man sich diesen Zusatz sparen, wenn eh sicher ist, dass die E-Mail Adressen in der DB unique sind?


Gruß Steffen
sNaiK274 ist offline   Mit Zitat antworten
Alt 13.02.2012, 21:06  
meikel
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von sNaiK274 Beitrag anzeigen
Könnte überflüssig sein, habe aber in die SQL-Anweisung noch ein LIMIT 1 eingesetzt.
Limit 1 erinnert mich an "geschweißtes mit Nieten". Wenn eine Abfrage nur ein Ergebnis haben soll und Du befürchtest, es könne doch mehr als eins sein, dann taugt das DB Design nix. Oder Du hast Heinzelmännchen... <ggg>

Zitat:
Sollte man sich diesen Zusatz sparen, wenn eh sicher ist, dass die E-Mail Adressen in der DB unique sind?
Wenn die (zB) email unique sein soll, dann setze das Spaltenattribut auf unique. Dann verhindert MySQL zuverlässig Doubletten.
  Mit Zitat antworten
Alt 13.02.2012, 21:15  
Neuer Benutzer
 
Registriert seit: 13.02.2012
Beiträge: 15
PHP-Kenntnisse:
Anfänger
sNaiK274 befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von meikel Beitrag anzeigen
Wenn die (zB) email unique sein soll, dann setze das Spaltenattribut auf unique. Dann verhindert MySQL zuverlässig Doubletten.
Ab und zu unterschätze ich einfach die Macht der MySQL Datenbank

LIMIT 1 ist demnach wieder rausgeflogen. Spalte wurde auf Unique gesetzt. Wunderbar, beim Anlegen der gleichen E-Mail Adresse über phpmyadmin fliegt mir "#1062 - Duplicate entry" um die Ohren, sehr gut. Schätze mal der Code und die Meldung werden dann auch beim mysqli_error im Skript ausgegeben, richtig?
sNaiK274 ist offline   Mit Zitat antworten
Alt 13.02.2012, 22:00  
meikel
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von sNaiK274 Beitrag anzeigen
Schätze mal
Nicht schätzen. Du willst doch Programmierer werden und kein Statistiker. Teste es einfach.
  Mit Zitat antworten
Alt 13.02.2012, 23:07  
Neuer Benutzer
 
Registriert seit: 13.02.2012
Beiträge: 15
PHP-Kenntnisse:
Anfänger
sNaiK274 befindet sich auf einem aufstrebenden Ast
Standard

Recht hast du. Daher mal sämtliche Überprüfungen ausgeklammert und versucht in die Datenbank zu pressen... keine Chance.
Zitat:
1062: "Duplicate entry..."
Immerhin hatte ich mit meiner Schätzung Recht, aber so Dinge werde ich in Zukunft prüfen und nicht auf gut Glück versuchen. Nochmals vielen Dank

Gruß Steffen
sNaiK274 ist offline   Mit Zitat antworten
Alt 14.02.2012, 08:36  
Erfahrener Benutzer
 
Registriert seit: 17.08.2010
Beiträge: 216
PHP-Kenntnisse:
Fortgeschritten
Dormilich befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von sNaiK274 Beitrag anzeigen
Variante 1: Prepared mit affected_rows (Variante 2: oder num_rows)

PHP-Code:
$sql 'SELECT
              COUNT(EMail)
            FROM
              Benutzer
            WHERE
              EMail = ?'
;
    
// Abfrage wird vorbereitet
    
$abfrage $db->prepare($sql);
    
// Fehlende Variablen zuweisen
    
$abfrage->bind_param('s',$email);
    
// Abfrage wird ausgeführt
    
$abfrage->execute();
    
// Ergebnisse werden gespeichert
    
$abfrage->store_result();
    
// Wenn ein Eintrag existiert -> E-Mail Adresse bereits hinterlegt -> Fehler
    
if($abfrage->affected_rows>0)    // Bzw. if($abfrage->num_rows>0)
    
$fehler[] = "Die eingegebene E-Mail Adresse existiert bereits und kann nicht verwendet werden"
warum affected_rows/num_rows nehmen, wenn der count im Query steckt?

nichtsdestotrotz ist die Absicherung auf MySQL-Seite (über UNIQUE) vorzuziehen.

mal als Beispiel in PDO
PHP-Code:
$pdo = new PDO(...); // hier kommen dann die tatsächlichen Verbindungsdaten rein
$ps $pdo->prepare('SELECT
              COUNT(EMail)
            FROM
              Benutzer
            WHERE
              EMail = :mail'
);
// EMail ist ein String, da können wir lazy bind machen
$ps->execute(array("mail" => $email));
// oder explizit
// $ps->bindValue("mail", $email, PDO::PARAM_STR);
// $ps->execute();
$count $ps->fetchColumn(); 
Dormilich ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
mysqli abfrage klappt nicht onkelzfreak1988 PHP Einsteiger 3 11.02.2012 12:31
mysqli Abfrage-Ergebnis in PHP Array speichern und in zweiter Abfrage weiterverwenden TMM010 PHP Einsteiger 8 09.11.2011 09:57
[Erledigt] MySQL: COUNT() bei Abfrage mehrerer Tabellen John Steed Datenbanken 11 13.07.2010 22:20
[Erledigt] Tabellen Alias im Ergebnis einer Mysqli Abfrage stoffel70 Datenbanken 3 18.05.2010 08:32
[Erledigt] MYSQLi Abfrage mit unbekannter Start- und Endposition (Pagination) trvlr Datenbanken 0 04.05.2010 17:32
[Erledigt] MySQL COUNT Abfrage NightBass PHP Tipps 2009 8 18.04.2009 17:04
[Erledigt] MYSQL COUNT() abfrage will nicht serious-cool PHP Tipps 2009 7 19.02.2009 12:52
Abfrage mit count, order by, group by...und Probleme BartTheDevil89 Datenbanken 2 15.06.2008 13:34
Mysql Abfrage über zwei Tabellen mit SUM und Count abyss Datenbanken 2 12.06.2008 22:19
Count() mit spezieller Abfrage... Matthiasnet Datenbanken 7 11.06.2007 16:55
[Erledigt] COUNT + 2xSUM in einer Abfrage Datenbanken 1 27.01.2006 16:01
Mysql Abfrage über 3 Tabellen in Verbidung mit COUNT() Datenbanken 8 29.06.2005 04:15
Mysql Abfrage über 3 Tabellen in Verbidung mit COUNT() PHP Tipps 2005-2 4 28.06.2005 07:47
Abfrage zweier Tabellen mit COUNT() funktion Datenbanken 23 20.09.2004 22:13

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
mysqli count, php mysqli count, pagination über mysqli, mysqli count ergebnis, mysqli count(), php-internen klasse mysqli abgeleitet, if ($db->connect_errno) { echo \'es konnte keine datenbankverbindung hergestellt werden!<br />\'; echo \'folgender fehler ist aufgetreten: (\' . $db->connect_errno . \') \' . $db->connect_error; exit;, mysqli num rows sum

Alle Zeitangaben in WEZ +2. Es ist jetzt 19:08 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum