客户端需要UTF-16编码的文件,但转换时,同事说不对,要小尾序的,其实不太明白这个意思,查了一下资料。

PHP里的代码也就这样了:
$content = iconv('UTF-8', 'UTF-16', $content);


从某篇文章发现这样的东西:
from_to($string, 'UTF-16le', 'UTF-8');


这说明了有其它的UTF-16的编码方式,我们看看维基的说明《UTF-16》:
引用
UTF-16是Unicode的其中一个使用方式。 UTF是 Unicode/UCS Transformation Format,即把Unicode转做某种格式的意思。

UTF-16的大尾序和小尾序储存形式都在用。一般来说,以Macintosh制作或储存的文字使用大尾序格式,以Microsoft或Linux制作或储存的文字使用小尾序格式。

字符“朱”:
UTF-16LE 小尾序  31 67
UTF-16BE 大尾序  67 31


PHP稍微修改一下就对了:
$content = iconv('UTF-8', 'UTF-16le', $content);


另外有这么个代码:UTF-8 to Code Point Array Converter in PHP
把字符都转换成代表的数字了,目前不知道什么用途。。

另外,需要转换PC格式为Unix格式时,需要在转换Utf-16之前处理,否则会出现好多乱码的哦
$content = str_replace("\r\n", "\n", $content);
$content = iconv('UTF-8', 'UTF-16le', $content);

Tags: ,
从大的编码转换到小的编码,是会产生字符缩减的,甚至有些字在目标字符集里不存在。

比如gb2312里,“囧”、“镕”都会产生转换失败,但很奇怪,gb2312的网页里是有这样的文字的,有点不解。
先看看官方的说明吧 iconv

引用
out_charset
The output charset.

If you append the string //TRANSLIT to out_charset transliteration is activated. This means that when a character can't be represented in the target charset, it can be approximated through one or several similarly looking characters. If you append the string //IGNORE, characters that cannot be represented in the target charset are silently discarded. Otherwise, str is cut from the first illegal character and an E_NOTICE is generated.


看示例可知

在输出字符里添加//TRANSLIT可以得到相近的意思的字符
添加//IGNORE可以忽略不能转换的
不添加,则在第一个错误的地方停止转换,也就是被截断了

如何知道被截断了或者转换失败?

有个例子可以参考一下(单位是字节还是字符,这里不确定)

<?
//code from http://www.aslibra.com
//code by hqlulu @ 2010-1-25

$title_origin = "something";
$title = iconv('utf-8', 'gb2312//IGNORE', $title_origin);
$percent = round(strlen($title_origin)/strlen($title), 3);

//UTF-8汉字 3字节 gb2312汉字 2字节
//最大比例为1.5,如果丢失文字,那就是有转换失败,并且比例变大
//简单例子:“我”的urlencode值 = %E6%88%91(utf-8) = %CE%D2(gb2312)

if($percent > 1.5 ){
  $error[] = array('str', $title_origin);
}
?>
Tags: ,
nginx配合codeIgniter有点麻烦,没有apache和lighttpd那么简单。

$HTTP["host"] == "www.aslibra.com" {
  server.document-root = "/path/to/www.aslibra.com/"
  url.rewrite = (
    "^/static/.*$" => "$0",
    "^/(.*)$" => "index.php/$1"
  )
  fastcgi.server = ( ".php" =>
    ( "weibo"=>( "host" => "127.0.0.1","port" => 9000) )
  )
}


在apache和lighttpd里面,判断 /index.php/sth 时,如果 /index.php是一个文件,就不会当做是文件路径了

我们可以这样简单的把某些路径rewrite,达到一样的效果:
1 保持地址格式是 /index.php/control/model
2 不产生404错误或者是no input的情况

server {
  index index.php index.htm;
  server_name  www.aslibra.com;
  root    /Data/webapps/www.aslibra.com;

  location /book/ {
    if (!-e $request_filename) {
      rewrite ^/book/(.*)$ /book/index.php/$1 last;
    }
  }
  location /book/index.php {
    fastcgi_pass   127.0.0.1:9000;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME    /Data/webapps/www.aslibra.com/book/index.php;
  }
}


我们还需要避免类似以下地址异常:

/book/?test 404 查询字符会查找test的control
/book/&test 错误 The URI you submitted has disallowed characters.

总体而言,是查询字符的问题,我们可以有两种方式处理:

方式一:在codeIgniter处理之前避免

我们定义系统使用REQUEST_URI来处理mvc参数,不修改系统的文件,我们修改自定义的文件

文件 application/config/config.php
指定为REQUEST_URI方式处理,不是用auto,auto方式会判断查询字符

| 'AUTO'      Default - auto detects
| 'PATH_INFO'    Uses the PATH_INFO
| 'QUERY_STRING'  Uses the QUERY_STRING
| 'REQUEST_URI'    Uses the REQUEST_URI
| 'ORIG_PATH_INFO'  Uses the ORIG_PATH_INFO
|
*/
$config['uri_protocol']  = "REQUEST_URI";


文件 index.php
我们可以直接砍掉查询字符,保证参数不受影响

//处理查询字符
$url = explode('?', $_SERVER['REQUEST_URI']);
$url = explode('&', $url[0]);
$_SERVER['REQUEST_URI'] = $url[0];

/*
|---------------------------------------------------------------
| LOAD THE FRONT CONTROLLER
|---------------------------------------------------------------
|
| And away we go...
|
*/
require_once BASEPATH.'codeigniter/CodeIgniter'.EXT;


方式二:发生错误之后调整

发生404错误时,我们自动跳转到相应的地址,比如去掉后面 ?xxxx 和 &xxxx

文件 application/errors/error_404.php

<?php
$url = explode('?', $_SERVER['REQUEST_URI']);
$url = explode('&', $url[0]);
if($url[0] != $_SERVER['REQUEST_URI']){
  echo "<meta http-equiv=\"refresh\" content=\"0;url=$url[0]\">";
}
?>
</head>


在 error_general.php 里也可以这样加一样的代码。

参考资料:

1 不错的nginx配置方式,本文有参考: CodeIgniter Nginx Rewrite Rule
2 CodeIgniter URLs & Nginx
3 lighttpd rewrite rule && apache mod_rewrite
分享一段代码,平时在使用的
// code from http://www.aslibra.com/
// by hqlulu
// replace <img (any code) src="(pic url)">
// to <img src="(pic url)">

function parse_img ( $content ) {
  preg_match_all ("/<img[^>]+src=\"(.+)\"[^>]*>/isU",
    $content,
    $out, PREG_PATTERN_ORDER);

  foreach($out[1] as $k=>$v){
    $content = str_replace($out[0][$k], '<img src="'.$out[1][$k].'">', $content);
  }

  return $content;
}


清理img标签里的其它属性,保留src,如果要清理别的,自行修改即可
Tags:
codeIgniter我用过一下,觉得比较的理想,很适合做开发,一个很小巧的php的MVC框架。
由于是一个框架模式,所以样例代码拿过来是很容易看清楚程序架构的,也很容易参考,这比自己写的程序要好很多,至少你很容易找到每个代码的功能和位置。

碰到一个问题:

apache里面可以这样做rewrite

<VirtualHost *:80>
    ServerName    www.aslibra.com
    DocumentRoot  F:\WebsiteLocal\www.aslibra.com
    RewriteEngine On
    RewriteRule   ^/(topic|user)  /index.php$0
    #RewriteRule   ^/(topic|user)  /index.php?$0
</VirtualHost>


两种写法都可以让index.php处理此链接,而第一种是最好的,用户输入查询也没事,比如 /topic?test=ds
第二种写法就不行了,会出现错误,地址匹配有特殊字符
但对于nginx的服务器,是不能那样写的,如果按第一种写法,会出现404错误,当作目录了
如果是lighttpd,那应该和apache类似,没有问题。

location ~^/(topic|user) {
        rewrite ^/(.*)  /index.php?/$1 last;
}


出现的错误是:

引用
An Error Was Encountered
The URI you submitted has disallowed characters.


出自(系统库文件URI.php):

function _filter_uri($str)
{
  if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
  {
    // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
    // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
    if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str))
    {
      show_error('The URI you submitted has disallowed characters.', 400);
    }
  }

  // Convert programatic characters to entities
  $bad  = array('$',     '(',     ')',     '%28',     '%29');
  $good  = array('&#36;',  '&#40;',  '&#41;',  '&#40;',  '&#41;');

  return str_replace($bad, $good, $str);
}


看代码,我们可以设置config里面 enable_query_strings 为TRUE
这次会得到什么结果:

引用
404 Page Not Found
The page you requested was not found.


这说明已经过了检查地址,到了路由这一部分了,这个错误是找不到相应的class/method所导致的
重要的URI处理是在 _fetch_uri_string 函数里面,调用这个过滤器是在路由控制里面:

从Router.php里面找到(大概90行)

// Fetch the complete URI string
$this->uri->_fetch_uri_string();
echo $this->uri->uri_string."<hr>"; //检查


我们可以看到路由取出来的地址是什么,比较两种方式
设置为:

$config['uri_protocol']  = "AUTO";
$config['enable_query_strings'] = TRUE;


测试地址为: /topic/test?site=aslibra.com
理想状态应该是进入 /topic/test

第一种情况,取得的uri为 site,这错的比较离谱
第二种为 /topic,检查server变量
引用
[QUERY_STRING] => /topic
    [REQUEST_URI] => /topic/test/?site=aslibra.com
    [SCRIPT_NAME] => /topic/test/
    [PHP_SELF] => /topic/test/
    [REQUEST_TIME] => 1259512731
    [argv] => Array
        (
            [0] => /topic
        )

    [argc] => 1
)


都发生了错误,修改auto为REQUEST_URI应该可以有救
对于这个是支持,因为有正常的class和method,但如果是一级参数,那就出错了,比如
/topic/?site=aslibra.com

这种情况最好的解决办法是钩子处理,在系统开始的时候把查询字符都忽略了
或者,在index.php调用CI之前,就去掉,比如

//code from http://aslibra.com/
$tmp = explode('?',$_SERVER['REQUEST_URI']);
$_SERVER['REQUEST_URI'] = $tmp[0];


钩子方式的解决办法:

//配置里 $config['enable_hooks'] = TRUE;

//config/hooks.php
$hook['pre_system'] = array(
                                'class'    => 'Uri',
                                'function' => 'fix',
                                'filename' => 'Uri.php',
                                'filepath' => 'hooks',
                                'params'   => ''
                                );


新建 hooks/Uri.php
<?php
//code from http://aslibra.com/
class Uri{
  
  function fix(){
    $tmp = explode('?',$_SERVER['REQUEST_URI']);
    $_SERVER['REQUEST_URI'] = $tmp[0];
  }
}
?>


那修改auto为REQUEST_URI应该可以,查询字符支持可以不支持了
分页: 8/20 第一页 上页 3 4 5 6 7 8 9 10 11 12 下页 最后页 [ 显示模式: 摘要 | 列表 ]

阅读推荐

服务器相关推荐

开发相关推荐

应用软件推荐