內容導讀:
- PHP 標記
- 編碼規範
- 程式碼註釋
- 常量
- 變數
- 資料型別
- 運算子
1.PHP 標記
PHP 和其他幾種 Web 語言一樣,都是使用一對標記對將 PHP 程式碼部分包含起來,以便和 html 程式碼相區分。當解析一個檔案時,PHP 會尋找起始和結束標記,也就是 <?php
和 ?>
,這告訴 PHP 開始和停止解析二者之間的程式碼。此種解析方式使得 PHP 可以被嵌入到各種不同的文件中去,而任何起始和結束標記之外的部分都會被 PHP 解析器忽略。
PHP 中一共有四種標記風格,其中指令碼風格和ASP 風格在 PHP 7 中已經廢止。簡短風格需要在 php.ini 中開啟 short_open_tag
開關或者 CLI 中使用了配置選項 --enable-short-tags
。
1.1 XML
<?php
echo "這是XML風格的標記";
?>
XML風格的標記是本書所使用的標記,也是推薦使用的標記,伺服器不能禁用。該風格的標記在 XML、XHTML 中都可以使用。
1.2 簡短風格
<? echo '這是簡短風格的標記'; ?>
1.3 指令碼風格
<script language="php">
echo '這是指令碼風格的標記';
</script>
1.4 ASP 風格
<%
echo '這是ASP風格的標記';
%>
1.5 需要注意
如果檔案內容是純 PHP 程式碼,最好在檔案末尾刪除 PHP 結束標記。這可以避免在 PHP 結束標記之後,萬一意外加入了空格或者換行符,會導致 PHP 開始輸出這些空白,而指令碼中此時並無輸出的意圖。
<?php
echo "Hello world";
echo "Last statement";
// 指令碼至此結束,並無 PHP 結束標記
2.編碼規範
2.1 書寫規範
[1].縮排
使用製表符(鍵)縮排,縮排單位為 4 個空格。編輯器中統一設定Tab 轉換成 4 個空格。
[2].大括號{}
有兩種大括號放置規則是可以使用的:
if ($expr)
{
…
}
或者
if ($expr){
…
}
[3].關鍵字、小括號、函式、運算子
- 小括號和關鍵字間用空格隔開。如:
if ($expr){ //if和“(”之間有一個空格
…
}
- 小括號和函式要緊貼在一起。以便區分關鍵字和函式。如:
round($num) //round和“(”之間沒有空格
- 運算子與兩邊的變數或表示式要有一個空格(字元連線運算子“.”除外)。如:
while ($boo == true){ //$boo和“==”,true和“==”之間都有一個空格
…
}
當程式碼段較大時,上、下應當加入空白行,兩個程式碼塊之間只使用一個空行,禁止使用多行。
儘量不要在 return 返回語句中使用小括號。如:
return 1; //除非是必要,否則不需要使用小括號
2.2 命名規則
[1].類命名
- 使用大寫字母作為詞的分隔,其他的字母均使用小寫。
- 名字的首字母使用大寫。
- 不要使用下劃線(‘_’)
如:Name、SuperMan、BigClassObject
[2].類屬性命名
- 屬性命名應該以字元“m”為字首。
- 字首“m”後採用與類命名一致的規則。
- “m”總是在名字的開頭起修飾作用,就像以“r”開頭表示引用一樣
如:mValue、mLongString
[3].方法命名
方法的作用都是執行一個動作,達到一個目的。所以名稱應該說明方法是做什麼。一般名稱的字首和字尾都有一定的規律,如:Is(判斷),Get(得到),Set(設定)。
方法的命名規範和類命名是一致的。
如:
class Example{
$mExam = "";
function SetExam(&$rExam){
…
}
function &rGetExam(){
…
}
}
[4].方法中引數命名
- 第一個字元使用小寫字母。
- 在首字元後的所有字元都按照類命名規則首字元大寫。
如:
class EchoAnyWord{
function EchoWord($firstWord,$secondWord){
…
}
}
[5].變數命名
- 所有字母都使用小寫。
- 使用’_’作為每個詞的分界。
如:
$msg_error;
$chk_pwd;
[6].引用變數
引用變數要帶有“r”字首。如:
class Example{
$mExam = "";
function SetExam(&$rExam){
…
}
function &rGetExam(){
…
}
}
[7].全域性變數全域性變數應該帶字首“g”。如:
$global = $gTest;$global = $g
[8].常量/全域性常量常量/全域性常量,應該全部使用大寫字母,單詞之間用“_’”來分割。如:
define('DEFAULT_NUM_AVE',90);
define('DEFAULT_NUM_SUM',500);
[9].靜態變數靜態變數應該帶字首“s”。如:
static $sStatus = 1;
[10].函式命名所有的名稱都使用小寫字母,多個單詞使用“__”來分隔。如:
function this_good_idea(){
…
}
[11].以上的各種命名規則,可以組合一起來使用。如:
class OtherExample{
$msValue = ""; //該引數既是類屬性,又是靜態變數
}
3.程式碼註釋
註釋即程式碼的解釋和說明,一般放到程式碼的上方或程式碼的尾部。用來說明程式碼或函式的編寫人、功能、時間等。
PHP 支援3種風格的程式註釋。
- C++風格的單行註釋(//)
<?php
echo '使用C++風格'; //這就是C++風格
?>
- C 風格的多行註釋(/…/)
<?php
/*C風格的
多行註釋
*/
echo '只會看到這句話';
?>
注意:多行註釋是不允許進行巢狀操作的。
- Shell 風格的註釋(#)
<?php
echo '這是Shell指令碼風格的註釋'; #這裡的內容是看不到的
?>
注意:在單行註釋中的內容不要出現“?>”標誌,直譯器會認為 PHP 指令碼結束,而去執行“?>”後面的程式碼
4.常量
4.1 宣告和使用常量
常量:可以理解為值不變的量。常量值被定義後,在指令碼的其他任何地方都不能改變。
常量的組成規則:一個常量由英文字母、下劃線和數字組成,但數字不能作為首字母出現。
在 PHP 中使用 define()函式來定義常量,該函式的語法格式為:
/*關鍵字.使用 const 關鍵字定義常量必須處於最頂端的作用區域,因為用此方法是在編譯時定義的。這就意味著不能在函式內,迴圈內以及 if 或 try/catch 語句之內用 const 來定義常量*/
const
bool define ( string name, mixed value [, bool case_insensitive] )
獲取常量的值
- mixed constant(string const_name)
- 使用常量名直接獲取值
判斷常量是否定義:
- bool defined(string constant_name);成功則返回 true,否則返回 false
關於常量的幾點說明:
- 常量前面沒有美元符號($);
- 常量只能用 define() 函式定義,而不能通過賦值語句;
- 常量可以不用理會變數範圍的規則而在任何地方定義和訪問;
- 常量一旦定義就不能被重新定義或者取消定義;
- 常量的值只能是標量。
4.2 預定義常量
常量名 | 功能 |
---|---|
FILE | 預設常量,PHP 程式檔名 |
LINE | 預設常量,PHP 程式行數 |
PHP_VERSION | 內建常量,PHP 程式的版本,如 7.3.12 |
PHP_OS | 內建常量,執行 PHP 解析器的作業系統名稱,如 Windows |
TRUE | 該常量是一個真值(true) |
FALSE | 該常量是一個假值(false) |
NULL | 一個 null 值 |
E_ERROR | 該常量指到最近的錯誤處 |
E_WARNING | 該常量指到最近的警告處 |
E_PARSE | 該常量指到解析語法有潛在問題處 |
E_NOTICE | 該常量為發生不尋常處的提示但不一定是錯誤處 |
注意
常量的值只能是標量
5.變數
5.1 宣告變數
變數是指在程式執行過程中數值可以變化的量。變數通過一個名字(變數名)來標識。系統為程式中的每一個變數分配一個儲存單元,變數名實質上就是計算機記憶體單元的命名。因此,藉助變數名即可訪問記憶體中的資料。
[1]變數定義
PHP 是弱型別語言,使用變數之前不需要宣告變數(PHP 4 之前需要宣告變數),只需為變數賦值即可。變數的語法格式如下:
$變數名稱=變數的值;
[2]變數名規則
- 在 PHP 中的變數名是區分大小寫的。
- 變數名必須是以美元符號($)開始。
- 變數名開頭可以以下劃線開始。
- 變數名不能以數字字元開頭。
- 變數名可以包含一些擴充套件字元(如重音拉丁字母),但不能包含非法擴充套件字元(如漢字字元和漢字字母)。
5.2 變數賦值
[1].直接賦值
直接賦值就是使用“=”直接將值賦給某變數
<?php
$name = value;//value表示值
?>
[2].傳值賦值
傳值賦值就是使用“=”將一個變數的值賦給另一個變數
<?php
$hello="ok";
$test = $hello;
?>
[3].引用賦值
引用賦值是一個變數引用另一個變數的值
<?php
$hello="ok";
$test = &$hello;//注意此處的 & 符號
$test=3;
echo $hello;
?>
5.3 變數作用域
作 用 域 | 說 明 |
---|---|
區域性變數 | 在函式的內部定義的變數,其作用域是所在函式 |
全域性變數 | 被定義在所有函式以外的變數,其作用域是整個 PHP 檔案,但在使用者自定義函式內部是不可用的。如果希望在使用者自定義函式內部使用全域性變數,則要使用 global 關鍵字宣告 |
靜態變數 | 能夠在函式呼叫結束後仍保留變數值,當再次回到其作用域時,又可以繼續使用原來的值。而一般變數是在函式呼叫結束後,其儲存的資料值將被清除,所佔的記憶體空間被釋放。使用靜態變數時,先要用關鍵字static來宣告變數,把關鍵字 static 放在要定義的變數之前 |
超全域性變數 | 它們在一個指令碼的全部作用域中都可用。在函式或方法中無需執行global $variable; 就可以訪問它們。$GLOBALS$_SERVER$_REQUEST$_POST$_GET$_FILES$_ENV$_COOKIE$_SESSION |
5.4 變數的主動銷燬
`void unset(變數);
<?php $hello='ok'; unset($hello); echo $hello;//報錯 ?>
`
5.5 可變變數
可變變數是一種獨特的變數,這種變數的名稱是由另外一個變數的值來確定的,宣告可變變數的方法是在變數名稱前加兩個“$”符號。
語法如下:
$$ 可變變數名稱=可變變數的值;
如:
<?php
$hello="ok";//注意這裡單、雙引號皆可以
$ok="我是字串";
echo $$hello;
?>
5.6常量變數區分
- 常量前沒$
- 常量只能用define()函式定義,不能通過賦值語句定義
- 常量不會理會變數的範圍規則而在任何地方定義和訪問
- 常量一旦定義就不能被重新定義或者取消定義
- 常量的值只能是標量
6.資料型別
6.1 8 種原始型別
- 4 種標量型別
boolean(布林型) integer(整型) float/double(浮點型) string(字串型)
- 兩種複合型別
array(陣列) object(物件)
- 兩種特殊型別
resource(資源) NULL。
6.2 標量型別
6.2.1 布林型
較為常用的資料型別之一,它儲存一個 true 值或者 false 值,其中 true 和 false 是 PHP 的內部關鍵字。通過 boolean 關鍵字程式實現邏輯判斷功能。
其他的資料型別都有布林屬性:
- 整型:為 0 時,其布林值為 false;非零為 true。
- 浮點型:為 0.0 時為 false。否則為 true。
- 字串型:為“”或者字串“0”時為 false,否則為 true;
- 陣列型:不含任何元素時為 false,否則為 true;
- 物件和資源型,永遠為 true;
- NULL 型,永遠為 false;
6.2.2 整型
整型資料型別只能包含整數。在 32 位的作業系統中,有效的範圍是-2^31 ~ 2^31-1。64 位為-2^63^~ 2^63^-1
整型數可以用二、十、八和十六表示。用八進位制前面必須加 0,十六進位制則需要加 0x。二進位制加 0b。
警告
PHP 7 以前的版本,如果向八進位制數傳遞了一個非法數字(即 8 或 9),則後面其餘數字會被忽略。PHP 7 以後,會產生 Parse Error。其他進位制也是一樣!!
6.2.3 浮點型
浮點資料型別用於表示實數。它提供的精度比整數大得多。在 32 位的作業系統中,有效的範圍是 1.7E- 308 ~ 1.7E+308。在 PHP 4.0 以前的版本中,浮點型的標識為 double,也叫做雙精度浮點數,兩者沒有區別。預設有兩種書寫格式:
- 標準格式。如 3.1415 -35.8
- 科學記數法格式:3.58E1 849.72E-3
注意
浮點型的數值只是一個近似值,要儘量避免浮點型數值之間比較大小,因為最後的結果往往是不準確的。
6.2.4 字串型
字串是連續的字元序列,由數字、字母和符號組成。字串中的每個字元只佔用一個位元組。在 PHP 中,有 3 種定義字串的方式,分別是單引號(’)、雙引號(”)和界定符(<<<)。
<?php $a =‘字串’;?>
<?php $a ="字串";?>
<?php
$a= <<<TXT //名字自定,保持上下一致即可。
你好
TXT;
?>
單引號與雙引號區別:
雙引號中所包含的變數會自動被替換成實際數值,而單引號中包含的變數則按普通字串輸出。
使用單引號時,只要對單引號“ ‘ ”進行轉義即可,但使用雙引號(“)時,還要注意“ ” ”、“$”等字元的使用。這些特殊字元都要通過轉義符“\”來顯示。
常用的轉義字元如下表所示。
轉義字元 | 輸出 |
---|---|
\n | 換行(LF 或 ASCII 字元 0x0A(10)) |
\r | 回車(CR 或 ASCII 字元 0x0D(13)) |
\t | 水平製表符(HT 或 ASCII 字元 0x09(9)) |
\ | 反斜槓 |
$ | 美元符號 |
' | 單引號 |
" | 雙引號 |
[0-7]{1,3} | 此正規表示式序列匹配一個用八進位制符號表示的字元,如\467 |
\x[0-9A-Fa-f]{1,2} | 此正規表示式序列匹配一個用十六進位制符號表示的字元,如\x9f |
注意
如果對非轉義字元使用了“\”,那麼在輸出時,“\”也會跟著一起被輸出。
Unix 系統裡,每行結尾只有“<換行>”,即“\n”;Windows 系統裡面,每行結尾是“<回車><換行>”,即“\r\n”
6.2.5標量型別宣告
用作於函式呼叫和返回語句。
強制模式(預設)
嚴格格式:嚴格要求使用者的資料輸入型別
語法格式:
declare(strict_types=1);//1表示嚴格校驗,0表示強制模式
function sum(int ...$ints){
return array_sum($ints);
}
print (sum(2,'3',4));//設定第一行開關進行測試
可用於宣告標量型別的引數型別包括:
int float bool string interface array callable
6.3 複合型別
6.3.1 陣列
陣列是一組資料的集合,它把一系列資料組織起來,形成一個可操作的整體。陣列中可以包括很多資料,如標量資料、陣列、物件、資源以及 PHP 中支援的其他語法結構等。陣列中的每個資料稱為一個元素,元素包括索引(鍵名)和值兩個部分。元素的索引可以由數字或字串組成,元素的值可以是多種資料型別
語法格式及案例:
$array = ['value1',' value2 '……]; //或
$array[key] = 'value'; //或
$array = array(key1 => value1, key2 => value2……);
//案例
$arr1 = array('This','is','a','example');
$arr2 = array(0 => 'php', 1=>'is', 'the' => 'the', 'str' => 'best');
$arr3[0] = 'tmpname';
6.3.2 物件(object)
程式語言所應用到的方法有兩種:程式導向和麵向物件。這裡的物件指的是物件導向中的類的例項。
6.4 特殊資料型別
6.4.1 資源(resource)
資源型別是 PHP 4 引進的。在使用資源時,系統會自動啟用垃圾回收機制,釋放不再使用的資源,避免記憶體消耗殆盡。因此,資源很少需要手工釋放。物件、開啟的檔案,資料庫連線都是資源型別。
6.4.2 空值(null)
表示沒有為該變數設定任何值,另外,空值(null)不區分大小寫,null 和 NULL 效果是一樣的。
被賦予空值的情況有以下 3 種:
- 還沒有賦任何值
- 被賦值 null
- 被 unset()函式處理過的變數
說明
is_null()函式是判斷變數是否為 null,如果變數為 null,則返回 true,否則返回 false。
6.5資料型別轉換
雖然PHP是弱型別語言,但有時仍然需要用到型別轉換。
6.5.1自動轉換
6.5.2強制轉換
[1] 只需在變數前加上用括號括起來的型別名稱即可。允許轉換的型別如下表:
轉換操作符 | 轉換型別 | 舉例 |
---|---|---|
(boolean) | 轉換成布林型 | (boolean)$num、(boolean)$str |
(string) | 轉換成字元型 | (string)$boo、(string)$flo |
(integer) | 轉換成整型 | (integer)$boo、(integer)$str |
(float) | 轉換成浮點型 | (float)$str、(float)$str |
(array) | 轉換成陣列 | (array)$str |
(object) | 轉換成物件 | (object)$str |
注意
- 轉換成boolean型時,null、0和未賦值的變數或陣列會被轉換為false,其他的為真
- 轉換成整型時,布林型的false轉換為0,true轉換為1,浮點型的小數部分被捨去,字元型如果以數字開頭就擷取到非數字位,否則輸出0。
[2] 使用Settype函式
bool settype ( mixed var, string type )//mixed是偽型別
注意
type的值不能是資源型別,轉型成功返回true,否則返回false。
[3]兩種方式區別
方法[1]中不改變原資料。方法[2]則會改變原有資料型別和值。
6.6資料型別檢測
[1] PHP內建以下檢測函式,判斷其是否屬於某個型別,如果符合則返回true,否則返回false。
函式 | 檢測型別 | 舉例 |
---|---|---|
is_bool | 檢查變數是否是布林型別 | is_bool(true)、is_book(false) |
is_string | 檢查變數是否是字串型別 | is_string(‘string’)、is_string(1234) |
is_float/is_double | 檢查變數是否為浮點型別 | is_float(3.1415)、is_float(‘3.1415)) |
is_integer/is_int | 檢查變數是否為整數 | is_integer(34)、is_integer(‘34’) |
is_null | 檢查變數是否為null | is_null(null) |
is_array | 檢查變數是否為陣列型別 | is_array($arr) |
is_object | 檢查變數是否是一個物件型別 | is_object($obj) |
is_numeric | 檢查變數是否為數字或由數字組成的字串 | is_numeric(‘5’)、is_numeric(‘bccd110’) |
[2] var_dump函式直接檢視
void var_dump ($expression, $_ = null)
7.運算子[^1]
7.1 各種運算子
[^1]: PHP Manual-語言參考-運算子
[1]算術運算子
[2]字串運算子
有兩個字串(string)運算子。
- 連線運算子(”.”),它返回其左右引數連線後的字串。
- 連線賦值運算子(”
.=
“),它將右邊引數附加到左邊的引數之後。
[3]賦值運算子
“=”右邊的值賦給左邊的變數或者常量
a.引用賦值
PHP 支援引用賦值,使用”$var = &$othervar;”語法。引用賦值意味著兩個變數指向了同一個資料,沒有拷貝任何東西。
b.算術賦值運算子
c.位賦值運算子
d.其他賦值運算子
[4] 位邏輯運算子
對二進位制位從低位到高位對齊後進行運算
注意
左移如果超出位數,返回0.
位移負的位置,會產生異常(1>>-1)
右移如果超出位數,返回0(1>>64)或-1(-1>>64).
[5]比較運算子
對變數或表示式的結果進行大小、真假等比較,如果比較結果為真,則返回true,如果為假,則返回false
注意
==與===區別
!==表示可能數值不同,可能型別不同
[6]錯誤控制運算子
@錯誤遮蔽運算子可以對程式中出現錯誤的表示式進行操作,對錯誤資訊進行遮蔽,其使用的方法就是在錯誤的表示式前加上@。例:
<?php
$err = @(5 / 0);//分別測試帶@與不帶@的輸出結果
?>
[7]三元運算子
(expr)?(expr2):(expr3)//expr成立執行expr2,否則執行expr3
[8]否定控制運算
用在運算元之前,用於對運算元值進行否定。包含邏輯否定和按位否定。
否定控制運算子 | 含義 |
---|---|
! | 邏輯否 |
~ | 按位否 |
[9]合併運算子合組合運算子
(expr)??(expr2)//php7新增,如果expr為真,返回expr,否則返回expr2
(expr)<==>(expr2) //php7新增,如果>或者<或者=,分別返回1,0,-1
7.2運算子優先順序與結合性
所謂運算子的優先順序,是指在應用中哪一個運算子先計算,哪一個後計算,與數學的四則運算遵循的“先乘除,後加減”是一個道理。運算子在運算中遵循的規則是:優先順序高的運算先執行,優先順序低的操作後執行,同一優先順序的操作按照從左到右的順序進行。也可以像四則運算那樣使用小括號,括號內的運算最先進行。
下表按照優先順序從高到低列出了運算子。同一行中的運算子具有相同優先順序,此時它們的結合方向決定求值順序。
8.表示式與語句
表示式式在特定語言中表達一個特定的操作或動作的語句。一個表示式包含運算元和操作符。
$a=5 //表示式
$a=5; //語句
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
read.douban.com/reader/column/4096...
本作品採用《CC 協議》,轉載必須註明作者和本文連結