玩转PHP字符串变量解析和函数,动态输出HTML

记得刚开始写代码的时候,看到动态输出ul,table就头晕;

因为当时对HTML标签,制表符PHP字符串,单引号/双引号的操作还很不熟练

几个项目后,再看这些代码,就有了很亲切的感觉


虽然用框架后都直接用封装好的控件输出,但是原生态的总是那么有魅力,让人细细品味


本文总结2个例子,一个无序列表的动态输出,一个表格的动态输出

在后面引用了手册里面的字符串部分,尤其是变量解析的细节和字符串操作部分。


目录:

  1. 首先是无序列表 ul
    1. 单引号
    2. 双引号
  2. 第二个例子是表格Table
  3. 关于特殊字符
  4. Heredoc结构
  5. Nowdoc结构
  6. 变量解析
    1. 简单句法规则
    2. 复杂句法规则
  7. 字符串操作
    1. 存取和修改字符串中的字符
    2. 有用的函数和操作符
    3. 转换成字符串
    4. 字符串转变成数字


  8. 字符串函数

首先是无序列表 ul


    public function build_ul_lists()
    {
        $initials26= array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
        $i=0;
        $html.="</br>";
        foreach ($initials26 as $key =>$initial)
        {   
            $html.= "\n<ul class=\"inline unstyled initial-button-list\"><button class=btn>".$initial."</button>";
            $labels=NULL;
           
            $words = $this->processSearch("","",$initial,1,12);

            for($i=0;$i<12;$i++)
            {
            	$link = '<a class="need_model" href="view.php?word_id='.$words[$i]['word_id'].'">'.$words[$i]['word'].'</a>';
                //另一种表达方式
                $link = "<a class='need_model' href='view.php?word_id=".$words[$i]['word_id']."'>".$words[$i]['word']."</a>";       
               $word_info = "$link";
                $labels.= "\n<li>&nbsp".$word_info."</li>";
            }
            
            $html.=$labels."</ul>";
        }
        echo $html;
    }


第5行:</br>在页面上输出一个换行

第8行:\n 在生成的HTML代码中 换行,方便阅读查看

第17行:\n 在生成的HTML代码中 换行,方便阅读查看

第17行:&nbsp 在页面上输出一个空格


单引号

定义一个字符串 的最简单的方法是用单引号把它包围起来 (标点符号')。

如果想要输出一个单引号,需在它的前面加个反斜线 (\)。在单引号前或在字符串的结尾处 想要输出反斜线,输入两条 (\\)。注意,如果在任何其它的字符前加了反斜线,反斜线将会被直接输出。


$link = '<a class="need_model" href="view.php?word_id='.$words[$i]['word_id'].'">'.$words[$i]['word'].'</a>';

在单引号字符串中的变量和特殊含义的字符将不会被替换。

因此,

 class="need_model"
直接写就行;

$words[$i]['word'].'</a>'
PHP变量不能写在单引号里面,而是写出来,并用'.'连接符连接。


双引号

如果字符串是包围在双引号(")中, PHP将对一些特殊的字符进行解析:

Escaped characters
Sequence Meaning
\n 换行 (LF or 0x0A (10) in ASCII)
\r 回车 (CR or 0x0D (13) in ASCII)
\t 水平方向的 tab(HT or 0x09 (9) in ASCII)
\v 竖直方向的 tab (VT or 0x0B (11) in ASCII) (since PHP 5.2.5)
\f 换页 (FF or 0x0C (12) in ASCII) (since PHP 5.2.5)
\\ 反斜线
\$ 美金dollar标记
\" 双引号
\[0-7]{1,3} 符合该表达式顺序的字符串是一个八进制的字符
\x[0-9A-Fa-f]{1,2} 符合该表达式顺序的字符串是一个十六进制的字符

$html.= "\n<ul class=\"inline unstyled initial-button-list\"><button class=btn>$initial</button>";
用双引号定义的字符串最重要的特征是变量会被解析!

因此,

<button class=btn>$initial</button>
PHP变量直接写在HTML里面就可以

class=\"inline unstyled initial-button-list\"
而要想输出双引号本身,则要加 \   (其实这个地方直接用单引号就OK了,HTML标签的属性值既可以用单引号包括,也可以用双引号包括)


对比单引号和双引号

$link = '<a class="need_model" href="view.php?word_id='.$words[$i]['word_id'].'">'.$words[$i]['word'].'</a>';

$link = "<a class='need_model' href='view.php?word_id=$words[$i]['word_id']'>{$words[$i]['word']}</a>"; 

当然是用双引号要简便,PHP变量直接写在HTML里面就可以;但是注意,复杂变量最好用{  }包起来



第二个例子是表格Table

    public function searchWordsByPage($keyword,$group,$initial,$page,$perPageNum)
    {
            $perPageNum=12;//每一页显示的条数为20条
            $currentPageFirst=($page-1)*$perPageNum+1;
            $currentPageLast=$page*$perPageNum;
            $tab_str="";
            $tab_str.="<table id='tab_searched' class ='table table-striped table-bordered table-hover table-condensed initial-button-list' align='center'>";
            $tab_str.="<thead><td><i class='icon-search'></i></td><td>词语</td><td>词语类型</td><td>正负极性</td><td>褒贬值[-3,3]</td><td>词语类别</td><td>编辑</td></thead>";

            //分页查询
            $words = $this->processSearch($keyword,$group,$initial,$currentPageFirst,$perPageNum);
            $i=$currentPageFirst-1;
            foreach ( $words as $key => $word )
            {   
                $i++;
                $labels=NULL;
                $labels.="<tr>";
                $labels.="<td width=5%>".$i."</td>";
	                    
	            //词语
                $link = "<a class='need_model' href='view.php?word_id=".$word['word_id']."'>".$word['word']."</a>";
	        $labels.="<td width='20%'>".$link."</td>";
	                    
	        //词语类型
	        $senti_type=($word['senti_type']==1)?"褒贬词":"程度副词";
	        $labels.="<td width='15%'>".$senti_type."</td>";
	        //正负极性
	        $senti_jixing=($word['senti_value']>0)?"正面":"负面";
	        $labels.="<td width='15%'>".$senti_jixing."</td>";
	        //褒贬值-3~3
	        $labels.="<td width='15%'>".$word['senti_value']."</td>";
	        //中英文:1,中文;2,英文
	        $word_type=($word['word_type']==1)?"中文":"English";
	        $labels.="<td width='15%'>".$word_type."</td>";
	        //编辑链接
	        $link2 = "<a class='need_model' href='view.php?word_id=".$word['word_id']."'>编辑</a>";
	        $labels.="<td width='15%'>".$link2."</td>";
	        $tab_str.=$labels;      
            }    
            $tab_str.="</table>";            
            return $tab_str;
    }


显示PHP错误

有时候,就算有语法错误,有可能没报出来,可以在程序开始之前,加入以下代码

        error_reporting(E_ALL);


关于特殊字符

Escaped characters
Sequence Meaning
\n 换行 (LF or 0x0A (10) in ASCII)
\r 回车 (CR or 0x0D (13) in ASCII)
\t 水平方向的 tab(HT or 0x09 (9) in ASCII)
\v 竖直方向的 tab (VT or 0x0B (11) in ASCII) (since PHP 5.2.5)
\f 换页 (FF or 0x0C (12) in ASCII) (since PHP 5.2.5)
\\ 反斜线
\$ 美金dollar标记
\" 双引号
\[0-7]{1,3} 符合该表达式顺序的字符串是一个八进制的字符
\x[0-9A-Fa-f]{1,2} 符合该表达式顺序的字符串是一个十六进制的字符


Heredoc结构

第三种定义字符串的方法是用heredoc句法结构:<<<

在该提示 符后面,要定义个标识符,然后是一个新行。

接下来是字符串 本身,最后要用前面定义的标识符作为结束标志。


结束时所引用的标识符必须在一行的开始位置,前面一个空格都不可以有!!!

结束标识符这行除了可能有一个分号(;)外,绝对不能包括 其它字符。

这意味着标识符不能缩进,分号的前后也不能有任何空白或tabs。

标识符的命名也要像其它标签一样遵守PHP的规则:只能包含 字母、数字和下划线,并且不能用数字和下划线作为开头。

Heredoc结构就象是没有使用双引号的双引号字符串

这就是说在heredoc结构中引号不用被替换,但是上文中列出的字符 (\n等)也可使用。

变量将被替换,但在heredoc结构中字符串表达复杂变量时,要格外小 心。


echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
My name is "MyName".

I am printing some Foo.

Now, I am printing some Bar2.

This should print a capital 'A': A

	   return <<<FORM_MARKUP
	   <form action="assets/inc/process.inc.php" method="post">
	   <fieldset>
	   <legend>$submit</legend>
	   <label for="word">词语</label>
	   <input type="text" name="word" id="word" value="$word->word" />
	   <label for="senti_type">类型</label>
	   <input type="text" name="senti_type" id="senti_type" value="$word->senti_type" />
	   <label for="senti_value">褒贬值</label>
	   <input type="text" name="senti_value" id="senti_value" value="$word->senti_value" />
	   <label for="word_type">中英文</label>
	   <input type="text" name="word_type" id="word_type" value="$word->word_type" />
	   <input type="hidden" name="word_id" value="$word->word_id" />
	   <input type="hidden" name="token" value="$_SESSION[token]" />
	   <input type="hidden" name="action" value="word_edit" />
       <p>
	   <input type="submit" name="word_submit" value="保存"  class="btn btn-success"/>
       </p>
	   </fieldset>
	   </form>
FORM_MARKUP;


Nowdoc结构


就象heredoc结构类似于双引号字符串,Nowdoc结构是类似於单引号字符串的。

Nowdoc结构很象heredoc结构,但是 nowdoc不进行解析操作

这种结构很适合用在不需要进行转义的PHP代码和其它大段文本。

一个nowdoc结构也用和heredocs结构一样的标记 <<<, 但是跟在后面的标志符要用 单引号括起来,就像<<<'EOT'这样。

heredocs结构的所有规则也同样适用于nowdoc结 构,尤其是结束标志符的规则


echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;

以上例程会输出:

My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41

变量解析

字符串用双引号或heredoc结构定义时,其中的变 量将会被解析。


这里共有两种语法规则:一种简单 规则,一种复杂规 则。

简单的句法规则是最常用和最方便的, 它可以用最少的代码在一个字符串中加入变量,数组 值,或 对象属性。

复杂的句法规则是在PHP4以后加入的,被花括号包围的表达式是其明显标记。


简单句法规则

当PHP解析器遇到一个美元符号 ($) , 它会和其它很多解析器一样,去尽量形成一个合法的变量名。可以用花括 号来明确变量名的界线。

<?php
$beer 
'Heineken';
echo 
"$beer's taste is great"//有效;单引号"'"是非法的变量名组成元素
echo "He drank some $beers"//无效;字母s是有效的变量名组成元素,但是这里的变量是$beer
echo "He drank some ${beer}s"// 有效
echo "He drank some {$beer}s"// 有效
?>

类似的,一个 数组 索引或一个对象 属性也可被解析。数组索引要用方括号 (]) 来表示边际, 对象属性则是和上述的变量规则相同。

<?php
// 下面的例子是在字符串中引用数组
// 当数组处于字符串外部时,要把数组的值用括号括起来且不要用花括号{ }

// 显示所有错误
error_reporting(E_ALL);

$fruits = array('strawberry' => 'red''banana' => 'yellow');

// 有效;但是注意在字符串外面不能这样引用数组
echo "A banana is $fruits[banana].";

// 有效
echo "A banana is {$fruits['banana']}.";

// 有效,但是PHP会先寻找常量banana
echo "A banana is {$fruits[banana]}.";

// 无效,要用花括号,这里将会产生一个解析错误
echo "A banana is $fruits['banana'].";

// 有效
echo "A banana is " $fruits['banana'] . ".";

// 有效
echo "This square is $square->width meters broad.";

// 无效,解决方法见复杂结构
echo "This square is $square->width00 centimeters broad.";
?>

如果想要表达更复杂的结构,请用复杂句法规则。


复杂句法规则

复杂句法规则不是结构复杂而命名,而是因为它可以使用复杂的表达式。

任何想用在字符串中标量变量,数组变量或对象属性都可使用这种方法。 只需简单地像在字符串以外的地方那样写出表达式, 然后用花括号{}把它括起来。 由于 { 无法被转义,只有 $ 要紧挨着 {才会被认出来,可以用 {\$ 来表达 {$。下面的示例可以更好的解释:

<?php
// 显示所有错误
error_reporting(E_ALL);

$great 'fantastic';

// 无效,输出: This is { fantastic}
echo "This is { $great}";

// 有效,输出: This is fantastic
echo "This is {$great}";
echo 
"This is ${great}";

// 有效
echo "This square is {$square->width}00 centimeters broad."

// 有效
echo "This works: {$arr[4][3]}";

// 这是错误的表达式,因为就象$foo[bar] 的格式不能在字符串以外的地方使用一样。
// 换句话说,只有在PHP能找到常量foo 的前提下才会正常工作;这里会产生一个E_NOTICE (undefined constant)级别的错误。
echo "This is wrong: {$arr[foo][3]}"

// 有效,当在字符串中使用多重数组时,一定要用括号将它括起来
echo "This works: {$arr['foo'][3]}";

// 有效
echo "This works: " $arr['foo'][3];

echo 
"This works too: {$obj->values[3]->name}";

echo 
"This is the value of the var named $name{${$name}}";

echo 
"This is the value of the var named by the return value of getName():
{${getName()}}";

echo 
"This is the value of the var named by the return value of
\$object->getName(): 
{${$object->getName()}}";

// 无效,输出: This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";
?>

也可以在字符串中用变量来调用类的属性。

<?php
class foo {
    var 
$bar 'I am bar.';
}

$foo = new foo();
$bar 'bar';
$baz = array('foo''bar''baz''quux');
echo 
"{$foo->$bar}\n";
echo 
"{$foo->$baz[1]}\n";
?>

以上例程会输出:


I am bar.
I am bar.

Note:

函数、行为、类的静态变量和类的常量只有在PHP 5以后才可在 {$} 中使用。然而,只有在用返回的值作为名 称的变量存在的情况下才会进行处理,只单一使用花括号 ({}) 无法处理从函数或行为的返回值或从类的常量或静态变量的返 回值。

<?php
// 显示所有错误
error_reporting(E_ALL);

class 
beers {
    const 
softdrink 'rootbeer';
    public static 
$ale 'ipa';
}

$rootbeer 'A & W';
$ipa 'Alexander Keith\'s';

// 有效,输出: I'd like an A & W
echo "I'd like an {${beers::softdrink}}\n";

// 也有效,输出: I'd like an Alexander Keith's
echo "I'd like an {${beers::$ale}}\n";
?>



字符串操作


存取和修改字符串中的字符

字符串中的字符可以通过一个以0为开始的,用类似数组结构中的方括号包含对应的数字来查找和修改,比如$str[42], 可以把 字符串想像数组

函数 substr()substr_replace()可以用来实现多于一个字符 的情况。


有用的函数和操作符

字符串可以用'.' (点) 操作符连接起来, 注意 '+' (加号) 操作符没有 这个功能。 更多信息参考 字符串操作符

对于字符串 的操作有很多有用的函数。

可以参考 字符串函数 了解大部分函数, 高级的查找&替换功能可以参考正则表达式函数Perl类型的正则 表达式函数

另外还有URL字符串的函数, 也有加密/解密字符串的函数。 (mcryptmhash).

最后,可以参考 字符类型函数


转换成字符串

一个值可以通过在其前面加上(string)或用strval()函数来转变成 字符串。

在一个需要字符串的表达式中,字符串会自动转变

比如在使用函数 echo()print() 时, 或在一个变量和一个字符串 进行比较时

就会发生这种转变 类型 类型转换 可以更好的解释下面的事情,也可参考函 数 settype()


一个booleanTRUE 值被转换成 字符串"1"

BooleanFALSE 被转换成"" (空的字符串)。

这种转变可以在 boolean字符串 之间往返进行。


一个 整数 浮点数 被转变为数字的字面样式的字符串 (包括浮点数中的指数部分),使用指数计数法的浮点数 (4.1E+6)也可转变


数组转换成 字符串 "Array",因此, echo()print() 无法显示出该数组的值。

如果显示一个数组值,可以用 echo $arr['foo']这种结构,更多内容见下文。


在PHP 4中对象被转换成字符串 "Object", 如果为了调试原因需要打印出对象的值,方法见正文。

为了得到对象的类的名称,可以用 get_class() 函数。

在PHP5中, 可以用 __toString


资源总会被转变成"Resource id #1"这种结构的字符串 , 其中的 1 是PHP分配给该资源的独特数字。

不用过多关注这种结构,它马上要转变了。为了得到一个 resource类型,可以用函数get_resource_type()


NULL 总是被转变成空的字符串。


如上面所说的,直接把数组对象资源 转换成字符串 不会得到超出其自身的更多信息。

可以使用函数 print_r()var_dump() 列出这些类型的内容。


大部分的PHP值可以转变成 字符串s 来长期储存,这被称作串行化,可以用函数serialize() 来实现。

如果PHP引擎设定支持 WDDX , PHP值也可储存成XML格式。


字符串转变成数字

当一个字符串 被用在了一个数字的环境中,结果和类型如下:

如果字符串 没有包含 '.','e'或'E' 并且数字值符合整数类型的限定 (PHP_INT_MAX定义的), 这个 字符串 可被认定是一个integer, 在其它情况下被认定为一个float


字符串的开始部分给定了它的值,如果字符串 以合法的数字开始,这个数字可直接使用。

否则,值就 是 0 (零)。 合法数值由符号,后面跟着一个或多个数字(可能有个小数点),再跟着可选的指数符号如'e' 或 'E',后面跟着一个或多个数字。

<?php
$foo 
"10.5";                // $foo is float (11.5)
$foo "-1.3e3";              // $foo is float (-1299)
$foo "bob-1.3e3";           // $foo is integer (1)
$foo "bob3";                // $foo is integer (1)
$foo "10 Small Pigs";       // $foo is integer (11)
$foo "10.2 Little Piggies"// $foo is float (14.2)
$foo "10.0 pigs " 1;          // $foo is float (11)
$foo "10.0 pigs " 1.0;        // $foo is float (11)     
?>

更多信息可以参考Unix手册中的strtod(3)。

本节中的示例可以通过复制/粘贴到下面的代码中来显示:

<?php
echo "\$foo==$foo; type is " gettype ($foo) . "<br />\n";
?>

不要想像在C语言中的那样,通过一个整数转换得到相应字符,使用函数 ord()chr() 实现ASCII码和字符间的转换。

字符串函数

  • 预定义常量
  • 字符串函数
    • addcslashes — 以 C 语言风格使用反斜线转义字符串中的字符
    • addslashes — 使用反斜线引用字符串
    • bin2hex — 将二进制数据转换成十六进制表示
    • chop — rtrim 的别名
    • chr — 返回指定的字符
    • chunk_split — 将字符串分割成小块
    • convert_cyr_string — 将字符由一种 Cyrillic 字符转换成另一种
    • convert_uudecode — 解码一个 uuencode 编码的字符串
    • convert_uuencode — 使用 uuencode 编码一个字符串
    • count_chars — 返回字符串所用字符的信息
    • crc32 — 计算一个字符串的 crc32 多项式
    • crypt — 单向字符串散列
    • echo — 输出一个或多个字符串
    • explode — 使用一个字符串分割另一个字符串
    • fprintf — 将格式化后的字符串写入到流
    • get_html_translation_table — 返回使用 htmlspecialchars 和 htmlentities 后的转换表
    • hebrev — 将逻辑顺序希伯来文(logical-Hebrew)转换为视觉顺序希伯来文(visual-Hebrew)
    • hebrevc — 将逻辑顺序希伯来文(logical-Hebrew)转换为视觉顺序希伯来文(visual-Hebrew),并且转换换行符
    • html_entity_decode — Convert all HTML entities to their applicable characters
    • htmlentities — Convert all applicable characters to HTML entities
    • htmlspecialchars_decode — Convert special HTML entities back to characters
    • htmlspecialchars — Convert special characters to HTML entities
    • implode — Join array elements with a string
    • join — 别名 implode
    • lcfirst — Make a string's first character lowercase
    • levenshtein — Calculate Levenshtein distance between two strings
    • localeconv — Get numeric formatting information
    • ltrim — Strip whitespace (or other characters) from the beginning of a string
    • md5_file — 计算指定文件的 MD5 散列值
    • md5 — 计算字符串的 MD5 散列值
    • metaphone — Calculate the metaphone key of a string
    • money_format — Formats a number as a currency string
    • nl_langinfo — Query language and locale information
    • nl2br — 在字符串所有新行之前插入 HTML 换行标记
    • number_format — Format a number with grouped thousands
    • ord — 返回字符的 ASCII 码值
    • parse_str — Parses the string into variables
    • print — 输出字符串
    • printf — 输出格式化字符串
    • quoted_printable_decode — Convert a quoted-printable string to an 8 bit string
    • quoted_printable_encode — Convert a 8 bit string to a quoted-printable string
    • quotemeta — Quote meta characters
    • rtrim — 删除字符串末端的空白字符(或者其他字符)
    • setlocale — Set locale information
    • sha1_file — 计算文件的 sha1 散列值
    • sha1 — 计算字符串的 sha1 散列值
    • similar_text — 计算两个字符串的相似度
    • soundex — Calculate the soundex key of a string
    • sprintf — Return a formatted string
    • sscanf — Parses input from a string according to a format
    • str_getcsv — 解析 CSV 字符串为一个数组
    • str_ireplace — str_replace 的忽略大小写版本
    • str_pad — 使用另一个字符串填充字符串为指定长度
    • str_repeat — 重复一个字符串
    • str_replace — 子字符串替换
    • str_rot13 — 对字符串执行 ROT13 转换
    • str_shuffle — 随机打乱一个字符串
    • str_split — 将字符串转换为数组
    • str_word_count — 返回字符串中单词的使用情况
    • strcasecmp — 二进制安全比较字符串(不区分大小写)
    • strchr — 别名 strstr
    • strcmp — 二进制安全字符串比较
    • strcoll — 基于区域设置的字符串比较
    • strcspn — 获取不匹配遮罩的起始子字符串的长度
    • strip_tags — 从字符串中去除 HTML 和 PHP 标记
    • stripcslashes — 反引用一个使用 addcslashes 转义的字符串
    • stripos — 查找字符串首次出现的位置(不区分大小写)
    • stripslashes — 反引用一个引用字符串
    • stristr — strstr 函数的忽略大小写版本
    • strlen — 获取字符串长度
    • strnatcasecmp — 使用“自然顺序”算法比较字符串(不区分大小写)
    • strnatcmp — 使用自然排序算法比较字符串
    • strncasecmp — 二进制安全比较字符串开头的若干个字符(不区分大小写)
    • strncmp — 二进制安全比较字符串开头的若干个字符
    • strpbrk — 在字符串中查找一组字符的任何一个字符
    • strpos — 查找字符串首次出现的位置
    • strrchr — 查找指定字符在字符串中的最后一次出现
    • strrev — 反转字符串
    • strripos — 计算指定字符串在目标字符串中最后一次出现的位置(不区分大小写)
    • strrpos — 计算指定字符串在目标字符串中最后一次出现的位置
    • strspn — 计算字符串中全部字符都存在于指定字符集合中的第一段子串的长度。
    • strstr — 查找字符串的首次出现
    • strtok — 标记分割字符串
    • strtolower — 将字符串转化为小写
    • strtoupper — 将字符串转化为大写
    • strtr — 转换指定字符
    • substr_compare — 二进制安全比较字符串(从偏移位置比较指定长度)
    • substr_count — 计算字串出现的次数
    • substr_replace — 替换字符串的子串
    • substr — 返回字符串的子串
    • trim — 去除字符串首尾处的空白字符(或者其他字符)
    • ucfirst — 将字符串的首字母转换为大写
    • ucwords — 将字符串中每个单词的首字母转换为大写
    • vfprintf — 将格式化字符串写入流
    • vprintf — 输出格式化字符串
    • vsprintf — 返回格式化字符串
    • wordwrap — 打断字符串为指定数量的字串


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章