-1

I´m working on a Wordpress plugin and for a strange reason, I save correctly strings in the database with the char but to display it, even if I don´t use the wordpress way with $wpdb but like this ( Notice : this piece of code was just to check if it was a deeper matter, it´s not to use it ) :

    $query = "SELECT option_value FROM wp_options WHERE option_name = '" . $this->current_options_name . "' LIMIT 1";
    $conn = new \mysqli("host", "username", "password", "dbname");
    $output = $conn->query($query);

    if ($output->num_rows > 0) {
        // output data of each row
        while($row = $output->fetch_assoc()) {
            var_dump($row);
        }
    } else {
        echo "0 results";
    }

That displays ? instead of in string values.

Important notices

  1. I don´t have this problem with the char $.
  2. The char is stored correctly in the database, I can see it in the table value inside PHPMyAdmin.

Someone has got an idea ?

J.BizMai
  • 2,035
  • 3
  • 16
  • 32
  • 1
    you have to have for example utf8 all the way through, so check database table column and connection string. and when you are at it use als ways **prepared statements with parameters** see https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php – nbk May 05 '20 at 19:05
  • 2
    Another idea: don't store €,£,$. Store a standard code (EUR, GBP, USD) in a separate column, and handle the display in your application code – Strawberry May 05 '20 at 19:09
  • @nbk Yes the DB is in 'utf8_general_ci' - in `wp-config.php`, I got `define('DB_CHARSET', 'utf8');` – J.BizMai May 05 '20 at 19:13
  • If everything is utf8 and i would check the connestring, your data in the databse is flawed – nbk May 05 '20 at 19:22
  • @nbk When I check in the DB thanks PHPMyAdmin, I can see € in the string value stored. – J.BizMai May 05 '20 at 19:24
  • good so check the connection string and solve you sql injection problems as well, but that isn't the issue here primaraly – nbk May 05 '20 at 19:26
  • @nbk, the current code to do the sql query was just a test to check if it was a problem with Wordpress and the object `$wpdb` or a deeper matter. I won´t use this code, I will use `$wpdb->results()`. – J.BizMai May 05 '20 at 19:30
  • 1
    See "question mark" in https://stackoverflow.com/questions/38363566/trouble-with-utf8-characters-what-i-see-is-not-what-i-stored – Rick James May 07 '20 at 03:52

2 Answers2

0

It's a character encoding issue. Characters are represented by numbers, and there's many character encodings saying what number is what character.

There's three, possibly different, encodings involved in your code. The database's encoding, PHP's encoding, and the web page's encoding. They all should agree on what encoding they're using. Or they must know what encoding the others are using and convert correctly.

? indicates a number which has no corresponding character in the character set your web page is using. $ is the same in many character sets so it's less sensitive to encoding goofs. € is often different, so it's sensitive to encoding goofs.

Any point handing text from one system to another could be mangling the text. Passing text from the web page into PHP, inserting text from PHP into the database, fetching text from the database into PHP, and text from PHP to the web page.

Simplest thing to do is to make sure they're all using UTF-8, the most common encoding which handles just about every character.

This PHP Round Table on Character Encoding and UTF-8 in PHP should walk you through fixing the problem. Also the answers to Setting PHP default encoding to utf-8.

You can check your database character set by following these answers.

Finally, check the character encoding of your web page. In most browsers this will be in "Page Info". For example, Stack Overflow has a Text Encoding of UTF-8.


Note: Do not use string concatenation to put values into SQL queries. Use bind parameters. It's less buggy and more secure.

Schwern
  • 127,817
  • 21
  • 150
  • 290
  • Thank you for this answer, I will see. this code to do the query was just a test to understand what happens, I will use `$wpdb` to do that. – J.BizMai May 05 '20 at 19:18
0

use this , where you add the characters set to the conectio0n. It does teh same as your test. But secure tehcharacterset is utf8mb4, because that is my default setting. Could be that you must change that to your needs

$mysqli= new mysqli("host", "username", "password", "dbname");
$mysqli->set_charset("utf8mb4");
$query = "SELECT option_value FROM wp_options WHERE option_name = ? LIMIT 1";
$stmt = $mysqli->prepare($query );
$stmt->bind_param("si", $this->current_options_name);
 $stmt->execute();
 $result = $stmt->get_result();
 if($result->num_rows === 0) {
   echo '0 results'; 
  } else {
    while($row = $result->fetch_assoc()) {
     var_dump($row);
    }
  }

$stmt->close();
nbk
  • 20,484
  • 4
  • 19
  • 35
  • So for this case I should change 'UTF-8' charset to 'utf8mb4' ? – J.BizMai May 05 '20 at 19:55
  • try it with uft8mb4 but in the mysql server should be visible what you have, but of xxourse you can define a table and column otherwise ;) – nbk May 05 '20 at 19:57
  • @J.BizMai `utf8mb4` is still UTF-8. It's a special MySQL version. MySQL's `utf8` cannot hold all UTF-8 characters. `utf8mb4` can. But both can hold €. See https://stackoverflow.com/questions/30074492/what-is-the-difference-between-utf8mb4-and-utf8-charsets-in-mysql – Schwern May 05 '20 at 21:14