> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 字符串操作（Str 类）

> 介绍 Laravel Str 类以及 Stringable（Fluent Strings）的用法，附实用示例。

## 什么是 Str 类

`Illuminate\Support\Str` 类提供了丰富的字符串操作方法。相比逐个调用 PHP 标准字符串函数，它提供统一直观的接口。

Laravel 的字符串操作有两种风格：

* **静态方法风格**：`Str::slug($title, '-')`，适合单次操作
* **Fluent 风格（方法链）**：`Str::of($title)->slug('-')->limit(50)`，可以把多个操作串起来

```php theme={null}
use Illuminate\Support\Str;

// 静态方法
$slug = Str::slug('My New Blog Post', '-');
// 'my-new-blog-post'

// Fluent（Str::of）
$result = Str::of('  My New Blog Post: Part 1  ')
    ->trim()
    ->slug('-')
    ->limit(30);
```

<Info>
  全局辅助函数 `str()` 与 `Str::of()` 等价。可以写 `str('hello')->upper()`。
</Info>

## 大小写与命名法转换

### `Str::camel()` / `Str::snake()` / `Str::kebab()` / `Str::studly()`

```php theme={null}
use Illuminate\Support\Str;

Str::camel('foo_bar');         // 'fooBar'
Str::snake('fooBar');          // 'foo_bar'
Str::kebab('fooBar');          // 'foo-bar'
Str::studly('foo_bar');        // 'FooBar'
```

### `Str::lower()` / `Str::upper()` / `Str::title()`

```php theme={null}
Str::lower('LARAVEL');       // 'laravel'
Str::upper('laravel');       // 'LARAVEL'
Str::title('hello world');   // 'Hello World'
```

## Slug 与 URL

### `Str::slug()` — 生成 URL 友好的 slug

```php theme={null}
Str::slug('Laravel 框架', '-');
Str::slug('My New Blog Post', '-'); // 'my-new-blog-post'
Str::slug('Hello World!', '_');     // 'hello_world'
```

<Tip>
  若包含非拉丁字符，slug 可能为空。可结合罗马字转换库，或使用 ID / 时间戳作为 URL。
</Tip>

### 用 `Str::of()` 一次完成生成与校验

```php theme={null}
$title = '  My New Blog Post: Part 1!  ';

$slug = Str::of($title)
    ->trim()
    ->slug('-')
    ->limit(50);
```

## 字符串截断

### `Str::limit()`

```php theme={null}
$text = 'Laravel 是构建美观 Web 应用的 PHP 框架。';

Str::limit($text, 20);
Str::limit($text, 20, ' → 更多');
Str::limit('The quick brown fox jumps over the lazy dog', 20, preserveWords: true);
```

### `Str::words()`

```php theme={null}
Str::words('Perfectly balanced, as all things should be.', 3, ' >>>');
// 'Perfectly balanced, as >>>'
```

## 检索与判断

### `Str::contains()`

```php theme={null}
Str::contains('This is my name', 'my');
Str::contains('This is my name', ['my', 'your']);
Str::contains('This is my name', 'MY', ignoreCase: true);
```

### `Str::startsWith()` / `Str::endsWith()`

```php theme={null}
Str::startsWith('https://laravel.com', 'https://');
Str::endsWith('photo.jpg', '.jpg');
Str::endsWith('photo.jpg', ['.jpg', '.png', '.gif']);
```

### `Str::is()` — 通配符匹配

```php theme={null}
Str::is('foo*', 'foobar');
Str::is('*/user/*', '/admin/user/profile');
Str::is('F*', 'foo', ignoreCase: true);
```

## 变换与替换

### `Str::replace()`

```php theme={null}
Str::replace('8.x', '13.x', 'Laravel 8.x');
Str::replace('laravel', 'Symphony', 'I love Laravel', caseSensitive: false);
```

### `Str::replaceArray()`

```php theme={null}
Str::replaceArray('?', ['上午 9 点', '下午 5 点'], '预约是 ? 到 ?');
```

### `Str::replaceMatches()` — 正则替换

```php theme={null}
Str::replaceMatches('/[^0-9]/', '', '(03) 1234-5678');
Str::replaceMatches('/\d+/', fn ($matches) => '[' . $matches[0] . ']', '1 个 2 只 3 支');
```

### `Str::remove()`

```php theme={null}
Str::remove('e', 'Peter Piper picked a peck of pickled peppers.');
Str::remove(['foo', 'bar'], 'foo and bar and baz');
```

### `Str::squish()`

```php theme={null}
Str::squish('  Laravel   Framework  '); // 'Laravel Framework'
```

## 前后操作

### `Str::before()` / `Str::after()`

```php theme={null}
Str::before('test@example.com', '@'); // 'test'
Str::after('test@example.com', '@');  // 'example.com'
Str::afterLast('App\Http\Controllers\UserController', '\\'); // 'UserController'
Str::beforeLast('App\Http\Controllers\UserController', '\\');
```

### `Str::between()`

```php theme={null}
Str::between('[debug] Error occurred in module', '[', ']'); // 'debug'
```

### `Str::start()` / `Str::finish()`

若已经以该字符开头/结尾则不重复添加。

```php theme={null}
Str::start('users/profile', '/');   // '/users/profile'
Str::start('/users/profile', '/');  // '/users/profile'
Str::finish('https://example.com', '/'); // 'https://example.com/'
```

### `Str::chopStart()` / `Str::chopEnd()`

```php theme={null}
Str::chopStart('https://laravel.com', 'https://');
Str::chopStart('http://laravel.com', ['https://', 'http://']);
Str::chopEnd('UserController.php', '.php');
```

## 脱敏与安全

### `Str::mask()`

```php theme={null}
Str::mask('yamada@example.com', '*', 4);        // 'yama**************'
Str::mask('1234-5678-9012-3456', '*', -4);      // '***************3456'
Str::mask('yamada@example.com', '*', 3, 5);     // 'yam*****example.com'
```

### `Str::excerpt()`

```php theme={null}
$text = 'Laravel 是构建美观 Web 应用的 PHP 框架。';
Str::excerpt($text, 'PHP', ['radius' => 10]);
```

## 随机字符串与标识符

### `Str::random()`

```php theme={null}
Str::random(32);
```

### `Str::uuid()` / `Str::ulid()`

```php theme={null}
(string) Str::uuid();
(string) Str::uuid7(); // 可按时间排序
(string) Str::ulid();
```

### `Str::password()`

```php theme={null}
Str::password(12);
```

### `Str::counted()` — 数量与单复数

```php theme={null}
Str::counted('order', 1);    // '1 order'
Str::counted('order', 1000); // '1,000 orders'
Str::of('order')->counted(3);
```

<Tip>
  用于英文界面根据数量切换单复数时非常方便，逗号分隔的数字格式会自动应用。
</Tip>

## Fluent Strings（方法链）

以 `Str::of()` 或 `str()` 开头会返回一个 `Stringable` 实例，支持方法链。最终转为字符串可用 `(string)` 强转或字符串上下文使用。

```php theme={null}
$result = Str::of('  hello world  ')
    ->trim()
    ->title()
    ->append('!')
    ->toString();
```

### 实用示例

**博客文章 slug 生成**

```php theme={null}
$slug = Str::of('  My New Blog Post: Part 1  ')
    ->trim()
    ->lower()
    ->slug('-')
    ->limit(50);
```

**从 URL 中提取域名**

```php theme={null}
$domain = Str::of('https://www.example.com/path/to/page')
    ->after('//')
    ->before('/')
    ->chopStart('www.');
// 'example.com'
```

**用户输入清洗**

```php theme={null}
$clean = Str::of($userInput)
    ->squish()
    ->limit(255)
    ->toString();
```

**从类名生成文件路径**

```php theme={null}
$path = Str::of('App\Http\Controllers\UserController')
    ->replace('\\', '/')
    ->append('.php')
    ->toString();
```

### 条件方法链（`when()`）

```php theme={null}
$result = Str::of('Laravel')
    ->when($isUppercase, fn ($str) => $str->upper())
    ->append(' Framework');
```

### `pipe()`

```php theme={null}
$result = Str::of('my-slug')
    ->pipe(fn ($str) => $str->replace('-', '_'))
    ->upper()
    ->toString();
```

## `Str::of()` 常用方法

```php theme={null}
$str = Str::of('Hello, World!');

$str->length();
$str->upper();
$str->lower();
$str->trim();
$str->slug();
$str->camel();
$str->contains('World');
$str->startsWith('Hello');
$str->endsWith('!');
$str->replace(',', '');
$str->prepend('>>> ');
$str->append(' <<<');
$str->reverse();
$str->wordCount();
```

## 小结

<AccordionGroup>
  <Accordion title="常用 Str 方法一览">
    | 方法                                      | 用途              |
    | --------------------------------------- | --------------- |
    | `Str::slug($str)`                       | 生成 URL 友好的 slug |
    | `Str::limit($str, $n)`                  | 按字符截断           |
    | `Str::contains($str, $needle)`          | 判断是否包含          |
    | `Str::startsWith($str, $needle)`        | 判断是否以 needle 开头 |
    | `Str::endsWith($str, $needle)`          | 判断是否以 needle 结尾 |
    | `Str::replace($search, $replace, $str)` | 替换              |
    | `Str::camel($str)`                      | camelCase       |
    | `Str::snake($str)`                      | snake\_case     |
    | `Str::kebab($str)`                      | kebab-case      |
    | `Str::studly($str)`                     | StudlyCase      |
    | `Str::upper($str)`                      | 大写              |
    | `Str::lower($str)`                      | 小写              |
    | `Str::squish($str)`                     | 压缩空白            |
    | `Str::after($str, $search)`             | 取 search 之后     |
    | `Str::before($str, $search)`            | 取 search 之前     |
    | `Str::between($str, $from, $to)`        | 取两串之间           |
    | `Str::mask($str, '*', $index)`          | 脱敏              |
    | `Str::random($length)`                  | 随机字符串           |
    | `Str::uuid()`                           | UUID            |
    | `Str::of($str)`                         | Fluent 起点       |
  </Accordion>

  <Accordion title="静态方法 vs Fluent（Str::of）">
    **静态方法适合**：

    * 只做 1\~2 次变换
    * 简洁易读

    **Fluent 适合**：

    * 需要三次以上变换
    * 含条件分支（`when()`）
    * 希望以上下阅读的方式表达流程
  </Accordion>

  <Accordion title="Str 类 vs PHP 标准函数">
    使用 `Str` 类而不是 `strtolower()`、`substr()`、`str_replace()` 等：

    * 能安全处理多字节字符（内部使用 `mb_*`）
    * 方法链更聚合
    * 参数顺序不再需要死记
    * 保持 Laravel 代码风格一致
  </Accordion>
</AccordionGroup>


## Related topics

- [Macroable trait](/zh/advanced/macroable.md)
- [InteractsWithData trait](/zh/advanced/interacts-with-data.md)
- [Core —— AT Protocol 核心操作](/zh/packages/laravel-bluesky/core.md)
- [Concurrency](/zh/packages/laravel-copilot-sdk/concurrency.md)
- [Fluent 类](/zh/advanced/fluent.md)
