silverman
Goto Top

Zwei Werte prüfen vor dem insert in der DB

Ich weiß wirklich nicht, was ich da falsch mache. Hier mein Code

ich würde gerne prüfen, ob die zwei Werte $sf_sid und $sf_sem schon in der Datenbank sind oder nicht. erst danach füge ich die übergebene Werte ein.
aber die werden einfach gespeichert auch wenn sie schon vorhanden sind, als ob es keine Prüfung stattfindet.

Die Daten werden über einen Formular an die Funktion übergeben.

Bitte um eure Hilfe


 public function add_newfee($sf_nid, $sf_sid, $sf_name, $sf_fee_eur, $sf_fee_cent, $sf_sem, $sf_semy, $sf_sp, $sf_uni, $sf_comment){
			
			
			if (!$sf_nid || !$sf_sid  || !$sf_name  || !$sf_fee_eur || !$sf_fee_cent || !$sf_sem || !$sf_semy || !$sf_sp || !$sf_uni) {
				echo '<div class="error">';  
    			echo 'Daten fehlen';  
				echo '<br>';  
				die(mysql_error());
				echo '</div>';  
				}
			
			require ('db_connect.php');			  
			$tbl_name="infrastructure.studyfees"; // Table name  
			
			// Connect to server and select databse.
			mysql_connect("$host", "$username", "$password")or die("cannot connect");  
			mysql_select_db("$db_name")or die("cannot select DB");  
			mysql_query("set names 'utf8'");  
			
			
		    $sf_checkID ="SELECT sf_nid,sf_name,sf_sem FROM $tbl_name WHERE sf_nid = '%$sf_nid%' AND sf_sem = '%$sf_sem%' ";  

				 echo mysql_error();
				 echo"<br><br>";  
				
				$result = mysql_query($sf_checkID);
				if (mysql_num_rows($result) > 0) {
				
				
				// $sf_nid_s = $row['0']; 
			    // $sf_sem_s = $row['2']; 
						
						echo '<div class="error">';  
						echo "es wurden Studiengebühren für";  
						echo "/ة ";  
						echo '<br>';  
						echo $result['sf_name'];  
						echo '<br>';  
						echo "schon bezahlt";  
						echo '</div>';  

						
						}
						
				else {
				
				$sf_insert="INSERT INTO $tbl_name(sf_nid,sf_sid,sf_name,sf_fee_eur,sf_fee_cent,sf_sem,sf_semy,sf_sp,sf_uni,sf_comment)  
				VALUES('$sf_nid','$sf_sid','$sf_name','$sf_fee_eur','$sf_fee_cent','$sf_sem','$sf_semy','$sf_sp','$sf_uni','$sf_comment')";  
					$write = mysql_query($sf_insert);
					if(!$write) //checking here if record is inserted
							{
		                echo '<div class="error">';  
						echo "daten wurde nicht gespeichert ";  
						echo '</div>';  
						
						echo '<div class="error">';		  
						die('Error:'. mysql_error());  
						echo '</div>';  
							}
						
						else
						{
						
						$sf_check_OK = mysql_query("SELECT sf_name,sf_fee_eur,sf_fee_cent FROM studyfees group by sf_name DESC LIMIT 1");  
						$row = mysql_fetch_assoc($sf_check_OK);
					 	echo '<div class="succes">';  
						print('es wurden  daten erfolgreich gespeichert');  
						echo '</div>';  
						echo '<div class="succes">';  
						print $row["sf_fee_eur"];  
						print ',';  
						print $row["sf_fee_cent"];  
						echo '</div>';  
						echo '<div class="succes">';  
						print('für: ');  
						print $row["sf_name"];  
						echo '</div>';  
						
						mysql_free_result($sf_check_OK);
						}
					   
					 }
					}

Content-Key: 147472

Url: https://administrator.de/contentid/147472

Printed on: April 16, 2024 at 14:04 o'clock

Member: Biber
Biber Jul 22, 2010 at 15:33:43 (UTC)
Goto Top
Moin SILVERMAN,

was soll denn " WHERE sf_nid = '%$sf_nid%' AND sf_sem = '%$sf_sem%' "; " machen??

Die Felder "sf_nid" und "sf_sem" sind vom Datentyp...?? Vielleicht ja sogar etwas VARCHAR()-artiges.

Aber selbst wenn das so sein sollte - was bewirken denn die Prozentzeichen davor/danach geplanterweise?

Symptom ist doch: du findest in keinem Fall den Satz, den du suchst.
Dann schau dir doch erstmal den Querystring an, den du erzeugst und copy/paste den in irgendeinen SQL-Client...

Grüße
Biber
Member: dog
dog Jul 22, 2010 at 20:24:47 (UTC)
Goto Top
add_newfee($sf_nid, $sf_sid, $sf_name, $sf_fee_eur, $sf_fee_cent, $sf_sem, $sf_semy, $sf_sp, $sf_uni, $sf_comment){

Für diese Variablenbenennung muss noch jemand sterben...

echo '<div class="error">';

Schöne Vermischung von Backend und Frontend Code...

die(mysql_error());

Aha, und genau welche SQL-Abfrage könnte an der Stelle fehlschlagen???

$sf_checkID ="SELECT sf_nid,sf_name,sf_sem FROM $tbl_name WHERE sf_nid = '%$sf_nid%' AND sf_sem = '%$sf_sem%' ";

Und alle Scriptkiddies so: "SQL-Injection, yeah!".

die('Error:'. mysql_error());

Stichwort: Information Disclosure

$sf_check_OK = mysql_query("SELECT sf_name,sf_fee_eur,sf_fee_cent FROM studyfees group by sf_name DESC LIMIT 1");

Aber mysql_insert_id() kennst du schon?

Aber selbst wenn das so sein sollte - was bewirken denn die Prozentzeichen davor/danach geplanterweise?

Hätte er ja korrekterweise ein LIKE verwendet währen es Platzhalter, so ist es ein % (war die Frage rhetorisch?)...
Member: nxclass
nxclass Jul 23, 2010 at 05:45:12 (UTC)
Goto Top
... man könnte ja über die Spalten ein UNIQUE Index setzten und ggf. mit REPLACE arbeiten.
Member: Biber
Biber Jul 23, 2010 at 06:32:40 (UTC)
Goto Top
Moin dog,

Stichwort: Information Disclosure
Andererseits....
So kritisch ist das ja nicht, wenn es sich auf einen fehlgeschlagenen INSERT bezieht..
$sf_insert="INSERT INTO $tbl_name(sf_nid,sf_sid,sf_name,sf_fee_eur,sf_fee_cent,sf_sem,sf_semy,sf_sp,sf_uni,sf_comment)
VALUES('$sf_nid','$sf_sid','$sf_name','$sf_fee_eur','$sf_fee_cent','$sf_sem','$sf_semy','$sf_sp','$sf_uni','$sf_comment')";
Selbst wenn dann $sf_name "Huber, Karl Georg" und $sf_sem=5 und $sf_uni="FU Berlin" und $sf_comment="Vordiplom 2x vergeigt" auf den Bildschirm durchschlägt...

Meinst du, es lässt sich zurückverfolgen? *gg

(war die Frage rhetorisch?)
Würde ich so etwas jemals tun?

Grüße
Biber
Member: SILVERMAN
SILVERMAN Jul 23, 2010 at 11:24:22 (UTC)
Goto Top
Moin Biber,

ich habe das Prozentzeichen entfernt .. die Prüfung wird stattfinden aber ich kriege folgende Fehlermeldung:

Warning: mysql_error(): supplied argument is not a valid MySQL-Link resource in :filename on line 112


Line 112 siht so aus

echo mysql_error($sf_checkID);


und der Wert von sf_name wird nicht gezeigt

$sf_checkID ="SELECT sf_nid,sf_name,sf_sem FROM $tbl_name WHERE sf_nid = '$sf_nid' AND sf_sem = '$sf_sem' ";  

				 echo mysql_error($sf_checkID);
				 echo"<br><br>";  
				
				$result = mysql_query($sf_checkID);
				if (mysql_num_rows($result) > 0) {
				
				
				// $sf_nid_s = $row['0']; 
			    // $sf_sem_s = $row['2']; 
						
						echo '<div class="error">';  
						echo "es wurden Studiengebühren für";  
						echo "/ة ";  
						echo '<br>';  
						echo $result['sf_name'];  
						echo '</div>';  

						
						}


welches Statement ist besser geeignet damit ich prüfe ob, schon für denjenigen bezahlt wurde und sein Name in der Meldung zeige.?

Danke
Member: SILVERMAN
SILVERMAN Jul 23, 2010 at 11:35:54 (UTC)
Goto Top
Hallo dog,

1- gute Nachricht keiner ist dadurch gestorben face-smile
2- findest du die Vermischung wirklich gut oder ..
3-
4- wie sieht eine sicherer Insert in diesem Fall aus?
5- Die Prozentzeichen waren ein Tipp im Internet, damit man keine Probleme mit den alten PHP Versionen kriegt.

Ich bin ja Anfänger und das sieht man klar und deutlich aber deine Art Hilfe zu leisten habe ich nicht ganz verstanden ..was kann ich mit deinen Kommentaren anfangen?

sorry für meine Ehrlichkeit aber ich hatte das Gefühlt, dass du vor mir stehst und mich auslachst statt mir zu sagen, was ich tun kann (siehe Biber Antwort).

Gruß
silverman
Member: dog
dog Jul 23, 2010 at 11:48:21 (UTC)
Goto Top
Lies doch bitte mal die PHP-Dokumentation.

mysql_error() nimmt eine MySQL-Connection-Resource und nicht einen String mit einer SQL-Abfrage drin...
Member: dog
dog Jul 23, 2010 at 11:58:02 (UTC)
Goto Top
Ich lache niemanden aus.
Bei mir ist es eher die Panik, dass solcher Code irgendwo produktiv eingesetzt wird.

Denn selben Mist hab ich auch mal gemacht als ich mit PHP angefangen habe, dann genauso eins auf den Deckel bekommen und seit dem bin ich vorsichtig.

Aber wenn du es im Detail nennst:

1. Du schreibst Code nicht so, dass du ihn verstehst, sondern, dass Andere ihn verstehen.
Und mit deinen Variablen kann absolut niemand was anfangen (nicht mal du nach 2 Wochen).
Es bringt niemanden um eindeutige Variablen zu benutzen und jeder gute Code-Editor vervollständigt die ohnehin.
Ich habe eine ganz einfache Regel: Wird die Variable für mehr als 10 Zeilen (also mein Sichtfeld) benutzt, muss sie eindeutig sein.

2. Nein, natürlich nicht.
Warum erstellst du eine Funktion, wenn die dann wieder HTML-Code erzeugt?
Der Sinn von Funktionen ist die Abstrahierung von Code und Aufspaltung von verschiedenen Layern.
Vielleicht willst du irgendwann mal nicht nur ein Frontend in HTML, sondern auch eine API schreiben und dann nützt dir eine Funktion die konkretes HTML ausgibt nichts mehr.

3. Siehe Zeile 8.
Ohne auch nur eine SQL-Abfrage ausgeführt zu haben kann es auch keinen Fehler geben. Logisch, oder?

4. Die Frage beantwortet Wikipedia zur Genüge: http://de.wikipedia.org/wiki/SQL-Injection#PHP
Erste Grundregel der Webprogrammierung: Traue NICHTS, das vom User kommt.

5. Ich weiß ja nicht, was der Tippgeber geraucht hat, aber es war mieses Zeug.
% ist ein Wildcard-Zeichen von MySQL und steht für "beliebig viele Zeichen an dieser Stelle".
Das funktioniert aber nicht mit einem =-Operator, sondern nur mit LIKE
Member: Biber
Biber Jul 23, 2010 at 11:59:26 (UTC)
Goto Top
Moin SILVERMAN,

da muss ich aber dog ausdrücklich in Schutz nehmen... er hat durchaus daruf hingewiesen, was du tun kannst und wo offene Flanken sind.

Insbesondere zu dem von dir gemeldeten "Fehler in Line 112" schrieb er:
die(mysql_error());

Aha, und genau welche SQL-Abfrage könnte an der Stelle fehlschlagen???

Wir können (und werden) die Fehlerchen schon rauspuhlen.
Aber es ist ja momentan nicht auf Tippfehler wie "einfaches Anführungszeichen vergessen" beschränkt,
sondern es sind noch ein paar Verständnis-Klemmer dabei.
Und da ist es immer sinnvoller, ein bisschen zu schubsen in die richtige Richtung als zu schreiben "Ersetze Zeile 37 durch dieses hier".

Noch mal in Ruhe drei Nachfragen:
  • die Primary Keys der Tabelle, die irgendwasID heißen, sind vom Datentyp... ????
  • du kannst die Statements trocken testen /hast die Statements trocken getestet über phpMyAdmin oder einen bedienbareren SQL-Client?
  • und hast du zufällig noch einen Link auf die "lieber ein paar Prozentzeichen aus Kompatibilitätsgründen"-Seite parat? Da muss irgendwas Missverständliches stehen...

Grüße
Biber

[Edit] Kommentar weitgehendst obsolet - steht schon alles bei dog. face-wink [/Edit]
Member: SILVERMAN
SILVERMAN Jul 26, 2010 at 09:14:43 (UTC)
Goto Top
Ok dog danke dir für die Tipps und sorry für mein Missverständnis.

1- Alle variablen habe ich in der Klasse oben richtig kommentiert, so dass jede die verstehen kann.
2- Wie du sieht versuche ich meine Fehlermeldung besser aussehen zu lassen .. soll hier ein return oder sowas in der Art einbauen und diese dann in Frontend formatieren? oder was ist besser geeignet?
3- habe ich korriegiert .. danke
4- Da hat du recht .. ist wirklich gut erklärt und ich werde es ausprobieren, obwohl es um eine interne Applikation handelt.
5- Das Prozentzeichen habe in Eile vergessen ich weiß, dass ich diese nur mit LIKE verbinden kann.


Biber
          • die Primary Keys der Tabelle, die irgendwasID heißen, sind vom Datentyp... ???? ich habe in diese Tabelle keine PKs, weil sich manche Spalten wiederholen.

                  • du kannst die Statements trocken testen /hast die Statements trocken getestet über phpMyAdmin oder einen bedienbareren SQL-Client? nein .. ich mach´s
                  • und hast du zufällig noch einen Link auf die "lieber ein paar Prozentzeichen aus Kompatibilitätsgründen"-Seite parat? Da muss irgendwas Missverständliches stehen... ich guck ma´

          Ich habe die Przentzeihen weggelassen jetzt klappt die Prüfung aber ich kriege folgende Fehlermeldung:

          Warning: mysql_error(): supplied argument is not a valid MySQL-Link resource in C:.....................  line 112

          und es wird keinen Namen in der Fehlermeldung ausgegeben

          was mache ich falsch?

          danke euch
Member: Biber
Biber Jul 26, 2010 at 18:48:50 (UTC)
Goto Top
Moin SILVERMAN,

nochmsl zu deiner Fehlermeldung "Supplied argument is not a valid MySQL-Link resource"...

Mir liegt zwar aher französisch als englisch, und mySQL spreche ich eigentlich gar nicht...

Aber als fachfremder Laie würde ich mal behaupten, da passiert genau das, was die Fehlermeldung aussagt.
Nämlich "mysql_error()" [und auch mysql_errno()] lassen sich entweder ohne Parameter aufrufen und liefern dann Fehlertext bzw. Fehlercode des letzten Statements.
Oder optional mit einem Parameter, der eine gültige Datenbankverbindung darstellt.
Was du aber nicht wirklich brauchst, denn in dem ganzen Fragment hast du ja höchstens eine einzige und nicht zwölf davon.
Der Fehler ist also ein aufgetretener Fehler, sondern schlicht und einfach eine falsch bzw. mit falschem Parameter aufgerufene Methode.

-> Lass den Parameter weg, dann hast du einen Fehler weniger.
Oder aber, wie auch mehrach angedeutet: Lass den ganzen Aufruf an dieser Stelle weg.
Denn WTHF glaubst du denn da prüfen zu können???? Ob das "SET UTF8" geklappt hat???


Erstaunlich finde ich nur, dass du im Code überhaupt so weit kommst... die ganzen Variablen, die wir nur erahnen können ($host, $dbname,...) scheinen ja irgendwo irgendwann von irgendwem global und gültig definiert worden zu sein.

Und auch noch mal ein letzter Versuch der Frageformulierung hierzu:
die Primary Keys der Tabelle, die irgendwasID heißen, sind vom Datentyp... ????
Okay, streiche den Begriff "PrimaryKeys"... setze einfach dafür "deine SELECT-Suchfelder"

Worauf ich mit der Frage hinauswollte:
Du suchst in deinem SELECT nach zwei mit deinen Suchwerten übereinstimmenden Feldern
... WHERE sf_nid = '%$sf_nid%' AND sf_sem = '%$sf_sem%' ";
Ein Feld heist "sf_nid " und sollte eigentlich gemäss allen Konventionen der DB-Modellierung incl. der Genfer Konvention eine ID (=numerisch) sein, das zweiten Feld heißt "sf_sem" was nun eher prosaisch klingt.... wie ein Zeichen/Stringfeld.
[Falls überhaupt irgendwelche Assoziation geweckt werden bei so einem Namen... wenn ich nachts aus der Kneipe Richtung Büro gehe und aus irgendeiner Seitengasse ruft jemand "sf_sem"... da müsste ich zweimal überlegen, was wohl gemeint ist]

Anyway.... jedenfalls vergleichst du beide Felder mit einem String. Ist das richtig und gewollt bzw was sind denn die ver###ten Datentypen?

Grüße
Biber
Member: dog
dog Jul 26, 2010 at 20:01:11 (UTC)
Goto Top
edenfalls vergleichst du beide Felder mit einem String

Zum Glück ist MySQL extrem nett:
> SELECT 1 = '1';  
+---------+
| 1 = '1' |  
+---------+
|       1 | 
+---------+
Member: Biber
Biber Jul 27, 2010 at 07:20:17 (UTC)
Goto Top
Moin dog,

face-wink ja schon....
Aber eins der gemeldeten Phänomene war/ist ja, dass dieses Such-Select in keinem Fall bereits vorhandene Datenstze findet.
Und irgendwo in diesem Skriptgestruktele muss man ja mal anfangen, ein bisschen was glattzuziehen.

Grüße
Biber
Member: SILVERMAN
SILVERMAN Jul 27, 2010 at 08:48:37 (UTC)
Goto Top
Ich danke euch Leute .. Ich habe die Lösung gefunden.

Die Lösung:

 $sf_checkID =mysql_query("SELECT sf_nid,sf_name,sf_sem FROM $tbl_name WHERE sf_nid = '$sf_nid' AND sf_sem = '$sf_sem' ");  

				
				
				//$result = mysql_query($sf_checkID);
				//$result = mysql_fetch_row($sf_checkID);
				
if (mysql_num_rows($sf_checkID) > 0) {
				
								while ($row = mysql_fetch_array($sf_checkID, MYSQL_NUM)) {
						// $sf_nid_s = $row['0']; 
						// $sf_sem_s = $row['2']; 
								
								echo '<div class="error">';  
								echo "es wurden Studiengebühren für den Student:";  
								echo "/in";  
								echo '<br>';  
								echo '<font color="#9F0000">';  
								printf($row[1]);
								echo '</font>';  
								echo '<br>';  
								echo "bereits bezahlt. Bitte überprüfen Sie ihre Angaben";  
								echo '</div>';  
								
								}
			
						
						}

Danke noch mal