首页 > 解决方案 > PHP/ExtJS - 将带有 unicode 的字符串转换回其原始字符

问题描述

我有一个网络应用程序(使用 ExtJS 构建),让用户可以在其中更新他们的基本信息。大多数更新程序都没有问题。但是,当我尝试更新用户名中带有 ñ 的用户时,PHP 将其更改为 Unicode u00f1

例如,我传递了名称Añana,PHP 显示的是Au00f1ana,其中“u00f1”替换了“ñ”。

我已经尝试将字符集设置为 utf-8, htmlspecialchars, mb_convert_encoding, utf8-decode, and html_entity_decode,但没有任何效果。

我为解决这个问题所做的就是使用原始字符strpos并将substr_replace其替换为 utf 代码。

if(strpos($my_string, 'u00f1') !== FALSE){
    $start_index = strpos($my_string, "u00f1"); 
    $last_name = substr_replace($my_string, "ñ", $start_index, 5);
}
elseif(strpos($my_string, 'u00F1') !== FALSE){
    $start_index = strpos($my_string, "u00F1"); 
    $last_name = substr_replace($my_string, "Ñ", $start_index, 5);        
}

有关更多上下文,这是我使用的商店: Ext.define('AppName.store.MyStore', { extend: 'Ext.data.Store',

    requires: [
        'AppName.model.model_for_store',
        'Ext.data.proxy.Ajax',
        'Ext.data.reader.Json',
        'Ext.data.writer.Json'
    ],

    constructor: function(cfg) {
        var me = this;
        cfg = cfg || {};
        me.callParent([Ext.apply({
            remoteFilter: true,
            remoteSort: true,
            storeId: 'MyStore',
            batchUpdateMode: 'complete',
            model: 'AppName.model.model_for_store',
            proxy: {
                type: 'ajax',
                batchActions: false,
                api: {
                    create: 'folder/folder/create.php',
                    read: 'folder/folder/read.php',
                    update: 'folder/folder/update.php',
                    destroy: 'folder/folder/delete.php'
                },
                url: '',
                reader: {
                    type: 'json',
                    keepRawData: true,
                    messageProperty: 'message',
                    rootProperty: 'data'
                },
                writer: {
                    type: 'json',
                    writeAllFields: true,
                    encode: true,
                    rootProperty: 'data'
                }
            }
        }, cfg)]);
    }
});

这是触发更新的 PHP 文件的开始:

<?php
require_once('../db_init.php');
require_once '../lib/response.php';
require_once '../lib/request.php';

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);

ini_set('default_charset', 'utf-8');

header("content-type: text/html; charset=UTF-8");  

error_reporting(E_ALL);

define('CHARSET', 'ISO-8859-1');
define('REPLACE_FLAGS', ENT_COMPAT | ENT_XHTML);

class my_object{ 
    //..... variables
}

$request = new Request(array());

if(isset($request->params)){

    $array_r=$request->params;

    $inputData->last_name=($array_r->last_name);
    $inputData->first_name=($array_r->first_name);
    $inputData->middle_name=($array_r->middle_name);

}
else{
    //echo "Update of User failed";
    $res = new Response();
    $res->success = false;
    $res->message = "Update User Failed!";
    $res->data = array();
    print_r($res->to_json());
}
?>

作为参考,这是我的Request.php文件

<?php

class Request {
    public $method, $params;

    public function __construct($params) {
       // $this->restful = (isset($params["restful"])) ? $params["restful"] : false;
        $this->method = $_SERVER["REQUEST_METHOD"];
        $this->parseRequest();
    }

    protected function parseRequest() {

            // grab JSON data if there...
            $this->params = (isset($_REQUEST['data'])) ? json_decode(stripslashes($_REQUEST['data'])) : null;

            if (isset($_REQUEST['data'])) {
                $this->params =  json_decode(stripslashes($_REQUEST['data']));
            } else {
                $raw  = '';
                $httpContent = fopen('php://input', 'r');
                //print_r($httpContent);
                while ($kb = fread($httpContent, 1024)) {
                    $raw .= $kb;
                }
                $params = json_decode(stripslashes($raw));
                if ($params) {
                    $this->params = $params->data;
                }
            }
    }
}
?>

虽然我已经检查了 ExtJS 的文档,并且对于encodeJSONWriter 中的属性,它说:

Configure `true` to send record data (all record fields if writeAllFields is true) as a JSON Encoded HTTP Parameter named by the rootProperty configuration. 

所以我的模型数据作为 JSON 编码的 HTTP 参数发送,PHP 能够解析它,因为 rootProperty 是data,它与我的 request.php 文件中的第 19 行匹配:

$this->params = (isset($_REQUEST['data'])) ? json_decode(stripslashes($_REQUEST['data'])) : null;

我认为json_decode(stripslashes(...)) is the one causing ñ` 将被转换为等效的 utf-8,并且带斜杠删除了我们通常在 utf-8 中看到的前导反斜杠。

我有一种感觉有一种更好的方法来编写它,它不会将转换ñ为 utf-8。

有没有人对此有更好的解决方案?

标签: php

解决方案


解决了。问题出stripslashrequest.php文件中。

当 ExtJS 通过 Store 发送数据时,我使用encode,它把它作为一个编码的 JSON 参数。鉴于没有转义的特殊字符,通常request.php文件获取并运行时不会有问题。json_decode问题是当我点击 时ñ,它被转换为\u00f1,并且前导斜线被修剪了。json_decode大概没有再次识别它,因为没有前导斜线。

主要归功于 IMSoP 在铅的评论中。


推荐阅读