Gå til innhold

PHP: Mysqli og tegnsett ved INSERT(latin1/utf8)


Gjest Slettet-IHWlGMJn

Anbefalte innlegg

Gjest Slettet-IHWlGMJn

Heisann

 

Jeg skjønner meg tydeligvis ikke helt på mysqli og hvordan forbindelsen til databasen er satt opp.

 

Jeg har en mysql-database der dens tabell("test") og felt ("id","text") er satt til utf-8.

Jeg bruker også utf-8 for visning av nettsiden der data vises.

 

Hvorfor må jeg decode input-teksten til latin1 i vedlagt eksempel? Hvorfor har databaseforbindelsen et tegnsett? Det sendes da bare bits og bytes over denne forbindelsen? Og hvorfor går det helt fint ved SELECT, men ikke INSERT?

 

Jeg har litt vanskelig for å ordlegge forvirringen min rundt dette og har derfor laget dette minimale eksempelet:

<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta charset="utf-8">
</head>
<body>
<?php
   $DB_NAME = 'dbname';
   $DB_HOST = 'host.example.com';
   $DB_USER = 'username';
   $DB_PASS = 'mypass';
   $mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
   if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
   }
   $charset = $mysqli->character_set_name();
   printf ("<p>Current character set is %s</p>\n", $charset);
   if ( isset($_POST['text']) && $_POST['text'] ) {
    echo '<p>POST: ' . $_POST['text'] . ' (encoding ' . mb_detect_encoding($_POST['text']) . ')</p>';
    if ( $stmt = $mysqli->prepare('INSERT INTO test (text) VALUES (?)') ) {
	    $stmt->bind_param("s", utf8_decode($_POST['text']));
	    $stmt->execute();
	    $stmt->close();
    }
   }
   $result = $mysqli->query("SELECT id, text FROM test ORDER BY id ASC") or die();
   if ( $result->num_rows > 0 ) {
    while ( $row = $result->fetch_assoc() ) {
	    echo '<p>' . $row['id'] . ': ' . htmlentities($row['text']) . "</p>\n";
    }
   }
   $mysqli->close();
?>
<form method="post" action="#">
<input type="text" name="text" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

MySQL:

show variables like 'character_set%'

Gir(Jeg henger ikke med på nøyaktig hvor alle disse tegnsettene brukes):

Variable_name   Value
character_set_client	latin1
character_set_connection		latin1
character_set_database  utf8
character_set_filesystem		binary
character_set_results   latin1
character_set_server	latin1
character_set_system	utf8
character_sets_dir	  /usr/share/mysql/charsets/

Hva nettsiden sier om jeg inputter "æ":

Current character set is latin1
POST: æ (encoding UTF-8)
1: æ

Jeg har også prøvd en variant med $mysqli->set_charset("utf8"). Da går INSERTs i databasen fint uten utf8_decode, men SELECTs skriver da ut f.eks "æ" og ikke "æ".

Endret av Slettet-IHWlGMJn
Lenke til kommentar
Videoannonse
Annonse
Gjest Slettet-IHWlGMJn

Har fundert litt videre på dette:

Det at INSERT ikke fungerer når tegnsettet til mysqli er satt til latin1 kan muligens forklares ved at det skjer en form for escaping internt inne i et prepared statement. Om tegnsettet her er feil så escaper den feil ... kanskje.

 

Men dette forklarer ikke at SELECT ikke fungerer når man setter tegnsettet til utf8 i mysqli.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...