unexpected $end in

Alles, was PHP betrifft, kann hier besprochen werden.

unexpected $end in

Postby I-c-H » 22. July 2008 20:40

Hallo,

mein Browser gibt mir folgende Fehlermeldung aus:

Parse error: syntax error, unexpected $end in C:\xampp\htdocs\Jokes04.php on line 105


Bitte nicht erschrecken, ich ERLERNE PHP gerade via eines Lehrbuches. Darum ist evntl. der ein oder andere Code, trotz ähnlicher Funktion, etwas anders aufgebaut worden, weil ich es woanders - für mich - attraktiver vorgefunden und nachgemacht habe.

Der Fehler muss sich irgendwo im Bereich zwischen "<?php if (isset($_GET['askdeletejoke'])):" und seinem Schlusstag "?>" befinden.

Entferne ich diesen nämlich völlig, läuft auch das Script Fehlerfrei, nur eben ohne die ausgedachte Extrafunktion.

Im Lehrbuch wurde mir beschrieben, wie ich einen Witz aus meiner Datenbank löschen kann. Nun wollte ich - selbstständig, ohne Vorlage - eine Sicherheitsabfrage erstellen, ob der betreffende Witz wirklich gelöscht werden sollte.

Hier der Quelltext:

Code: Select all
<html>
<head>
<title>Witze</title>
</head>
<body>

<P>Herzlich willkommen!</P>
<?php if (isset($_GET['addjoke'])):?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<label>Bitte geben Sie hier Ihren Witz ein:<br />
<textarea name="joketext" rows="10" cols="40">
</textarea></label><br />
<input type="submit" value="Speichern" />
</form>

<?php if (isset($_GET['askdeletejoke'])):
//Fragen,  ob der Witz wirklich gelöscht werden soll
 
  if (isset($_GET['askdeletejoke'])) {
   $jokeid = $_GET['askdeletejoke']; 
   $joketext = $_GET['askdeletejoke'];
   echo ('<p>Soll nachfolgender Witz wirklich aus der Witzeliste entfernt werden?</p>');
   echo '<p>'
   .'<a href="'.$_SERVER['PHP_SELF'].'?deletejoke='.$jokeid.'">'
   .'Ja</a>'
   .'<a href="'.$_SERVER['PHP_SELF'].'">Nein</a>'
    .'</p>';

  }
  // Falls ein Witz gelöscht werden soll,
  // aus der Datenbank löschen.
  if (isset($_GET['deletejoke'])) {
    $jokeid = $_GET['deletejoke'];
    $sql = "DELETE FROM Jokes
        WHERE ID = $jokeid ";
    if (@mysql_query($sql)) {
      echo ('<p>Der Witz wurde gelöscht.</p>');
    } else {
      echo '<p>Fehler beim Löschen des Witzes: ' .
          mysql_error() . '</p>';
    }
  }
 ?>
 
<?php else:

//Verbindung zur Datenbank herstellen
$dbcnx = @mysql_connect('localhost', 'root', 'GEHEIM');
   if(!dbcnx) {
   exit('<p> Eine Verbindung zur Witze-Datenbank konnte leider nicht hergestellt werden!<br>Begründung:' . mysql_error() . '</P>');
}
//Datenkbank auswählen
mysql_select_db('jokes');
   if(!@mysql_select_db('jokes')) {
   exit('Die Witzedatenbank ist zur Zeit nicht abrufbar. Bitte versuche es später noch einmal!');
   }
   
//Falls ein Witz hinzugefügt wurde:
if (isset($_POST['joketext'])) {
    $joketext = $_POST['joketext'];
    $sql = "INSERT INTO Jokes SET
        JokeText='$joketext',
        JokeDate=CURDATE()";
    if (@mysql_query($sql)) {
      echo '<p>Ihr Witz wurde hinzugefügt.</p>';
    } else {
      echo '<p>Fehler beim Hinzufügen des Witzes: ' .
          mysql_error() . '</p>';
    }
  }
?>
<P>Dies sind derzeit alle Witze aus unserer Datenbank:</P>
<blockquote>
<?php

// ID und text aller Witze auslesen
  $result = @mysql_query('SELECT ID, JokeText FROM Jokes');
  if (!$result) {
    exit('<p>Fehler bei der Ausführung der Abfrage: ' .
        mysql_error() . '</p>');
  }

  // Text jedes Witzes in einem Absatz anzeigen,
  // mit einem "Diesen Witz löschen"-Link daneben.
  while ($row = mysql_fetch_array($result)) {
    $jokeid = $row['ID'];
    $joketext = $row['JokeText'];
    echo '<p>' . $joketext .
        ' <a href="' . $_SERVER['PHP_SELF'] .
        '?askdeletejoke=' . $jokeid . '">' .
        '<br>Diesen Witz löschen</a></p>';
  }
 
//Link zum Hinzufügen eines Witzes

echo '<p><a href="' . $_SERVER['PHP_SELF'] .
   '?addjoke=1">Einen Witz hinzufügen!</a></p>';
   
endif;

?>
</blockquote>
</body>
</html>


Für PHP-Scripte verwende ich den Notepad++ Editor.
BITTE gebt mir nur Hinweise zur Fehlerkorrektur - ich bin mir sicher, dass man es anders, professioneller oder schöner lösen kann bzw. schreiben kann, doch ich bin gerade am Erlernen und möchte erst einmal einen Weg beherrschen, bevor ich mich an den Nächsten wage.

DANKE!
I-c-H
 
Posts: 24
Joined: 20. July 2008 16:20

Postby Wiedmann » 22. July 2008 20:48

Der Fehler muss sich irgendwo im Bereich zwischen "<?php if (isset($_GET['askdeletejoke'])):" und seinem Schlusstag "?>" befinden.

Was macht dieser Doppelpunkt da?
Wiedmann
AF Moderator
 
Posts: 17102
Joined: 01. February 2004 12:38
Location: Stuttgart / Germany

Postby I-c-H » 22. July 2008 20:50

Der Stand bei dem Script, von dem ich abgeschrieben habe, auch da, allerdings hast du Recht, jetzt wo ich ihn herausgenommen habe, funktioniert die Anzeige der Seite, doch meine Funktion überhaupt nicht mehr :?


Zusätzlich zu dieser Frage, gleich noch eine hinterher:

Code: Select all
<?php if (isset($_GET['addjoke'])):?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<label>Bitte geben Sie hier Ihren Witz ein:<br />
<textarea name="joketext" rows="10" cols="40">
</textarea></label><br />
<input type="submit" value="Speichern" />
</form>

Warum darf der Doppelpunkt DA stehen?


Ich habe den oberen Teil jetzt einfach mal verändert, trotzdem arbeitet meine Funktion überhaupt nicht. Hm...

Code: Select all
<?php if (isset($_GET['askdeletejoke'])) {
//Fragen,  ob der Witz wirklich gelöscht werden soll
 
    $jokeid = $_GET['askdeletejoke']; 
   $joketext = $_GET['askdeletejoke'];
   echo ('<p>Soll nachfolgender Witz wirklich aus der Witzeliste entfernt werden?</p>');
   echo '<p>'.$joketext
   .'<a href="'.$_SERVER['PHP_SELF'].'?deletejoke='.$jokeid.'">'
   .'Ja</a>'
   .'<a href="'.$_SERVER['PHP_SELF'].'">Nein</a>'
    .'</p>';

  }
I-c-H
 
Posts: 24
Joined: 20. July 2008 16:20

Postby Xardas der Dunkle » 22. July 2008 21:04

Der Doppelpunkt muss bei der alternativen Schreibweise für Strukturen wie sie hier verwendet wird notiert werden.

Das Problem bei dem Script ist, das das 2te endif fehlt.
Ich habe mal versucht den Code etwas aufzuräumen ..., ob es so passt kA, zumal mein Editor den : hinter dem else bemängelt :shock:.

Code: Select all
<html>
<head>
<title>Witze</title>
</head>
<body>

<P>Herzlich willkommen!</P>
<?php
if (isset($_GET['addjoke'])):
?>

    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <label>Bitte geben Sie hier Ihren Witz ein:<br />
    <textarea name="joketext" rows="10" cols="40">
    </textarea></label><br />
    <input type="submit" value="Speichern" />
    </form>

<?php
endif;

if (isset($_GET['askdeletejoke'])):

    //Fragen,  ob der Witz wirklich gelöscht werden soll
    if (isset($_GET['askdeletejoke'])) {
        $jokeid = $_GET['askdeletejoke'];
        echo '<p>Soll nachfolgender Witz wirklich aus der Witzeliste entfernt werden?</p>';
        echo '<p>'
           . '<a href="'.$_SERVER['PHP_SELF'].'?deletejoke=' . intval($jokeid) . '">Ja</a> '
           . '<a href="'.$_SERVER['PHP_SELF'].'">Nein</a>'
           . '</p>';
    }

    // Falls ein Witz gelöscht werden soll,
    // aus der Datenbank löschen.
    if (isset($_GET['deletejoke'])) {
        $jokeid = $_GET['deletejoke'];
        $sql = "DELETE FROM Jokes WHERE ID = " . intval($jokeid);

        if (@mysql_query($sql)) {
            echo ('<p>Der Witz wurde gelöscht.</p>');
        } else {
            echo '<p>Fehler beim Löschen des Witzes: ' . mysql_error() . '</p>';
        }
    }

else:

    //Verbindung zur Datenbank herstellen
    $dbcnx = @mysql_connect('localhost', 'root', 'GEHEIM');
    if(!dbcnx) {
       exit '<p>Eine Verbindung zur Witze-Datenbank konnte leider nicht hergestellt werden!<br />Begründung:' . mysql_error() . '</p>' ;
    }

    //Datenkbank auswählen
    mysql_select_db('jokes');
    if(!@mysql_select_db('jokes')) {
        exit('Die Witzedatenbank ist zur Zeit nicht abrufbar. Bitte versuche es später noch einmal!');
    }

    //Falls ein Witz hinzugefügt wurde:
    if (isset($_POST['joketext'])) {
        $joketext = $_POST['joketext'];
        $sql = "INSERT INTO Jokes SET JokeText='" . mysql_real_escape_string($joketext) . "', JokeDate=CURDATE()";

        if (@mysql_query($sql)) {
            echo '<p>Ihr Witz wurde hinzugefügt.</p>';
        } else {
            echo '<p>Fehler beim Hinzufügen des Witzes: ' . mysql_error() . '</p>';
        }
    }
?>
<p>Dies sind derzeit alle Witze aus unserer Datenbank:</p>
<blockquote>
<?php

    // ID und text aller Witze auslesen
    $result = @mysql_query('SELECT ID, JokeText FROM Jokes');
    if (!$result) {
    exit('<p>Fehler bei der Ausführung der Abfrage: ' .
        mysql_error() . '</p>');
    }

    // Text jedes Witzes in einem Absatz anzeigen,
    // mit einem "Diesen Witz löschen"-Link daneben.
    while ($row = mysql_fetch_array($result)) {
        $jokeid = intval($row['ID']);
        $joketext = htmlspecialchars($row['JokeText']);
        echo '<p>' . $joketext . ' <a href="' . $_SERVER['PHP_SELF'] . '?askdeletejoke=' . $jokeid . '"><br />Diesen Witz löschen</a></p>';
    }
 
    //Link zum Hinzufügen eines Witzes
    echo '<p><a href="' . $_SERVER['PHP_SELF'] . '?addjoke=1">Einen Witz hinzufügen!</a></p>';

endif;

?>
</blockquote>
</body>
</html>
User avatar
Xardas der Dunkle
 
Posts: 482
Joined: 09. March 2008 19:40
Location: /var/www

Postby I-c-H » 22. July 2008 21:08

Xardas der Dunkle wrote:Der Doppelpunkt muss bei der alternativen Schreibweise für Strukturen wie sie hier verwendet wird notiert werden.

Das Problem bei dem Script ist, das das 2te endif fehlt.
Ich habe mal versucht den Code etwas aufzuräumen ..., ob es so passt kA, zumal mein Editor den : hinter dem else bemängelt :shock:.

Code: Select all
<html>
<head>
<title>Witze</title>
</head>
<body>

<P>Herzlich willkommen!</P>
<?php
if (isset($_GET['addjoke'])):
?>

    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <label>Bitte geben Sie hier Ihren Witz ein:<br />
    <textarea name="joketext" rows="10" cols="40">
    </textarea></label><br />
    <input type="submit" value="Speichern" />
    </form>

<?php
endif;

if (isset($_GET['askdeletejoke'])):

    //Fragen,  ob der Witz wirklich gelöscht werden soll
    if (isset($_GET['askdeletejoke'])) {
        $jokeid = $_GET['askdeletejoke'];
        echo '<p>Soll nachfolgender Witz wirklich aus der Witzeliste entfernt werden?</p>';
        echo '<p>'
           . '<a href="'.$_SERVER['PHP_SELF'].'?deletejoke=' . intval($jokeid) . '">Ja</a> '
           . '<a href="'.$_SERVER['PHP_SELF'].'">Nein</a>'
           . '</p>';
    }

    // Falls ein Witz gelöscht werden soll,
    // aus der Datenbank löschen.
    if (isset($_GET['deletejoke'])) {
        $jokeid = $_GET['deletejoke'];
        $sql = "DELETE FROM Jokes WHERE ID = " . intval($jokeid);

        if (@mysql_query($sql)) {
            echo ('<p>Der Witz wurde gelöscht.</p>');
        } else {
            echo '<p>Fehler beim Löschen des Witzes: ' . mysql_error() . '</p>';
        }
    }

else:

    //Verbindung zur Datenbank herstellen
    $dbcnx = @mysql_connect('localhost', 'root', 'GEHEIM');
    if(!dbcnx) {
       exit '<p>Eine Verbindung zur Witze-Datenbank konnte leider nicht hergestellt werden!<br />Begründung:' . mysql_error() . '</p>' ;
    }

    //Datenkbank auswählen
    mysql_select_db('jokes');
    if(!@mysql_select_db('jokes')) {
        exit('Die Witzedatenbank ist zur Zeit nicht abrufbar. Bitte versuche es später noch einmal!');
    }

    //Falls ein Witz hinzugefügt wurde:
    [b]if (isset($_POST['joketext'])) {[/b]
        $joketext = $_POST['joketext'];
        $sql = "INSERT INTO Jokes SET JokeText='" . mysql_real_escape_string($joketext) . "', JokeDate=CURDATE()";

        if (@mysql_query($sql)) {
            echo '<p>Ihr Witz wurde hinzugefügt.</p>';
        } else {
            echo '<p>Fehler beim Hinzufügen des Witzes: ' . mysql_error() . '</p>';
        }
    }
?>
<p>Dies sind derzeit alle Witze aus unserer Datenbank:</p>
<blockquote>
<?php

    // ID und text aller Witze auslesen
    $result = @mysql_query('SELECT ID, JokeText FROM Jokes');
    if (!$result) {
    exit('<p>Fehler bei der Ausführung der Abfrage: ' .
        mysql_error() . '</p>');
    }

    // Text jedes Witzes in einem Absatz anzeigen,
    // mit einem "Diesen Witz löschen"-Link daneben.
    while ($row = mysql_fetch_array($result)) {
        $jokeid = intval($row['ID']);
        $joketext = htmlspecialchars($row['JokeText']);
        echo '<p>' . $joketext . ' <a href="' . $_SERVER['PHP_SELF'] . '?askdeletejoke=' . $jokeid . '"><br />Diesen Witz löschen</a></p>';
    }
 
    //Link zum Hinzufügen eines Witzes
    echo '<p><a href="' . $_SERVER['PHP_SELF'] . '?addjoke=1">Einen Witz hinzufügen!</a></p>';

[b]endif;[/b]

?>
</blockquote>
</body>
</html>

Die von mir fett markierten Zeilen hängen also miteinander zusammen? Ein "if isset" muss also immer mit einem "endif;" geschlossen werden?


EDIT:
Das "else" und das "endif" müssen gelöscht werden, jeweils in dem Teil, wo ich fett markiert habe.

Nächste Frage(n): :)

Ich bekomme jetzt über meine Funktion nur die ID ausgegeben, mir ist auch klar, warum: Ich habe unten beim Löschlink nur die ID hintergesetzt - wie schaffe ich es, dass er den joketext auch übernimmt? Via GET möchte ich es nicht machen, da meine Browserzeile dann x-stellig wird. Gibts noch eine Möglichkeit?
(Mir ist natürlich klar, dass ich mit Hilfe der ID nun den joketext auch aus der Datenbank abrufen kann - aber mir geht es hier speziell um SOLCHE Problematiken mit einem Link)


Wie kann ich einen Tabstopp via HTML setzen? Meine Google-Suchergebnisse geben dort nichts aus.


EDIT²:
DANKE für deine Mühe!
I-c-H
 
Posts: 24
Joined: 20. July 2008 16:20

Postby Xardas der Dunkle » 22. July 2008 21:49

Nein die Zeilen gehören nicht zusammen ... :P

Sondern die:
Code: Select all
<html>
<head>
<title>Witze</title>
</head>
<body>

<P>Herzlich willkommen!</P>
<?php
if (isset($_GET['addjoke'])):
?>

    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <label>Bitte geben Sie hier Ihren Witz ein:<br />
    <textarea name="joketext" rows="10" cols="40">
    </textarea></label><br />
    <input type="submit" value="Speichern" />
    </form>

<?php
endif;

[b]if (isset($_GET['askdeletejoke'])):[/b]

    //Fragen,  ob der Witz wirklich gelöscht werden soll
    if (isset($_GET['askdeletejoke'])) {
        $jokeid = $_GET['askdeletejoke'];
        echo '<p>Soll nachfolgender Witz wirklich aus der Witzeliste entfernt werden?</p>';
        echo '<p>'
           . '<a href="'.$_SERVER['PHP_SELF'].'?deletejoke=' . intval($jokeid) . '">Ja</a> '
           . '<a href="'.$_SERVER['PHP_SELF'].'">Nein</a>'
           . '</p>';
    }

    // Falls ein Witz gelöscht werden soll,
    // aus der Datenbank löschen.
    if (isset($_GET['deletejoke'])) {
        $jokeid = $_GET['deletejoke'];
        $sql = "DELETE FROM Jokes WHERE ID = " . intval($jokeid);

        if (@mysql_query($sql)) {
            echo ('<p>Der Witz wurde gelöscht.</p>');
        } else {
            echo '<p>Fehler beim Löschen des Witzes: ' . mysql_error() . '</p>';
        }
    }

[b]else:[/b]

    //Verbindung zur Datenbank herstellen
    $dbcnx = @mysql_connect('localhost', 'root', 'GEHEIM');
    if(!dbcnx) {
       exit '<p>Eine Verbindung zur Witze-Datenbank konnte leider nicht hergestellt werden!<br />Begründung:' . mysql_error() . '</p>' ;
    }

    //Datenkbank auswählen
    mysql_select_db('jokes');
    if(!@mysql_select_db('jokes')) {
        exit('Die Witzedatenbank ist zur Zeit nicht abrufbar. Bitte versuche es später noch einmal!');
    }

    //Falls ein Witz hinzugefügt wurde:
    if (isset($_POST['joketext'])) {
        $joketext = $_POST['joketext'];
        $sql = "INSERT INTO Jokes SET JokeText='" . mysql_real_escape_string($joketext) . "', JokeDate=CURDATE()";

        if (@mysql_query($sql)) {
            echo '<p>Ihr Witz wurde hinzugefügt.</p>';
        } else {
            echo '<p>Fehler beim Hinzufügen des Witzes: ' . mysql_error() . '</p>';
        }
    }
?>
<p>Dies sind derzeit alle Witze aus unserer Datenbank:</p>
<blockquote>
<?php

    // ID und text aller Witze auslesen
    $result = @mysql_query('SELECT ID, JokeText FROM Jokes');
    if (!$result) {
    exit('<p>Fehler bei der Ausführung der Abfrage: ' .
        mysql_error() . '</p>');
    }

    // Text jedes Witzes in einem Absatz anzeigen,
    // mit einem "Diesen Witz löschen"-Link daneben.
    while ($row = mysql_fetch_array($result)) {
        $jokeid = intval($row['ID']);
        $joketext = htmlspecialchars($row['JokeText']);
        echo '<p>' . $joketext . ' <a href="' . $_SERVER['PHP_SELF'] . '?askdeletejoke=' . $jokeid . '"><br />Diesen Witz löschen</a></p>';
    }
 
    //Link zum Hinzufügen eines Witzes
    echo '<p><a href="' . $_SERVER['PHP_SELF'] . '?addjoke=1">Einen Witz hinzufügen!</a></p>';

[b]endif;[/b]

?>
</blockquote>
</body>
</html>


/EDIT:
Und man sollte es nicht nur wegen der länge nicht in der URL übergeben ... vllt ist dir ja aufgefallen ich habe in dem Code oben an einigen stellen die id in ein intval gepackt.
Ein paar Foren weiter oben hatte gerade erst wer das Problem das seine Seite über SQL Injections gehackt wurde.
User avatar
Xardas der Dunkle
 
Posts: 482
Joined: 09. March 2008 19:40
Location: /var/www

Postby I-c-H » 22. July 2008 21:55

Alles klar, ich glaube aber, ich habs verstanden :).

Hm, auf die anderen Fragen hast du keine Antworten, oder?

Wegen dem Intervall: Nein, wo denn? Ich finde da nichts.
EDIT: Solltest du die specialchars meinen, doch die habe ich entdeckt.

Aber wie die mich weiterbringen soll, ist mir unklar, da mir die auch noch unbekannt ist.
I-c-H
 
Posts: 24
Joined: 20. July 2008 16:20

Postby Nobbie » 22. July 2008 22:35

>Wie kann ich einen Tabstopp via HTML setzen?

Gar nicht.
Nobbie
 
Posts: 13170
Joined: 09. March 2008 13:04

Postby I-c-H » 22. July 2008 23:01

Also muss ich meine JA/NEIN - Abfrage quasi via Tabelle oder über CSS realisieren? Schade.

Dann bliebe eigentlich nur noch die Frage über:
Wie kann ich den zu löschenden JokeText anzeigen?
Relevante Scriptfragmente sind folgende...:

Dies ist der Link, auf welchen ich klicken muss
// Text jedes Witzes in einem Absatz anzeigen,
// mit einem "Diesen Witz löschen"-Link daneben.
while ($row = mysql_fetch_array($result)) {
$jokeid = $row['ID'];
$joketext = $row['JokeText'];
echo '<p>' . $joketext .
' <a href="' . $_SERVER['PHP_SELF'] .
'?askdeletejoke=' . $jokeid . '">' .
'<br>Diesen Witz löschen</a></p>';
}


...und dies ist die Frage, ob ich den Witz WIRKLICH löschen will - die ID erhalte ich über $_GET, doch der JokeText will nicht mit - verständlicherweise.

if (isset($_GET['askdeletejoke'])) {
//Fragen, ob der Witz wirklich gelöscht werden soll

$jokeid = $_GET['askdeletejoke'];
$joketext = $_POST['askdeletejoke'];
echo ('<p>Soll nachfolgender Witz wirklich aus der Witzeliste entfernt werden?</p>');
echo '<p>' .$joketext
.'<blockquote><table border="0">
<colgroup>
<col width="80">
<col width="80">
<col width="80">
</colgroup>
<tr>
<td><a href="'.$_SERVER['PHP_SELF'].'?deletejoke='.$jokeid.'">'
.'Ja</a></td><td>oder</td>'
.'<td><a href="'.$_SERVER['PHP_SELF'].'">Nein</a></td></tr></table></blockquote><br>'
.'</p>';

}

Ich möchte möglichst eine MySQL Abfrage umgehen, da ich glaube, dass das eine unnötige Belastung für den Server ist - sollte ich falsch liegen, belehrt mich ruhig! :)

Das ich Design- und Scriptelemente voneinander trennen sollte, um einen guten Stil zu erhalten, ist mir bewusst - doch soweit bin ich noch nicht :).

Gute Nacht,
und noch mals Danke!
I-c-H
 
Posts: 24
Joined: 20. July 2008 16:20

Postby Xardas der Dunkle » 23. July 2008 00:47

Nich Intervall, intval: http://de3.php.net/manual/de/function.intval.php und http://de3.php.net/manual/de/function.h ... lchars.php

Siehe dazu: http://de3.php.net/manual/de/security.d ... ection.php

Ich möchte möglichst eine MySQL Abfrage umgehen, da ich glaube, dass das eine unnötige Belastung für den Server ist - sollte ich falsch liegen, belehrt mich ruhig! Smile

*Belehr* Diese kleine SQL Abfrage stört den Server ganz und gar nicht, das ist ein klacks für ihn. Belasten sind nur riesige Querys die er nicht innerhalb von ein paar Millisekunden abarbeiten kann.
User avatar
Xardas der Dunkle
 
Posts: 482
Joined: 09. March 2008 19:40
Location: /var/www

Postby I-c-H » 23. July 2008 10:14

Diese SQL-Abfrage würde auch nicht störend ausfallen, wenn meinetwegen utopische 1.000.000 User auf meiner Seite sitzen und verschiedene SQL-Abfragen tätigen würden?

NOCH verstehe ich vieles aus dem SQL-Link den du mir da geschickt hast nicht.

Sollte mein Lehrbuch in späteren Kapiteln nicht auf solche Sicherheitsrisiken hinweisen, werde ich mich aber noch mal ans Forum wenden - sofern mir dann noch Fragen kommen.

Vielen Dank aber für deine Mühe!:)
I-c-H
 
Posts: 24
Joined: 20. July 2008 16:20

Postby I-c-H » 02. August 2008 19:35

Code: Select all
$jokelist = @mysql_query("SELECT JokeText, Name
FROM Jokes, Autoren WHERE AID=Autoren.ID");
...


Mal wieder ich :).

Ich bin auf eine Zeile in meinem Buch gestoßen, die ich mir nicht ganz erklären kann:

Was genau heißt es, wenn ich als Bedingung festlege, dass die AID (Autoren-ID) = Autoren.ID sein soll?

In meiner Datenbank habe ich eine Tabelle namens "Autoren" und eine namens "Jokes".
In Autoren existiert die Spalte "ID", wie auch in der Tabelle Jokes - allerdings habe ich in der Jokestabelle eine weitere Spalte mit AID.

Als Bedingung wird nun verlangt, dass die Spalte ID mit der AID gleich sein soll.
Gebe ich durch den Punkt bei "WHERE AID=Autoren.ID" an, dass man mit der ID aus der Tabelle Autoren vergleichen soll (gebe ich also eine Art Pfad an?)?

Nächste Frage:
In der Tabelle Autoren habe ich eine Spalte die ich mit "Namen" bezeichnet habe. Mal angenommen, ich hätte nun in der Tabelle Jokes ebenfalls eine Spalte, welche ich mit "Namen" bezeichne (könnte ja sein, dass ich meinem Witz einen Namen geben will - oder einen Titel).
Woher weiß dann die Abfrage, welchen "Namen" sie nun ausgeben soll? Oder ganz allgemein gefasst: Wenn ich zwei Spalten aus zwei verschiedenen Tabellen habe, die beide die gleiche Bezeichnung tragen, wie unterscheide ich dann in so einer Abfrage, welche Spalte gemeint ist?

DANKESCHÖN!
I-c-H
 
Posts: 24
Joined: 20. July 2008 16:20

Postby Xardas der Dunkle » 02. August 2008 20:37

Gebe ich durch den Punkt bei "WHERE AID=Autoren.ID" an, dass man mit der ID aus der Tabelle Autoren vergleichen soll (gebe ich also eine Art Pfad an?)?

Ja.

Nächste Frage:
In der Tabelle Autoren habe ich eine Spalte die ich mit "Namen" bezeichnet habe. Mal angenommen, ich hätte nun in der Tabelle Jokes ebenfalls eine Spalte, welche ich mit "Namen" bezeichne (könnte ja sein, dass ich meinem Witz einen Namen geben will - oder einen Titel).
Woher weiß dann die Abfrage, welchen "Namen" sie nun ausgeben soll? Oder ganz allgemein gefasst: Wenn ich zwei Spalten aus zwei verschiedenen Tabellen habe, die beide die gleiche Bezeichnung tragen, wie unterscheide ich dann in so einer Abfrage, welche Spalte gemeint ist?


Entweder genauso:
Code: Select all
SELECT Jokes.Name AS `Title`, Autoren.Name ...

oder da das aber ganz schön lang werden kann kann man den Tabellen beim auslesen ein Alias verpassen:
Code: Select all
SELECT j.Name AS `Title`, a.Name ... FROM `Jokes` j, `Autoren` a


Und noch was, das was du da oben machst, nennt sich Crossjoin, dabei passiert folgendes, es werden erst ALLE Datensätze aus der Datenbank ausgelesen und dann über das WHERE gefiltert, das kann bei großen Datenbanken ganz schon lange dauern.
Daher gibt es neben dem Crossjoin noch den INNER JOIN, den LEFT JOIN und den RIGHT JOIN (letzteres brauch man eig. nie da es eig. nur ein umgedrehter LEFT JOIN ist).

Beim INNER JOIN stehen beide Tabellen direkt in Beziehung d.h. es wird nur was gefunden wenn die Verknüpfung erfolgreich ist.
Also z.B. das der Autor für den Joke in der Autorentabelle auch wirklich existieren muss:

Code: Select all
SELECT j.`JokeText`, j.`Name` AS `JokeTitel`, a.* FROM `Jokes` j INNER JOIN `Autoren` a ON(a.`ID` = `AID`)


Beim LEFT/RIGHT JOIN ist das nicht so, wenn die Beziehung nicht stattfindet werden die Felder der 2. Tabelle mit dem Wert NULL aufgefüllt:

Code: Select all
SELECT j.`JokeText`, j.`Name` AS `JokeTitel`, a.* FROM `Jokes` j LEFT JOIN `Autoren` a ON(a.`ID` = `AID`)


(RIGHT JOIN Sehe wie gesagt genauso aus, nur würden dort die Jokes den Autoren zugeordnet werden.)

mfG

/edit: Noch was vergessen! Beim Join werden die Beziehungen über ON oder USING hergestellt.
Wie ON aufgebaut ist siehst du oben. (Achtung ON ist nur dafür da die Beziehung aufzubauen, Filtern tust du weiterhin mit WHERE).
Falls das Feld was in Beziehung gesetzt werden soll bei beiden Tabellen gleich heißt, kann man anstatt ON auch USING verwenden:
Code: Select all
USING(`ID`)
User avatar
Xardas der Dunkle
 
Posts: 482
Joined: 09. March 2008 19:40
Location: /var/www

Postby I-c-H » 02. August 2008 23:57

Vielen Dank für die schnelle Reaktion!

Was mir unklar an deinen Ausführungen ist, ist was "j.", "a." und AS für besondere Bedeutungen haben.

AS benötige ich bei meinem normalen Join ja auch nicht, sobald ich aber zwei Pfade angebe, scheine ich ein "AS" und ein "a." zu benötigen - warum? Welche Wirkung haben sie?
Kann ich die auch noch woanders verwenden?

Hat ein right Join gegenüber einem Left Join überhaupt keinen Unterschied? Du sagst das es relativ egal ist - gibt es Ausnahmen?

Der INNER Join würde sich dann beim von mir aufgegriffenem Beispiel am besten machen, oder?

Haben ON und USING einen Wirkungsunterschied?

SELECT j.`JokeText`, j.`Name` AS `JokeTitel`, a.* FROM `Jokes` j INNER JOIN `Autoren` a ON(a.`ID` = `AID`)
Welche Wirkung hat der Stern?

Soll ich Crossjoins denn generell vermeiden, oder ausschließlich bei kleineren Tabellen anwenden? Haben die anderen Joins denn einen höheren Rechenaufwand bzw. wird der Crossjoin beim professionellen Programmieren überhaupt noch angewandt?

DANKE für die Mühe und das Erklären!
I-c-H
 
Posts: 24
Joined: 20. July 2008 16:20

Postby Xardas der Dunkle » 03. August 2008 00:31

Was mir unklar an deinen Ausführungen ist, ist was "j.", "a." und AS für besondere Bedeutungen haben.

AS brauch man wenn man ein Feld in der Ausgabe umbenennen möchte bzw. einem Funktionsaufruf einen Namen geben will.
In deinem Fall hast du zwei Felder mit dem Namen: "Name", d.h. du musst mind. einen davon umbenennen: j.`Name` AS `Title`.

j. und a. dienen hier als Alias für die langen Tabellennamen (j ist schließlich schöner als immer Jokes schreiben zu müssen), diese Aliase habe ich wie folgt definiert:
Code: Select all
FROM `Jokes` j INNER JOIN `Autoren` a

Wie du siehst steht hinter dem Namen jeweils der Alias.
Dieser kann auch abc oder gurke sein, aber bei so langen Namen kann man auch gleich den echten Tabellennamen nehmen ;).

Hat ein right Join gegenüber einem Left Join überhaupt keinen Unterschied? Du sagst das es relativ egal ist - gibt es Ausnahmen?

Nur das eben die Wirkungsweise komplett umgedreht wird. Beim RIGHT JOIN hat eben die Rechts stehende Tabelle Vorrang vor der links stehenden.
Und beim Left Join ist es genau umgedreht.

Der INNER Join würde sich dann beim von mir aufgegriffenem Beispiel am besten machen, oder?

Nicht unbedingt, ich würde einen LEFT JOIN bevorzugen.
So würden auch Witze ohne Autoren gefunden werden.


Haben ON und USING einen Wirkungsunterschied?

Nein, du kannst USING auch ganz vergessen und stattdessen immer ON verwenden:
Code: Select all
ON(t1.`ID` = t2.`ID`)


Welche Wirkung hat der Stern?

Alle Felder einer Tabelle auslesen, spart einem viel Schreibarbeit, wenn man eh alle Felder benötigt.

Soll ich Crossjoins denn generell vermeiden,

Ja solltest du, es gibt nur wenige Ausnahmen, wo man den Crossjoin wirklich brauch.

Haben die anderen Joins denn einen höheren Rechenaufwand bzw.

Das vllt. schon, aber sie sind trotzdem messbar schneller (auch wenn es im Milli- oder Nanosekunden Bereich liegt) als ein Crossjoin.

wird der Crossjoin beim professionellen Programmieren überhaupt noch angewandt?

Er wird verwendet, sonst gäbe es ihn ja net ;).
Z.b. wird in der Nachfolger Version dieses Forums einer verwendet, aber das jetzt zu erklären ist etwas zu hoch.

mfG
User avatar
Xardas der Dunkle
 
Posts: 482
Joined: 09. March 2008 19:40
Location: /var/www

Next

Return to PHP

Who is online

Users browsing this forum: No registered users and 12 guests