a permanent way of doing mysqli->set_charset()?

后端 未结 3 917
耶瑟儿~
耶瑟儿~ 2021-02-04 06:20

after setting all config file and runtime options for charset that i can find to utf-8, new mysqli connections made with php still has its charset set to latin1, which effective

相关标签:
3条回答
  • 2021-02-04 06:44

    according to the following posts from MySQL

    http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html http://dev.mysql.com/doc/refman/5.0/en/charset-applications.html

    your settings are not completely right i.e.

    use

     [mysqld]
     character-set-server=utf8
     collation-server=utf8_general_ci
    

    instead of

     [mysqld]
     default-character-set=utf8
    

    for the client I only found

     [mysql]
     default-character-set=utf8
    

    not

     [client]
     default-character-set=utf8
    

    try and give me some feedback.

    I can remember that I once read about a setting var to switch off the ability for a client to change the character setting. But I can't find the ref in mysql documentation now. If I find it I let you know.

    Hope that helps.

    Regards

    UPDATE

    @Unisland BTW I found this thread http://www.webmasterworld.com/php/3553642.htm where a similar problem is discussed

    Try either

    So you may try to add a:
    [mysqld]
    init-connect='SET NAMES utf8'

    or

    [client]
    default-character-set=utf8

    [mysqld]
    character-set-server=utf8
    default-character-set=utf8
    default-collation=utf8_unicode_ci
    character-set-client = utf8

    to set this as a default for all connections, or start with these queries after your specific script connects to the database before sending other queries: SET NAMES utf8; SET CHARACTER_SET utf8;

    0 讨论(0)
  • 2021-02-04 06:55

    You have diagnosed the basic problem correctly: While you can change the default MySQL client charset in the client machine's my.cnf or .my.cnf, these files are not used by PHP.

    If you think about how PHP's MySQLi/MySQL extensions work, this will make sense -- they have nothing to do with the mysql client program and aren't going to crawl your filesystem for config files, because they use libmysql directly.

    To change libmysql's actual default charset, you'll just need to rebuild libmysql. That may not be an answer you like (since you're using precompiled MySQL binaries), but it is the actual answer. The defaults are set at compile time, and then can be overridden at runtime.

    If you don't want to do this and calling set_charset() annoys you, my suggestion would be to simply extend the MySQLi class and use that class in place of mysqli. i.e.:

    class MyDB extends mysqli {
      // (You could set defaults for the params here if you want
      //  i.e. $host = 'myserver', $dbname = 'myappsdb' etc.)
      public function __construct($host = NULL, $username = NULL, $dbname = NULL, $port = NULL, $socket = NULL) {
        parent::__construct($host, $username, $dbname, $port, $socket);
        $this->set_charset("utf8");
      } 
    } 
    

    Typically in an application you'll have some kind of database abstraction layer anyway, so you can either have this layer use MyDB instead of mysqli, or you can have this layer be MyDB and add or override any methods you want (I've done this with simple ORM-less apps).

    It's a good practice to always have some kind of database abstraction layer, even if it starts as just class MyDB extends mysqli {} because then you'll never have to search/replace your entire codebase to make small changes.

    RE: your workaround, as you explain, this essentially hardcodes your entire db server to UTF-8 regardless of what clients request. Instead of having multiple databases, each with its own charset, the server only works with UTF-8 and may silently mangle data if clients connect with another charset. This is fundamentally wrong because you've effectively moved one aspect of your application's configuration (database charset) from the app/client machine to the database server where it doesn't really belong.

    If you think about the application stack's layers,

    [server] <=> [network] <=> [client libmysql] <=> [PHP binary] <=> [app]
    

    then you'll understand that the "correct" place for an app-specific configuration like this is in the app itself, not elsewhere in the stack. You may not like having to specify your database's charset in PHP, but if you think about it, that's really where it belongs, because it's also where you're specifying the database itself that you want to connect to -- it's a connection parameter, not a server configuration issue. Hardcoding the charset anywhere else makes your application non-portable.

    0 讨论(0)
  • 2021-02-04 06:56

    I know this is a very old thread, but I just encountered this issue on my Fedora 30 KDE laptop after installing MariaDB (and have spent over an hour looking for the answer). On my Ubuntu 18.04 server, everything just works without having to modify any config files, but on my laptop running Fedora 30 KDE, I had to:

    $ sudo vi /etc/my.cnf.d/client.cnf
    

    and then added default-character-set in the [client-mariadb] section:

    [client-mariadb]
    default-character-set = utf8mb4
    

    I had to do the same for the server config:

    $ sudo vi /etc/my.cnf.d/mariadb-server.cnf
    

    and then added the following in the [mysqld] section:

    [mysqld]
    character-set-server  = utf8mb4
    collation-server      = utf8mb4_general_ci
    

    Then just restart MariaDB:

    $ sudo systemctl restart mariadb.service
    

    After this, there's no need to explicitly set the character set within PHP scripts.

    0 讨论(0)
提交回复
热议问题