codeigniter 无法在数据库中存储表情符号

q5iwbnjs  于 8个月前  发布在  其他
关注(0)|答案(7)|浏览(76)

情况

如果这个问题已经被问到了,我先道歉,但是这些解决方案对我不起作用。
无论我怎么尝试,我都无法在数据库中存储emoji。它们被保存为????
唯一正确保存的表情符号是那些只需要3个字节的表情符号,比如害羞的脸或太阳。
实际的utf8 mb 4不工作。

它已经在Android和iOS上进行了测试。同样的结果。

版本

MySQL:5.5.49
CodeIgniter:3.0.0

步骤

1.我修改了数据库字符集和排序规则属性。
ALTER DATABASE my_database CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci
1.我修改了表字符集和排序规则属性。
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
1.我已经将表中的每个字段设置为Encoding:UTF-8(ut8mb4)和排序:utf8mb4_unicode_ci
1.我已经修改了CodeIgniter应用程序中的数据库连接。
1.我运行了以下内容:SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci
1.最后,我也尝试了这个:REPAIR TABLE table_name; OPTIMIZE TABLE table_name;
一切都应该已经设置妥当,但它不工作。

数据库设置

这是运行以下命令的结果:

`SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';`

表格设置

表格结构的屏幕截图:

数据库连接

以下是database.php中的数据库连接设置(注意,这不是唯一的数据库,还有其他使用utf8连接的数据库)

$db['my_database'] = array(
        'dsn'           => '',
        'hostname'      => PROJECT_DATABASE_HOSTNAME,
        'username'      => PROJECT_DATABASE_USERNAME,
        'password'      => PROJECT_DATABASE_PASSWORD,
        'database'      => PROJECT_DATABASE_NAME,
        'dbdriver'      => 'mysqli',
        'dbprefix'      => '',
        'pconnect'      => FALSE,
        'db_debug'      => TRUE,
        'cache_on'      => FALSE,
        'cachedir'      => '',
        'char_set'      => 'utf8mb4',
        'dbcollat'      => 'utf8mb4_unicode_ci',
        'swap_pre'      => '',
        'encrypt'       => FALSE,
        'compress'      => FALSE,
        'stricton'      => FALSE,
        'failover'      => array(),
        'save_queries'  => TRUE
    );

我的.CNF设置

这是文件my.cnf的全部内容:

[mysqld]
default-storage-engine=MyISAM
innodb_file_per_table=1
max_allowed_packet=268435456
open_files_limit=10000
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

问题

你知道为什么不工作吗?我是不是漏了什么?

  • 酒店

我不确定,但问题的原因可能是这样的:
正如你在我的.cnf中看到的,character-set-server被清楚地设置为utf8mb4
但是在数据库中运行查询之后:
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
结果是character-set-server = latin1
你知道为什么吗?为什么实际上没有更新?

  • 酒店

应用程序使用几个不同数据库。这一个设置为utf8 mb 4,但所有其他设置为utf8。即使它们是独立的数据库也可能是问题?
谢谢你,谢谢!

编辑:

这是SHOW CREATE TABLE app_messages;的结果

CREATE TABLE `app_messages` (
  `message_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `project_id` bigint(20) NOT NULL,
  `sender_id` bigint(20) NOT NULL,
  `receiver_id` bigint(20) NOT NULL,
  `message` text COLLATE utf8mb4_unicode_ci,
  `timestamp` bigint(20) DEFAULT NULL,
  `is_read` enum('x','') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`message_id`)
) ENGINE=InnoDB AUTO_INCREMENT=496 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

编辑2:

我运行了以下命令:

INSERT INTO app_messages (message_id, project_id, sender_id, receiver_id, message, timestamp, is_read)
VALUES ('496','322','77','188', '😜' ,'1473413606','x');

另外两个与和相似
它们被插入表中,没有问题:

但在实际应用中我真正看到的是:?(这次只有一个?(4)不

fivyi3re

fivyi3re1#

建议:

如果你需要使用emoji,首先在localhost上进行简单的测试。创建一个新的数据库,并制作一个新的应用程序用于测试目的。
如果你按照我在问题中写的步骤或者按照本教程操作:https://mathiasbynens.be/notes/mysql-utf8mb4#utf8-to-utf8mb4它必须工作。
在本地使用一个新的基本应用程序,你将有更多的控制权和更多的空间来进行你需要的所有测试。

解决方案:

在我的例子中,问题出在CodeIgniter中的数据库配置中。它没有正确地设置char_set和排序规则,这是一个愚蠢的忽略:我正在覆盖保存消息的功能中的数据库设置,以确保它与移动的数据库一起工作。

之前:

function message_save ( $data = FALSE )
{   
    $project_db_config                  = array();
    $project_db_config['hostname']      = 'MY_HOST';
    $project_db_config['username']      = 'MY_USERNAME';
    $project_db_config['password']      = 'MY_PASSWORD';
    $project_db_config['database']      = 'MY_DATABASE';

    $mobile_db                          = $this->load->database( $project_db_config, TRUE );

    // other code to save message       
}

之后:

function message_save ( $data = FALSE )
{
    $mobile_db_connection = $this->load->database('admin_mobile_mh', TRUE);
  
    // other code to save message
}

结论:

应用程序必须正确设置与数据库的连接。如果您正确设置了数据库,但没有与应用程序建立正确的连接,则无法正常工作。
因此,如果你遇到类似的问题,请确保API正确地将char_set设置为utf8mb4,将db_collat设置为utf8mb4_unicode_ci

ffdz8vbo

ffdz8vbo2#

我所知道的获取????的唯一方法是不声明 * 列 * utf8mb4。我知道您显然已经确定列是这样声明的,但是请运行SHOW CREATE TABLE table_name;来进一步确认。
如果列重写CHARACTER SET,则系统默认值、数据库默认值和表默认值都不相关。
给所有其他尝试的答案的注解:COLLATION不相关,只有CHARACTER SET与此问题相关。

5t7ly7z5

5t7ly7z53#

my.cnf首先加载,然后是conf.d/*.cnf
不要修改my.cnf *(这可能会被conf.d/*.cnf中的配置覆盖),而是创建一个自定义覆盖配置,例如conf.d/90-my.cnf

  • 前缀90可确保最后加载自定义设置,这意味着它们将覆盖任何早期设置。*

要确保重新加载新配置,请参阅Reload Without Restarting the MySQL service

配置结构示例(Linux)

.
├── conf.d
│   ├── 90-my.cnf
│   ├── conn.cnf
│   ├── my5.6.cnf
│   └── mysqld_safe_syslog.cnf
├── debian.cnf
├── debian-start
└── my.cnf

conf.d/90-my.cnf

# https://mathiasbynens.be/notes/mysql-utf8mb4
# http://stackoverflow.com/q/3513773/934739

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]

character-set-client-handshake = FALSE

# The server character set and collation are used as default values if the
# database character set and collation are not specified in CREATE DATABASE
# statements. They have no other purpose.
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
lnxxn5zx

lnxxn5zx4#

您可以将Table字段的值改为utf8mb4,而不是varchar
确保所有表的默认字符集和文本字段都转换为utf8mb4,除了设置客户端和服务器字符集,例如。ALTER TABLE mytable charset=utf8mb4, MODIFY COLUMN textfield1 VARCHAR(255) CHARACTER SET utf8mb4,MODIFY COLUMN textfield2 VARCHAR(255) CHARACTER SET utf8mb4;等等。

h22fl7wq

h22fl7wq5#

嗨,我用表情符号android和我存储到orm数据库使用**EMOJI_INDEX**.我保存在数据库中的字符串形式的正常消息,但当我得到的时候,我检查是否有任何表情符号,然后将其转换成有处理表情符号.

textMessage.setText(getItem(pos).file != null ? "":EmojiUtil.getInstance(context).processEmoji(getItem(pos).message, textMessage.getTextSize()));

从这里看一下我是如何将Emoji_Index更改为process的

if (emojiImages == null || emojiImages.isRecycled()) {
        InputStream localInputStream;
        try {
            localInputStream = context.getAssets().open("emoji/emoji_2x.png");
            Options opts = new Options();
            opts.inPurgeable = true;
            opts.inInputShareable = true;
            emojiImages = BitmapFactory.decodeStream(localInputStream, null, opts);
        } catch (IOException e) {
            return Html.fromHtml(paramString);
        }
    }

有关更多信息,请参阅here。谢谢,希望这对你有帮助。

isr3a4wc

isr3a4wc6#

我在Linux上的服务器版本有问题。我不得不手动更改文件database_interface.lib.php,并绕过此
if(!PMA_DRIZZLE){ if(!public void run($nums ['nums]){
把它改成这样:(注意utf8mb4_unicode_ci引用)

// Skip charsets for Drizzle
if (!PMA_DRIZZLE) {
    if (! empty($GLOBALS['collation_connection'])) {
        PMA_DBI_query("SET CHARACTER SET 'utf8mb4';", $link, PMA_DBI_QUERY_STORE);
        $set_collation_con_query = "SET collation_connection = '"
            . PMA_Util::sqlAddSlashes($GLOBALS['collation_connection']) . "';";
        PMA_DBI_query(
            $set_collation_con_query,
            $link,
            PMA_DBI_QUERY_STORE
        );
    } else {
        PMA_DBI_query(
            "SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';",
            $link,
            PMA_DBI_QUERY_STORE
        );
    }
}
vu8f3i0k

vu8f3i0k7#

更新答案

您可以尝试使用字符集utf8排序规则utf8_unicode_ci而不是utf8mb4_unicode_ci
运行此查询

ALTER TABLE table_name CHANGE `column_name` `column_name` TEXT CHARSET utf8 COLLATE utf8_unicode_ci;

旧答案应该使用排序规则utf8mb4_bin,而不是utf8mb4_unicode_ci

运行此查询

ALTER TABLE table_name CHANGE `column_name` `column_name` TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin;

表情符号将被存储为代码,并在Android和iOS应用程序中再次转换为表情符号。我在我的项目中也使用了这些代码。

相关问题