目录
 字符串的定义和使用
 字符串转换
 PHP 字符串的本质
 多字节字符串
 Zend Multibyte
首页 后端开发 php教程 PHP中的字符串、编码、UTF-8

PHP中的字符串、编码、UTF-8

Jan 23, 2017 pm 02:58 PM

最近看了不少编码方面的文章,所以分二篇博文说下“PHP、字符串、编码、UTF-8”相关知识,本篇博文是上半部分,分为四大块内容,分别是“字符串的定义和使用”、“字符串转换”、“PHP 字符串的本质”、“多字节字符串”。上半部分比较基础、。

 字符串的定义和使用

  PHP 中能够通过四种方法设置字符串:

  单引号字符串

  单引号字符串类似于 Python 中的原始字符串,也就是说单引号字符串没有变量解析功能和特殊字符转义功能。比如$str='hello\nworld',其中的\n并没有换行功能。

  双引号字符串

  双引号字符串具备单引号字符串没有的变量解析功能和特殊字符转义功能。

  个人对于十六进制和八进制的字符串特殊转义很感兴趣,特别补充:

\[0-7]{1,3} #八进制表达方式
\x[0-9A-Fa-f]{1,2} #十六进制表达方式
登录后复制

  heredoc

  这种表达式类似于 Python 中的长字符串,能够定义包含多行的字符串。其语法定义很严格,使用起来需要注意。

$str=<<<EOD
hello\n
world
EOD;
登录后复制

  Nowdoc

  Nowdoc类似于单引号字符串,不会解析变量。比较适合定义一大段文本且无需对其中的特殊字符进行转义。

  变量解析

  PHP字符串最强大的部分就是变量解析,可以在运行时根据上下文解析变量(这才是解释型语言),可以产生很多妙用。

  简单的变量解析就是在字符串中可以包含“变量”,“数组”,“对象属性”,复杂的语法规则就是使用{}符号来进行操作(组成一个表达式)。

  通过一个例子看看变量解析的强大之处

class beers {
    const softdrink = &#39;softdrink&#39;;
    public static $ale = &#39;ale&#39;;
    public $data = array(1,3,"k"=>4);
}
 $softdrink = "softdrink";
$ale = "ale";
$arr = array("arr1","arr2","arr3"=>"arr4","arr4"=>array(1,2));
$arr4 = "arr4";
$obj = new beers;
echo "line1:{$arr[1]}\n";
echo "line2:{$arr[&#39;arr4&#39;][0]}\n";
echo "line3:{$obj->data[1]}\n";
echo "line4:{${$arr[&#39;arr3&#39;]}}\n";
echo "line5:{${$arr[&#39;arr3&#39;]}[1]}\n";
echo "line6:{${beers::softdrink}}\n";
echo "line7:{${beers::$ale}}\n";
登录后复制

 字符串转换

  PHP 语言比 Python 简单的另外一个原因就是类型的隐式转换,会简化很多操作,这里通过字符串转换来说明。

  字符串类型强制转换

$var = 10 ;
$dvar = (string)$var ;
echo $dvar . "_" . gettype($dvar);
登录后复制

  strval()函数是获取变量的字符串值:

$var = 10.2 ;
$dvar = strval($var) ;
echo gettype($var) . "_" . $dvar . "_" . gettype($dvar);
登录后复制

  settype()函数是设置变量的类型:

$str = "10hello";
settype($str, "integer");
echo $str ;
登录后复制

  在强制类型转换过程中,将其他类型的值转换为字符串的时候会遵循一定的规则,比如一个布尔值 boolean 的 TRUE 被转换成 string 的 “1”。相关规则最好还是理解下。

  自动类型转换

  上面的二个转换属于显示转换,而更要关注的是自动类型转换,在一个需要字符串的表达式中,会自动转换为类型,具体见例子:

$bool = true;
$str = 10 + "hello"
echo $bool . "_" . $str ;
登录后复制

 PHP 字符串的本质

  引用 PHP 文档的解释:

PHP 中的 string 的实现方式是一个由字节组成的数组再加上一个整数指明缓冲区长度。并无如何将字节转换成字符的信息,由程序员来决定。字符串由什么值构成没有限制,包括值为 0 的字节可以出现在字符串的任何位置。

PHP并不特别指明字符串的编码,那字符串到底是怎样编码的呢,这取决于程序员。字符串会按照 PHP 文件的编码来对字符串进行编码。比如你的文件编码是 GBK,那么你代码内容都是 GBK的。

  补充二进制安全这个概念,其值为 0 (NULL)的字节可以处于字符串任何位置,而 PHP 的部分非二进制函数底层是调用的 C 函数,会把 NULL 后面的字符忽略。

 只要 PHP 的文件编码是能兼容 ASCII 的,那么字符串操作就可以很好的被处理。但是字符串操作本质上还是 Native 的(不管文件编码是什么),所以在使用的时候需要注意:

  • 某些函数假定字符串是以单字节编码的,但并不需要将字节解释为特定的字符。比如 sbustr() 函数。

  • 很多函数是需要显示的传递编码参数,不然会从 PHP.INI 文件中获取默认值,比如 htmlentities() 函数。

  • 还有一些函数和本地区域有关,这些函数也只能是单字节操作的。

  一般情况下,虽然 PHP 内部不支持 Unicode 字符,但是支持 UTF-8 编码,绝大部分情况下不会有什么问题,但是下列的情况可能就处理不了了:

  • 非 UTF-8 编码字符串如何进行转换

  • 一个 UTF-8 编码的网页,但是用户在提交表单的时候,可能使用 GBK 的编码(不遵守 meta tag)

  • 一个 UTF-8 编码的 PHP 文件,使用 strlen("中国")返回的是 6 而不是实际的字符数(2)

  那么如何解决该问题呢? PHP 提供了 mbstring 扩展 !

 多字节字符串

  mbstring 扩展默认不是打开的,安装的时候需要 --enable-mbstring。

  我们首先看看 PHP.INI 中对于 mbstring 指令的配置,花了好久才逐步明白。

  • mbstring.language 这个参数我就理解为 UTF-8 了

  • mbstring.internal_encoding 这个编码和 PHP 文件编码没有关系,只是在大部分 mbstring 函数里面需要指定待处理字符串的编码,假如不显示指定,默认就获取该参数的值,该参数的值在高版本 PHP 中用 default_charset 参数代替了。

  • mbstring.http_input 该参数指定 HTTP input 的默认编码(不包含 GET 参数)。一般和 HTML 页面的编码保持一致,该参数的值用 default_charset 参数代替。

  • mbstring.http_output 该参数误导我了,HTTP output 是什么,PHP 输出不就是页面,怎么会有这概念?

  • mbstring.encoding_translation,这个参数重点说下,默认是关闭的,假如打开,PHP 会对 POST 变量和上传文件的名称自动转换编码为 mbstring.internal_encoding 指定的值,不过我没有试验过,大家可以上传一个中文名的文件。建议关闭,让程序员来处理相关问题。

  后面看看 mbstring 扩展的一些函数:

  • mb_http_input():检测 HTTP input 字符编码,觉得对于文件上传的文件名有必要处理。

  • mb_convert_encoding():比较常用的函数,注意第三个参数。

  • mb_detect_order():设置/获取字符编码的检测顺序。

  • mb_list_encodings():返回系统支持的编码列表。

  重点说明下:PHP 文件支持的编码有一定要,要兼容 ASCII。

  但是不要使用 BIG-5 作为 PHP 文件编码,尤其字符串以 identifiers 或 literals 形式出现,假如实在 PHP 文件编码要是 BIG-5,那么对于输入输出的内容尽量转换为 UTF-8。

 Zend Multibyte

  最后说下 Zend Multibyte 这个概念,理解的不是特别深刻,首先不要和 mbstring 扩展混在一块。 Zend Multibyte 模式默认是关闭的,可以通过 zend.multibyte 指令打开。然后通过 declare() 函数来指定 PHP 解析器的编码。

  那这个指令出现的意义是什么?上面说过 PHP 文件的编码需要是兼容 ASCII 的,那么类似于 BIG-5 这样的非兼容 ASCII 编码怎么办,可以通过这个指令来操作,当 PHP 解析器读取 mbstring.script_encoding 编码并用该编码来解析 PHP 文件。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

会话如何劫持工作,如何在PHP中减轻它? 会话如何劫持工作,如何在PHP中减轻它? Apr 06, 2025 am 12:02 AM

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

在PHPStorm中如何进行CLI模式的调试? 在PHPStorm中如何进行CLI模式的调试? Apr 01, 2025 pm 02:57 PM

在PHPStorm中如何进行CLI模式的调试?在使用PHPStorm进行开发时,有时我们需要在命令行界面(CLI)模式下调试PHP�...

描述扎实的原则及其如何应用于PHP的开发。 描述扎实的原则及其如何应用于PHP的开发。 Apr 03, 2025 am 12:04 AM

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

如何在系统重启后自动设置unixsocket的权限? 如何在系统重启后自动设置unixsocket的权限? Mar 31, 2025 pm 11:54 PM

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...

解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

框架安全功能:防止漏洞。 框架安全功能:防止漏洞。 Mar 28, 2025 pm 05:11 PM

文章讨论了框架中的基本安全功能,以防止漏洞,包括输入验证,身份验证和常规更新。

See all articles