不设Content-Type charset会导致浏览器按ISO-8859-1或本地编码解析,中文显示为问号或方块;必须在任何输出前用header('Content-Type: text/html; charset=utf-8')声明,且PHP文件需UTF-8无BOM、数据库连接与内部编码同步为UTF-8。

PHP输出HTML时没设Content-Type charset会怎样
浏览器收不到明确的字符编码声明,默认按ISO-8859-1或系统本地编码解析,中文就变问号或方块。哪怕PHP文件本身是UTF-8,echo "你好" 也会乱码——因为HTTP响应头里缺 Content-Type: text/html; charset=utf-8。
- 用
header('Content-Type: text/html; charset=utf-8');必须在任何输出(包括空格、BOM、echo)之前调用,否则报Warning: Cannot modify header information - 如果用了模板引擎或框架(如Laravel、ThinkPHP),通常在配置里统一设编码,不用手写
header(),但得确认它真生效了 - 检查是否PHP文件开头有BOM:用编辑器(如VS Code)切换到“UTF-8无BOM”保存,否则BOM会被当成输出,
header()就失效
PHP文件自身编码和数据库连接编码要同步
光设HTTP头不够。PHP脚本读取的字符串、查询数据库返回的数据,都依赖底层编码一致。常见组合是:PHP文件存为UTF-8无BOM + MySQL连接指定utf8mb4 + 表字段用utf8mb4_unicode_ci。
- MySQLi连接时加
$mysqli->set_charset('utf8mb4');,PDO则在DSN里加;charset=utf8mb4 -
mysql_*函数已废弃,别用mysql_query("SET NAMES utf8")—— 它只设客户端编码,不解决排序和四字节emoji问题 - 用
mb_internal_encoding('UTF-8')统一PHP内部字符串函数(如mb_strlen)的默认编码,避免多字节处理出错
PHP CLI脚本也得管编码?
命令行下没有HTTP头,但终端显示、文件写入、JSON输出仍可能乱码。尤其Windows cmd默认GBK,echo "中文" 直接变乱码。
- Windows上运行前先执行
chcp 65001切到UTF-8(临时生效) - PHP里用
mb_convert_encoding($str, 'UTF-8', 'GBK')做兼容转换,但更稳妥的是让输入源(如CSV、API响应)本身就是UTF-8 - 生成JSON时务必用
json_encode($data, JSON_UNESCAPED_UNICODE),否则中文被转成\u4f60\u597d
怎么养成“默认加编码”的习惯
靠记容易漏,靠工具更可靠。不是每次写header(),而是把编码设置变成骨架的一部分。
立即学习“PHP免费学习笔记(深入)”;
- 所有新PHP文件模板第一行加:
(注意无空行) - IDE设置默认新建PHP文件编码为UTF-8无BOM,并开启“保存时自动转换”
- 用PHP-CS-Fixer或PHP_CodeSniffer配规则,自动检测缺失
header('Content-Type')或非UTF-8文件编码 - 上线前必查三点:HTTP响应头有没有
charset=utf-8、数据库连接是否utf8mb4、PHP文件是否含BOM
真正卡住人的往往不是某一行代码,而是HTTP头、文件编码、数据库连接、终端环境这四个地方有一处没对齐。盯住这四点,比背“加个header就行”管用得多。











