From ffebb3ffa89c5595af5e440a76051ef995cd21c6 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 21:53:46 +0800 Subject: [PATCH 01/16] Support auto translate to english --- .github/workflows/docs-translate.yaml | 35 ++++++++++++- bin/doc-translate.github-model.js | 52 +++++++++++++++++++ bin/doc-translate.js | 73 +++++++++++++-------------- 3 files changed, 121 insertions(+), 39 deletions(-) create mode 100644 bin/doc-translate.github-model.js diff --git a/.github/workflows/docs-translate.yaml b/.github/workflows/docs-translate.yaml index a3d66a61b..2fe802f94 100644 --- a/.github/workflows/docs-translate.yaml +++ b/.github/workflows/docs-translate.yaml @@ -6,7 +6,7 @@ on: - 'docs/**' jobs: - translate: + translate-zh: runs-on: ubuntu-latest steps: - name: Checkout @@ -48,3 +48,36 @@ jobs: uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: Update docs and translate + + translate-en: + runs-on: ubuntu-latest + env: + DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + version: 9 + run_install: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Start Translate + run: | + cp docs/index.md docs/en/index.md + pnpm run doc-translate + + - name: Commit Updated + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Update docs and translate \ No newline at end of file diff --git a/bin/doc-translate.github-model.js b/bin/doc-translate.github-model.js new file mode 100644 index 000000000..bc0f12968 --- /dev/null +++ b/bin/doc-translate.github-model.js @@ -0,0 +1,52 @@ +import OpenAI from "openai"; +import { promises as fs } from 'fs'; +import path from 'path'; + +const token = process.env["GITHUB_TOKEN"]; +const endpoint = "https://models.inference.ai.azure.com"; +const modelName = "o1-mini"; + +async function translateFiles() { + const client = new OpenAI({ + baseURL: endpoint, + apiKey: token, + dangerouslyAllowBrowser: true + }); + + const docsPath = path.join(process.cwd(), 'docs/zh-cn'); + + async function translateFile(filePath) { + const content = await fs.readFile(filePath, 'utf8'); + const response = await client.chat.completions.create({ + messages: [ + { role: "user", content: "You are a professional translator. Translate the following Markdown content from Chinese to English. Preserve all Markdown formatting." }, + { role: "user", content: content } + ], + model: modelName + }); + + const translatedContent = response.choices[0].message.content; + const englishPath = filePath.replace('/zh-cn/', '/en/'); + await fs.mkdir(path.dirname(englishPath), { recursive: true }); + await fs.writeFile(englishPath, translatedContent); + console.log(`Translated: ${filePath} -> ${englishPath}`); + } + + async function processDirectory(dirPath) { + const files = await fs.readdir(dirPath, { withFileTypes: true }); + + for (const file of files) { + const fullPath = path.join(dirPath, file.name); + + if (file.isDirectory()) { + await processDirectory(fullPath); + } else if (file.name.endsWith('.md')) { + await translateFile(fullPath); + } + } + } + + await processDirectory(docsPath); +} + +translateFiles().catch(console.error); diff --git a/bin/doc-translate.js b/bin/doc-translate.js index bc0f12968..f9ea1272e 100644 --- a/bin/doc-translate.js +++ b/bin/doc-translate.js @@ -1,52 +1,49 @@ import OpenAI from "openai"; -import { promises as fs } from 'fs'; +import { readdir, readFile, writeFile, mkdir } from 'fs/promises'; import path from 'path'; -const token = process.env["GITHUB_TOKEN"]; -const endpoint = "https://models.inference.ai.azure.com"; -const modelName = "o1-mini"; +const endpoint = "https://api.deepseek.com"; +const token = process.env["DEEPSEEK_API_KEY"]; -async function translateFiles() { - const client = new OpenAI({ +const openai = new OpenAI({ baseURL: endpoint, apiKey: token, - dangerouslyAllowBrowser: true - }); - - const docsPath = path.join(process.cwd(), 'docs/zh-cn'); - - async function translateFile(filePath) { - const content = await fs.readFile(filePath, 'utf8'); - const response = await client.chat.completions.create({ - messages: [ - { role: "user", content: "You are a professional translator. Translate the following Markdown content from Chinese to English. Preserve all Markdown formatting." }, - { role: "user", content: content } - ], - model: modelName +}); + +async function translateContent(content) { + const completion = await openai.chat.completions.create({ + messages: [ + { role: "system", content: "You are a professional translator. Translate the following Chinese markdown content to English. Keep all markdown formatting intact." }, + { role: "user", content: content } + ], + model: "deepseek-chat", }); + return completion.choices[0].message.content; +} - const translatedContent = response.choices[0].message.content; - const englishPath = filePath.replace('/zh-cn/', '/en/'); - await fs.mkdir(path.dirname(englishPath), { recursive: true }); - await fs.writeFile(englishPath, translatedContent); - console.log(`Translated: ${filePath} -> ${englishPath}`); - } +async function translateFiles(srcDir, destDir) { + try { + const files = await readdir(srcDir, { recursive: true }); - async function processDirectory(dirPath) { - const files = await fs.readdir(dirPath, { withFileTypes: true }); + for (const file of files) { + if (!file.endsWith('.md')) continue; - for (const file of files) { - const fullPath = path.join(dirPath, file.name); + const srcPath = path.join(srcDir, file); + const destPath = path.join(destDir, file); + const destFolder = path.dirname(destPath); - if (file.isDirectory()) { - await processDirectory(fullPath); - } else if (file.name.endsWith('.md')) { - await translateFile(fullPath); - } - } - } + await mkdir(destFolder, { recursive: true }); - await processDirectory(docsPath); + const content = await readFile(srcPath, 'utf8'); + const translatedContent = await translateContent(content); + const finalContent = translatedContent.replace(/\/zh-cn\//g, '/en/'); + await writeFile(destPath, finalContent); + + console.log(`Translated: ${file}`); + } + } catch (error) { + console.error('Translation error:', error); + } } -translateFiles().catch(console.error); +translateFiles('docs/zh-cn', 'docs/en'); \ No newline at end of file From 54d74afd359a63b16edcec8480e53721c2cc56c9 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 21:54:34 +0800 Subject: [PATCH 02/16] docs: update code block syntax in encryption documentation to use PHP --- docs/zh-cn/components/encryption.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-cn/components/encryption.md b/docs/zh-cn/components/encryption.md index cbf6e88a3..774617352 100644 --- a/docs/zh-cn/components/encryption.md +++ b/docs/zh-cn/components/encryption.md @@ -16,7 +16,7 @@ php bin/hyperf.php vendor:publish friendsofhyperf/encryption ## 使用 -```shell +```php $encryptString = encrypt($string); $decryptString = decrypt($encryptString); ``` From fb884b70207b4e6d8c822da8705e53298461375b Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 21:55:30 +0800 Subject: [PATCH 03/16] fix: update translation command in GitHub Actions workflow --- .github/workflows/docs-translate.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs-translate.yaml b/.github/workflows/docs-translate.yaml index 2fe802f94..bf4baa465 100644 --- a/.github/workflows/docs-translate.yaml +++ b/.github/workflows/docs-translate.yaml @@ -75,7 +75,7 @@ jobs: - name: Start Translate run: | cp docs/index.md docs/en/index.md - pnpm run doc-translate + pnpm run docs:translate - name: Commit Updated uses: stefanzweifel/git-auto-commit-action@v4 From f53d9bf6a90a1f6aed244a316a43d3848a8f15a7 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 21:57:33 +0800 Subject: [PATCH 04/16] docs: update translation for cache documentation to improve clarity --- docs/zh-cn/components/cache.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-cn/components/cache.md b/docs/zh-cn/components/cache.md index f5ba4fa95..b64b99c7e 100644 --- a/docs/zh-cn/components/cache.md +++ b/docs/zh-cn/components/cache.md @@ -62,4 +62,4 @@ di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { ## 参考 -Likes [Laravel-Cache](https://laravel.com/docs/8.x/cache) +参照 [Laravel-Cache](https://laravel.com/docs/8.x/cache) From 85708e57b86f9b48051ffcc163c86d1078993bf3 Mon Sep 17 00:00:00 2001 From: huangdijia Date: Tue, 31 Dec 2024 13:59:20 +0000 Subject: [PATCH 05/16] Update docs and translate --- docs/zh-hk/components/cache.md | 2 +- docs/zh-hk/components/encryption.md | 2 +- docs/zh-tw/components/cache.md | 2 +- docs/zh-tw/components/encryption.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh-hk/components/cache.md b/docs/zh-hk/components/cache.md index d43e5afd7..63fa26db8 100644 --- a/docs/zh-hk/components/cache.md +++ b/docs/zh-hk/components/cache.md @@ -62,4 +62,4 @@ di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { ## 參考 -Likes [Laravel-Cache](https://laravel.com/docs/8.x/cache) +參照 [Laravel-Cache](https://laravel.com/docs/8.x/cache) diff --git a/docs/zh-hk/components/encryption.md b/docs/zh-hk/components/encryption.md index cf9ee1baf..c9e82942b 100644 --- a/docs/zh-hk/components/encryption.md +++ b/docs/zh-hk/components/encryption.md @@ -16,7 +16,7 @@ php bin/hyperf.php vendor:publish friendsofhyperf/encryption ## 使用 -```shell +```php $encryptString = encrypt($string); $decryptString = decrypt($encryptString); ``` diff --git a/docs/zh-tw/components/cache.md b/docs/zh-tw/components/cache.md index c63403ade..280f49666 100644 --- a/docs/zh-tw/components/cache.md +++ b/docs/zh-tw/components/cache.md @@ -62,4 +62,4 @@ di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { ## 參考 -Likes [Laravel-Cache](https://laravel.com/docs/8.x/cache) +參照 [Laravel-Cache](https://laravel.com/docs/8.x/cache) diff --git a/docs/zh-tw/components/encryption.md b/docs/zh-tw/components/encryption.md index facd45a08..d1222efa2 100644 --- a/docs/zh-tw/components/encryption.md +++ b/docs/zh-tw/components/encryption.md @@ -16,7 +16,7 @@ php bin/hyperf.php vendor:publish friendsofhyperf/encryption ## 使用 -```shell +```php $encryptString = encrypt($string); $decryptString = decrypt($encryptString); ``` From c3fc727bb01367c9f55985de10432c6dde80f930 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:07:52 +0800 Subject: [PATCH 06/16] ci: add dependency on translate-zh job for English translation --- .github/workflows/docs-translate.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs-translate.yaml b/.github/workflows/docs-translate.yaml index bf4baa465..25a42e4da 100644 --- a/.github/workflows/docs-translate.yaml +++ b/.github/workflows/docs-translate.yaml @@ -50,6 +50,7 @@ jobs: commit_message: Update docs and translate translate-en: + needs: translate-zh runs-on: ubuntu-latest env: DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} From b29705b28ac4500183ce0a3f4bfc1f2c2e1a4c1b Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:09:17 +0800 Subject: [PATCH 07/16] docs: update wording for clarity in cache and fast-paginate documentation --- docs/zh-cn/components/cache.md | 2 +- docs/zh-cn/components/fast-paginate.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh-cn/components/cache.md b/docs/zh-cn/components/cache.md index b64b99c7e..6a9be1749 100644 --- a/docs/zh-cn/components/cache.md +++ b/docs/zh-cn/components/cache.md @@ -62,4 +62,4 @@ di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { ## 参考 -参照 [Laravel-Cache](https://laravel.com/docs/8.x/cache) +参阅 [Laravel-Cache](https://laravel.com/docs/8.x/cache) diff --git a/docs/zh-cn/components/fast-paginate.md b/docs/zh-cn/components/fast-paginate.md index f305f8f77..adb24b466 100644 --- a/docs/zh-cn/components/fast-paginate.md +++ b/docs/zh-cn/components/fast-paginate.md @@ -20,7 +20,7 @@ select * from contacts -- The full data that you want to show your ) ``` -> 运行上述查询时,您可能会遇到错误!例如 `This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery.` +> 运行上述查询时,您可能会遇到错误!例如 `This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery.` > 在这个包中,我们将它们作为[两个独立的查询](https://github.com/hammerstonedev/fast-paginate/blob/154da286f8160a9e75e64e8025b0da682aa2ba23/src/BuilderMixin.php#L62-L79)来运行以解决这个问题! 根据您的数据集,性能提升可能会有所不同,但这种方法允许数据库检查尽可能少的数据以满足用户的需求。 From fa44465cab9f83dcf6a8b5865c161adecd634c3e Mon Sep 17 00:00:00 2001 From: huangdijia Date: Tue, 31 Dec 2024 14:10:25 +0000 Subject: [PATCH 08/16] Update docs and translate --- docs/zh-hk/components/cache.md | 2 +- docs/zh-hk/components/fast-paginate.md | 2 +- docs/zh-tw/components/cache.md | 2 +- docs/zh-tw/components/fast-paginate.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh-hk/components/cache.md b/docs/zh-hk/components/cache.md index 63fa26db8..a1ba165af 100644 --- a/docs/zh-hk/components/cache.md +++ b/docs/zh-hk/components/cache.md @@ -62,4 +62,4 @@ di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { ## 參考 -參照 [Laravel-Cache](https://laravel.com/docs/8.x/cache) +參閲 [Laravel-Cache](https://laravel.com/docs/8.x/cache) diff --git a/docs/zh-hk/components/fast-paginate.md b/docs/zh-hk/components/fast-paginate.md index 63915369b..c38ed35d7 100644 --- a/docs/zh-hk/components/fast-paginate.md +++ b/docs/zh-hk/components/fast-paginate.md @@ -20,7 +20,7 @@ select * from contacts -- The full data that you want to show your ) ``` -> 運行上述查詢時,您可能會遇到錯誤!例如 `This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery.` +> 運行上述查詢時,您可能會遇到錯誤!例如 `This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery.` > 在這個包中,我們將它們作為[兩個獨立的查詢](https://github.com/hammerstonedev/fast-paginate/blob/154da286f8160a9e75e64e8025b0da682aa2ba23/src/BuilderMixin.php#L62-L79)來運行以解決這個問題! 根據您的數據集,性能提升可能會有所不同,但這種方法允許數據庫檢查儘可能少的數據以滿足用户的需求。 diff --git a/docs/zh-tw/components/cache.md b/docs/zh-tw/components/cache.md index 280f49666..5a4ac5006 100644 --- a/docs/zh-tw/components/cache.md +++ b/docs/zh-tw/components/cache.md @@ -62,4 +62,4 @@ di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { ## 參考 -參照 [Laravel-Cache](https://laravel.com/docs/8.x/cache) +參閱 [Laravel-Cache](https://laravel.com/docs/8.x/cache) diff --git a/docs/zh-tw/components/fast-paginate.md b/docs/zh-tw/components/fast-paginate.md index 529ec68d2..ac8d9c520 100644 --- a/docs/zh-tw/components/fast-paginate.md +++ b/docs/zh-tw/components/fast-paginate.md @@ -20,7 +20,7 @@ select * from contacts -- The full data that you want to show your ) ``` -> 執行上述查詢時,您可能會遇到錯誤!例如 `This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery.` +> 執行上述查詢時,您可能會遇到錯誤!例如 `This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery.` > 在這個包中,我們將它們作為[兩個獨立的查詢](https://github.com/hammerstonedev/fast-paginate/blob/154da286f8160a9e75e64e8025b0da682aa2ba23/src/BuilderMixin.php#L62-L79)來執行以解決這個問題! 根據您的資料集,效能提升可能會有所不同,但這種方法允許資料庫檢查儘可能少的資料以滿足使用者的需求。 From 20fe4e6a1e9d5f351f78af8145ba1fbb2df50961 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:20:37 +0800 Subject: [PATCH 09/16] ci: add git pull command before translation job --- .github/workflows/docs-translate.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs-translate.yaml b/.github/workflows/docs-translate.yaml index 25a42e4da..8bdb40574 100644 --- a/.github/workflows/docs-translate.yaml +++ b/.github/workflows/docs-translate.yaml @@ -75,6 +75,7 @@ jobs: - name: Start Translate run: | + git pull cp docs/index.md docs/en/index.md pnpm run docs:translate From 0fdbc9a27056d434432ebb6b733222212319aec8 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:25:59 +0800 Subject: [PATCH 10/16] ci: enhance translation workflow with environment setup and package installation --- .github/workflows/docs-translate.yaml | 54 ++++++++++----------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/.github/workflows/docs-translate.yaml b/.github/workflows/docs-translate.yaml index 8bdb40574..cc8de06a0 100644 --- a/.github/workflows/docs-translate.yaml +++ b/.github/workflows/docs-translate.yaml @@ -7,11 +7,25 @@ on: jobs: translate-zh: + env: + DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + version: 9 + run_install: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -36,50 +50,22 @@ jobs: cd .. rm -rf opencc4php + - name: Install Packages + run: pnpm install + - name: Setup Dependencies run: composer install - - name: Start Translate + - name: Start Translate ZH run: | cp docs/index.md docs/zh-cn/index.md php bin/doc-translate - - name: Commit Updated - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Update docs and translate - - translate-en: - needs: translate-zh - runs-on: ubuntu-latest - env: - DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - name: Install pnpm - with: - version: 9 - run_install: false - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install - - - name: Start Translate + - name: Start Translate EN run: | - git pull - cp docs/index.md docs/en/index.md pnpm run docs:translate - name: Commit Updated uses: stefanzweifel/git-auto-commit-action@v4 with: - commit_message: Update docs and translate \ No newline at end of file + commit_message: Update docs and translate From 7717da1934defb2fb8b57d3b0e7ea99cd3fdd9d0 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:28:24 +0800 Subject: [PATCH 11/16] ci: rename translation job from translate-zh to translate --- .github/workflows/docs-translate.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs-translate.yaml b/.github/workflows/docs-translate.yaml index cc8de06a0..ff4f94553 100644 --- a/.github/workflows/docs-translate.yaml +++ b/.github/workflows/docs-translate.yaml @@ -6,7 +6,7 @@ on: - 'docs/**' jobs: - translate-zh: + translate: env: DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} runs-on: ubuntu-latest From 067b9d733f711a9925e74e2f8570890dd80955fc Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:29:08 +0800 Subject: [PATCH 12/16] ci: reorder steps in translation workflow for clarity --- .github/workflows/docs-translate.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs-translate.yaml b/.github/workflows/docs-translate.yaml index ff4f94553..2416f7965 100644 --- a/.github/workflows/docs-translate.yaml +++ b/.github/workflows/docs-translate.yaml @@ -14,8 +14,8 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 - name: Install pnpm + - name: Install pnpm + uses: pnpm/action-setup@v4 with: version: 9 run_install: false From 52205fb9d153fc6a750e380459cfe2a169aad5a8 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:37:07 +0800 Subject: [PATCH 13/16] ci: implement retry logic and batch processing for translation --- bin/doc-translate.js | 71 ++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/bin/doc-translate.js b/bin/doc-translate.js index f9ea1272e..39aa7a723 100644 --- a/bin/doc-translate.js +++ b/bin/doc-translate.js @@ -4,43 +4,64 @@ import path from 'path'; const endpoint = "https://api.deepseek.com"; const token = process.env["DEEPSEEK_API_KEY"]; +const MAX_CONCURRENT = 5; // 最大并发数 +const MAX_RETRIES = 3; // 最大重试次数 const openai = new OpenAI({ baseURL: endpoint, apiKey: token, }); -async function translateContent(content) { - const completion = await openai.chat.completions.create({ - messages: [ - { role: "system", content: "You are a professional translator. Translate the following Chinese markdown content to English. Keep all markdown formatting intact." }, - { role: "user", content: content } - ], - model: "deepseek-chat", - }); - return completion.choices[0].message.content; +async function translateWithRetry(content, retries = 0) { + try { + const completion = await openai.chat.completions.create({ + messages: [ + { role: "system", content: "You are a professional translator. Translate the following Chinese markdown content to English. Keep all markdown formatting intact." }, + { role: "user", content: content } + ], + model: "deepseek-chat", + }); + return completion.choices[0].message.content; + } catch (error) { + if (retries < MAX_RETRIES) { + await new Promise(resolve => setTimeout(resolve, 1000 * (retries + 1))); + return translateWithRetry(content, retries + 1); + } + throw error; + } +} + +async function processFile(srcPath, destPath) { + const destFolder = path.dirname(destPath); + await mkdir(destFolder, { recursive: true }); + + const content = await readFile(srcPath, 'utf8'); + const translatedContent = await translateWithRetry(content); + const finalContent = translatedContent.replace(/\/zh-cn\//g, '/en/'); + await writeFile(destPath, finalContent); + console.log(`Translated: ${path.basename(srcPath)}`); } async function translateFiles(srcDir, destDir) { try { const files = await readdir(srcDir, { recursive: true }); - - for (const file of files) { - if (!file.endsWith('.md')) continue; - - const srcPath = path.join(srcDir, file); - const destPath = path.join(destDir, file); - const destFolder = path.dirname(destPath); - - await mkdir(destFolder, { recursive: true }); - - const content = await readFile(srcPath, 'utf8'); - const translatedContent = await translateContent(content); - const finalContent = translatedContent.replace(/\/zh-cn\//g, '/en/'); - await writeFile(destPath, finalContent); - - console.log(`Translated: ${file}`); + const mdFiles = files.filter(file => file.endsWith('.md')); + + // 将文件分批处理 + for (let i = 0; i < mdFiles.length; i += MAX_CONCURRENT) { + const batch = mdFiles.slice(i, i + MAX_CONCURRENT); + const promises = batch.map(file => { + const srcPath = path.join(srcDir, file); + const destPath = path.join(destDir, file); + return processFile(srcPath, destPath).catch(error => { + console.error(`Error translating ${file}:`, error); + }); + }); + + await Promise.all(promises); } + + console.log('All translations completed!'); } catch (error) { console.error('Translation error:', error); } From 0742887b18595a6cc383936e0594dd0bf2edafc9 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:38:32 +0800 Subject: [PATCH 14/16] docs: update comments in cache.md to provide Chinese translations --- docs/zh-cn/components/cache.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh-cn/components/cache.md b/docs/zh-cn/components/cache.md index 6a9be1749..197f5f696 100644 --- a/docs/zh-cn/components/cache.md +++ b/docs/zh-cn/components/cache.md @@ -29,7 +29,7 @@ class IndexController public function index() { return $this->cache->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); } } @@ -41,7 +41,7 @@ class IndexController use FriendsOfHyperf\Cache\Facade\Cache; Cache::remember($key, $ttl=60, function() { - // return sth + // 返回值 }); ``` @@ -52,11 +52,11 @@ use FriendsOfHyperf\Cache\Facade\Cache; use FriendsOfHyperf\Cache\CacheManager; Cache::store('co')->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); ``` From 45e99ef48aae0e080acb9d72fdf702bfd7a9f932 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:39:56 +0800 Subject: [PATCH 15/16] docs: update cache.md for improved clarity in reference section --- docs/zh-cn/components/cache.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-cn/components/cache.md b/docs/zh-cn/components/cache.md index 197f5f696..55cb896c1 100644 --- a/docs/zh-cn/components/cache.md +++ b/docs/zh-cn/components/cache.md @@ -62,4 +62,4 @@ di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { ## 参考 -参阅 [Laravel-Cache](https://laravel.com/docs/8.x/cache) +有关更多信息,请参阅 [Laravel-Cache](https://laravel.com/docs/8.x/cache) From 4a45330278770a62c21a4643030cc42cfb7d5422 Mon Sep 17 00:00:00 2001 From: huangdijia Date: Tue, 31 Dec 2024 14:45:23 +0000 Subject: [PATCH 16/16] Update docs and translate --- docs/en/components/amqp-job.md | 2 +- docs/en/components/cache.md | 14 +- docs/en/components/command-signals.md | 4 +- docs/en/components/command-validation.md | 4 +- docs/en/components/compoships.md | 24 +- docs/en/components/confd.md | 8 +- docs/en/components/config-consul.md | 2 +- docs/en/components/console-spinner.md | 4 +- docs/en/components/di-plus.md | 4 +- docs/en/components/elasticsearch.md | 2 +- docs/en/components/fast-paginate.md | 24 +- docs/en/components/grpc-validation.md | 2 +- docs/en/components/http-client.md | 2 +- docs/en/components/http-logger.md | 4 +- docs/en/components/ide-helper.md | 6 +- docs/en/components/index.md | 2 +- docs/en/components/ipc-broadcaster.md | 2 +- docs/en/components/lock.md | 22 +- docs/en/components/mail.md | 12 +- docs/en/components/middleware-plus.md | 4 +- docs/en/components/model-factory.md | 4 +- docs/en/components/model-hashids.md | 64 ++-- docs/en/components/model-morph-addon.md | 2 +- docs/en/components/model-observer.md | 16 +- docs/en/components/model-scope.md | 6 +- docs/en/components/mysql-grammar-addon.md | 10 +- docs/en/components/notification-easysms.md | 6 +- docs/en/components/notification-mail.md | 4 +- docs/en/components/notification.md | 18 +- docs/en/components/openai-client.md | 14 +- docs/en/components/pest-plugin-hyperf.md | 2 +- docs/en/components/pretty-console.md | 8 +- docs/en/components/purifier.md | 24 +- docs/en/components/recaptcha.md | 6 +- docs/en/components/redis-subscriber.md | 36 ++- docs/en/components/sentry.md | 14 +- docs/en/components/tcp-sender.md | 35 ++- docs/en/components/telescope-elasticsearch.md | 2 +- docs/en/components/telescope.md | 41 +-- docs/en/components/tinker.md | 12 +- docs/en/components/trigger.md | 6 +- docs/en/components/validated-dto.md | 273 ++++++++++++++++-- docs/en/components/web-tinker.md | 2 +- docs/en/faq/index.md | 2 +- docs/en/guide/index.md | 2 +- docs/en/guide/introduce/about.md | 2 +- docs/en/guide/start/components.md | 53 ++-- docs/en/index.md | 27 +- docs/zh-hk/components/cache.md | 10 +- docs/zh-tw/components/cache.md | 10 +- 50 files changed, 553 insertions(+), 306 deletions(-) diff --git a/docs/en/components/amqp-job.md b/docs/en/components/amqp-job.md index abcca4384..611ce9853 100644 --- a/docs/en/components/amqp-job.md +++ b/docs/en/components/amqp-job.md @@ -2,7 +2,7 @@ ## Introduction -`friendsofhyperf/amqp-job` is an asynchronous task component based on the `hyperf/amqp` component. It supports dispatching tasks to an AMQP service, which are then consumed by consumers. By encapsulating the `hyperf/amqp` component, it provides a more convenient way to dispatch and consume tasks. +`friendsofhyperf/amqp-job` is an asynchronous task component based on the `hyperf/amqp` component, which supports dispatching tasks to the AMQP service and then consuming them via consumers. It encapsulates the `hyperf/amqp` component, providing a more convenient way to dispatch and consume tasks. ## Installation diff --git a/docs/en/components/cache.md b/docs/en/components/cache.md index db7ca85b5..c5d704b58 100644 --- a/docs/en/components/cache.md +++ b/docs/en/components/cache.md @@ -12,7 +12,7 @@ composer require friendsofhyperf/cache ## Usage -### Annotations +### Annotation ```php namespace App\Controller; @@ -29,7 +29,7 @@ class IndexController public function index() { return $this->cache->remember($key, $ttl=60, function() { - // return sth + // Return value }); } } @@ -41,7 +41,7 @@ class IndexController use FriendsOfHyperf\Cache\Facade\Cache; Cache::remember($key, $ttl=60, function() { - // return sth + // Return value }); ``` @@ -52,14 +52,14 @@ use FriendsOfHyperf\Cache\Facade\Cache; use FriendsOfHyperf\Cache\CacheManager; Cache::store('co')->remember($key, $ttl=60, function() { - // return sth + // Return value }); di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { - // return sth + // Return value }); ``` -## References +## Reference -Like [Laravel-Cache](https://laravel.com/docs/8.x/cache) \ No newline at end of file +For more information, please refer to [Laravel-Cache](https://laravel.com/docs/8.x/cache) \ No newline at end of file diff --git a/docs/en/components/command-signals.md b/docs/en/components/command-signals.md index 66cdccad2..462e80759 100644 --- a/docs/en/components/command-signals.md +++ b/docs/en/components/command-signals.md @@ -1,6 +1,6 @@ # Command Signals -Signal handling component for Hyperf Command. +Hyperf Command Signal Handling Component. ## Installation @@ -47,7 +47,7 @@ class FooCommand extends HyperfCommand } ``` -## Running +## Execution - `Ctrl + C` diff --git a/docs/en/components/command-validation.md b/docs/en/components/command-validation.md index 1b46a4814..eee84971b 100644 --- a/docs/en/components/command-validation.md +++ b/docs/en/components/command-validation.md @@ -1,6 +1,6 @@ # Command Validation -A validation component for Hyperf command line. +A validation component for Hyperf command-line applications. ## Installation @@ -27,7 +27,7 @@ class FooCommand extends HyperfCommand use ValidatesInput; /** - * The command line to execute + * The command line to be executed. */ protected string $name = 'foo:hello {?name : The name of the person to greet.}'; diff --git a/docs/en/components/compoships.md b/docs/en/components/compoships.md index 663849861..3353461b2 100644 --- a/docs/en/components/compoships.md +++ b/docs/en/components/compoships.md @@ -1,10 +1,10 @@ # Compoships -**Compoships** provides the ability to define relationships based on two (or more) columns in Hyperf's Model ORM. When dealing with third-party or pre-existing schemas/databases, there is often a need to match multiple columns in the definition of Eloquent relationships. +**Compoships** provides the ability to specify relationships based on two (or more) columns in Hyperf's Model ORM. This is particularly useful when dealing with third-party or pre-existing schemas/databases where you need to match multiple columns in the definition of Eloquent relationships. -## Problem +## The Problem -Eloquent does not support composite keys. Therefore, it is not possible to define relationships from one model to another by matching multiple columns. Attempting to use `where` clauses (as shown in the example below) does not work when eager loading relationships because **$this->team_id** is null when handling the relationship. +Eloquent does not support composite keys. Therefore, it is not possible to define a relationship from one model to another by matching multiple columns. Attempting to use a `where` clause (as shown in the example below) does not work when eager loading relationships because **$this->team_id** is null when the relationship is being processed. ```php namespace App; @@ -23,7 +23,7 @@ class User extends Model ## Installation -It is recommended to install the **Compoships** component using [Composer](http://getcomposer.org/). +It is recommended to install **Compoships** via [Composer](http://getcomposer.org/). ```shell composer require friendsofhyperf/compoships @@ -33,17 +33,17 @@ composer require friendsofhyperf/compoships ### Using the `FriendsOfHyperf\Compoships\Database\Eloquent\Model` Class -Simply have your model classes extend the `FriendsOfHyperf\Compoships\Database\Eloquent\Model` base class. `FriendsOfHyperf\Compoships\Database\Eloquent\Model` extends the `Eloquent` base class without altering its core functionality. +Simply have your model class extend the `FriendsOfHyperf\Compoships\Database\Eloquent\Model` base class. `FriendsOfHyperf\Compoships\Database\Eloquent\Model` extends the `Eloquent` base class without altering its core functionality. ### Using the `FriendsOfHyperf\Compoships\Compoships` Trait -If for some reason you cannot extend `FriendsOfHyperf\Compoships\Database\Eloquent\Model` in your model, you can use the `FriendsOfHyperf\Compoships\Compoships` trait. Simply use this trait in your model. +If for some reason you cannot extend your model from `FriendsOfHyperf\Compoships\Database\Eloquent\Model`, you can utilize the `FriendsOfHyperf\Compoships\Compoships` trait. Just use the trait in your model. **Note:** To define a multi-column relationship from model *A* to another model *B*, **both models must extend `FriendsOfHyperf\Compoships\Database\Eloquent\Model` or use the `FriendsOfHyperf\Compoships\Compoships` trait** ### Usage -... Now we can define relationships from model *A* to another model *B* by matching two or more columns (by passing an array of columns instead of a string). +... Now we can define a relationship from model *A* to another model *B* by matching two or more columns (by passing an array of columns instead of a string). ```php namespace App; @@ -61,7 +61,7 @@ class A extends Model } ``` -We can use the same syntax to define the inverse relationship: +We can use the same syntax to define the inverse of the relationship: ```php namespace App; @@ -81,15 +81,15 @@ class B extends Model ### Example -As an example, suppose we have a task list with categories, managed by multiple user teams, where: +As an example, let's assume we have a task list with categories, managed by multiple user teams, where: - A task belongs to a category - A task is assigned to a team - A team has many users - A user belongs to a team -- A user is responsible for a category's tasks +- A user is responsible for tasks in a category -The user responsible for a specific task is the currently responsible user for that category within the team. +The user responsible for a specific task is the user currently responsible for that category within the assigned team. ```php namespace App; @@ -107,7 +107,7 @@ class User extends Model } ``` -The same syntax can be used to define the inverse relationship: +The same syntax can be used to define the inverse of the relationship: ```php namespace App; diff --git a/docs/en/components/confd.md b/docs/en/components/confd.md index 2033a7451..e9bc05539 100644 --- a/docs/en/components/confd.md +++ b/docs/en/components/confd.md @@ -1,6 +1,6 @@ # Confd -Configuration management component for Hyperf. +Hyperf's configuration management component. ## Installation @@ -13,13 +13,13 @@ composer require friendsofhyperf/nacos ## Commands -Fetch configuration from `etcd/nacos` and update `.env`. +Fetch configurations from `etcd/nacos` and update `.env`. ```shell php bin/hyperf.php confd:env ``` -## Define Listener +## Defining Listeners ```php withSpinner(User::all(), function($user) { diff --git a/docs/en/components/di-plus.md b/docs/en/components/di-plus.md index 834d1ad37..53cf53a9d 100644 --- a/docs/en/components/di-plus.md +++ b/docs/en/components/di-plus.md @@ -1,6 +1,6 @@ # DI Plus -A dependency injection enhancement component for Hyperf. +Enhanced Dependency Injection Component for Hyperf. ## Installation @@ -38,7 +38,7 @@ class Foo2 } ``` -Supports annotation-based configuration +Supports annotation-based injection ```php When running the query above, you might encounter errors! For example, `This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery.` -> In this package, we run these as [two separate queries](https://github.com/hammerstonedev/fast-paginate/blob/154da286f8160a9e75e64e8025b0da682aa2ba23/src/BuilderMixin.php#L62-L79) to mitigate this problem! +> When running the above query, you might encounter an error! For example, `This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery.` +> In this package, we run them as [two separate queries](https://github.com/hammerstonedev/fast-paginate/blob/154da286f8160a9e75e64e8025b0da682aa2ba23/src/BuilderMixin.php#L62-L79) to solve this issue! -Depending on your dataset, the performance improvement may vary, but this approach allows the database to inspect as little data as possible to fulfill the user's request. +Depending on your dataset, the performance improvement may vary, but this approach allows the database to examine as little data as possible to meet the user's needs. -While this method is unlikely to perform worse than traditional `offset`/`limit`, it is still a possibility, so be sure to test on your dataset! +While this method is unlikely to perform worse than the traditional `offset` / `limit`, it is possible, so be sure to test it on your data! -> If you'd like to read a 3,000-word article on the theory behind this package, visit [aaronfrancis.com/2022/efficient-pagination-using-deferred-joins](https://aaronfrancis.com/2022/efficient-pagination-using-deferred-joins). +> If you want to read a 3,000-word article on the theory behind this package, visit [aaronfrancis.com/2022/efficient-pagination-using-deferred-joins](https://aaronfrancis.com/2022/efficient-pagination-using-deferred-joins). ## Installation @@ -35,13 +35,13 @@ While this method is unlikely to perform worse than traditional `offset`/`limit` composer require friendsofhyperf/fast-paginate ``` -No further steps are required. The service provider will be automatically loaded by Hyperf. +No additional steps are required; the service provider will be automatically loaded by Hyperf. ## Usage -Wherever you would use `Model::query()->paginate()`, you can use `Model::query()->fastPaginate()` instead! It's that simple! The method signature is the same. +Anywhere you would use `Model::query()->paginate()`, you can use `Model::query()->fastPaginate()`! It's that simple! The method signature is the same. -Relationships are also supported: +Relations are also supported: ```php User::first()->posts()->fastPaginate(); diff --git a/docs/en/components/grpc-validation.md b/docs/en/components/grpc-validation.md index 9207f3612..b96444c07 100644 --- a/docs/en/components/grpc-validation.md +++ b/docs/en/components/grpc-validation.md @@ -1,6 +1,6 @@ # Grpc Validation -GRPC validation component for Hyperf. +A GRPC validation component for Hyperf. ## Installation diff --git a/docs/en/components/http-client.md b/docs/en/components/http-client.md index 7b1b7cb6b..4baa6d37b 100644 --- a/docs/en/components/http-client.md +++ b/docs/en/components/http-client.md @@ -16,6 +16,6 @@ use FriendsOfHyperf\Http\Client\Http; $response = Http::get('https://example.com'); ``` -## Reference Documentation +## Documentation For more information, please refer to the [Laravel HTTP Client Documentation](https://laravel.com/docs/9.x/http-client). \ No newline at end of file diff --git a/docs/en/components/http-logger.md b/docs/en/components/http-logger.md index 80efa41e1..a28908cd6 100644 --- a/docs/en/components/http-logger.md +++ b/docs/en/components/http-logger.md @@ -1,11 +1,11 @@ # Http Logger -An HTTP logging component provided for Hyperf. +An HTTP logging component for Hyperf. ## Installation ```shell -composer require "friendsofhyperf/http-logger" +composer require "friendsofhyperf/http-logger ``` ## Publish Configuration diff --git a/docs/en/components/ide-helper.md b/docs/en/components/ide-helper.md index fa78acffa..0fdd128de 100644 --- a/docs/en/components/ide-helper.md +++ b/docs/en/components/ide-helper.md @@ -1,6 +1,6 @@ # IDE Helper -The IDE helper component for Hyperf +The IDE Helper component for Hyperf ## Installation @@ -10,13 +10,13 @@ composer require friendsofhyperf/ide-helper ## Usage -- Generate model helpers +- Generate Model Helper ```shell php ./bin/hyperf.php ide-helper:model ``` -- Generate macro helpers +- Generate Macro Helper ```shell php ./bin/hyperf.php ide-helper:macro diff --git a/docs/en/components/index.md b/docs/en/components/index.md index ad2c5d2b7..c7f545eac 100644 --- a/docs/en/components/index.md +++ b/docs/en/components/index.md @@ -1,3 +1,3 @@ # Components -👈 Please check the menu on the left and select a component. \ No newline at end of file +👈 Please refer to the menu on the left to select components \ No newline at end of file diff --git a/docs/en/components/ipc-broadcaster.md b/docs/en/components/ipc-broadcaster.md index 3f936068e..e29100320 100644 --- a/docs/en/components/ipc-broadcaster.md +++ b/docs/en/components/ipc-broadcaster.md @@ -1,6 +1,6 @@ # Ipc Broadcaster -The Hyperf process communication broadcaster component. +Hyperf Inter-Process Communication Broadcast Component. ## Installation diff --git a/docs/en/components/lock.md b/docs/en/components/lock.md index e9b6e896f..41c048037 100644 --- a/docs/en/components/lock.md +++ b/docs/en/components/lock.md @@ -1,6 +1,6 @@ # Lock -The Hyperf atomic lock component. +Hyperf Atomic Lock Component. ## Installation @@ -10,7 +10,7 @@ The Hyperf atomic lock component. composer require friendsofhyperf/lock ``` -- Publish configuration +- Publish Configuration ```shell php bin/hyperf.php vendor:publish friendsofhyperf/lock -i config @@ -24,21 +24,21 @@ You can use the `lock()` method to create and manage locks: $lock = lock($name = 'foo', $seconds = 10, $owner = null); if ($lock->get()) { - // Acquired the lock for 10 seconds... + // Lock acquired for 10 seconds... $lock->release(); } ``` -The `get` method can also accept a closure. After the closure executes, the lock will be automatically released: +The `get` method can also accept a closure. The lock will be automatically released after the closure is executed: ```php lock('foo')->get(function () { - // Acquired an indefinite lock and automatically released it... + // Lock acquired indefinitely and automatically released... }); ``` -If the lock is unavailable when requested, you can specify a number of seconds to wait. If the lock cannot be acquired within the specified timeout, a `FriendsOfHyperf\Lock\Exception\LockTimeoutException` will be thrown. +If the lock is not available when requested, you can control the number of seconds to wait. If the lock cannot be acquired within the specified time limit, a `FriendsOfHyperf\Lock\Exception\LockTimeoutException` will be thrown: ```php use FriendsOfHyperf\Lock\Exception\LockTimeoutException; @@ -48,19 +48,19 @@ $lock = lock('foo', 10); try { $lock->block(5); - // Acquired the lock after waiting up to 5 seconds... + // Lock acquired after waiting for up to 5 seconds... } catch (LockTimeoutException $e) { - // Failed to acquire the lock... + // Unable to acquire lock... } finally { optional($lock)->release(); } lock('foo', 10)->block(5, function () { - // Acquired the lock after waiting up to 5 seconds... + // Lock acquired after waiting for up to 5 seconds... }); ``` -Annotation-based approach: +Annotation Method ```php use FriendsOfHyperf\Lock\Annotation\Lock; @@ -74,7 +74,7 @@ class Foo public function bar() { $this->lock->get(function () { - // Acquired an indefinite lock and automatically released it... + // Lock acquired indefinitely and automatically released... }); } } diff --git a/docs/en/components/mail.md b/docs/en/components/mail.md index e68f636eb..c66b552c6 100644 --- a/docs/en/components/mail.md +++ b/docs/en/components/mail.md @@ -1,6 +1,6 @@ # Mail -The email component supports sending emails using drivers such as SMTP, SendMail, Log, and more. It also supports Markdown template rendering. +The email component supports sending emails using drivers such as SMTP, SendMail, and Log, and also supports Markdown template rendering. ## Installation @@ -96,8 +96,8 @@ return [ 'log' => [ 'transport' => 'log', - 'group' => env('MAIL_LOG_GROUP', 'default'), - 'name' => env('MAIL_LOG_NAME', 'mail'), + 'group' => env('MAIL_LOG_GROUP','default'), + 'name' => env('MAIL_LOG_NAME','mail'), ], 'array' => [ @@ -157,7 +157,7 @@ return [ ]; ``` -### Creating a Mail Class +### Building the Mail Class ```shell php bin/hyperf.php gen:mail TestMail @@ -217,7 +217,7 @@ class TestMail extends Mailable } ``` -### Define a Controller or Service +### Defining the Controller or Service ```php // app/Controller/IndexController.php @@ -230,7 +230,7 @@ class IndexController extends AbstractController { $user = $this->request->input('user', 'Hyperf'); $mailer = Mail::mailer('smtp'); - $mailer->alwaysFrom('root@imoi.cn', 'Hyperf'); + $mailer->alwaysFrom('root@imoi.cn','Hyperf'); $mailer->to('2771717608@qq.com')->send(new \App\Mail\TestMail($user)); $method = $this->request->getMethod(); diff --git a/docs/en/components/middleware-plus.md b/docs/en/components/middleware-plus.md index c6bbba17c..76056d240 100644 --- a/docs/en/components/middleware-plus.md +++ b/docs/en/components/middleware-plus.md @@ -52,7 +52,7 @@ Router::addRoute(['GET', 'POST', 'HEAD'], '/', 'App\Controller\IndexController:: ]); ``` -- Set Middleware Aliases +- Set Middleware Alias ```php // config/autoload/dependencies.php @@ -62,7 +62,7 @@ return [ ]; ``` -- Use Middleware Aliases +- Use Middleware Alias ```php use App\Middleware\FooMiddleware; diff --git a/docs/en/components/model-factory.md b/docs/en/components/model-factory.md index 027f3953b..72446d8cc 100644 --- a/docs/en/components/model-factory.md +++ b/docs/en/components/model-factory.md @@ -6,7 +6,7 @@ composer require friendsofhyperf/model-factory --dev ``` -Additionally, publish the vendor configuration files to your application (mandatory for dependencies): +Additionally, publish the vendor configuration file to your application (required for dependencies): ```shell php bin/hyperf.php vendor:publish friendsofhyperf/model-factory @@ -23,6 +23,7 @@ declare(strict_types=1); use App\Model\User; + $factory->define(User::class, function (Faker\Generator $faker) { return [ 'name' => $faker->name, @@ -56,6 +57,7 @@ class UserSeeder extends Seeder 'name' => 'Admin' ]); + // Create 20 random users factory(User::class, 20)->create(); } diff --git a/docs/en/components/model-hashids.md b/docs/en/components/model-hashids.md index 11aa7e086..fb149bcc5 100644 --- a/docs/en/components/model-hashids.md +++ b/docs/en/components/model-hashids.md @@ -1,15 +1,15 @@ # Model Hashids -Using hashids instead of integer IDs in URLs and list items can be more attractive and elegant. For more information, please visit [hashids.org](https://hashids.org/). +Using hashids instead of integer IDs in URLs and list items can be more attractive and clever. For more information, visit [hashids.org](https://hashids.org/). -This package adds hashids to Hyperf models by dynamically encoding/decoding them, instead of persisting them to the database. Therefore, no extra database columns are required, and better performance can be achieved by using primary keys in queries. +This package adds hashids to Hyperf models by dynamically encoding/decoding them, rather than persisting them to the database. This eliminates the need for additional database columns and allows for higher performance by using primary keys in queries. Features include: - Generating hashids for models - Resolving hashids to models - Ability to customize hashid settings for each model -- Using hashids for route model binding (optional) +- Using hashids for route binding (optional) ## Installation @@ -17,36 +17,39 @@ Features include: composer require friendsofhyperf/model-hashids ``` -Additionally, publish the vendor configuration file to your application (required by the dependency): +Additionally, publish the vendor configuration file to your application (required for dependencies): ```shell php bin/hyperf.php vendor:publish friendsofhyperf/model-hashids ``` -## Configuration +## Setup -Basic functionality is provided by using the `HasHashid` trait, and hashid-based route model binding can be enabled by using the `HashidRouting` trait. +Basic functionality is provided by using the `HasHashid` trait, and then hashid-based route binding can be added by using `HashidRouting`. ```php + use Hyperf\Database\Model\Model; use FriendsOfHyperf\ModelHashids\Concerns\HasHashid; use FriendsOfHyperf\ModelHashids\Concerns\HashidRouting; -class Item extends Model +Class Item extends Model { use HasHashid, HashidRouting; } + ``` ### Customizing Hashid Settings -Hashid settings can be customized for each model by overriding the `getHashidsConnection()` method. It must return the name of the connection in `config/autoload/hashids.php`. +You can customize hashid settings for each model by overriding `getHashidsConnection()`. It must return the name of the connection in `config/autoload/hashids.php`. ## Usage ### Basics ```php + // Generating the model hashid based on its key $item->hashid(); @@ -61,28 +64,30 @@ Item::findByHashid($hashid); // throwing a ModelNotFoundException on failure Item::findByHashidOrFail($hashid); -// Decoding a hashid to its equivalent ID +// Decoding a hashid to its equivalent id $item->hashidToId($hashid); -// Encoding an ID to its equivalent hashid +// Encoding an id to its equivalent hashid $item->idToHashid($id); // Getting the name of the hashid connection $item->getHashidsConnection(); + ``` -### Adding the Hashid to the Serialized Model +### Adding Hashid to Serialized Models -To set it as a default: +Set it as the default: ```php + use Hyperf\Database\Model\Model; use FriendsOfHyperf\ModelHashids\Concerns\HasHashid; class Item extends Model { use HasHashid; - + /** * The accessors to append to the model's array form. * @@ -90,19 +95,19 @@ class Item extends Model */ protected $appends = ['hashid']; } + ``` -To set it for specific routes: +Set it for a specific route: -```php -return $item->append('hashid')->toJson(); -``` +`return $item->append('hashid')->toJson();` -### Implicit Route Model Binding +### Implicit Route Binding -If you want to resolve hashid values for models in implicit route model bindings, you can use the `HashidRouting` trait in the model. +If you want to resolve implicit route bindings using the model's hashid value, you can use `HashidRouting` in the model. ```php + use Hyperf\Database\Model\Model; use FriendsOfHyperf\ModelHashids\Concerns\HasHashid; use FriendsOfHyperf\ModelHashids\Concerns\HashidRouting; @@ -111,23 +116,27 @@ class Item extends Model { use HasHashid, HashidRouting; } + ``` -This trait overrides the `getRouteKeyName()`, `getRouteKey()`, and `resolveRouteBindingQuery()` methods to use hashids as the route key. +It overrides `getRouteKeyName()`, `getRouteKey()`, and `resolveRouteBindingQuery()` to use hashids as the route key. -It supports Laravel’s feature for specifying custom route keys. +It supports Laravel's custom specific route key functionality. ```php + Route::get('/items/{item:slug}', function (Item $item) { return $item; }); + ``` #### Customizing the Default Route Key Name -If you want to use a different field as the default for implicit route model bindings, you can override the `getRouteKeyName()` method to return the field name used in the resolution process, and the `getRouteKey()` method to return its value in links. +If you want to resolve implicit route bindings using another field by default, you can override `getRouteKeyName()` to return the field name used in the resolution process and `getRouteKey()` to return its value in links. ```php + use Hyperf\Database\Model\Model; use FriendsOfHyperf\ModelHashids\Concerns\HasHashid; use FriendsOfHyperf\ModelHashids\Concerns\HashidRouting; @@ -146,21 +155,25 @@ class Item extends Model return $this->slug; } } + ``` -You can still specify hashid for particular routes: +You can still specify the hashid for specific routes. ```php + Route::get('/items/{item:hashid}', function (Item $item) { return $item; }); + ``` -#### Supporting Laravel’s Additional Implicit Route Model Binding Features +#### Supporting Other Laravel Implicit Route Binding Features -When using `HashidRouting`, features such as soft deletes and scoped route bindings are also supported. +When using `HashidRouting`, you can still use soft-deletes and child route bindings. ```php + Route::get('/items/{item}', function (Item $item) { return $item; })->withTrashed(); @@ -168,4 +181,5 @@ Route::get('/items/{item}', function (Item $item) { Route::get('/user/{user}/items/{item}', function (User $user, Item $item) { return $item; })->scopeBindings(); + ``` \ No newline at end of file diff --git a/docs/en/components/model-morph-addon.md b/docs/en/components/model-morph-addon.md index 81d53c7c6..388a4ecc2 100644 --- a/docs/en/components/model-morph-addon.md +++ b/docs/en/components/model-morph-addon.md @@ -1,6 +1,6 @@ # Model Morph Addon -A polymorphic extension package that supports using polymorphic relationships in Hyperf models. +The Model Morph Addon supports polymorphic relationships in Hyperf models. ## Installation diff --git a/docs/en/components/model-observer.md b/docs/en/components/model-observer.md index 1622ed301..97588e98c 100644 --- a/docs/en/components/model-observer.md +++ b/docs/en/components/model-observer.md @@ -1,6 +1,6 @@ # Model Observer -The Model Observer component is designed for the Hyperf framework. +The Model Observer component, designed for the Hyperf framework. ## Installation @@ -29,15 +29,15 @@ class FooObserver { public function creating(User $model) { - // do something... + // do sth... } public function created(User $model) { - // do something... + // do sth... } - // other events + // another events } ``` @@ -55,19 +55,19 @@ class FooObserver { public function creating($model) { - // do something... + // do sth... } public function created($model) { - // do something... + // do sth... } - // other events + // another events } ``` -- Bind to model +- Binding to a model ```php namespace App\Model; diff --git a/docs/en/components/model-scope.md b/docs/en/components/model-scope.md index 4b7c06f15..35df67ffd 100644 --- a/docs/en/components/model-scope.md +++ b/docs/en/components/model-scope.md @@ -1,6 +1,6 @@ # Model Scope -The model scope annotation for Hyperf. +The Model Scope annotation component for the Hyperf framework. ## Installation @@ -10,7 +10,7 @@ composer require friendsofhyperf/model-scope ## Usage -- Define a Scope +- Defining a Scope ```php namespace App\Model\Scope; @@ -31,7 +31,7 @@ class AncientScope implements Scope } ``` -- Attach Scope to a Model +- Binding to a Model ```php namespace App\Model; diff --git a/docs/en/components/mysql-grammar-addon.md b/docs/en/components/mysql-grammar-addon.md index fd8028157..f8cfa32e1 100644 --- a/docs/en/components/mysql-grammar-addon.md +++ b/docs/en/components/mysql-grammar-addon.md @@ -1,6 +1,6 @@ # Mysql Grammar Addon -The MySqlGrammar addon for Hyperf. +MySqlGrammar extension component for the Hyperf framework. ## Installation @@ -8,7 +8,7 @@ The MySqlGrammar addon for Hyperf. composer require friendsofhyperf/mysql-grammar-addon --dev ``` -## Before Use +## Before Usage ```php /** @@ -26,7 +26,7 @@ class Event extends Model {} ``` -## After Use +## After Usage ```php /** @@ -34,9 +34,9 @@ class Event extends Model * @property int $user_id User ID * @property string $group_name Event Group * @property string $event_name Event Name - * @property string $page_name Page + * @property string $page_name Page Name * @property string $extra Extra Information - * @property string $device pc, android, ios, touch + * @property string $device pc,android,ios,touch * @property string $device_id Device ID * @property \Carbon\Carbon $created_at Creation Time */ diff --git a/docs/en/components/notification-easysms.md b/docs/en/components/notification-easysms.md index fb61e7ea6..e56aa572d 100644 --- a/docs/en/components/notification-easysms.md +++ b/docs/en/components/notification-easysms.md @@ -8,7 +8,7 @@ composer require friendsofhyperf/notification-easysms:~3.1.0 ## Usage -### Use `Notifiable` Trait in Model +### Use `Notifiable` trait in Model ```php toSms()). - * Documentation: https://github.com/overtrue/easy-sms?tab=readme-ov-file#%E5%AE%9A%E4%B9%89%E7%9F%AD%E4%BF%A1 + * The returned content will be assembled into the SMS model new Message($notification->toSms()). + * Documentation https://github.com/overtrue/easy-sms?tab=readme-ov-file#%E5%AE%9A%E4%B9%89%E7%9F%AD%E4%BF%A1 */ public function toSms(mixed $notifiable): array|Message { diff --git a/docs/en/components/notification-mail.md b/docs/en/components/notification-mail.md index 9b3169879..7d337bf5e 100644 --- a/docs/en/components/notification-mail.md +++ b/docs/en/components/notification-mail.md @@ -51,7 +51,7 @@ class User extends Model php bin/hyperf.php gen:markdown-mail Test ``` -Output +Output: ```php @@ -85,7 +85,7 @@ class Test extends Notification */ public function toMail(object $notifiable): MailMessage { - return (new MailMessage)->from('xxx@xxx.cn', 'Hyperf')->replyTo('xxx@qq.com', 'zds')->markdown('email'); + return (new MailMessage)->from('xxx@xxx.cn','Hyperf')->replyTo('xxx@qq.com','zds')->markdown('email'); } /** diff --git a/docs/en/components/notification.md b/docs/en/components/notification.md index 5d56c334f..9ef4d7181 100644 --- a/docs/en/components/notification.md +++ b/docs/en/components/notification.md @@ -8,7 +8,7 @@ composer require friendsofhyperf/notification:~3.1.0 ## Usage -### Using the `Notifiable` trait in a Model +### Using the `Notifiable` Trait in a Model ```php notify(new TestNotification('System Message: xxx')); +// Notify a message +$user->notify(new TestNotification('System Notification:xxx')); $noReadCount = $user->unreadNotifications()->count(); -$this->output->success('Sent successfully. Unread messages count: ' . $noReadCount); +$this->output->success('Sent successfully, unread messages count:' . $noReadCount); $notifications = $user->unreadNotifications()->first(); -$this->output->success('Message content: ' . $notifications->data['message']); +$this->output->success('Message content:' . $notifications->data['message']); $notifications->markAsRead(); $noReadCount = $user->unreadNotifications()->count(); -$this->output->success('Marked as read. Unread messages count: ' . $noReadCount); +$this->output->success('Marked as read, unread messages count:' . $noReadCount); ``` ### SMS Notifications @@ -237,10 +237,10 @@ return [ ``` -#### Usage in Controller +#### Using in a Controller ```php $user = User::create(); -// Send a notification -$user->notify(new TestNotification('System Message: xxx')); +// Notify a message +$user->notify(new TestNotification('System Notification:xxx')); ``` \ No newline at end of file diff --git a/docs/en/components/openai-client.md b/docs/en/components/openai-client.md index de6cef115..64b5b297a 100644 --- a/docs/en/components/openai-client.md +++ b/docs/en/components/openai-client.md @@ -2,9 +2,9 @@ ------ -**OpenAI PHP** for Laravel is a robust community PHP API client that allows you to interact with the [Open AI API](https://beta.openai.com/docs/api-reference/introduction). +**OpenAI PHP** for Laravel is a powerful community PHP API client that allows you to interact with the [Open AI API](https://beta.openai.com/docs/api-reference/introduction). -> **Note:** This repository contains the Hyperf integration code for **OpenAI PHP**. If you want to use the **OpenAI PHP** client in a framework-agnostic way, please refer to the [openai-php/client](https://github.com/openai-php/client) repository. +> **Note:** This repository contains the Hyperf integration code for **OpenAI PHP**. If you want to use the **OpenAI PHP** client in a framework-agnostic way, please check out the [openai-php/client](https://github.com/openai-php/client) repository. ## Quick Start @@ -28,7 +28,7 @@ This will create a `config/autoload/openai.php` configuration file in your proje OPENAI_API_KEY=sk-... ``` -Finally, you can access the OpenAI API using the `OpenAI\Client` instance from the container: +Finally, you can use the `OpenAI\Client` instance from the container to access the OpenAI API: ```php use OpenAI\Client; @@ -43,7 +43,7 @@ echo $result['choices'][0]['text']; // an open-source, widely-used, server-side ## Azure -To use the Azure OpenAI service, you need to manually build the client using a factory. +To use the Azure OpenAI service, you must manually build the client using the factory. ```php $client = OpenAI::factory() @@ -53,9 +53,9 @@ $client = OpenAI::factory() ->make(); ``` -When using Azure, you must deploy a model identified by `{deployment-id}`, which is integrated into the API calls. Therefore, you don't need to specify a model during the call because it is already included in the `BaseUri`. +To use Azure, you must deploy a model, which is identified by {deployment-id}, integrated into the API call. Therefore, you do not need to provide the model during the call, as it is already included in the BaseUri. -For example, a basic completion call would look like this: +Thus, a basic example completion call would be: ```php $result = $client->completions()->create([ @@ -65,4 +65,4 @@ $result = $client->completions()->create([ ## Official Guide -For usage examples, please refer to the [openai-php/client](https://github.com/openai-php/client) repository. \ No newline at end of file +For usage examples, please check out the [openai-php/client](https://github.com/openai-php/client) repository. \ No newline at end of file diff --git a/docs/en/components/pest-plugin-hyperf.md b/docs/en/components/pest-plugin-hyperf.md index be6071784..42bc805e5 100644 --- a/docs/en/components/pest-plugin-hyperf.md +++ b/docs/en/components/pest-plugin-hyperf.md @@ -1,6 +1,6 @@ # Pest Plugin Hyperf -> This is a [Pest](https://pestphp.com) plugin that allows your Hyperf project to run Pest tests in a coroutine-based Swoole environment. +> This is a [Pest](https://pestphp.com) plugin that enables your Hyperf project's Pest to run in a Swoole-based coroutine environment. ## Installation diff --git a/docs/en/components/pretty-console.md b/docs/en/components/pretty-console.md index 7ed6b461e..bf04c3e2b 100644 --- a/docs/en/components/pretty-console.md +++ b/docs/en/components/pretty-console.md @@ -1,6 +1,6 @@ # Pretty Console -The pretty console component for Hyperf. +A beautiful console component for Hyperf. ![Pretty Console](https://user-images.githubusercontent.com/5457236/178333036-b11abb56-ba70-4c0d-a2f6-79afe3a0a78c.png) @@ -23,14 +23,14 @@ class FooCommand extends HyperfCommand { use Prettyable; - public function handle() + public function function handle() { $this->components->info('Your message here.'); } } ``` -## Acknowledgements +## Acknowledgments - [nunomaduro/termwind](https://github.com/nunomaduro/termwind) -- [The idea from PR of Laravel](https://github.com/laravel/framework/pull/43065) \ No newline at end of file +- [The idea from pr of laravel](https://github.com/laravel/framework/pull/43065) \ No newline at end of file diff --git a/docs/en/components/purifier.md b/docs/en/components/purifier.md index 3974c9c66..4e7e33ec8 100644 --- a/docs/en/components/purifier.md +++ b/docs/en/components/purifier.md @@ -1,26 +1,26 @@ # Purifier -An HTML filter derived from [mews/purifier](https://github.com/mewebstudio/Purifier). +HTML Filter. Derived from [mews/purifier](https://github.com/mewebstudio/Purifier). ## Installation -Use Composer to install this package: +Install this component using Composer: ```shell composer require friendsofhyperf/purifier ``` -Service providers will be automatically discovered. You do not need to add any providers manually. +The service provider will be automatically discovered. You don't need to add the Provider anywhere. ## Usage -Use the following method in your requests or middleware to clean HTML: +Use the following method in a request or middleware to clean HTML: ```php clean($request->get('inputname')); ``` -Or: +Or ```php ApplicationContext::getContainer()->get(Purifier::class)->clean($request->get('inputname')); @@ -33,14 +33,14 @@ clean('This is my H1 title', 'titles'); clean('This is my H1 title', array('Attr.EnableID' => true)); ``` -Or: +Or ```php ApplicationContext::getContainer()->get(Purifier::class)->clean('This is my H1 title', 'titles'); ApplicationContext::getContainer()->get(Purifier::class)->clean('This is my H1 title', array('Attr.EnableID' => true)); ``` -Using [URI filters](http://htmlpurifier.org/docs/enduser-uri-filter.html): +Using [URI Filter](http://htmlpurifier.org/docs/enduser-uri-filter.html) ```php ApplicationContext::getContainer()->get(Purifier::class)->clean('This is my H1 title', 'titles', function (HTMLPurifier_Config $config) { @@ -49,7 +49,7 @@ ApplicationContext::getContainer()->get(Purifier::class)->clean('This is my H1 t }); ``` -Alternatively, if you want to clean HTML in a database model, you can use our custom casts: +Alternatively, if you want to clean HTML in your database models, you can use our custom casts: ```php CleanHtml::class, // Cleans when both setting and retrieving values - 'description' => CleanHtmlInput::class, // Cleans when setting values - 'history' => CleanHtmlOutput::class, // Cleans when retrieving values + 'bio' => CleanHtml::class, // Cleans both when getting and setting the value + 'description' => CleanHtmlInput::class, // Cleans when setting the value + 'history' => CleanHtmlOutput::class, // Cleans when getting the value ]; } ``` @@ -79,7 +79,7 @@ To use your own settings, publish the configuration. php bin/hyperf.php vendor:publish friendsofhyperf/purifier ``` -The configuration file `config/autoload/purifier.php` will look like this: +The configuration file `config/autoload/purifier.php` is as follows: ```php diff --git a/docs/en/components/recaptcha.md b/docs/en/components/recaptcha.md index b8607db2e..ad1fa0be9 100644 --- a/docs/en/components/recaptcha.md +++ b/docs/en/components/recaptcha.md @@ -1,6 +1,6 @@ # ReCaptcha -The Google ReCaptcha component for Hyperf. +A Google ReCaptcha component for Hyperf. ## Installation @@ -34,7 +34,7 @@ class V2CaptchaMiddleware extends ReCaptchaMiddleware } ``` -- Using the Validator +- Validator Usage ```php 'g-recaptcha is required', - 'g-recaptcha.recaptcha' => 'Google ReCaptcha verification failed', + 'g-recaptcha.recaptcha' => 'Google ReCaptcha Verify Fails', ] ); diff --git a/docs/en/components/redis-subscriber.md b/docs/en/components/redis-subscriber.md index feb8dc6bc..7a881ec40 100644 --- a/docs/en/components/redis-subscriber.md +++ b/docs/en/components/redis-subscriber.md @@ -1,14 +1,12 @@ # Redis Subscriber -Forked from [mix-php/redis-subscriber](https://github.com/mix-php/redis-subscriber) +A Redis native protocol subscriber based on Swoole coroutines, forked from [mix-php/redis-subscriber](https://github.com/mix-php/redis-subscriber). -Redis native protocol subscriber based on Swoole coroutine. +This Redis subscription library, based on Swoole coroutines, connects directly to the Redis server using sockets, without relying on the phpredis extension. The subscriber offers the following advantages: -A subscription library based on Swoole coroutine that connects directly to the Redis server using Socket, without relying on the `phpredis` extension. This subscriber has the following advantages: - -- **Seamless Modification**: Channels can be added or removed at any time, enabling seamless channel switching. -- **Cross-Coroutine Safe Shutdown**: Subscriptions can be safely closed at any time. -- **Message Retrieval via Channels**: Inspired by the Golang [go-redis](https://github.com/go-redis/redis) library, this package wraps functionality to retrieve subscription messages via channels. +- Smooth Modifications: You can add or cancel subscription channels at any time, enabling seamless channel switching. +- Cross-Coroutine Safe Closure: The subscription can be closed at any moment. +- Channel Message Retrieval: The library's encapsulation style is inspired by the [go-redis](https://github.com/go-redis/redis) library in Golang, retrieving subscription messages through channels. ## Installation @@ -16,18 +14,18 @@ A subscription library based on Swoole coroutine that connects directly to the R composer require friendsofhyperf/redis-subscriber ``` -## Subscribe to Channels +## Subscribing to Channels -- Exceptions will be thrown in case of connection or subscription failures. +- Connection and subscription failures will throw exceptions. ```php -$sub = new \FriendsOfHyperf\Redis\Subscriber\Subscriber('127.0.0.1', 6379, '', 5); // Exception will be thrown if connection fails -$sub->subscribe('foo', 'bar'); // Exception will be thrown if subscription fails +$sub = new \FriendsOfHyperf\Redis\Subscriber\Subscriber('127.0.0.1', 6379, '', 5); // Throws an exception if connection fails +$sub->subscribe('foo', 'bar'); // Throws an exception if subscription fails $chan = $sub->channel(); while (true) { $data = $chan->pop(); - if (empty($data)) { // Both manual close and abnormal Redis disconnection will return false + if (empty($data)) { // Returns false if manually closed or if the Redis connection is abnormally disconnected if (!$sub->closed) { // Handle abnormal Redis disconnection var_dump('Redis connection is disconnected abnormally'); @@ -38,7 +36,7 @@ while (true) { } ``` -When a subscription message is received: +Received subscription message: ```shell object(FriendsOfHyperf\Redis\Subscriber\Message)#8 (2) { @@ -53,9 +51,9 @@ object(FriendsOfHyperf\Redis\Subscriber\Message)#8 (2) { | Method | Description | | --- | --- | -| `subscribe(string ...$channels) : void` | Add subscriptions | -| `unsubscribe(string ...$channels) : void` | Remove subscriptions | -| `psubscribe(string ...$channels) : void` | Add pattern-based subscriptions | -| `punsubscribe(string ...$channels) : void` | Remove pattern-based subscriptions | -| `channel() : Hyperf\Engine\Channel` | Get the message channel | -| `close() : void` | Close the subscription | +| subscribe(string ...$channels) : void | Add subscriptions | +| unsubscribe(string ...$channels) : void | Cancel subscriptions | +| psubscribe(string ...$channels) : void | Add pattern subscriptions | +| punsubscribe(string ...$channels) : void | Cancel pattern subscriptions | +| channel() : Hyperf\Engine\Channel | Get message channel | +| close() : void | Close subscription | \ No newline at end of file diff --git a/docs/en/components/sentry.md b/docs/en/components/sentry.md index 382c06c4e..5551b8198 100644 --- a/docs/en/components/sentry.md +++ b/docs/en/components/sentry.md @@ -1,6 +1,6 @@ # Sentry -The sentry component for Hyperf. +Sentry component for Hyperf. ## Installation @@ -14,12 +14,12 @@ composer require friendsofhyperf/sentry php bin/hyperf.php vendor:publish friendsofhyperf/sentry ``` -## Register `LoggerHandler` +## Register LoggerHandler ```php warning('this is a test warning issue!'); return [ @@ -45,7 +45,7 @@ return [ ``` -## Configure Sentry to Handle Application Logs +## Configure Sentry Runtime Logs ```php [ @@ -24,9 +24,9 @@ composer require friendsofhyperf/tcp-sender 'port' => 9401, 'sock_type' => SWOOLE_SOCK_TCP, 'callbacks' => [ - Event::ON_CONNECT => [TcpServer::class, 'onConnect'], - Event::ON_CLOSE => [TcpServer::class, 'onClose'], - Event::ON_RECEIVE => [TcpServer::class, 'onReceive'], + Event::ON_CONNECT => [TcpServer::class,'onConnect'], + Event::ON_CLOSE => [TcpServer::class,'onClose'], + Event::ON_RECEIVE => [TcpServer::class,'onReceive'], ], 'options' => [ // Whether to enable request lifecycle event @@ -48,7 +48,7 @@ use Hyperf\Contract\OnReceiveInterface; use FriendsOfHyperf\TcpSender\Sender; use Swoole\Server; -class TcpServer implements OnCloseInterface, OnReceiveInterface +class TcpServer implements OnCloseInterface,OnReceiveInterface { public function __construct(private Sender $sender) { @@ -59,19 +59,21 @@ class TcpServer implements OnCloseInterface, OnReceiveInterface */ public function onConnect($server, $fd, $reactorId): void { - $server->send($fd, sprintf('Client %s connected.' . PHP_EOL, $fd)); + $server->send($fd, sprintf('Client %s connected.'.PHP_EOL, $fd)); } public function onClose($server, int $fd, int $reactorId): void { - $server->send($fd, sprintf('Client %s closed.' . PHP_EOL, $fd)); + $server->send($fd, sprintf('Client %s closed.'.PHP_EOL, $fd)); } public function onReceive($server, int $fd, int $reactorId, string $data): void { - $server->send($fd, sprintf('Client %s sent: %s' . PHP_EOL, $fd, $data)); + $server->send($fd, sprintf('Client %s send: %s'.PHP_EOL, $fd, $data)); var_dump($data); } + + } ``` @@ -94,24 +96,26 @@ class TcpServer implements OnReceiveInterface public function onConnect(Connection $connection, $fd): void { // Set the mapping between fd and connection - $this->sender->setResponse($fd, $connection); - $connection->send(sprintf('Client %s connected.' . PHP_EOL, $fd)); + $this->sender->setResponse($fd,$connection); + $connection->send(sprintf('Client %s connected.'.PHP_EOL, $fd)); } public function onClose($connection, int $fd): void { // Remove the mapping between fd and connection - $this->sender->setResponse($fd, null); + $this->sender->setResponse($fd,null); } public function onReceive($server, int $fd, int $reactorId, string $data): void { - $server->send($fd, sprintf('Client %s sent: %s' . PHP_EOL, $fd, $data)); + $server->send($fd, sprintf('Client %s send: %s'.PHP_EOL, $fd, $data)); } + + } ``` -## Usage in Controllers +## Usage in Controller ```php You can choose between using listeners or middleware. +> Listeners and middleware, choose one -### Request Listeners +### Request Listener -Add the listeners in the `config/autoload/listeners.php` configuration file. +Add the listener in the `config/autoload/listeners.php` configuration file ```php env('TELESCOPE_DB_CONNECTION', 'default'), @@ -91,13 +92,13 @@ In the `config/autoload/telescope.php` file, you can configure the database conn ## Tags -You may want to attach custom tags to entries. To do so, you can use the **`Telescope::tag`** method. +You may wish to attach your own custom tags to entries. To do this, you may use the **`Telescope::tag`** method. ## Batch Filtering -You may want to record entries only under specific conditions. To do so, you can use the **`Telescope::filter`** method. +You may want to record entries only under certain special conditions. To do this, you may use the **`Telescope::filter`** method. -Example: +Example ```php use FriendsOfHyperf\Telescope\Telescope; @@ -116,7 +117,7 @@ class TelescopeInitListener implements ListenerInterface public function process(object $event): void { - // Attach your own custom tags + // attach your own custom tags Telescope::tag(function (IncomingEntry $entry) { if ($entry->type === 'request') { return [ @@ -126,10 +127,10 @@ class TelescopeInitListener implements ListenerInterface } }); - // Filter entries + // filter entry Telescope::filter(function (IncomingEntry $entry): bool { - if ($entry->type === 'request') { - if ($entry->content['uri'] === 'xxxx') { + if ($entry->type === 'request'){ + if ($entry->content['uri'] == 'xxxx') { return false; } } diff --git a/docs/en/components/tinker.md b/docs/en/components/tinker.md index 8253ecdd7..22fe5e410 100644 --- a/docs/en/components/tinker.md +++ b/docs/en/components/tinker.md @@ -1,6 +1,6 @@ # Tinker -The Powerful REPL for Hyperf. +A powerful REPL tool for Hyperf. ## Installation @@ -22,7 +22,7 @@ php bin/hyperf.php tinker ## Commands -- Running Commands +- Run Commands ````shell Psy Shell v0.10.4 (PHP 7.3.11 — cli) @@ -37,7 +37,7 @@ Psy Shell v0.10.4 (PHP 7.3.11 — cli) >>> ```` -- Viewing Command Help +- View Command Help ```shell >>> help @@ -66,7 +66,7 @@ Psy Shell v0.10.4 (PHP 7.3.11 — cli) inspire Display an inspiring quote ``` -- Fetching Environment Variables +- Get Environment Variables ```shell Psy Shell v0.10.4 (PHP 7.2.34 — cli) @@ -145,7 +145,7 @@ object(App\Model\User)#81816 (28) { => null ``` -- Viewing Documentation +- View Documentation ```shell >>> doc md5 @@ -157,7 +157,7 @@ PHP manual not found >>> ``` -- Viewing Source Code +- View Source Code ```shell >>> show App\Model\User diff --git a/docs/en/components/trigger.md b/docs/en/components/trigger.md index 974cab7ed..cca3e3dd3 100644 --- a/docs/en/components/trigger.md +++ b/docs/en/components/trigger.md @@ -8,7 +8,7 @@ composer require friendsofhyperf/trigger ``` -- Publish configuration +- Publish Configuration ```shell php bin/hyperf.php vendor:publish friendsofhyperf/trigger @@ -24,7 +24,7 @@ return [ ]; ``` -## Define Triggers +## Define Trigger ```php namespace App\Trigger; @@ -53,7 +53,7 @@ class FooTrigger extends AbstractTrigger } ``` -## Define Subscribers +## Define Subscriber ```php namespace App\Subscriber; diff --git a/docs/en/components/validated-dto.md b/docs/en/components/validated-dto.md index ff6eaccf6..cb32d2ec2 100644 --- a/docs/en/components/validated-dto.md +++ b/docs/en/components/validated-dto.md @@ -22,7 +22,7 @@ The `DTO` will be created in the `app/DTO` directory. ## Defining Validation Rules -You can validate data using the same rules as you would for validating `Request` data: +You can validate data just like you would with `Request` data: ```php email; // 'deeka@example.com' $dto->password; // 'D3Crft!@1b2A' ``` -If you pass attributes not defined in the `rules` method, those attributes will be ignored and unavailable in the `DTO`: +If you pass properties that are not in the `rules` method of the `DTO`, those data will be ignored and will not be available in the `DTO`: ```php $dto = UserDTO::fromArray([ 'name' => 'Deeka Wong', 'email' => 'deeka@example.com', 'password' => 'D3Crft!@1b2A', - 'username' => 'john_doe', + 'username' => 'john_doe', ]); $dto->username; // This property is not available in the DTO @@ -205,7 +205,7 @@ $dto->username; // This property is not available in the DTO ## Defining Default Values -Sometimes you may have optional properties with default values. You can define default values in the `defaults` method: +Sometimes we might have some optional properties and can have default values. You can define default values for `DTO` properties in the `defaults` method: ```php username; // 'deeka_wong' ## Transforming DTO Data -You can transform the DTO into various formats: +You can transform your DTO into some formats: -### To an Array +### To Array ```php $dto = UserDTO::fromArray([ @@ -268,7 +268,7 @@ $dto->toArray(); // ] ``` -### To a JSON String +### To JSON String ```php $dto = UserDTO::fromArray([ @@ -280,7 +280,7 @@ $dto = UserDTO::fromArray([ $dto->toJson(); // '{"name":"Deeka Wong","email":"deeka@example.com","password":"D3Crft!@1b2A"}' -$dto->toJson(true); // Pretty-printed JSON +$dto->toJson(true); // You can call it like this to pretty-print your JSON // { // "name": "Deeka Wong", // "email": "deeka@example.com", @@ -288,7 +288,7 @@ $dto->toJson(true); // Pretty-printed JSON // } ``` -### To an Eloquent Model +### To Eloquent Model ```php $dto = UserDTO::fromArray([ @@ -303,22 +303,23 @@ $dto->toModel(\App\Model\User::class); // email: "deeka@example.com", // password: "D3Crft!@1b2A", // } + ``` ## Custom Error Messages, Attributes, and Exceptions -You can define custom messages and attributes for the validator by implementing the `messages` and `attributes` methods in the `DTO` class: +You can define custom messages and attributes by implementing the `messages` and `attributes` methods in the `DTO` class: ```php /** - * Define custom error messages for the validator. + * Define custom messages for validator errors. */ protected function messages() { return []; } /** - * Define custom attributes for the validator. + * Define custom attributes for validator errors. */ protected function attributes() { return []; @@ -327,11 +328,11 @@ protected function attributes() { ## Type Casting -You can easily cast DTO properties by defining the `casts` method in the `DTO`: +You can easily cast your DTO properties by defining the `casts` method in your DTO: ```php /** - * Define type casting for DTO properties. + * Define the type casting for the DTO properties. * * @return array */ @@ -345,13 +346,223 @@ protected function casts(): array } ``` -## Available Cast Types +## Available Casts + +### Array + +For JSON strings, it will be converted to an array, and for other types, it will be wrapped in an array. + +```php +protected function casts(): array +{ + return [ + 'property' => new ArrayCast(), + ]; +} +``` + +### Boolean + +For string values, this uses the `filter_var` function with the `FILTER_VALIDATE_BOOLEAN` flag. + +```php +protected function casts(): array +{ + return [ + 'property' => new BooleanCast(), + ]; +} +``` + +### Carbon + +This accepts any value that the `Carbon` constructor accepts. If an invalid value is found, it will throw a `\FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new CarbonCast(), + ]; +} +``` + +You can also pass a timezone when defining the cast, which will be used when casting the value if needed. + +```php +protected function casts(): array +{ + return [ + 'property' => new CarbonCast('Europe/Lisbon'), + ]; +} +``` + +You can also pass a format when defining the cast to be used when casting the value. If the property's format is different from the specified one, it will throw a `\FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new CarbonCast('Europe/Lisbon', 'Y-m-d'), + ]; +} +``` + +### CarbonImmutable + +This accepts any value that the `CarbonImmutable` constructor accepts. If an invalid value is found, it will throw a `\FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new CarbonImmutableCast(), + ]; +} +``` + +You can also pass a timezone when defining the cast, which will be used when casting the value if needed. + +```php +protected function casts(): array +{ + return [ + 'property' => new CarbonImmutableCast('Europe/Lisbon'), + ]; +} +``` + +You can also pass a format when defining the cast to be used when casting the value. If the property's format is different from the specified one, it will throw a `\FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new CarbonImmutableCast('Europe/Lisbon', 'Y-m-d'), + ]; +} +``` + +### Collection + +For JSON strings, it will first be converted to an array and then wrapped into a `Collection` object. + +```php +protected function casts(): array +{ + return [ + 'property' => new CollectionCast(), + ]; +} +``` + +If you want to cast all elements in the `Collection`, you can pass a `Castable` to the `CollectionCast` constructor. Suppose you want to cast all items in the `Collection` to integers: + +```php +protected function casts(): array +{ + return [ + 'property' => new CollectionCast(new IntegerCast()), + ]; +} +``` + +This works for all `Castable`, including `DTOCast` and `ModelCast` for nested data. + +### DTO + +This works for arrays and JSON strings. This will validate the data and cast it for the given DTO. + +If the data is invalid for the DTO, this will throw a `Hyperf\Validation\ValidationException`. + +If the property is not a valid array or a valid JSON string, this will throw a `FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +If the class passed to the `DTOCast` constructor is not a `ValidatedDTO` instance, this will throw a `FriendsOfHyperf\ValidatedDTO\Exception\CastTargetException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new DTOCast(UserDTO::class), + ]; +} +``` + +### Float + +If a non-numeric value is found, it will throw a `FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new FloatCast(), + ]; +} +``` + +### Integer + +If a non-numeric value is found, it will throw a `FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new IntegerCast(), + ]; +} +``` + +### Model + +This works for arrays and JSON strings. + +If the property is not a valid array or a valid JSON string, this will throw a `FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +If the class passed to the `ModelCast` constructor is not a `Model` instance, this will throw a `FriendsOfHyperf\ValidatedDTO\Exception\CastTargetException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new ModelCast(User::class), + ]; +} +``` + +### Object + +This works for arrays and JSON strings. + +If the property is not a valid array or a valid JSON string, this will throw a `FriendsOfHyperf\ValidatedDTO\Exception\CastException`. + +```php +protected function casts(): array +{ + return [ + 'property' => new ObjectCast(), + ]; +} +``` + +### String -[Omitted for brevity but similar definitions apply.] +If the data cannot be cast to a string, this will throw a `FriendsOfHyperf\ValidatedDTO\Exception\CastException`. -## Creating Custom Cast Types +```php +protected function casts(): array +{ + return [ + 'property' => new StringCast(), + ]; +} +``` -You can create custom cast types by implementing the `FriendsOfHyperf\ValidatedDTO\Casting\Castable` interface. This interface has one required method: +## Creating Your Own Casts + +You can easily create new `Castable` types for your project by implementing the `FriendsOfHyperf\ValidatedDTO\Casting\Castable` interface. This interface has one method that must be implemented: ```php /** @@ -364,11 +575,16 @@ You can create custom cast types by implementing the `FriendsOfHyperf\ValidatedD public function cast(string $property, mixed $value): mixed; ``` -For example: +Suppose you have a `URLWrapper` class in your project, and you want it to always return a `URLWrapper` instance instead of a simple string when a URL is passed to your `DTO`: ```php class URLCast implements Castable { + /** + * @param string $property + * @param mixed $value + * @return URLWrapper + */ public function cast(string $property, mixed $value): URLWrapper { return new URLWrapper($value); @@ -376,7 +592,7 @@ class URLCast implements Castable } ``` -You can then apply this cast in your DTO: +Then you can apply it to your DTO: ```php class CustomDTO extends ValidatedDTO @@ -388,6 +604,11 @@ class CustomDTO extends ValidatedDTO ]; } + protected function defaults(): array + { + return []; + } + protected function casts(): array { return [ diff --git a/docs/en/components/web-tinker.md b/docs/en/components/web-tinker.md index cc2bcae31..bb3b6c5aa 100644 --- a/docs/en/components/web-tinker.md +++ b/docs/en/components/web-tinker.md @@ -26,4 +26,4 @@ php bin/hyperf.php start ## Access -Visit `http://127.0.0.1:9501/tinker` to access the Web Tinker page. \ No newline at end of file +Visit `http://127.0.0.1:9501/tinker` to enter the Web Tinker page. \ No newline at end of file diff --git a/docs/en/faq/index.md b/docs/en/faq/index.md index 318b08dc2..87b993045 100644 --- a/docs/en/faq/index.md +++ b/docs/en/faq/index.md @@ -1 +1 @@ -# Frequently Asked Questions +# Frequently Asked Questions \ No newline at end of file diff --git a/docs/en/guide/index.md b/docs/en/guide/index.md index bad55622f..8b3a7945c 100644 --- a/docs/en/guide/index.md +++ b/docs/en/guide/index.md @@ -1 +1 @@ -# Getting Started +# Getting Started \ No newline at end of file diff --git a/docs/en/guide/introduce/about.md b/docs/en/guide/introduce/about.md index bd0d6af95..3b4d30f2f 100644 --- a/docs/en/guide/introduce/about.md +++ b/docs/en/guide/introduce/about.md @@ -1 +1 @@ -# About FriendsOfHyperf +# About FriendsOfHyperf \ No newline at end of file diff --git a/docs/en/guide/start/components.md b/docs/en/guide/start/components.md index 167138bb6..cdb9bce60 100644 --- a/docs/en/guide/start/components.md +++ b/docs/en/guide/start/components.md @@ -1,27 +1,34 @@ # Components -## Supported Components List +## List of Supported Components -|Repository|Stable Version|Total Downloads|Monthly Downloads| +| Repository | Stable Version | Total Downloads | Monthly Downloads | |--|--|--|--| -|[amqp-job](https://github.com/friendsofhyperf/amqp-job)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/amqp-job/v)](https://packagist.org/packages/friendsofhyperf/amqp-job)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/amqp-job/downloads)](https://packagist.org/packages/friendsofhyperf/amqp-job)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/amqp-job/d/monthly)](https://packagist.org/packages/friendsofhyperf/amqp-job)| -|[cache](https://github.com/friendsofhyperf/cache)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/cache/v)](https://packagist.org/packages/friendsofhyperf/cache)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/cache/downloads)](https://packagist.org/packages/friendsofhyperf/cache)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/cache/d/monthly)](https://packagist.org/packages/friendsofhyperf/cache)| -|[command-signals](https://github.com/friendsofhyperf/command-signals)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/command-signals/v)](https://packagist.org/packages/friendsofhyperf/command-signals)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/command-signals/downloads)](https://packagist.org/packages/friendsofhyperf/command-signals)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/command-signals/d/monthly)](https://packagist.org/packages/friendsofhyperf/command-signals)| -|[command-validation](https://github.com/friendsofhyperf/command-validation)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/command-validation/v)](https://packagist.org/packages/friendsofhyperf/command-validation)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/command-validation/downloads)](https://packagist.org/packages/friendsofhyperf/command-validation)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/command-validation/d/monthly)](https://packagist.org/packages/friendsofhyperf/command-validation)| -|[compoships](https://github.com/friendsofhyperf/compoships)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/compoships/v)](https://packagist.org/packages/friendsofhyperf/compoships)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/compoships/downloads)](https://packagist.org/packages/friendsofhyperf/compoships)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/compoships/d/monthly)](https://packagist.org/packages/friendsofhyperf/compoships)| -|[confd](https://github.com/friendsofhyperf/confd)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/confd/v)](https://packagist.org/packages/friendsofhyperf/confd)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/confd/downloads)](https://packagist.org/packages/friendsofhyperf/confd)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/confd/d/monthly)](https://packagist.org/packages/friendsofhyperf/confd)| -|[config-consul](https://github.com/friendsofhyperf/config-consul)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/config-consul/v)](https://packagist.org/packages/friendsofhyperf/config-consul)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/config-consul/downloads)](https://packagist.org/packages/friendsofhyperf/config-consul)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/config-consul/d/monthly)](https://packagist.org/packages/friendsofhyperf/config-consul)| -|[console-spinner](https://github.com/friendsofhyperf/console-spinner)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/console-spinner/v)](https://packagist.org/packages/friendsofhyperf/console-spinner)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/console-spinner/downloads)](https://packagist.org/packages/friendsofhyperf/console-spinner)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/console-spinner/d/monthly)](https://packagist.org/packages/friendsofhyperf/console-spinner)| -|[di-plus](https://github.com/friendsofhyperf/di-plus)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/di-plus/v)](https://packagist.org/packages/friendsofhyperf/di-plus)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/di-plus/downloads)](https://packagist.org/packages/friendsofhyperf/di-plus)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/di-plus/d/monthly)](https://packagist.org/packages/friendsofhyperf/di-plus)| -|[elasticsearch](https://github.com/friendsofhyperf/elasticsearch)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/elasticsearch/v)](https://packagist.org/packages/friendsofhyperf/elasticsearch)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/elasticsearch/downloads)](https://packagist.org/packages/friendsofhyperf/elasticsearch)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/elasticsearch/d/monthly)](https://packagist.org/packages/friendsofhyperf/elasticsearch)| -|[encryption](https://github.com/friendsofhyperf/encryption)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/encryption/v)](https://packagist.org/packages/friendsofhyperf/encryption)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/encryption/downloads)](https://packagist.org/packages/friendsofhyperf/encryption)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/encryption/d/monthly)](https://packagist.org/packages/friendsofhyperf/encryption)| -|[exception-event](https://github.com/friendsofhyperf/exception-event)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/exception-event/v)](https://packagist.org/packages/friendsofhyperf/exception-event)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/exception-event/downloads)](https://packagist.org/packages/friendsofhyperf/exception-event)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/exception-event/d/monthly)](https://packagist.org/packages/friendsofhyperf/exception-event)| -|[facade](https://github.com/friendsofhyperf/facade)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/facade/v)](https://packagist.org/packages/friendsofhyperf/facade)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/facade/downloads)](https://packagist.org/packages/friendsofhyperf/facade)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/facade/d/monthly)](https://packagist.org/packages/friendsofhyperf/facade)| -|[fast-paginate](https://github.com/friendsofhyperf/fast-paginate)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/fast-paginate/v)](https://packagist.org/packages/friendsofhyperf/fast-paginate)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/fast-paginate/downloads)](https://packagist.org/packages/friendsofhyperf/fast-paginate)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/fast-paginate/d/monthly)](https://packagist.org/packages/friendsofhyperf/fast-paginate)| -|[grpc-validation](https://github.com/friendsofhyperf/grpc-validation)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/grpc-validation/v)](https://packagist.org/packages/friendsofhyperf/grpc-validation)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/grpc-validation/downloads)](https://packagist.org/packages/friendsofhyperf/grpc-validation)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/grpc-validation/d/monthly)](https://packagist.org/packages/friendsofhyperf/grpc-validation)| -|[helpers](https://github.com/friendsofhyperf/helpers)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/helpers/v)](https://packagist.org/packages/friendsofhyperf/helpers)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/helpers/downloads)](https://packagist.org/packages/friendsofhyperf/helpers)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/helpers/d/monthly)](https://packagist.org/packages/friendsofhyperf/helpers)| -|[http-client](https://github.com/friendsofhyperf/http-client)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/http-client/v)](https://packagist.org/packages/friendsofhyperf/http-client)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/http-client/downloads)](https://packagist.org/packages/friendsofhyperf/http-client)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/http-client/d/monthly)](https://packagist.org/packages/friendsofhyperf/http-client)| -|[http-logger](https://github.com/friendsofhyperf/http-logger)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/http-logger/v)](https://packagist.org/packages/friendsofhyperf/http-logger)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/http-logger/downloads)](https://packagist.org/packages/friendsofhyperf/http-logger)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/http-logger/d/monthly)](https://packagist.org/packages/friendsofhyperf/http-logger)| -|[ide-helper](https://github.com/friendsofhyperf/ide-helper)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/ide-helper/v)](https://packagist.org/packages/friendsofhyperf/ide-helper)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/ide-helper/downloads)](https://packagist.org/packages/friendsofhyperf/ide-helper)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/ide-helper/d/monthly)](https://packagist.org/packages/friendsofhyperf/ide-helper)| -|[ipc-broadcaster](https://github.com/friendsofhyperf/ipc-broadcaster)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/ipc-broadcaster/v)](https://packagist.org/packages/friendsofhyperf/ipc-broadcaster)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/ipc-broadcaster/downloads)](https://packagist.org/packages/friendsofhyperf/ipc-broadcaster)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/ipc-broadcaster/d/monthly)](https://packagist.org/packages/friendsofhyperf/ipc-broadcaster)| -|[lock](https://github.com/friendsofhyperf/lock)|[![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/lock/v)](https://packagist.org/packages/friendsofhyperf/lock)|[![Total Downloads](https://poser.pugx.org/friendsofhyperf/lock/downloads)](https://packagist.org/packages/friendsofhyperf/lock)|[![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/lock/d/monthly)](https://packagist.org/packages/friendsofhyperf/lock)| +| [amqp-job](https://github.com/friendsofhyperf/amqp-job) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/amqp-job/v)](https://packagist.org/packages/friendsofhyperf/amqp-job) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/amqp-job/downloads)](https://packagist.org/packages/friendsofhyperf/amqp-job) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/amqp-job/d/monthly)](https://packagist.org/packages/friendsofhyperf/amqp-job) | +| [cache](https://github.com/friendsofhyperf/cache) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/cache/v)](https://packagist.org/packages/friendsofhyperf/cache) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/cache/downloads)](https://packagist.org/packages/friendsofhyperf/cache) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/cache/d/monthly)](https://packagist.org/packages/friendsofhyperf/cache) | +| [command-signals](https://github.com/friendsofhyperf/command-signals) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/command-signals/v)](https://packagist.org/packages/friendsofhyperf/command-signals) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/command-signals/downloads)](https://packagist.org/packages/friendsofhyperf/command-signals) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/command-signals/d/monthly)](https://packagist.org/packages/friendsofhyperf/command-signals) | +| [command-validation](https://github.com/friendsofhyperf/command-validation) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/command-validation/v)](https://packagist.org/packages/friendsofhyperf/command-validation) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/command-validation/downloads)](https://packagist.org/packages/friendsofhyperf/command-validation) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/command-validation/d/monthly)](https://packagist.org/packages/friendsofhyperf/command-validation) | +| [compoships](https://github.com/friendsofhyperf/compoships) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/compoships/v)](https://packagist.org/packages/friendsofhyperf/compoships) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/compoships/downloads)](https://packagist.org/packages/friendsofhyperf/compoships) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/compoships/d/monthly)](https://packagist.org/packages/friendsofhyperf/compoships) | +| [confd](https://github.com/friendsofhyperf/confd) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/confd/v)](https://packagist.org/packages/friendsofhyperf/confd) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/confd/downloads)](https://packagist.org/packages/friendsofhyperf/confd) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/confd/d/monthly)](https://packagist.org/packages/friendsofhyperf/confd) | +| [config-consul](https://github.com/friendsofhyperf/config-consul) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/config-consul/v)](https://packagist.org/packages/friendsofhyperf/config-consul) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/config-consul/downloads)](https://packagist.org/packages/friendsofhyperf/config-consul) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/config-consul/d/monthly)](https://packagist.org/packages/friendsofhyperf/config-consul) | +| [console-spinner](https://github.com/friendsofhyperf/console-spinner) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/console-spinner/v)](https://packagist.org/packages/friendsofhyperf/console-spinner) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/console-spinner/downloads)](https://packagist.org/packages/friendsofhyperf/console-spinner) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/console-spinner/d/monthly)](https://packagist.org/packages/friendsofhyperf/console-spinner) | +| [di-plus](https://github.com/friendsofhyperf/di-plus) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/di-plus/v)](https://packagist.org/packages/friendsofhyperf/di-plus) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/di-plus/downloads)](https://packagist.org/packages/friendsofhyperf/di-plus) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/di-plus/d/monthly)](https://packagist.org/packages/friendsofhyperf/di-plus) | +| [elasticsearch](https://github.com/friendsofhyperf/elasticsearch) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/elasticsearch/v)](https://packagist.org/packages/friendsofhyperf/elasticsearch) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/elasticsearch/downloads)](https://packagist.org/packages/friendsofhyperf/elasticsearch) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/elasticsearch/d/monthly)](https://packagist.org/packages/friendsofhyperf/elasticsearch) | +| [encryption](https://github.com/friendsofhyperf/encryption) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/encryption/v)](https://packagist.org/packages/friendsofhyperf/encryption) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/encryption/downloads)](https://packagist.org/packages/friendsofhyperf/encryption) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/encryption/d/monthly)](https://packagist.org/packages/friendsofhyperf/encryption) | +| [exception-event](https://github.com/friendsofhyperf/exception-event) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/exception-event/v)](https://packagist.org/packages/friendsofhyperf/exception-event) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/exception-event/downloads)](https://packagist.org/packages/friendsofhyperf/exception-event) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/exception-event/d/monthly)](https://packagist.org/packages/friendsofhyperf/exception-event) | +| [facade](https://github.com/friendsofhyperf/facade) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/facade/v)](https://packagist.org/packages/friendsofhyperf/facade) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/facade/downloads)](https://packagist.org/packages/friendsofhyperf/facade) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/facade/d/monthly)](https://packagist.org/packages/friendsofhyperf/facade) | +| [fast-paginate](https://github.com/friendsofhyperf/fast-paginate) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/fast-paginate/v)](https://packagist.org/packages/friendsofhyperf/fast-paginate) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/fast-paginate/downloads)](https://packagist.org/packages/friendsofhyperf/fast-paginate) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/fast-paginate/d/monthly)](https://packagist.org/packages/friendsofhyperf/fast-paginate) | +| [grpc-validation](https://github.com/friendsofhyperf/grpc-validation) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/grpc-validation/v)](https://packagist.org/packages/friendsofhyperf/grpc-validation) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/grpc-validation/downloads)](https://packagist.org/packages/friendsofhyperf/grpc-validation) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/grpc-validation/d/monthly)](https://packagist.org/packages/friendsofhyperf/grpc-validation) | +| [helpers](https://github.com/friendsofhyperf/helpers) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/helpers/v)](https://packagist.org/packages/friendsofhyperf/helpers) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/helpers/downloads)](https://packagist.org/packages/friendsofhyperf/helpers) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/helpers/d/monthly)](https://packagist.org/packages/friendsofhyperf/helpers) | +| [http-client](https://github.com/friendsofhyperf/http-client) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/http-client/v)](https://packagist.org/packages/friendsofhyperf/http-client) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/http-client/downloads)](https://packagist.org/packages/friendsofhyperf/http-client) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/http-client/d/monthly)](https://packagist.org/packages/friendsofhyperf/http-client) | +| [http-logger](https://github.com/friendsofhyperf/http-logger) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/http-logger/v)](https://packagist.org/packages/friendsofhyperf/http-logger) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/http-logger/downloads)](https://packagist.org/packages/friendsofhyperf/http-logger) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/http-logger/d/monthly)](https://packagist.org/packages/friendsofhyperf/http-logger) | +| [ide-helper](https://github.com/friendsofhyperf/ide-helper) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/ide-helper/v)](https://packagist.org/packages/friendsofhyperf/ide-helper) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/ide-helper/downloads)](https://packagist.org/packages/friendsofhyperf/ide-helper) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/ide-helper/d/monthly)](https://packagist.org/packages/friendsofhyperf/ide-helper) | +| [ipc-broadcaster](https://github.com/friendsofhyperf/ipc-broadcaster) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/ipc-broadcaster/v)](https://packagist.org/packages/friendsofhyperf/ipc-broadcaster) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/ipc-broadcaster/downloads)](https://packagist.org/packages/friendsofhyperf/ipc-broadcaster) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/ipc-broadcaster/d/monthly)](https://packagist.org/packages/friendsofhyperf/ipc-broadcaster) | +| [lock](https://github.com/friendsofhyperf/lock) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/lock/v)](https://packagist.org/packages/friendsofhyperf/lock) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/lock/downloads)](https://packagist.org/packages/friendsofhyperf/lock) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/lock/d/monthly)](https://packagist.org/packages/friendsofhyperf/lock) | +| [macros](https://github.com/friendsofhyperf/macros) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/macros/v)](https://packagist.org/packages/friendsofhyperf/macros) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/macros/downloads)](https://packagist.org/packages/friendsofhyperf/macros) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/macros/d/monthly)](https://packagist.org/packages/friendsofhyperf/macros) | +| [mail](https://github.com/friendsofhyperf/mail) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/mail/v)](https://packagist.org/packages/friendsofhyperf/mail) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/mail/downloads)](https://packagist.org/packages/friendsofhyperf/mail) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/mail/d/monthly)](https://packagist.org/packages/friendsofhyperf/mail) | +| [middleware-plus](https://github.com/friendsofhyperf/middleware-plus) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/middleware-plus/v)](https://packagist.org/packages/friendsofhyperf/middleware-plus) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/middleware-plus/downloads)](https://packagist.org/packages/friendsofhyperf/middleware-plus) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/middleware-plus/d/monthly)](https://packagist.org/packages/friendsofhyperf/middleware-plus) | +| [model-factory](https://github.com/friendsofhyperf/model-factory) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/model-factory/v)](https://packagist.org/packages/friendsofhyperf/model-factory) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/model-factory/downloads)](https://packagist.org/packages/friendsofhyperf/model-factory) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/model-factory/d/monthly)](https://packagist.org/packages/friendsofhyperf/model-factory) | +| [model-hashids](https://github.com/friendsofhyperf/model-hashids) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/model-hashids/v)](https://packagist.org/packages/friendsofhyperf/model-hashids) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/model-hashids/downloads)](https://packagist.org/packages/friendsofhyperf/model-hashids) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/model-hashids/d/monthly)](https://packagist.org/packages/friendsofhyperf/model-hashids) | +| [model-morph-addon](https://github.com/friendsofhyperf/model-morph-addon) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/model-morph-addon/v)](https://packagist.org/packages/friendsofhyperf/model-morph-addon) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/model-morph-addon/downloads)](https://packagist.org/packages/friendsofhyperf/model-morph-addon) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyperf/model-morph-addon/d/monthly)](https://packagist.org/packages/friendsofhyperf/model-morph-addon) | +| [model-observer](https://github.com/friendsofhyperf/model-observer) | [![Latest Stable Version](https://poser.pugx.org/friendsofhyperf/model-observer/v)](https://packagist.org/packages/friendsofhyperf/model-observer) | [![Total Downloads](https://poser.pugx.org/friendsofhyperf/model-observer/downloads)](https://packagist.org/packages/friendsofhyperf/model-observer) | [![Monthly Downloads](https://poser.pugx.org/friendsofhyper \ No newline at end of file diff --git a/docs/en/index.md b/docs/en/index.md index 41a6a883d..a6a3d5485 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -1,15 +1,13 @@ +```markdown --- # https://vitepress.dev/reference/default-theme-home-page layout: home hero: - name: "FriendsOfHyperf" - text: "The most popular components for Hyperf." - tagline: "Make Hyperf as simple and powerful as Laravel 🚀" + name: "Hyperf Fans" + text: "The Most Popular Hyperf Components" + tagline: "Make Hyperf as Simple and Powerful as Laravel 🚀" actions: - # - theme: brand - # text: Guide - # link: /en/guide/ - theme: brand text: Components link: /en/components/ @@ -19,7 +17,7 @@ hero: features: - title: Sentry - details: This is the Sentry SDK for Hyperf. + details: This is the Hyperf SDK for Sentry. link: /en/components/sentry/ - title: Telescope details: Telescope is an elegant debugging assistant for the Hyperf framework. @@ -28,10 +26,10 @@ features: details: Tinker is a powerful REPL for the Hyperf framework. link: /en/components/tinker/ - title: Web Tinker - details: Tinker in your browser. - link: /zh-cn/components/web-tinker/ + details: Use Tinker in your browser. + link: /en/components/web-tinker/ - title: Encryption - details: Encryption provides simple and convenient encryption and decryption functionality. + details: Encryption provides a simple and convenient way to encrypt and decrypt data. link: /en/components/encryption/ - title: Cache details: Cache provides an expressive and unified caching API. @@ -40,12 +38,13 @@ features: details: HttpClient provides a simple and convenient HTTP client. link: /en/components/http-client/ - title: Validated DTO - details: Validated DTO provides simple and convenient data validation functionality. + details: Validated DTO provides a simple and convenient way to validate data. link: /en/components/validated-dto/ - title: Lock - details: Lock provides simple and convenient distributed locking functionality. + details: Lock provides a simple and convenient distributed locking mechanism. link: /en/components/lock/ - title: More - details: More components... + details: More components… link: /en/components/ ---- \ No newline at end of file +--- +``` \ No newline at end of file diff --git a/docs/zh-hk/components/cache.md b/docs/zh-hk/components/cache.md index a1ba165af..d4256f141 100644 --- a/docs/zh-hk/components/cache.md +++ b/docs/zh-hk/components/cache.md @@ -29,7 +29,7 @@ class IndexController public function index() { return $this->cache->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); } } @@ -41,7 +41,7 @@ class IndexController use FriendsOfHyperf\Cache\Facade\Cache; Cache::remember($key, $ttl=60, function() { - // return sth + // 返回值 }); ``` @@ -52,14 +52,14 @@ use FriendsOfHyperf\Cache\Facade\Cache; use FriendsOfHyperf\Cache\CacheManager; Cache::store('co')->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); ``` ## 參考 -參閲 [Laravel-Cache](https://laravel.com/docs/8.x/cache) +有關更多信息,請參閲 [Laravel-Cache](https://laravel.com/docs/8.x/cache) diff --git a/docs/zh-tw/components/cache.md b/docs/zh-tw/components/cache.md index 5a4ac5006..b44890dbf 100644 --- a/docs/zh-tw/components/cache.md +++ b/docs/zh-tw/components/cache.md @@ -29,7 +29,7 @@ class IndexController public function index() { return $this->cache->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); } } @@ -41,7 +41,7 @@ class IndexController use FriendsOfHyperf\Cache\Facade\Cache; Cache::remember($key, $ttl=60, function() { - // return sth + // 返回值 }); ``` @@ -52,14 +52,14 @@ use FriendsOfHyperf\Cache\Facade\Cache; use FriendsOfHyperf\Cache\CacheManager; Cache::store('co')->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); di(CacheManager::class)->store('co')->remember($key, $ttl=60, function() { - // return sth + // 返回值 }); ``` ## 參考 -參閱 [Laravel-Cache](https://laravel.com/docs/8.x/cache) +有關更多資訊,請參閱 [Laravel-Cache](https://laravel.com/docs/8.x/cache)