Charset fehler ?

ichwieder

Benutzer
Beiträge
10
Hallo zusammen,
ich hoffe es ist hier richtig.

Ich wollt meine alte Homepage mal fertig machen und habe den Server Aktualliesiert.
Vorher hatte ich

10.2.44-MariaDB - MariaDB Server
Server-Zeichensatz: cp1252 West European (latin1)

jetzt

10.11.4-MariaDB-1~deb12u1 - Debian 12
Server-Zeichensatz: UTF-8 Unicode (utf8mb4)

seit dem funktioniert die Registrierung nicht mehr :/

die ensprechende Tabele users kommt anscheinend nicht mit dem zeichensatz zurecht.

vorher war es utf8_general_ci
jetzt ist es auf utf8mb4_general_ci geämdert.

mit der alten utf8_general geht es

liegt es jetzt wirklich am zeichensatz ?
 
Werbung:
ich habe keine Bildung, um das sagen zu können, das Problem ist aber eher nach der Logik von:
Kannst du chinesische Zeichen lesen?
ich vermute nicht ;)
entsprechend kennt sich der Computer nicht aus, wie er die zeichen zu interpretieren hat

in Europa ist es üblich, dass der UTF-8 Zeichensatz verwendet wird, sprich eher alles nach Möglichkeit auf UTF-8 stellen in Zukunft, bei PostgreSQL war das irgendeine Einstellung, welche vor der SQL-Installation getroffen werden musste, ich habe mich ewig mit Eigenregerge damals über Google informiert, wie ich das ändern kann.

Ich habe/hatte einen Ubuntu-Server, dort glaube ich war das umstellen der Locales ein Befehl wie:
Code:
export lc_all=de_at.utf-8

oder ähnliches, als Zusatzinfo: ich bin österreicher, von daher auch de_at und so weiter ;)

Ich hoffe, das hilft dir, man kann auch direkt bei dem SQL-Server den Zeichensatz ändern, dazu bei mir einfach (im pgAdmin) mit rechtsklick auf die Datenbank den Punkt "properties" öffnen, dort kann man das "Encoding" umstellen, ich probiere es einmal lieber nicht, sonst hätte ich einen zu großen Verlust, falls es nicht geht und dann alles "weg" ist, ...
 
die ensprechende Tabele users kommt anscheinend nicht mit dem zeichensatz zurecht.
Das ist spekulativ formuliert.

seit dem funktioniert die Registrierung nicht mehr
Das ist empirisch aus Deiner Sicht so, sagt uns aber nichts. Welche Fehlermeldungen gibt es?

Und wenn, sind es PHP oder andere App Server Fehlermeldungen oder DB Fehler?

Und überhaupt, welche Registrierung?
Die eines neuen Users?
Die eines Dinx?
 
ja standart ist
de_DE.UTF-8

Wenn ich die DB umstellen möchte habe ich nur utf8mb4 /utf8mb3 ect.

sowie ich gelesen habe ist uft8mb4 der nachfolger von utf8 aber soll abwätrzkompatible sein.

@dabadepdu
wenn man auf Registrieren drückt steht nur
db-fehler

(das ist er code für die überprüfung)

PHP:
function bark($msg){
    stderr("Registrierung fehlgeschlagen!", $msg);
}

function validusername($username){
    if($username == "")
        return false;

    $allowedchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    for($i = 0; $i < strlen($username); ++$i)
        if(strpos($allowedchars, $username[$i]) === false)
            return false;
    return true;
}

$registered = number_format($database->row_count('users'));
if($registered >= $GLOBALS["MAX_USERS"])
    stderr("Sorry", "Das aktuelle Benutzerlimit (" . number_format($GLOBALS["MAX_USERS"]) . ") wurde erreicht. Inactive Accounts werden regelmäßig gelöscht, versuche es also einfach später nochmal...");

if($_SERVER["REQUEST_METHOD"] == "POST"){
    foreach(explode(":","wantusername:wantpassword:passagain:email") as $k){
        if(!isset($_POST[$k]))
            bark("Eingaben fehlen!");
        else
            $$k = $_POST[$k];
    }

    if(empty($wantusername) || empty($wantpassword) || empty($email))
        bark("Du musst alle Felder ausfüllen.");

    if(strlen($wantusername) > 12)
        bark("Sorry, Dein Benutzername ist zu lang (Maximum sind 12 Zeichen)");

    if($wantpassword != $passagain)
        bark("Die Passwörter stimmen nicht überein! Du musst Dich vertippt haben. bitte versuche es erneut!");

    if(strlen($wantpassword) < 6)
        bark("Sorry, Dein Passwort ist zu kurz (Mindestens 6 Zeichen)");

    if(strlen($wantpassword) > 40)
        bark("Sorry, Dein Passwort ist zu lang (Maximal 40 Zeichen)");

    if($wantpassword == $wantusername)
        bark("Sorry, Dein Passwort darf nicht mit Deinem Benutzernamen identisch sein.");

    if(!validemail($email))
        bark("Die E-Mail Adresse sieht nicht so aus, als ob sie gültig wäre.");

    if(!validusername($wantusername))
        bark("Ungültiger Benutzername.");


    if($_POST["rulesverify"] != "yes" || $_POST["faqverify"] != "yes" || $_POST["ageverify"] != "yes")
        bark("Sorry, aber Du bist nicht dafür qualifiziert, ein Mitglied dieser Seite zu werden.");

    $con = "email='" . $email . "' OR username='" . $wantusername . "'";
    $c = number_format($database->row_count("users", $con));
    if($c != 0)
        bark("Der Username oder die E-Mail Adresse werden schon verwendet.");


    foreach($GLOBALS["EMAIL_BADWORDS"] as $badword){
        if(preg_match("/".preg_quote($badword)."/i", $email))
            bark("Diese E-Mail Adresse kann nicht für eine Anmeldung an diesem Tracker verwendet werden. Wir akzeptieren keine Wegwerf-Mailadressen!");
    }

    $secret = mksecret();
    $wantpasshash = md5($secret . $wantpassword . $secret);
    $editsecret = mksecret();
    $passkey = mksecret(8);
    $qry = $GLOBALS['DB']->prepare("SELECT `id` FROM `stylesheets` WHERE `default`='yes'");
    $qry->execute();
    if($qry->rowCount() > 0){
        $row = $qry->fetchObject();
        $stylesheet = $row->id;
    }else
        $stylesheet = 1;
    $dt = get_date_time();

    $status = "confirmed";

    $res = user::addUser($wantusername,$wantpasshash,$passkey,$secret,$editsecret,$email,$status,$stylesheet,$dt);
    if($res === false)
        bark("db-error");
    if($status != "confirmed"){
        $psecret = md5($editsecret);
        $body = "Du oder jemand anderes hat auf " . $GLOBALS["SITENAME"] . " einen neuen Account erstellt und diese E-Mail Adresse (" . $email . ") dafür verwendet.\n\n ".
            "Wenn Du den Account nicht erstellt hast, ignoriere diese Mail. In diesem Falle wirst Du von uns keine weiteren Nachrichten mehr erhalten. Die Person,  ".
            "die Deine E-Mail Adresse benutzt hat, hatte die IP-Adresse " . $_SERVER["REMOTE_ADDR"] . ". Bitte antworte nicht auf diese automatisch erstellte Nachricht.\n\n ".
            "Um die Anmeldung zu bestätigen, folge bitte dem folgenden Link: " . $DEFAULTBASEURL . "/confirm.php?id=" . $res . "&secret=" . $psecret . "\n\n".
            "Wenn du dies getan hast, wirst Du in der Lage sein, Deinen neuen Account zu verwenden. Wenn die Aktivierung fehlschlägt, oder Du diese nicht vornimmst, wird ".
            "Dein Account innerhalb der nächsten Tage wieder gelöscht. Wir empfehlen Dir dringlichst, die Regeln und die FAQ zu lesen, bevor Du unsere seite verwendest.";
        mail($email, $GLOBALS["SITENAME"]." Anmeldebestätigung", $body, "From: ".$GLOBALS["SITEEMAIL"]);
        header("Refresh: 0; url=ok.php?type=signup&email=" . urlencode($email));
    }else
        header("Refresh: 0; url=ok.php?type=confirmed");
}
 
Add:
auf dem Homepage server habe ich auch von debian 10 auf 12 upgedatet und auf php8 da funktioniert alles.
Nur das da noch 10.2.44-MariaDB ist und da gibt es noch utf8_general_ci
 
ich habe jetzt bei dem aufbau generell auch mal das charset hinzugefügt
PHP:
$db_info = array(
    "db_host" => "localhost",
    "db_port" => "3306",
    "db_user" => "benutzerX",
    "db_pass" => "xxxxxxxxxxx",
    "db_name" => "test",
    "db_charset" => "utf8mb4_general_ci"
);
$ddna = ["mysql:host=".$db_info['db_host'].';port='.$db_info['db_port'].';dbname='.$db_info['db_name'],$db_info['db_user'], $db_info['db_pass'], $db_info['db_charset']];
    
    oder auch
        "db_charset" => "utf8mb4"
        "db_charset" => "utf8"

Bringt alles leider kein erfolg :/

das problem ist ich bekomme nicht angezeigt wo der fehler ist. auch in den logs ist nix :/
 
ich habe jetzt bei dem aufbau generell auch mal das charset hinzugefügt
PHP:
$db_info = array( […]
     "db_charset" => "utf8mb4_general_ci"
);
$ddna = ["mysql:host=".$db_info['db_host'].';port='.$db_info['db_port'].';dbname='.$db_info['db_name'],$db_info['db_user'], $db_info['db_pass'], $db_info['db_charset']];
   
    oder auch
        "db_charset" => "utf8mb4"
        "db_charset" => "utf8"
utf8mb4_general_ci ist auf jeden Fall schonmal falsch: das ist ein Kollation (also Sortierregel), keine Charsetangabe. utf8 ist ebenfalls falsch, richtig ist nur utf8mb4. Aber wie sieht der Verbindungsaufbau genau aus? Du baust hier wohl einen DSN zusammen - dieser muss allerdings bei der Verwendung von PDO die charset-Angabe enthalten.

Außerdem: was ist jetzt eigentlich genau das Problem? Die Aussage "geht nicht" ist da etwas wenig …

Noch ein paar Hinweise zum Code aus #4:
$$k = $_POST[$k];
Ganz schlechter Stil (wie auch die Verwendung von $GLOBALS) - so wird der Code sehr schlecht lesbar da nur schwer erkennbar ist wo irgendwelche Werte her kommen. Außerdem kann man problemlos mit den Werten in $_POST weiter arbeiten, ein umkopieren ist nicht notwendig.
if(strlen($wantpassword) > 40)
Es gibt keinen Grund die Länge von Passwörtern zu beschränken.
$con = "email='" . $email . "' OR username='" . $wantusername . "'";
$c = number_format($database->row_count("users", $con));
Das richt gewaltig nach nicht behandeltem Kontextwechsel.
$wantpasshash = md5($secret . $wantpassword . $secret);
Nein! md5() sollte schon lange nicht mehr zum Hashen von Passwörtern verwendet werden da es als geknackt anzusehen ist - verwende password_hash() (in Kombination mit password_verify()) dafür.
mail($email, $GLOBALS["SITENAME"]." Anmeldebestätigung", $body, "From: ".$GLOBALS["SITEEMAIL"]);
Verwende nicht mail() (damit ist es eher Glückssache ob eine Mail ankommt) sondern eine Mailerklasse (wie z.B. PHPMailer).
 
Naja, der code wird stück für stück überarbeitet. (Die Seite wurde vor über 10 Jahren gemacht) momentan ist das einzige Proiblem, seit der MariaDB Aktualliesierung das die Registrierung nicht mehr funktioniert.
 
Naja, der code wird stück für stück überarbeitet. (Die Seite wurde vor über 10 Jahren gemacht) momentan ist das einzige Proiblem, seit der MariaDB Aktualliesierung das die Registrierung nicht mehr funktioniert.
Wie gesagt: "funktioniert nicht" ist keine Fehlerbeschreibung mit der man auch nur ansatzweise etwas anfangen kann …

Auf die Hinweise zur Charset-Angabe beim Aufbau der Verbindung gehst du aber überhaupt nicht ein - wenn da keine Angabe erfolgt wird der Standardwert verwendet und der kann sich ändern was dann eben Probleme macht da die Daten nicht im erwarteten Format geliefert werden.
 
Das problem ist , wenn man die datein ein gibt und auf registrieren drückt, kommt danach nur

Registrierung fehlgeschlagen!
db-error

char ist so:
"db_charset" => "utf8mb4"

der aufbau ist in etwa so. (wenn du das meinst)
PHP:
$database = new db($ddna);
$GLOBALS['DB'] = $database->getPDO();

die entsprechende classe
PHP:
class db
{
    private $con;
    public $data = array();

    function __construct($ddna = array()) {
        if(!isset($ddna, $ddna[0], $ddna[1], $ddna[2]))
            die("ddna fehlerhaft");
        try{
            $this->con = new PDO($ddna[0], $ddna[1], $ddna[2]);
            $this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
            $this->con->query('SET NAMES utf8mb4');
        }catch(PDOException $e){
            throw new Exception('Konnte nicht zur Datenbank verbinden!');
        }
    }
    
    public function getPDO(){
        return $this->con;
    }
    
    public function row_count($table,$condition = '1=1'){
        $sql = "SELECT COUNT(*) FROM " . $table . " WHERE " . $condition;
        $qry = $this->con->prepare($sql);
        $qry->execute();
        return $qry->fetchColumn(0);
    }
}
 
Das problem ist , wenn man die datein ein gibt und auf registrieren drückt, kommt danach nur

Registrierung fehlgeschlagen!
db-error
Dann liefert user::addUser() false zurück - warum das so ist lässt sich ohne den Code zu kennen nicht sagen.

$this->con = new PDO($ddna[0], $ddna[1], $ddna[2]);
Das habe ich mir schon gedacht. In $ddna[0] (also dem ersten Arrayelement in dem Array das in #7 $ddna zugewiesen wird) steht der DSN in welchem das Charset festgelegt wird (also »;charset=utf8mb4« anhängen) - das Charset in dem Array einfach als zusätzliches Element anzuhängen bringt exakt garnichts wenn die Klasse den Wert ignoriert.

$this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
Das ist für die Fehlersuche jetzt nur wenig hilfreich Fehlermeldungen einfach auszuschalten (zumindest solange man nicht dafür sorgt sie trotzdem angezeigt zu bekommen.
$this->con->query('SET NAMES utf8mb4');
Nein, das Charset wird anders gesetzt, siehe Handbuch.
 
also das quasi so ?

PHP:
$ddna = ["mysql:host=".$db_info['db_host'].';port='.$db_info['db_port'].';charset=utf8mb4;dbname='.$db_info['db_name'],$db_info['db_user'], $db_info['db_pass']];
 
Werbung:
Zurück
Oben