PHP網站開發遇到的中文編碼

2020-12-17 站長之家

PHP程序設計中中文編碼問題曾經困擾很多人,導致這個問題的原因其實很簡單,每個國家(或區域)都規定了計算機信息交換用的字符編碼集,如美國的擴展 ASCII 碼, 中國的 GB2312-80,日本的 JIS 等。作為該國家/區域內信息處理的基礎,字符編碼集起著統一編碼的重要作用。字符編碼集按長度分為 SBCS(單字節字符集),DBCS(雙字節字符集)兩大類。早期的軟體(尤其是作業系統),為了解決本地字符信息的計算機處理,出現了各種本地化版本(L10N),為了區分,引進了 LANG, Codepage 等概念。但是由於各個本地字符集代碼範圍重疊,相互間信息交換困難;軟體各個本地化版本獨立維護成本較高。因此有必要將本地化工作中的共性抽取出來,作一致處理,將特別的本地化處理內容降低到最少。這也就是所謂的國際化(118N)。各種語言信息被進一步規範為 Locale 信息。處理的底層字符集變成了幾乎包含了所有字形的 Unicode。

現在大部分具有國際化特徵的軟體核心字符處理都是以 Unicode 為基礎的,在軟體運行時根據當時的ocale/Lang/Codepage 設置確定相應的本地字符編碼設置,並依此處理本地字符。在處理過程中需要實現 Unicode 和本地字符集的相互轉換,甚或以 Unicode 為中間的兩個不同本地字符集的相互轉換。這種方式在網絡環境下被進一步延伸,任何網絡兩端的字符信息也需要根據字符集的設置轉換成可接受的內容。

資料庫中的字符集編碼問題

流行的關係資料庫系統都支持資料庫字符集編碼,也就是說在創建資料庫時可以指定它自己的字符集設置,資料庫的數據以指定的編碼形式存儲。當應用程式訪問數據時,在入口和出口處都會有字符集編碼的轉換。對於中文數據,資料庫字符編碼的設置應當保證數據的完整性。GB2312、GBK、UTF-8 等都是可選的資料庫字符集編碼;當然我們也可以選擇 ISO8859-1 (8-bit),只是我們得在應

用程序寫數據之前先將 16Bit 的一個漢字或 Unicode 拆分成兩個 8-bit 的字符,讀數據之後也需要將兩個字節合併起來,同時還要判別其中的 SBCS 字符,因此我們並不推薦採用 ISO8859-1 作為資料庫字符集編碼。這樣不但沒有充分利用資料庫自身的字符集編碼支持,而且同時也增加了編程的複雜度。編程時,可以先用資料庫管理系統提供的管理功能檢查其中的中文數據是否正確。

PHP 程序在查詢資料庫之前,首先執行 mysql_query("SET NAMES xxxx"); 其中 xxxx 是你網頁的編碼(charset=xxxx),如果網頁中 charset=utf8,則 xxxx=utf8,如果網頁中 charset=gb2312,則xxxx=gb2312,幾乎所有 WEB 程序,都有一段連接資料庫的公共代碼,放在一個文件裡,在這文件裡,加入 mysql_query("SET NAMES xxxx") 就可以了。

SET NAMES 顯示客戶端發送的 SQL 語句中使用什麼字符集。因此,SET NAMES 'utf-8' 語句告訴伺服器「將來從這個客戶端傳來的信息採用字符集 utf-8」。它還為伺服器發送回客戶端的結果指定了字符集(例如,如果你使用一個 SELECT 語句,它表示列值使用了什麼字符集)。

定位問題時常用的技巧

定位中文編碼問題通常採用最笨的也是最有效的辦法―在你認為有嫌疑的程序處理後列印字符串的內碼。通過列印字符串的內碼,你可以發現什麼時候中文字符被轉換成 Unicode,什麼時候Unicode 被轉回中文內碼,什麼時候一個中文字成了兩個 Unicode 字符,什麼時候中文字符串被轉成了一串問號,什麼時候中文字符串的高位被截掉了……

取用合適的樣本字符串也有助於區分問題的類型。如:"aa啊 aa?@aa" 等中英相間,GB、GBK特徵字符均有的字符串。一般來說,英文字符無論怎麼轉換或處理,都不會失真(如果遇到了,可以嘗試著增加連續的英文字母長度)。

解決各種應用的亂碼問題

1) 使用 標籤設置頁面編碼

這個標籤的作用是聲明客戶端的瀏覽器用什麼字符集編碼顯示該頁面,xxx 可以為 GB2312、GBK、UTF-8(和 MySQL 不同,MySQL 是 UTF8)等等。因此,大部分頁面可以採用這種方式來告訴瀏覽器顯示這個頁面的時候採用什麼編碼,這樣才不會造成編碼錯誤而產生亂碼。但是有的時候我們會發現有了這句還是不行,不管 xxx 是哪一種,瀏覽器採用的始終都是一種編碼,這個情況我後面會談到。

請注意, 是屬於 HTML 信息的,僅僅是一個聲明,僅表明伺服器已經把 HTML 信息傳到了瀏覽器。

2) header("content-type:text/html; charset=xxx");

這個函數 header() 的作用是把括號裡面的信息發到 http 標頭。如果括號裡面的內容為文中所說那樣,那作用和 標籤基本相同,大家對照第一個看發現字符都差不多的。但是不同的是如果有這段函數,瀏覽器就會永遠採用你所要求的 xxx 編碼,絕對不會不聽話,因此這個函數是很有用的。為什麼會這樣呢?那就得說說 http 標頭和 HTML信息的差別了:

http 標頭是伺服器以 http 協議傳送 HTML 信息到瀏覽器前所送出的字串。而 標籤是屬於 HTML 信息的,所以 header() 發送的內容先到達瀏覽器,通俗點就是 header() 的優先級高於 (不知道可不可以這樣講)。假如一個 php 頁面既有header("content-type:text/html;charset=xxx"),又有,瀏覽器就只認前者 http 標頭而不認 meta 了。當然這個函數只能在 php 頁面內使用。

同樣也留有一個問題,為什麼前者就絕對起作用,而後者有時候就不行呢?這就是接下來要談的Apache 的原因了。

3) AddDefaultCharset

Apache 根目錄的 conf 文件夾裡,有整個 Apache 的配置文檔 httpd.conf。

用文本編輯器打開 httpd.conf,第 708 行(不同版本可能不同)有 AddDefaultCharset xxx,xxx為編碼名稱。這行代碼的意思:設置整個伺服器內的網頁文件 http 標頭裡的字符集為你默認的 xxx字符集。有這行,就相當於給每個文件都加了一行 header("content-type:text/html; charset=xxx")。這下就明白為什麼明明 設置了是 utf-8,可瀏覽器始終採用 gb2312 的原因。

如果網頁裡有 header("content-type:text/html; charset=xxx"),就把默認的字符集改為你設置的字符集,所以這個函數永遠有用。如果把 AddDefaultCharset xxx 前面加個"#",注釋掉這句,而且頁面裡不含 header("content-type…"),那這個時候就輪到 meta 標籤起作用了。

下面列出以上的優先順序:

.. header("content-type:text/html; charset=xxx")

.. AddDefaultCharset xxx

..

如果你是 web 程式設計師,建議給你的每個頁面都加個header("content-type:text/html;charset=xxx"),這樣就可以保證它在任何伺服器都能正確顯示,可移植性也比較強。

4) php.ini 中的 default_charset 配置:

php.ini 中的 default_charset = "gb2312" 定義了 php 的默認語言字符集。一般推薦注釋掉此行,讓瀏覽器根據網頁頭中的 charset 來自動選擇語言而非做一個強制性的規定,這樣就可以在同臺伺服器上提供多種語言的網頁服務。

結束語

其實 php 開發中的中文編碼並沒有想像的那麼複雜,雖然定位和解決問題沒有定規,各種運行環境也各不盡然,但後面的原理是一樣的。了解字符集的知識是解決字符問題的基礎。不過,隨著中文字符集的變化,不僅僅是 php 編程,中文信息處理中的問題還是會存在一段時間的

相關焦點

  • PHP 開發中的中文編碼問題
    首頁 > 語言 > 關鍵詞 > php最新資訊 > 正文 PHP 開發中的中文編碼問題
  • 實例解析:PHP程序開發中的中文編碼問題
    PHP程序設計中中文編碼問題曾經困擾很多人,導致這個問題的原因其實很簡單,每個國家(或區域)都規定了計算機信息交換用的字符編碼集,如美國的擴展 ASCII 碼, 中國的 GB2312-80,日本的 JIS 等。作為該國家/區域內信息處理的基礎,字符編碼集起著統一編碼的重要作用。
  • PHP開發編碼規範特麼要注意
    開發團隊根據自己的實際情況,可以對本規範進行補充或裁減。2 整體要求技術部php開發規範將參照PEAR的規範,基本採用PEAR指定的規範,在其基礎上增加、修改或刪除部分適合具體開發環境的規範。本規範只針對PHP開發過程中編碼的規範,對於PHP開發項目中文件、目錄、資料庫等方面的規範,將不重點涉及。
  • php中文亂碼問題的終極解決方案匯總
    在開始之前,我們先來談談為什麼會出現中文亂碼?一般來說,亂碼的出現有2種原因,一種是由於編碼(charset) 設置錯誤,導致瀏覽器以錯誤的編碼來解析,從而出現了滿屏亂七八糟的「天書」,第二種就是文件被以錯誤的編碼打開,然後保存,比如一個文本文件原先是GB2312編碼的,卻以UTF-8編碼打開再保存,就會出現亂碼的問題。本篇文章,就帶大家了解一下,怎麼解決php中亂碼的問題。
  • 2019年網站開發學習PHP還是JAVA?哪個好?
    源 / php中文網      源 / www.php.cn對於剛接觸IT的同學們來說,學習PHP還是Java?哪個好?的確是一個能讓人產生選擇困難症的問題。而即便是專業的編程人員也會面臨同樣的問題,俗話說技多不壓身。那麼想要在PHP和Java中進行抉擇,你就需要了解他們各自的優勢及不足之處。
  • PHPCMS開發文檔裡看到PHP編碼規範
    註:這是從PHPCMS開發文檔裡看到編碼規範,雖名為PHPCMS的開發規範,但我覺得所有的PHP編程都該如此。寫了那麼多PHP,很多編碼對照這規範都感覺欠缺很多,今後一定要對照糾正。Phpcms 編碼規範1. 引言…. 22. 適用範圍…. 23.
  • 基於MySQL資料庫的UTF8中文網站全文檢索的實現
    基於MySQL資料庫的UTF8中文網站全文檢索的實現 現在的網際網路上,很多網站都提供了全文搜索功能,瀏覽者可以通過輸入關鍵字或者是短語來搜索特定的資料。
  • PHP中文字符串反轉編碼錯誤解決方式
    php echo strrev("I love China!"); ?>6、運行結果!php echo strrev("I love China"); ?>運行結果:ianihC evol I結論:可以正常將字符串進行轉化,無任何異常。
  • PHP編碼風格規範詳細介紹
    由於PHP的靈活性,很多人寫起代碼來也不講求一個好的代碼規範,使得本就靈活的PHP代碼看起來很亂,其實PSR規範中的PSR-1和PSR-2已經定義了在PHP編碼中的一些規範
  • 如何正確運用PHP json_encode函數進行中文轉換
    如何正確運用PHP json_encode函數進行中文轉換 json_encode 和 json_decode這兩個函數的具體用法 網上有很多相關的文章 ,本文主要介紹
  • php常量是什麼?它和變量有什麼區別?
    本篇將介紹php常量是什麼?它和變量有什麼區別?有興趣的朋友可以了解一下!一、前言php是一門很受歡迎的程式語言之一,它的語法簡單易學,迎來了一大批自學者,小編也是其中之一。小編自學php學了四個多月吧!雖然算不上精通,但是也算得上小有成就,獨立開發中小型網站還是不成問題的。
  • 培養自己的php編碼規範,養成一個好習慣
    我們寫代碼的時候,一個好的編碼規範,對我們來說能夠起到很多意向不到的效果。至少會有一下的好處:1、提高我們的編碼效率。整齊劃一的代碼方便我們進行複製粘貼嘛!2、提高代碼的可讀性。3、顯示我們專業。別人看到了我們的代碼,發現整個代碼的書寫流程都整齊劃一,瞬間逼格就上去了!4、方便團隊協同工作。
  • php中如何對變量進行json編碼和解碼? - 老羅說教育
    在php網站的製作過程中,前臺和後臺界面的交互,經常要涉及數據的交互,而數據的交互,很多都是由json來封裝數據的,然後再後端通過解碼,將json格式的數據轉換成數組或者是其他形式的數據格式來處理,所以,對json的解碼和編碼對於數據交互是非常重要的,下面我們就來了解一下php中如何對變量進行
  • 1.PHP網站後門
    一、前言一般的,利用能夠執行系統命令、加載代碼的函數,或者組合一些普通函數,完成一些高級間諜功能的網站後門的腳本
  • php字符串常用處理,運算符和幾個常用的字符串函數
    小編自學php大概花了3個多月,說不上精通,但是還算小有成就,獨立開發中小型網站還是不成問題的。小編大學是計算機系的,學過很多計算機語言(c語言、java、彙編、c#等),所以自學php就相當的快。為了讓更多的php學習者了解到php更多的知識,小編結合自己的理解和自學時所做的筆記,整理了一些知識點。藉助百家號這個大平臺分享給大家,希望對大家有所幫助!
  • (實用篇)多個PHP中文字符串截取函數
    以下是文章分享1群,由於群人數已超過300,不能掃碼進群,這個任務呢,就由小篇來拉你們進群了,掃描下面二維碼,加小篇好友~字符串截取是一個非常常見的編程任務,而往往帶中文的字符串截取會經常用到。>截取GB2312中文字符串:<?
  • 如何讓網站不同頁面調用不同PHP版本
    寫在前面我目前的網站開發環境是用lampp搭建的(PHP7+Apache+MySQL)。最近在用一個開源的網頁工具,但是該工具是php5.3寫的。。。那麼如何使不同的網站調用不同的php版本呢?可以使用寶塔一鍵安裝開發環境,在寶塔中是可以隨意切換php版本的,或者是PHPstudy也可以。但是我並沒有這麼做。。。因為我調試nginx到一半才發現可以用寶塔。。。
  • encode 和decode——帶你探索編碼與解碼的世界
    GB2312編碼是在ASCII編碼基礎上擴展來的,在1980年由中國國家標準總局發布,其中最主要的變化就是引入了簡體中文的編碼,一共容納了包括簡體中文在內的6000多個字符。僅僅是簡體中文肯定是不夠用的,1995年,GBK編碼在GB2312編碼的基礎上進行擴充,加入了繁體中文和一些符號的編碼,擴充後容納了20000多個字符。
  • php數據類型有哪些?
    本篇將介紹php數據類型有哪些?有興趣的朋友可以了解一下!一、前言php是一門很受歡迎的程式語言,而且簡單易學,因此迎來了很多自學者,小編也是其中一個。每一門程式語言都有自己的數據類型,php也不例外,也有自己的數據類型。但是php和其它語言不一樣,它是一門弱語言,在聲明變量的時候不需要指定數據類型。
  • php語言是什麼?學好php需要掌握什麼?
    php容易學習,使用廣泛,主要適用於Web開發領域,PHP是Hypertext Preprocessor的簡稱,用中文翻譯過來的意思是「超文本預處理器」它是一種通用開源腳本語言。php的語法有C、Java和Perl的特點也有自創的特點,經過了24年的發展php從最初的1.0發展7.0版本,php的功能已經發展非常強大,php是適合編程零基礎入手的一門程式語言,下面為大家介紹一下學習php需要經過哪些過程?