Seite 1 von 1

Datenbank speichert keine Umlaute

Verfasst: 28.07.2014 19:23
von mps
Hallo zusammen,

ich habe ein Admin-Tool entwickelt, dass Dinge in die Tabelle "phpbb_config" speichert bzw. die vorhandenen Dinge ersetzt. Immer wenn ich etwas mit ß, ä, Ä, ö, Ö, ü, Ü speichern will, werden diese Zeichen mit "??" ersetzt. Was kann ich dagegen tun?

Datenbank ist leider nicht so meine Stärke...

Vielen Dank!

Gruß,
mps

Re: Datenbank speichert keine Umlaute

Verfasst: 28.07.2014 19:52
von Elsensee
Ich wette, der Fehler liegt bereits bei der Abfrage der Werte - die sendest du ja sicher als POST mit (oder auch als GET.. völlig egal)
Hier musst du darauf achten, dass du den multibyte-Parameter der Funktion request_var auf true setzt, etwa:

Code: Alles auswählen

$falsch = request_var('falsch', ''); // = K??se
$richtig = request_var('true', '', true); // = Käse

Re: Datenbank speichert keine Umlaute

Verfasst: 28.07.2014 20:30
von Helmut
Hallo mps,

wie schaut denn dein Code aus mit dem du die Tabelle phpbb_config füllst und wie du den Wert wieder abfrägst?

Das wäre eine typische Zeile wenn Text mit eingetragen ist: $name = utf8_normalize_nfc(request_var('name', '', true));

Hast du geschaut ob die Umlaute richtig in der DB stehen und nur falsch ausgegeben werden, oder steht es schon falsch in der DB?

Gruß Helmut

Re: Datenbank speichert keine Umlaute

Verfasst: 05.09.2014 22:37
von mps
Hallo,

sorry Leute - irgendwie habe ich das Thema vergessen (tut mir leid).

Also: In der Datenbank werden auch die Fragezeichen dargestellt.

Die Abfrage steht in der funtions.php:

Code: Alles auswählen

        //Beginn Quick-Links
        'LINK_TEXT_1'                    => $config['link_text_1'],
        'LINK_URL_1'                    => $config['link_url_1'],
        'LINK_TEXT_2'                    => $config['link_text_2'],
        'LINK_URL_2'                    => $config['link_url_2'],
        'LINK_TEXT_3'                    => $config['link_text_3'],
        'LINK_URL_3'                    => $config['link_url_3'],
        'LINK_TEXT_4'                    => $config['link_text_4'],
        'LINK_URL_4'                    => $config['link_url_4'],
        'LINK_TEXT_5'                    => $config['link_text_5'],
        'LINK_URL_5'                    => $config['link_url_5'],
        'LINK_TEXT_6'                    => $config['link_text_6'],
        'LINK_URL_6'                    => $config['link_url_6'],
        'LINK_TEXT_7'                    => $config['link_text_7'],
        'LINK_URL_7'                    => $config['link_url_7'],
        'LINK_TEXT_8'                    => $config['link_text_8'],
        'LINK_URL_8'                    => $config['link_url_8'],
        'LINK_TEXT_9'                    => $config['link_text_9'],
        'LINK_URL_9'                    => $config['link_url_9'],
        'LINK_TEXT_10'                    => $config['link_text_10'],
        'LINK_URL_10'                    => $config['link_url_10'],

        'ZUFALL_NUMMER_LINKS'            => mt_rand(1,10),

        //Ende Quick-Links 
Vielen Dank für eure bisherige Hilfe.

Gruß,
mps

Re: Datenbank speichert keine Umlaute

Verfasst: 16.10.2014 11:13
von mps
Hallo,

ich habe jetzt den Code verändert und speichere die Links nun in einer eigenen Tabelle (phpbb_links). Leider bekomme ich beim SQL-Update (via Formular) folgenden Hinweiß von PHPBB:
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 66: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 67: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 68: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 69: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 70: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 71: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 72: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 73: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 74: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/quicklinks_action.php on line 75: mysqli_query() expects parameter 1 to be mysqli, object given
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 4801: Cannot modify header information - headers already sent by (output started at [ROOT]/quicklinks_action.php:1)
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 4803: Cannot modify header information - headers already sent by (output started at [ROOT]/quicklinks_action.php:1)
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 4804: Cannot modify header information - headers already sent by (output started at [ROOT]/quicklinks_action.php:1)
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 4805: Cannot modify header information - headers already sent by (output started at [ROOT]/quicklinks_action.php:1)
Was genau bedeutet das? Die Datei (quicklinks_action.php) ist die Datei, die nach dem absenden des Formulars aufgerufen wird. Hier noch der entsprechende Auszug aus quicklinks_action.php

Code: Alles auswählen

/*
* Nun folgt erst Dein PHP Code für die neue Seite, also:
* Variablen setzen, Datenbankabfragen, Einfügen und Entfernen von Einträgen usw...
*
* Dies ist nun ein sehr primitives Beispiel.
* Es soll nur veranschaulichen wie es funktioniert.
*
*/
// SQL-Verbindung

include("config.php");

$datenbank = mysqli_connect("$dbhost", "$dbuser", "$dbpasswd", "$dbname");
if(!$datenbank)
{
  exit("Verbindungsfehler: ".mysqli_connect_error());
}

$link1 = $_POST["link_1"];
$link2 = $_POST["link_2"];
$link3 = $_POST["link_3"];
$link4 = $_POST["link_4"];
$link5 = $_POST["link_5"];
$link6 = $_POST["link_6"];
$link7 = $_POST["link_7"];
$link8 = $_POST["link_8"];
$link9 = $_POST["link_9"];
$link10 = $_POST["link_10"];
$text1 = $_POST["text_1"];
$text2 = $_POST["text_2"];
$text3 = $_POST["text_3"];
$text4 = $_POST["text_4"];
$text5 = $_POST["text_5"];
$text6 = $_POST["text_6"];
$text7 = $_POST["text_7"];
$text8 = $_POST["text_8"];
$text9 = $_POST["text_9"];
$text10 = $_POST["text_10"];

$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link1', text = '$text1' WHERE id = '1'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link2', text = '$text2' WHERE id = '2'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link3', text = '$text3' WHERE id = '3'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link4', text = '$text4' WHERE id = '4'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link5', text = '$text5' WHERE id = '5'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link6', text = '$text6' WHERE id = '6'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link7', text = '$text7' WHERE id = '7'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link8', text = '$text8' WHERE id = '8'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link9', text = '$text9' WHERE id = '9'");
$update = mysqli_query($db, "UPDATE phpbb_links Set link = '$link10', text = '$text10' WHERE id = '10'");
Es ist wahrscheinlich alles von vorne bis hinten falsch, was ich programmiert habe... :-?

Vielen Dank schon einmal

Gruß,
mps

Re: Datenbank speichert keine Umlaute

Verfasst: 16.10.2014 13:38
von Elsensee
Auf keinen Fall wirst du diese Datei so benutzen. Okay? Okay.

Ich nehme nun einfach mal an, dass das nur der Code unterhalb des ganzen phpBB-spezifischen Codes ist. Die Zeilennummern würden andernfalls ja auch korrekt sein.

Wie auch immer. Nein!
Aber der Reihe nach:

1. Du includierst die config.php, was aber unsinnig und gefährlich ist, weil
2. du zum zweiten Mal eine Datenbank-Verbindung aufbaust... Warum? Du hast doch den ganzen phpBB-Code eingebunden, da ist doch bereits eine Datenbank-Verbindung? Benutze die bitte.
3. Du benutzt direkt die vom User erhaltenen Daten und erhöhst so das Risiko - nein... du ermöglichst eine SQL-Injection.
4. Du benutzt nicht die phpBB-eigenen Funktionen für Datenbanken
5. Deine Datenbank-Verbindung war in $datenbank, nicht in $db... Das käme von phpBB...

Hier meine Lösungsvorschläge:
1. include('config.php'); rausnehmen
2. zweite Datenbank-Verbindung rausnehmen
3.1 $link1 = request_var('link_1', ''); (Bzw. wenn du Umlaute erlauben möchtest: request_var('link_1', '', true);
3.2 + 4 + 5: Beispiel für's erste:

Code: Alles auswählen

$db->sql_query("UPDATE phpbb_links SET link = '" . $db->sql_escape($link1) . "', text = '" . $db->sql_escape($text1) . "' WHERE id = 1;"); 
Das wäre eine Möglichkeit, dies richtig zu machen. Sieht auch schöner aus, finde ich, aber das ist ja immer subjektiv. :wink:

Ich hoffe, du hast auch die Berechtigungen geklärt. Also, wenn das nur Admins sehen sollen, dass es auch nur Admins sehen können.

Re: Datenbank speichert keine Umlaute

Verfasst: 16.10.2014 14:42
von mps
Hallo,

vielen Dank für deine Hilfe. Da hat sich meine Befürchtung scheinbar bestätigt. Nun komme ich jedoch bei der Abfrage nicht ganz weiter. Mein Teil in der index.php:

Code: Alles auswählen

// Quicklinks:

$links_safety = $_GET["safety"];

//Check: Rechte (Moderator = "m_"; Admin = "a_")
if ($auth->acl_getf_global('m_'))
{
$links_change = "1";
}
else
{
    $links_change = "0";
}

//Nummer setzen

if($links_safety != "")
{
  $links_number = "$links_safety";
}
else
{
$links_number = mt_rand(1,10);
}

//TEXT&ADRESSEN_ZUWEISEN:

$db->sql_query("SELECT * FROM phpbb_links WHERE id = $links_number;");

while($row = $db->sql_fetchrow($result))
{
  $ql_link = $row->link;
  $ql_text = $row->text;
};

//QL_ENDE 
Erläuterung: Zu erst wird die Variable $safety gefüllt, falls vorhanden. Danach werden die Mod-Rechte des Users kontrolliert und dementsprechend eine Variable bestimmt. Danach wird eine ID bestimmt, entweder wird die safetyübernommen oder eine Zufallszahl generiert. Zum Schluss kommt der Punkt, wo es nicht so will - die Abfrage von Link und Text.

Natürlich habe ich auch die Variablen im Template-Array an das Template weiter gegeben und auch im Template anzeigen lassen.

Code: Alles auswählen

//QL_START
    'LINKS_CHANGE'  => $links_change,
    'QL_NUMBER'     => $links_number,
    'QL_LINK'    => $ql_link,
    'QL_TEXT'    => $ql_text,
    //QL_ENDE 
Template, welches in die index_body.html eingebunden wurde:

Code: Alles auswählen

<div align="center">
<h3><a class="titles" href="{QL_LINK}" target="_blank">{QL_TEXT}</a></h3>
<!-- IF LINKS_CHANGE == "1" -->
<br />
<span>Link: {QL_NUMBER}</span>&nbsp;|&nbsp;<a href="./quicklinks.php" class="iframe" title="Quick-Links &auml;ndern">&Auml;ndern</a>&nbsp;|&nbsp;<span>Tipp: Gehe auf "www.ep-board.de/index.php?safety=XX" und setze bei XX zum Beispiel 3 oder 10 ein, um diese Links direkt anzeigen zu lassen.</span>
<!-- ENDIF -->
</div>
Auch das ist bestimmt wieder von oben bis unten verkehrt... :(

Re: Datenbank speichert keine Umlaute

Verfasst: 16.10.2014 15:37
von Elsensee
Hast du dir den Wikipedia-Artikel zur SQL Injection wenigstens mal angeguckt? :roll:

Kann es sein, dass $links_safety nur Zahlen erhalten soll? Denn dann heißt es:

Code: Alles auswählen

$links_safety = request_var('safety', 0);
Dies verhindert effektiv eine SQL-Injection, da hier geguckt wird, ob hier eine Zahl vorliegt. Wenn ja, dann wird auch eine Zahl zurückgegben. Wenn nicht oder einfach nichts übergeben wurde, wird 0 zurückgegeben. Also auch eine Zahl.
Einen KB-Artikel haben wir zu der Funktion offenbar nicht, aber im phpBB Development Wiki ist ein schöner Artikel: https://wiki.phpbb.com/Function.request_var (allerdings auf Englisch)

Du kannst, wenn du willst, dann auch bei den Zuweisungen zu $links_change die Anführungszeichen entfernen und nur die Zahlen dort stehen lassen.

Dann würde ich anstelle von if($links_safety != "") lieber if (!empty($links_safety)) nehmen und bei der Zuweisung in der If-Bedingung ebenfalls die Anführungszeichen entfernen. Dieses Mal aus rein optischen Gründen. :P

Den SQL-Query kannst du nun so lassen, da wir nun sichergestellt haben, dass nur Zahlen vorkommen. :wink: Allerdings muss davor noch ein $result =
Ja ich weiß, eben bei der SQL-Query war das nicht. Ganz einfach, weil bei UPDATE nichts zurückkommt. Bei SELECT sollte aber was zurückkommen, deswegen muss da das $result davor.

Doch die While-Schleife ist ebenfalls falsch. $row ist ein Array. Die beiden Zeilen müssen also lauten:

Code: Alles auswählen

$ql_link = $row['link'];
$ql_text = $row['text'];
Hast du das eigentlich mal laufen lassen, denn dann sollte die Fehlermeldung kommen, dass er das Semikolon nach der geschweiften Klammer nicht mag. Das kommt soweit ich weiß auch nie nach geschweiften Klammern. :)

Mal ne generelle Frage: Basierend auf den Kommentaren könnte vielleicht das hier das richtige sein? => KB:quicklinks
Da entfällt das Programmieren sogar ganz. ;)

Re: Datenbank speichert keine Umlaute

Verfasst: 16.10.2014 16:16
von mps
Elsensee hat geschrieben:Hast du dir den Wikipedia-Artikel zur SQL Injection wenigstens mal angeguckt?
Überflogen, bis ich vor lauter unbekannten Begriffen aufgegeben habe. Aber ich verstehe jetzt, was der Fehler war.
Elsensee hat geschrieben:Hast du das eigentlich mal laufen lassen, denn dann sollte die Fehlermeldung kommen, dass er das Semikolon nach der geschweiften Klammer nicht mag. Das kommt soweit ich weiß auch nie nach geschweiften Klammern.
Weiß ich ebenfalls, nur leider Tippe ich dann trotzdem, warum auch immer, noch eines zu viel ein. Fehlermeldung kam aber nicht. Habe ich natürlich nun geändert.
Elsensee hat geschrieben:Mal ne generelle Frage: Basierend auf den Kommentaren könnte vielleicht das hier das richtige sein? => Quicklinks
Da entfällt das Programmieren sogar ganz.
Vom Name her das Gleiche - die Aufgabe aber völlig falsch. Es sollen auf der Startseite wechselnde Links angezeigt werden. Genau so wie hier: http://www.ep-board.de/

Nun möchte ich die Sache etwas erweitern, in dem man die Links nun direkt von der Startseite aus ändern kann (anstatt vorher nur übers ACP). Unter jedem Link ist jetzt (nur für Mods) ein Link, der eine Lightbox öffnet. Dort hat man dann eine Übersicht über alle Links und kann diese auch verändern. Ein kleines Problem habe ich jetzt aber doch noch. Wenn man die Lightbox nun öffnet, dann kommt folgender Hinweiß:
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 4801: Cannot modify header information - headers already sent by (output started at [ROOT]/quicklinks.php:1)
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 4803: Cannot modify header information - headers already sent by (output started at [ROOT]/quicklinks.php:1)
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 4804: Cannot modify header information - headers already sent by (output started at [ROOT]/quicklinks.php:1)
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 4805: Cannot modify header information - headers already sent by (output started at [ROOT]/quicklinks.php:1)
Wie kriege ich das jetzt noch weg?

EDIT: Fehler behoben. Ein Leerzeichen vor <?php hat diesen ausgelöst.

Re: Datenbank speichert keine Umlaute

Verfasst: 16.10.2014 16:27
von tas2580
Ich hätte als Ergänzung zu dem was Elsensee schon zu SQL-Injection geschrieben hat noch einen Tipp.

Erzwinge in deinen Queris immer Integer indem du vor der Variable ein (int) schreibst:

Code: Alles auswählen

$sql = 'SELECT foo FROM bar WHERE id = ' . (int) $id;
Das hat den Vorteil das du auch sicher bist wenn sich die Variable im laufe des Scripts noch ändert. mit request_var('id', 0) erzwingst du zwar das was übergeben wird ein Integer ist, aber bei komplexeren Scripten kann sich die Variable ja nochmal ändern.
Ein weiterer Vorteil ist das du sofort siehst wenn du escapen musst, sobald in einem Query kein (int) vor einer Variable steht muss escaped werden. Es sollte also niemals eine Variable direkt in einem SQL Query vorkommen. Entweder es heißt (int) $variable oder $db->sql_escape($variable), nur $variable wäre also immer falsch.
Wenn du mal Scripte für nicht phpBB schreibst hast du request_var() nicht zur Verfügung und musst dich selber drum kümmern das nichts böses in dein Query gelangt. Mit dem (int) vor der Variable bist du auch dann immer auf der sicheren Seite.

Gruß Tobi