Variablen aus Funktion global verfügbar machen
tomtom
- php
Hallo,
Ich bin gearade dabei mir ein Script zu erstellen, mit dem man seinen Account freischalten kann.
Leider geling mir das nicht ganz. >_<
Das Problem ist folgendes:
Wenn die Funktion eine falsche Eingabe im Formular wahrnimmt, dann soll der Fehler neben dem Forumlar ausgegeben werden (z.B. 'Bitte dieses Feld füllen' bei einem leeren Feld).
Dieses System der Fehleranzeige ist sehr oft zu sehen, denke ich mal und dürfte eigentlich garnicht so schwer sein..
Ich gestehe, dass die Methode, die ich hier anwende, nicht die ist, die man in diesem Falle verwenden soll.
Leider weiß ich aber nicht, wie ich die oben beschriebene Funktion anders gestallten kann.
Hier die PHP-Funktion und das Formular (in gekürzter Funktion).
Es wäre sehr sehr nett, wenn sich jemand meinem Problem annehmen könnte =)
<?php
function register() {
// globale Variablen definieren
$wunsch_name = $_POST['wunschname'];
$passwort1 = $_POST['passwort1'];
$passwort2 = $_POST['passwort2'];
$email1 = $_POST['email1'];
$email2 = $_POST['email2'];
// bereits vergebene Benutzernamen auslesen
$sql = "SELECT
user_benutzername
FROM
".MYSQL_PREFIX."users
";
$result = mysql_query($sql) OR die(mysql_error());
$benutzernamen = array();
while ($entry = mysql_fetch_assoc($result)) {
array_push($benutzernamen, $entry['user_benutzername']);
}
// Eingaben auf 'leer' prüfen
$wrong = 0;
if($wunsch_name == '') {
$name_empty = 1;
$wrong ++;
}
if($passwort1 == '') {
$pw1_empty = 1;
$wrong ++;
}
if($passwort2 == '') {
$pw2_empty = 1;
$wrong ++;
}
if($email1 == '') {
$mail1_empty = 1;
$wrong ++;
}
if($email2 == '') {
$mail2_empty = 1;
$wrong ++;
}
// Prüfen, ob Benutzername schon vorhanden
if (!in_array($wunsch_name, $benutzernamen)) {
$username_ok = 1;
}
// Prüfen ob PW1 == PW2
if ($passwort1 == $passwort2) {
$pw_ok = 1;
}
// Prüfen ob MAIL1 == MAIL2
if ($email1 == $email2) {
$email_ok = 1;
}
// Wenn alles OK, dann registieren
if ($wrong == 0) {
if(isset($username_ok) AND isset($pw_ok) AND isset($code_ok)) {
// REGISTRIEREN
echo '<span style="color:#0F0">Dein Account wurde erfolgreich freigeschaltet. Viel Spaß.</span>';
}
}
}
// Funktion aufrufen, wenn SUBMIT betätigt wird
if(isset($_POST['submit_register'])) {
register();
}
?>
<!-- Das verkürzte Formular -->
<form action="index.php" method="post">
Wunsch-Name:
<input name="wunschname" type="text" class="standard_form_text" size="20" />
[code lang=php]<?php
if(isset($_POST['submit_register']) AND isset($name_empty)) {
echo 'Bitte dieses Feld füllen';
}
?>
<!-- weitere Eingaben...... -->
</form>
[/code]
Tschuldigung !
Habe vergessen zu sagen, dass im Formular keine Hinwesie erscheinen, da $name_empty bei
<?php
if(isset($_POST['submit_register']) AND isset($name_empty)) {
echo 'Bitte dieses Feld füllen';
}
?>
nicht global verfügbar ist, was eigentlich direkt die Frage ist, auf die ich hinaus will:
Kann ich Variablen aus Funktionen global machen und wenn ja, wie?
Wenn's nicht anders geht, müssen SUPERGLOBALS her ;-)
Wenn ich dein Vorhaben jetzt richtig verstehe, warum gibst Du dann die Fehlermeldungen bzw. die jeweiligen Variablen nicht per return zurück?
Gruß
Dynamite
Wenn ich dein Vorhaben jetzt richtig verstehe, warum gibst Du dann die Fehlermeldungen bzw. die jeweiligen Variablen nicht per return zurück?
Gruß
Dynamite
Eine berechtigte Frage ;-)
Erstmal Danke dafür, dass du mir helfen willst.
Mit return habe ich schon versucht, eben diese Fehlermeldungen anzeigen zu lassen.
Ich habe das allerdings so verstanden (so wurde es mir jedenfalls beigebracht), dass das return-Kostrukt ähnlich wie der echo-Befehl arbeitet.
Demnach wird die Fehlermeldung ja dort ausgegeben, wo ich die Funktion aufrufe, was ja nicht soll.
schreibt amn z.B. return 'TestText' in die Funktion, wird an dieser Stelle der Text "TestText" asugegeben.
Wenn meine Annahmen wirklich falsch ist und man mit return beliebig viele Variablen 'globalisieren' kann, frage ich mich, warum folgendes nicht geht? =(
if($wunsch_name == '') {
$name_empty = 1;
$wrong ++;
return $name_empty;
}
Gruß tomtom.
Hi,
Mit return habe ich schon versucht, eben diese Fehlermeldungen anzeigen zu lassen.
Ich habe das allerdings so verstanden (so wurde es mir jedenfalls beigebracht), dass das return-Kostrukt ähnlich wie der echo-Befehl arbeitet.Demnach wird die Fehlermeldung ja dort ausgegeben, wo ich die Funktion aufrufe, was ja nicht soll.
Nein.
Mit return kannst du Werte (genauer: einen Wert, der allerdings bspw. auch vom Typ Array sein kann) an die aufrufende Stelle zurückgeben.
Was an der aufrufenden Stelle damit passiert, liegt an dir.
Du kanst den Rückgabewert bspw. einer Variablen zuweisen, und dann später auf diese zugreifen.
MfG ChrisB
Nein.
Mit return kannst du Werte (genauer: einen Wert, der allerdings bspw. auch vom Typ Array sein kann) an die aufrufende Stelle zurückgeben.Was an der aufrufenden Stelle damit passiert, liegt an dir.
Du kanst den Rückgabewert bspw. einer Variablen zuweisen, und dann später auf diese zugreifen.MfG ChrisB
Danke für die schnelle Antwort ^.^
Wenn ich dich jetzt richtig verstehe, gehört der return-Befehl also nicht IN in die Funktion, sondern dort hin, wo ich eben diesen Wer aufrufen will.
Es tut mir sehr leid, aber scheinbar kann ich deiner Erklärung nicht ganz folgen, denn das habe ich soeben ausprobiert. =)
<form action="index.php" method="post">
Wunsch-Name:
<input name="wunschname" type="text" class="standard_form_text" size="20" />
[code lang=php]<?php
return $name_empty;
if(isset($_POST['submit_register']) AND isset($name_empty)) {
echo 'Bitte dieses Feld füllen';
}
?>
</form>[/code]
Ausgabe
Notice: Undefined variable: name_empty in C:\Programme\XAMPP Windows 1.7.0\htdocs\index.php on line 426
Steht das obrige wirklich so ein deinem Script? Ein verlassenes return ohne Funktion?
Ein verlassenes return ohne Funktion?
»»
Ich verstehe nicht genau, was du mir sagen willst >_<
Gehört das return nun IN die Funktion (wovon ich ausgehe) oder an die Stelle, wo ich es brauche ?
Da die Nachfrage kam, ob das alles wirklich so in meine Script steht (ob es auch Ironie war oder nicht - kann ich in diesem Falle leider nicht einschätzen :) ),
hab ich den Code nochmal aufgeführt.
Nochmals Danke für die schnelle Antwort ^^
<?php
function register() {
// globale Variablen definieren
$wunsch_name = $_POST['wunschname'];
$passwort1 = $_POST['passwort1'];
$passwort2 = $_POST['passwort2'];
$email1 = $_POST['email1'];
$email2 = $_POST['email2'];
// bereits vergebene Benutzernamen auslesen
$sql = "SELECT
user_benutzername
FROM
".MYSQL_PREFIX."users
";
$result = mysql_query($sql) OR die(mysql_error());
$benutzernamen = array();
while ($entry = mysql_fetch_assoc($result)) {
array_push($benutzernamen, $entry['user_benutzername']);
}
// Eingaben auf 'leer' prüfen
$wrong = 0;
if($wunsch_name == '') {
$name_empty = 1;
$wrong ++;
}
if($passwort1 == '') {
$pw1_empty = 1;
$wrong ++;
}
if($passwort2 == '') {
$pw2_empty = 1;
$wrong ++;
}
if($email1 == '') {
$mail1_empty = 1;
$wrong ++;
}
if($email2 == '') {
$mail2_empty = 1;
$wrong ++;
}
// Prüfen, ob Benutzername schon vorhanden
if (!in_array($wunsch_name, $benutzernamen)) {
$username_ok = 1;
}
// Prüfen ob PW1 == PW2
if ($passwort1 == $passwort2) {
$pw_ok = 1;
}
// Prüfen ob MAIL1 == MAIL2
if ($email1 == $email2) {
$email_ok = 1;
}
// Wenn alles OK, dann registieren
if ($wrong == 0) {
if(isset($username_ok) AND isset($pw_ok) AND isset($code_ok)) {
// REGISTRIEREN
echo '<span style="color:#0F0">Dein Account wurde erfolgreich freigeschaltet. Viel Spaß.</span>';
}
}
}
// Funktion aufrufen, wenn SUBMIT betätigt wird
if(isset($_POST['submit_register'])) {
register();
}
?>
<!-- Das verkürzte Formular -->
<form action="index.php" method="post">
Wunsch-Name:
<input name="wunschname" type="text" class="standard_form_text" size="20" />
[code lang=php]<?php
// HIER IST DAS RETURN
return $name_empty;
if(isset($_POST['submit_register']) AND isset($name_empty)) {
echo 'Bitte dieses Feld füllen';
}
?>
<!-- weitere Eingaben...... -->
</form>[/code]
Gehört das return nun IN die Funktion (wovon ich ausgehe) oder an die Stelle, wo ich es brauche ?
return ist für den Rückgabewert der Funktion innerhalb einer Funktion verantwortlich - in deinem Script sehe ich aber keine Funktion mehr.
Vieleicht solltest Du dir das hier mal durchlesen.
Gruß
Dynamite
Vieleicht solltest Du dir das hier mal durchlesen.
Gruß
Dynamite
Wow Quakenet ;-) .... das waren meine ersten Schritte mit PHP.
Danke für den Link.
Daraus lässt sich entnehmen dass "Mit return gleichzeitig die Funktion beendet wird".
Irgendwoher kenn ich das noch, da ich es ja vorher schon mit return versucht habe, aber nicht zum gewünschten Ergebnis gekommen bin.
Genau das war nämlich der Clue an der Sache: Die Funktion wird beendet und NUR der Wert, der mit return 'zurückgegeben' wird, wird beim Aufruf der Funktion wiedergegeben.
In meinem Fall heißt das also, dass nur die Fehlermeldung für das leere "Wunschname-Feld" angezeigt wird und die Funktion danach beendet wird.
Muss ich denn wirklich jede einzelne Abfrage (Wunsch-Name leer, Email leer, Passwort1 == Passwort2) in je einer einzelnen Funktion deklarieren, um meinen Script mit return zu realisieren?
Das würde ich für sehr umständlich erachten ;-)
Danke.
tommi
Ja - auch ich erachte es als sehr umständlich, dass man alles mindestens zwei Mal erklären muss.
Ich entschuldige mich dafür, dass ich es nicht sofort begriffen habe.
Dass man mit return ein ganzes Array zurückliefern kann, habe ich zwar gelesen, zu diesem Zeitpunkt aber nicht als Lösungsansatz betrachtet.
Dein Beitrag hat mir wirklich sehr geholfen und mir die Augen geöffnet.
Ganz besonders die Tips haben mir dabei gefallen.
Viel vielen Dank =)
Ich werde das mit dem Array ausprobieren und deine Tips umsetzten.
Wenn der Script funktioniert und wenn ihr wollt, melde ich mich nochmal.
Gruß
tomtom
»» Ja - auch ich erachte es als sehr umständlich, dass man alles mindestens zwei Mal erklären muss.
»»Ich entschuldige mich dafür, dass ich es nicht sofort begriffen habe.
Entschuldigen musst du dich nicht dafür, sie es als Verbesserungsvorschlag an deiner Lernstrategie. Früher hat man gesagt "Erst denken, dann Handeln" - jetzt "Lies alle Posts aufmerksam durch, dann frag' weiter" :)
Wenn der Script funktioniert und wenn ihr wollt, melde ich mich nochmal.
Wenn etwas funktioniert und du deine Lösung (und vor allem deinen Lösungsweg) hier postest, wird sich sicher jemand finden, der irgendwann auf der Suche nach einer Lösung für ein ähnliches Problem genau auf deinen Beitrag im Archiv stößt. Wenn du also einen guten Eindruck hinterlassen möchtest und etwas gutes für die Menschheit tun willst, melde dich wieder.
Zudem: nur weil etwas funktioniert, heisst es noch lange nicht, dass es vernünftig oder sicher ist - wenn du lernwillig bist, wird man dir für dein nächstes Zwischenergebnis sicher einige weitere Tipps und Verbesserungsvorschläge geben. Ggf. stöberst du auch mal hier im Archiv herum - zu diesem Thema (Benutzerregistrierung, sicheres Login, Formuarprüfung, usw.) gibt es massenhaft Beiträge.
Dann erstatte ich mal Bericht über meine Vortschritte:
Sicher fragt man sich jetzt was der freischaltcode oder $_POST['schluessel'] ist. Dies ist einfach nur ein Schlüssel, den man bei der Freischaltung benötigt. Die Freischaltcodes liegen bereits in der Datenbank unter den richtigen Namen der Benutzer, sprich dass sich nur Personen freischalten können, die die Datenbank kennt. Die Sicherheitsschlüssel sollen später an die jenigen Personen weitergegeben werden.
Zunächst die Funktion, die beim abschicken des Formulars ausgeführt wird:
<?php
function register() {
$errors = array();
// Kontrolle der Eingabe
if($_POST['wunschname'] == '') {
$errors[] = 'empty_name';
}
if($_POST['passwort1'] == '') {
$errors[] = 'empty_pw1';
}
if($_POST['passwort2'] == '') {
$errors[] = 'empty_pw2';
}
if($_POST['email1'] == '') {
$errors[] = 'empty_email1';
}
if($_POST['email2'] == '') {
$errors[] = 'empty_email2';
}
if($_POST['schluessel'] == '') {
$errors[] = 'empty_schluessel';
}
if ($_POST['passwort1'] != $_POST['passwort2']) {
$errors[] = 'pw_no_match';
}
if ($_POST['email1'] != $_POST['email2']) {
$errors[] = 'email_no_match';
}
if(count($errors) > 0) {
return $errors;
}
// Freischaltcodes auslesen
$sql = "SELECT
user_id,
user_name,
user_vorname,
user_freischaltcode
FROM
".MYSQL_PREFIX."users
WHERE
user_freischaltcode = '".$_POST['schluessel']."'
";
$result = mysql_query($sql) OR die(mysql_error());
while ($entry = mysql_fetch_assoc($result)) {
$key_exist = $entry['user_freischaltcode'];
}
// Prüfen, ob Freischaltcode richtig ist
if (!isset($key_exist)) {
$errors[] = 'wrong_key';
return $errors;
}
// bereits vergebene Benutzernamen auslesen
$sql = "SELECT
user_benutzername
FROM
".MYSQL_PREFIX."users
WHERE
user_benutzername = '".$_POST['wunschname']."'
";
$result = mysql_query($sql) OR die(mysql_error());
while ($entry = mysql_fetch_assoc($result)) {
$name_exist = $entry['user_benutzername'];
}
// Prüfen, ob Benutzername schon vorhanden
if (isset($name_exist)) {
$errors[] = 'username_exist';
return $errors;
}
// Wenn alles OK, dann REGISTRIEREN
$sql = "UPDATE
".MYSQL_PREFIX."users
SET
user_benutzername ='".htmlspecialchars($_POST['wunschname'])."',
user_passwort ='".htmlspecialchars(md5($_POST['passwort1']))."',
user_email ='".htmlspecialchars($_POST['email1'])."',
user_freigeschaltet ='1',
user_freischaltcode =''
WHERE
user_freischaltcode = '".$_POST['schluessel']."'
";
$result = mysql_query($sql) OR die(mysql_error());
$sql = "SELECT
user_id,
user_name,
user_vorname,
user_benutzername
FROM
".MYSQL_PREFIX."users
WHERE
user_benutzername = '".$_POST['wunschname']."'
";
$result = mysql_query($sql) OR die(mysql_error());
while ($user_infos = mysql_fetch_assoc($result)) {
$name = $user_infos['user_name'];
$vorname = $user_infos['user_vorname'];
$username = $user_infos['user_benutzername'];
}
$success = array(
'success' => '1',
'name' => $name,
'vorname' => $vorname,
'username' => $username);
return $success;
}
Die Fehler-Texte, die beim Formular ausgegeben werden sollen(Danke hierfür an suit):
~~~php
$error_messages = array(
'default' =>
array(
'empty_name' => 'Fill in your favor username',
'empty_pw1' => 'Fill in your favor Passwort',
'empty_pw2' => 'Confirm your Passwort',
'empty_email1' => 'Fill in your email-address',
'empty_email2' => 'Confirm your email-address',
'empty_schluessel' => 'Verification-Key is needed',
'pw_no_match' => 'Passwords do not match',
'email_no_match' => 'Email-Adress' do not match',
'wrong_key' => 'This is not a valid key',
'username_exist' => 'This username already exist'
),
'de' =>
array(
'empty_name' => 'Der Benutzername fehlt',
'empty_pw1' => 'Bitte gebe dein Passwort ein',
'empty_pw2' => 'Bitte bestätige dein Passwort',
'empty_email1' => 'Bitte gebe deine Emailadresse an',
'empty_email2' => 'Bitte bestätige deine Emailadresse',
'empty_schluessel' => 'Sicherheitsschlüssel fehlt',
'pw_no_match' => 'Die Passwörter stimmen nicht überein',
'email_no_match' => 'Diese Adressen stimmen nicht überein',
'wrong_key' => 'Dieser Schlüssel ist nicht gültig',
'username_exist' => 'Dieser Benutzername ist bereits vergeben'
)
);
?>
Hier ein Standard-Meldetext, der ausgegeben wird, wenn das Formular abgeschickt wird:
~~~php
<?php
if(isset($_POST['submit_register'])) {
$proof = register();
}
if(isset($_POST['submit_register']) AND !isset($proof['success'])){
echo 'Überprüfe deine Eingaben nochmal';
}
if(isset($_POST['submit_register']) AND isset($proof['success'])){
echo '<span style="color:#0F0">Der Account ';
echo $proof['username'];
echo ' wurde erfolgreich für ';
echo $proof['vorname'].' '.$proof['name'];
echo ' freigeschaltet. Viel Spaß.</span>';
}
?>
Hierdurch wird das Fenster, mit dem man sich freischaltet, bei Fehler-Eingabe wieder angezeigt:
<?php
echo '<div id="box-register" style="margin-top:40px;';
if (isset($_POST['submit_register']) AND $proof['success'] != 1) {
$get_post_back = 1;
echo 'display:block">';
} else {
echo 'display:none">';
}
?>
Und folglich das Formular (gekürzt), in dem die Daten eingetragen werden:
<form action="index.php" method="post">
<table border="0" style="width:800px;color:silver">
<tr>
<td>
Wunsch-Name:
</td>
<td>
[code lang=php]<?php
echo '<input name="wunschname" type="text" class="standard_form_text" size="20" ';
if(isset($get_post_back)) {
echo 'value="'.$_POST['wunschname'].'"';
}
echo ' />';
if(isset($_POST['submit_register']) AND in_array('empty_name',register())) {
echo '<span style="color:darkred">'.$error_messages['de']['empty_name'].'</span>';
} elseif (isset($_POST['submit_register']) AND in_array('username_exist',register())) {
echo '<span style="color:darkred">'.$error_messages['de']['username_exist'].'</span>';
}
?>
</td>
</tr>
<tr>
<td>
Passwort:
</td>
<td>
~~~php
<?php
echo '<input name="passwort1" type="password" class="standard_form_text" size="20" ';
if(isset($get_post_back)) {
echo 'value="'.$_POST['passwort1'].'"';
}
echo ' />';
if(isset($_POST['submit_register']) AND in_array('empty_pw1',register())) {
echo '<span style="color:darkred">'.$error_messages['de']['empty_pw1'].'</span>';
}
?>
</td>
</tr>
<!-- to be contiune... -->[/code]
Dieser Code ist noch ziemlich 'unschön' und auch noch nicht vollständig,doch zumindest funktionierts =)
Würde mich trotzdem für ein kleines Feedback freuen.
Danke
Dann erstatte ich mal Bericht über meine Vortschritte:
Du solltest die Benutzereingaben zur weiteren verwendung in SQL-Statements dringend mit mysql_real_escape_string() behandeln.
$error_messages = array(
echo ' freigeschaltet. Viel Spaß.</span>';
Wenn du dein error_messages-Array umbenennst in sagen wir "dictionary" oder sonstwie kannst du auch andere strings wie "du bist freigeschaltet" usw dort aufnehmen.
Weiters hast du mein Beispiel mit englisch als Default und deutsch zusätzlich übernommen obwohl du augenscheinlich nur deutsch benötigst - ggf. solltest du also Deutsch als Defaultsprache definieren und die übersetzung einfach entfernen. Die Sprachteilung nutzt du scheinbar ohnehin nicht. Un frägst hardcodiert immmer 'de' ab.
echo '<span style="color:darkred">'.$error\_messages['de']['empty\_pw1'].'</span>';
Hier solltest du ein <span class="error"> oder ggf. ein <p class="error" drausmachen.
Wenn du alle Fehlermeldungen später mal hell-rot machen möchtest oder einen roten Rahmen herum haben möchtest, brauchst du nur noch das CSS angreifen, nicht deinen PHP-Code.
Ansonsten gibts sicher noch einiges was zu sagen wäre - ich bin aber sehr kurz angebunden.
Dieses System der Fehleranzeige ist sehr oft zu sehen, denke ich mal und
Es wäre sehr sehr nett, wenn sich jemand meinem Problem annehmen könnte =)
<?php
function register() {
// globale Variablen definieren
$wunsch_name = $_POST['wunschname'];
$passwort1 = $_POST['passwort1'];
$passwort2 = $_POST['passwort2'];
$email1 = $_POST['email1'];
$email2 = $_POST['email2'];
Vermeide es sinnlos Variablen herumzukopieren (bzw. verweise zu erstellen) - das macht deinen code nur unleserlich.
// bereits vergebene Benutzernamen auslesen $sql = "SELECT user_benutzername FROM ".MYSQL_PREFIX."users "; $result = mysql_query($sql) OR die(mysql_error()); $benutzernamen = array(); while ($entry = mysql_fetch_assoc($result)) { array_push($benutzernamen, $entry['user_benutzername']); }
Warum prüfst du nicht gleich, ob $_POST['wunschname'] schon exsistiert - es ist höchst ineffizent, alle Benutzer auszulesen, in ein array zu schreiben und diese dann durchzuackern - ich möchte nicht wissen, wie langsam das wird, wenn du mal 50000 Benutzer in deiner Datenbank hast.
Ebenso würde ich sämtliche Eingabeprüfungen vor die SQL-Abfrage schieben, wenn diese scheitern - z.B. wenn der Benutzername ein Leerstring ist - kannst du dir die Abfrage gleich schenken und musst die Datenbank nicht belasten.
Ebenso solltest du den Fehlerzähler ausbauen und gegen eine Fehlernummern-Lösung tauschen.
Wenn ein Fehler auftritt, setzt du exakt diesen Wert in ein array für deine Fehler.
[code lang=php]$fehler = array();
// wenn Benutzername leer
$fehler[] = 'user_is_empty';
// wenn Passwörter unterschiedlich
$fehler[] = 'passwords_do_not_match';
Später wertest du die Fehler dann aus, indem du in einem array die eigentliche Fehlermeldungen rausliest.
~~~php
$fehlerteste = array(
'default' => array(
'user_is_empty' => 'Username is empty!',
'passwords_do_not_match' => 'Your Passwords don't match!',
),
'de' => array(
'user_is_empty' => 'Benutzername ist leer!',
'passwords_do_not_match' => 'Die Passwörter stimmen nicht überein!',
),
);