《現代 PHP》學習筆記(十二):建立元件

前言

本文為《現代 PHP》一書的學習筆記。

環境

  • Windows 10
  • Wnmp 3.1.0

建立元件

製作 PHP 元件可以跟 PHP 社群分享個人成果。

不要重複撰寫已存在的元件,如果改良現有元件,考慮將其以 pull request 的方式發送到原始元件,否則重複的元件會有混淆或是破壞 PHP 元件生態系統的風險。

元件名稱

使用小寫字母組成服務提供者和元件名稱,並避免與其他元件名稱重複。

決定服務提供者名稱前,要先在 Packagist 查詢過,確保沒被其他人使用。

名稱空間

元件的名稱空間不一定要跟元件的服務提供者和元件名稱相同,前者在 PHP 程式碼會使用到,後者只是用來讓 Packagist 和 Composer 辨識元件的依據。

檔案系統結構

src/

此目錄包含元件的原始碼。

tests/

此目錄包含元件的測試。

composer.json

這是 Composer 部署檔,用來描述元件並讓 Composer 的自動載入器對應元件的 PSR-4 名稱空間到 src/ 目錄。

README.md

Markdown 檔提供關於元件的資訊,包含名稱、敘述、作者、用途、貢獻者指南、軟體授權許可和榮譽。

CONTRIBUTING.md

Markdown 檔敘述其他人如何貢獻這個元件。

LICENSE

此純文字檔包含了這個元件的軟體授權許可。

CHANGELOG.md

Markdown 檔條列出元件每個版本的改動。

composer.json 檔

composer.json 檔是必要的,而且應該是有效的 JSON 格式。

範例 4-2:URL 掃描器元件 composer.json 檔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
"name": "modernphp/scanner",
"description": "Scan URLs from a CSV file and report inaccessible URLs",
"keywords": ["url", "scanner", "csv"],
"homepage": "http://example.com",
"license": "MIT",
"authors": [
{
"name": "Josh Lockhart",
"homepage": "https://github.com/codeguy",
"role": "Developer"
}
],
"support": {
"email": "help@example.com"
},
"require": {
"php" : ">=5.6.0",
"guzzlehttp/guzzle": "^6.1"
},
"require-dev": {
"phpunit/phpunit": "^5.0"
},
"suggest": {
"league/csv": "^8.0"
},
"autoload": {
"psr-4": {
"Oreilly\\ModernPHP\\": "src/"
}
}
}
  • name:元件的服務提供者和元件名稱,以 / 字元分割。
  • description:包含關於元件的簡單敘述。
  • keywords:包含適當數量的關鍵詞。
  • homepage:是元件網站的 URL。
  • licence:是元件所採用的軟體授權。
  • authors:包含作者的資料。
  • support:敘述使用者如何找到技術支援。
  • require:列出相依性元件的服務提供者、元件名稱以及最低需求版本。
  • require-dev:同上,但僅列出開發階段的相依性元件。
  • suggest:列出建議的相依性元件,Composer 不會自動安裝。
  • autoload:告訴 Composer 自動載入器如何自動載入此元件。

README.md 檔

這是通常是使用這接觸到的第一個元件介紹檔,它至少提供以下資訊:

  • 元件名稱和敘述
  • 安裝教學
  • 使用教學
  • 測試教學
  • 貢獻指引
  • 作者榮譽
  • 軟體授權許可

實作元件

每個元件類別、介面和特徵機制都必須在 src/ 目錄之下,並且存在 composer.json 列出的名稱空間字首之下。

範例 4-3:URL 掃描器元件類別

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
namespace Oreilly\ModernPHP\Url;

class Scanner
{
/**
* @var array An array of URLs
*/
protected $urls;

/**
* @var \GuzzleHttp\Client
*/
protected $httpClient;

/**
* Constructor
* @param array $urls An array of URLs to scan
*/
public function __construct(array $urls)
{
$this->urls = $urls;
$this->httpClient = new \GuzzleHttp\Client();
}

/**
* Get invalid URLs
* @return array
*/
public function getInvalidUrls()
{
$invalidUrls = [];
foreach ($this->urls as $url) {
try {
$statusCode = $this->getStatusCodeForUrl($url);
} catch (\Exception $e) {
$statusCode = 500;
}

if ($statusCode >= 400) {
array_push($invalidUrls, [
'url' => $url,
'status' => $statusCode
]);
}
}

return $invalidUrls;
}

/**
* Get HTTP status code for URL
* @param string $url The remote URL
* @return int The HTTP status code
*/
protected function getStatusCodeForUrl($url)
{
$httpResponse = $this->httpClient->options($url);

return $httpResponse->getStatusCode();
}
}
  • 此範例並沒有剖析和疊代 CSV 檔,而是在 Scanner 類別建構式中插入 URL 陣列。

版本控制

提交到 Packagist 之前,必須先發布到公開的程式碼儲存庫,例如 GitHub。

可以為元件建立一個語意化版本作為標籤,例如 1.0.0

提交 Packagist

登入 Packagist 後,點選導覽列的 Submit 按鈕,輸入完整的儲存庫網址,Packagist 會進行驗證,完成元件提交程序後,Packagist 會將頁面導向元件列表,列表會從 composer.json 檔中擷取各種資訊。

啟動 GitHub 或 Bitbucket 的掛鉤,讓元件儲存庫更新時送出一個提醒給 Packagist。

使用元件

現在每個人都可以使用 Composer 安裝 URL 掃描器元件。

輸入以下命令來安裝:

1
composer require modernphp/scanner

範例 4-4:URL 掃描器使用

1
2
3
4
5
6
7
8
9
require 'vendor/autoload.php';

$urls = [
'http://www.apple.com',
'http://php.net',
'http://sdfssdwerw.org'
];
$scanner = new \Oreilly\ModernPHP\Url\Scanner($urls);
print_r($scanner->getInvalidUrls());

參考資料

  • Josh Lockhart(2015)。現代 PHP。台北市:碁峯資訊。