Hallo pl,
oh. Danke für den Hinweis.
Joseba, ich habe mal wieder eine lange Geschichte für Dich.
- die Funktion sql() wird nicht aufgerufen
- die Methode PostOkT sollte eigentlich benutzt werden, um einen POST zu verarbeiten. Aber:
- Der Konstruktor von ClassProveContakt3 liest die $_POST Variablen aus und speichert sie in Eigenschaften des Objekts ($this->Name, $this->Email, $this->Message.
- Der Konstruktor setzt PostOK auf FALSE wenn ein Wert fehlt
- In PostOkT() wird abgefragt, ob PostOK TRUE ist, und wenn ja, wird die Methode verlassen. D.h. PostOkT läuft nur durch, wenn Eingabewerte fehlen. Das sieht falsch aus.
- In PostOkT wird als nächstes abgefragt ob Eingabefelder leer sind und eine Fehlermeldung ausgegeben. Die Information "es gibt leere Eingabefelder" wird aber schon daran erkannt, dass $this->PostOK den Wert FALSE hat.
- Dein Objekt hat bereits eine $DateTime Eigenschaft, die sollte man im Konstruktor setzen und dann nur noch verwenden.
Das heißt:
Vor dem Konstruktor fügst Du hinzu:
private $ips;
Denn du speicherst $_SERVER['REMOTE_ADDR'] in dieser Eigenschaft. Dann sollte man die Eigenschaft auch deklarieren. Beachte die Regeln zum Datenschutz: Wenn Du eine IP in der Datenbank speicherst, musst Du das in deiner Datenschutzerklärung aufschreiben. Und du musst einen Grund haben, warum Du die IP speicherst.
Im Konstruktor fügst Du hinzu:
$this->DateTime = date('m/d/Y h:i:s a', time());
ABER: das ist USA-Datumsformat. Für welches Land willst Du deine Seite machen?
Deine Funktion PostOkT könnte so aussehen:
function PostOkT()
{
if (! $this -> PostOK)
{
echo "<br><b><h3>*** Please enter all required fields ***</h3></b>";
}
else
{
echo "<br>"
. "<b>From: </b>" . htmlspecialchars( $this->Name )
. "<b> at: </b>" . htmlspecialchars( $this>DateTime )
. "<br><br>" . htmlspecialchars( $this->Message )
. "<br><hr>";
$this->writeCommentToDatabase()
}
}
Die sql()-Funktion habe ich umbenannt in writeCommentToDatabase. Gute Namen für Methoden sind wichtig. Deine sql-Funktion macht vieles, was bereits in PostItT gelaufen ist. Das kann man einfacher haben. Ich zeige auch mal wie deine mysqli-Aufrufe aussehen sollten.
function writeCommentToDatabase()
{
$connection = mysqli_connect("localhost", "root", "pass", "meine");
if (mysqli_connect_error())
{
echo "<br>Cannot connect to database: " . mysqli_connect_error();
return false;
}
$sqlDate = date("Y-m-d H:i:s");
$sName = mysqli_real_escape_string($connection, $this->Name);
$sEmail= mysqli_real_escape_string($connection, $this->Name);
$sMessage = mysqli_real_escape_string($connection, $this->Name);
$success = mysqli_query("INSERT INTO mela(name, email, message, datetime, ips) VALUES ('$sName', '$sEmail', '$sMessage', '$sqlDate', '$this->ips')");
if ($success)
echo "<br/><br/><span>Data Inserted successfully...!!</span>";
}
else{
echo "<p>Insertion Failed <br/>" . mysqli_error($connection);
}
}
mysqli_close($connection);
return $success;
}
Beachte das Error-Handling bei Connect: Da kann man mysqli_error noch nicht verwenden, weil mysqli_error eine gültige Connection braucht.
Wie Du das Datum in der Datenbank speicherst, darüber müssen wir reden. Dein $this->DateTime ist ein String, und ist für Menschen gemacht. Welchen Typ hat die Spalte datetime in deiner Datenbank? Ist es ein String? Ist es ein DateTime? Wenn es ein String ist, kannst Du das Datum speichern wie Du willst. Aber ein DateTime speichert man besser in einer DateTime-Column. In der mysqli-Schnittstelle gibt es aber eigentlich nur Strings. Um dein Datum für eie DateTime-Column zu übertragen, musst Du es als yyyy-mm-dd hh:mm:ss senden. Darum habe ich die Variable $sqlDate erzeugt. Ob das für Dich funktioniert, musst Du nun prüfen.
MYSQLi gibt es auch in der objektorientierten Version. Damit sähe deine Funktion so aus:
function writeCommentToDatabase()
{
$mysqli = new mysqli("localhost", "root", "pass", "meine");
if ($mysqli->connect_error)
{
echo "<br>Cannot connect to database: " . $mysqli->connect_error;
return false;
}
$sqlDate = date("Y-m-d H:i:s");
$sName = $mysqli->escape_string($this->Name);
$sEmail= $mysqli->escape_string($this->Email);
$sMessage = $mysqli->escape_string($this->Message);
$success = $mysqli->query("INSERT INTO mela(name, email, message, datetime, ips) VALUES ('$sName', '$sEmail', '$sMessage', '$sqlDate', '$this->ips')");
if ($success)
echo "<br/><br/><span>Data Inserted successfully...!!</span>";
}
else{
echo "<p>Insertion Failed <br/>" . $mysqli->error;
}
}
$mysqli->close();
return $success;
}
Ja, und Dedlfix schrieb, dass man besser PDO verwenden sollte. PDO ist eine Datenbankschnittstelle, die für alle Datenbanken gleich funktioniert. Es ist objektorientiert, und dass man mit MySQL arbeitet, legt man nur einmal beim Erzeugen des pdo-Objekts fest. Mit PDO sieht es etwas komplizierter aus (mehr Funktionsaufrufe, mehr Fehlerprüfung):
function writeCommentToDatabase()
{
try
{
$db = new PDO("mysql:dbname=meine;host=localhost", "root", "pass");
}
catch (PDOException $pe)
{
echo "<br>Cannot connect to database: " . $pe->getMessage();
return false;
}
$statement = $db->prepare("INSERT INTO mela(name, email, message, datetime, ips) VALUES (:name, :email, :message, :date, :ips)");
if (!$statement)
{
echo "<br><br>prepare failed: SQLSTATE=" . $db->errorCode() . ", Error Info=" . print_r($dbh->errorInfo(), true) . "</p>";
$ok = FALSE;
}
else
{
$ok = $statement->bindValue(':name', $this->Name, PDO::PARAM_STR);
&& $statement->bindValue(':email', $this->Email, PDO::PARAM_STR);
&& $statement->bindValue(':message', $this->Message, PDO::PARAM_STR);
&& $statement->bindValue(':date', date("Y-m-d H:i:s"), PDO::PARAM_STR);
&& $statement->bindValue(':ips', $this->ips, PDO::PARAM_STR);
if (!$ok)
{
echo "<br><br>bindValue failed: SQLSTATE=" . $db->errorCode() . ", Error Info=" . print_r($dbh->errorInfo(), true) . "</p>";
}
}
if ($ok)
{
$ok = $statement->execute();
if (!$ok)
{
echo "<br><br>execute failed: SQLSTATE=" . $db->errorCode() . ", Error Info=" . print_r($dbh->errorInfo(), true) . "</p>";
}
}
echo "<br/><br/><span>Data Inserted successfully...!!</span>";
}
$db->close();
return $ok;
}
Eine solche Funktion sollte man in Teilfunktionen aufteilen, und das Öffnen der Datenbankverbindung macht man besser einmal zu Beginn des Scripts und stellt das Datenbank-Objekt dann global zur Verfügung (oder als Property deiner ClassProveContakt3 Klasse).
Ja, es wird immer komplizierter. Aber dein Script hat auch schon eine Menge Aufgaben zu lösen.
Rolf
--
sumpsi - posui - clusi