PHP 字串 (String)

字串是一連串的字元,用來儲存文字資料。PHP 提供了多種建立和操作字串的方式。

建立字串

單引號

單引號字串不會解析變數和大部分跳脫字元:

<?php
$name = 'Alice';

echo 'Hello, World!';
echo 'Hello, $name!';  // Hello, $name!(不會解析變數)
echo 'It\'s a book';   // 只有 \' 和 \\ 會被解析
echo 'C:\\Users\\Name';
?>

雙引號

雙引號字串會解析變數和跳脫字元:

<?php
$name = "Alice";
$age = 25;

echo "Hello, $name!";             // Hello, Alice!
echo "Age: {$age} years old";     // Age: 25 years old
echo "Line 1\nLine 2";            // 換行
echo "Tab:\tHere";                // Tab
?>

變數解析

<?php
$name = "Alice";
$user = ['name' => 'Bob', 'age' => 30];

// 簡單變數
echo "Hello, $name!";

// 陣列元素
echo "User: {$user['name']}";

// 複雜表達式使用大括號
$items = ['apple', 'banana'];
echo "First: {$items[0]}";

// 物件屬性
class Person {
    public string $name = 'Charlie';
}
$person = new Person();
echo "Name: {$person->name}";
?>

跳脫字元

跳脫字元說明單引號雙引號
\\反斜線
\'單引號
\"雙引號
\n換行
\r歸位
\tTab
\$錢字號
\0NUL 位元組
<?php
// 換行
echo "Line 1\nLine 2\n";

// Tab
echo "Column1\tColumn2\n";

// 引號
echo "He said \"Hello\"\n";
echo 'It\'s fine\n';

// 路徑
echo "C:\\Users\\Name\n";
?>

Heredoc

Heredoc 類似雙引號字串,可以跨多行且會解析變數:

<?php
$name = "Alice";
$age = 25;

$html = <<<HTML
<div class="user">
    <h1>$name</h1>
    <p>Age: $age</p>
</div>
HTML;

echo $html;
?>

Heredoc 語法規則

  • 開始標籤 <<<IDENTIFIER 後面不能有任何字元
  • 結束標籤必須獨立一行(PHP 7.3+ 可以縮排)
  • 標籤名稱可以自訂,通常使用 EOFHTMLSQL
<?php
// PHP 7.3+ 可以縮排
function getTemplate() {
    $name = "Alice";
    return <<<EOF
        Hello, $name!
        This is a template.
        EOF;
}
?>

Nowdoc

Nowdoc 類似單引號字串,不會解析變數:

<?php
$name = "Alice";

$code = <<<'CODE'
<?php
echo "Hello, $name!";
// $name 不會被解析
?>
CODE;

echo $code;
?>

字串連接

使用 . 運算子連接字串:

<?php
$first = "Hello";
$second = "World";

// 連接
$greeting = $first . ", " . $second . "!";
echo $greeting;  // Hello, World!

// 連接並賦值
$message = "Hello";
$message .= " World";
echo $message;  // Hello World
?>

字串長度

<?php
$str = "Hello";
echo strlen($str);  // 5

// 中文字串(UTF-8 一個中文字佔 3 bytes)
$chinese = "你好";
echo strlen($chinese);     // 6
echo mb_strlen($chinese);  // 2(需要 mbstring 擴展)
?>

字串索引

<?php
$str = "Hello";

// 取得單一字元
echo $str[0];   // H
echo $str[1];   // e
echo $str[-1];  // o(負數從尾端算)

// 修改字元
$str[0] = "J";
echo $str;      // Jello
?>

字串比較

<?php
// == 比較(會自動轉型)
var_dump("10" == 10);     // bool(true)

// === 嚴格比較
var_dump("10" === 10);    // bool(false)

// strcmp 比較(區分大小寫)
echo strcmp("apple", "banana");  // 負數(apple < banana)
echo strcmp("apple", "Apple");   // 正數(a > A)

// strcasecmp 比較(不區分大小寫)
echo strcasecmp("apple", "Apple");  // 0(相等)
?>

常用字串函數

大小寫轉換

<?php
$str = "Hello World";

echo strtoupper($str);   // HELLO WORLD
echo strtolower($str);   // hello world
echo ucfirst($str);      // Hello World(首字母大寫)
echo ucwords($str);      // Hello World(每個單字首字母大寫)
echo lcfirst("Hello");   // hello(首字母小寫)
?>

去除空白

<?php
$str = "  Hello World  ";

echo trim($str);    // "Hello World"(去除兩端空白)
echo ltrim($str);   // "Hello World  "(去除左邊空白)
echo rtrim($str);   // "  Hello World"(去除右邊空白)

// 去除指定字元
echo trim("xxHelloxx", "x");  // "Hello"
?>

搜尋和取代

<?php
$str = "Hello World";

// 搜尋位置
echo strpos($str, "World");   // 6
echo strpos($str, "world");   // false(區分大小寫)
echo stripos($str, "world");  // 6(不區分大小寫)

// 取代
echo str_replace("World", "PHP", $str);  // Hello PHP
echo str_ireplace("world", "PHP", $str); // Hello PHP(不區分大小寫)
?>

擷取字串

<?php
$str = "Hello World";

echo substr($str, 0, 5);   // "Hello"
echo substr($str, 6);      // "World"
echo substr($str, -5);     // "World"(從尾端算)
echo substr($str, 0, -6);  // "Hello"(不包含最後 6 個字元)
?>

分割和合併

<?php
// 分割
$str = "apple,banana,orange";
$arr = explode(",", $str);
print_r($arr);  // ['apple', 'banana', 'orange']

// 合併
$arr = ['apple', 'banana', 'orange'];
$str = implode(", ", $arr);
echo $str;  // "apple, banana, orange"
?>

字串格式化

sprintf

<?php
$name = "Alice";
$age = 25;
$price = 99.5;

// %s 字串, %d 整數, %f 浮點數
echo sprintf("Name: %s, Age: %d", $name, $age);
// Name: Alice, Age: 25

// 指定寬度和精度
echo sprintf("Price: $%.2f", $price);  // Price: $99.50
echo sprintf("ID: %05d", 42);          // ID: 00042(補零)
?>

printf

直接輸出格式化字串:

<?php
printf("Hello, %s!", "Alice");  // Hello, Alice!
?>

字串是不可變的?

PHP 字串可以透過索引修改,但建議建立新字串:

<?php
$str = "Hello";

// 可以修改
$str[0] = "J";
echo $str;  // Jello

// 但通常建立新字串更安全
$str = "Hello";
$newStr = "J" . substr($str, 1);
echo $newStr;  // Jello
?>

多位元組字串 (mbstring)

處理中文等多位元組字串時,使用 mb_* 函數:

<?php
$str = "你好世界";

// 標準函數(以 bytes 計算)
echo strlen($str);      // 12

// mbstring 函數(以字元計算)
echo mb_strlen($str);   // 4

echo mb_substr($str, 0, 2);  // "你好"
?>
使用 mb_* 函數需要啟用 mbstring 擴展。大部分 PHP 安裝預設已啟用。

實際應用範例

格式化輸出

<?php
function formatPrice(float $price, string $currency = 'TWD'): string {
    $symbols = ['TWD' => 'NT$', 'USD' => '$', 'EUR' => '€'];
    $symbol = $symbols[$currency] ?? $currency;
    return $symbol . number_format($price, 2);
}

echo formatPrice(1234.5);  // NT$1,234.50
?>

生成 slug

<?php
function slugify(string $text): string {
    $text = strtolower($text);
    $text = preg_replace('/[^a-z0-9]+/', '-', $text);
    $text = trim($text, '-');
    return $text;
}

echo slugify("Hello World! This is a Test");
// hello-world-this-is-a-test
?>

截斷文字

<?php
function truncate(string $text, int $length = 100, string $suffix = '...'): string {
    if (mb_strlen($text) <= $length) {
        return $text;
    }
    return mb_substr($text, 0, $length) . $suffix;
}

echo truncate("這是一段很長的文字,需要截斷顯示", 10);
// 這是一段很長的文字...
?>