Composer構建現代PHP帝國(二)——編寫自己的Composer包
簡介:你或許使用過多個框架,或許自己開發過很多元件,多個類庫,介面等。會不會因為切換框架而頭疼,是不是還得修改你的程式碼,可能還得在某一框架裡面重新包含這些檔案進來。現在有兩個工具可以幫助你解決這一問題,它們分別是Composer和PEAR.我們主要推薦Composer,並使用Composer開發基於psr系列規範化的元件,類庫等。可以達到一次程式設計,隨處可用的效果。當然,這是得注意一下PHP版本。下面我們將一一領略使用Composer建立自己的元件,並在Thinphp和Laravel中使用來證明為何說Composer一統PHP天下的時代來臨。
要點:
理解composer如何實現自動載入第三方元件; 理解psr-0和psr-4的規範; 理解基於psr-0,psr-4,classmap,files如何實現自動載入。 理解Composer和Packagist
如:要編寫一個Api類,該類主要是使用CURL模擬HTTP的GET和POST請求.
1.先建立目錄結構:
$ mkdir -p sexyphp/curl-http-request/src/
如: sexyphp/curl-http-request/src/
2.建立檔案
$touch sexyphp/curl-http-request/src/Api.php
3.寫入檔案內容:
格式如: namespace DIRNAME\...\DIRNAME; Use DIRNAME\...\DIRNAME\FILENAME; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } 內容: <?php namespace Sexyphp\Src; use Sexyphp\Src\Curl; class Api { private $curl; private $pathSuffix; /** * Api constructor. */ public function __construct($pathSuffix) { $this->curl = new Curl(); $this->pathSuffix = $pathSuffix; } public function getData($uri) { $out = $this->curl->get($this->pathSuffix.$uri); if ($this->curl->http_code != 200) { throw new \Exception("error: can't connect server"); } if(is_null(json_decode($out))){ if(env('APP_DEBUG')){ var_dump($out); } throw new \Exception('error: is not json'); } $json = $this->str2json($out); if ( !isset($json["code"])) { if(env('APP_DEBUG')){ echo $out; } throw new \Exception('error:not find json[code]'); } return $out; } public function postData($uri, $vars = array()) { $out = $this->curl->post($this->pathSuffix.$uri, $vars); $json = $this->str2json($out); if ($json["code"] == 200) { return $json["data"]; } else { throw new \Exception($json["msg"]); } } private function str2json($str) { return json_decode($str,true); } }
4.通過上面的操作,已經完成該了兩個類庫的開發,那麼如何使用Composer來實現依賴關係呢!聰明的你,應該想到了需要建立一個composer.json檔案了.
1) composer包的目錄結構 你現在可以看看Laravel或者Thinphp包含有vendor目錄下面的元件,仔細看看都有什麼規律嗎?咱們以laravel框架下的vendor/laravel為例,當然其他框架的也可以看看,大致都是一樣的規律,這就是統一規範的好處!那就是不讓你隨便定義元件檔案和程式碼結構,你有你的style,我有我的style,那就叫花式虐狗了.
example for laravel/laravel: laravel framework src ... ... dirname../**.[class].php composer.json LICENCE.md README.md
一個供應商可能還有N個開源工具在同一個包裡面,上面是一個常見的結構,還有一種如下:
example for laravel/phpunit:
phpunit
php-code-coverage
src
...
...
dirname../**.[class].php
composer.json
LICENCE.md
README.md
php-timer
src
...
...
dirname../**.[class].php
composer.json
LICENCE.md
README.md
其實我個人也只推薦這兩種,雖然說基於名稱空間你可隨處都放,只要自動載入能找到就行.所以標準就是要大家規範化程式設計,養成良好的擼程式碼習慣,太騷氣的程式碼容易惹禍上身哦!
2).建立composer.json實現自動載入所需依賴元件,簡單的元件json格式如下:
{
"name": "sexyphp/curl-http-request",
"description": "The Sexyphp curl-http-request.",
"keywords": ["sexyphp", "curl","http request"],
"type": "library",
"license": "MIT",
"homepage": "http://sexyphp.com",
"support": {
"issues": "https://github.com/sexyphp/composer/issues",
"source": "https://github.com/sexyphp/composer/tree/master/vendor/sexyphp"
},
"authors": [
{
"name": "LiangFeng",
"email": "[email protected]"
}
],
"require": {
"php": "^5.3|^7.0"
},
"replace": {
},
"require-dev": {
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
}
}
5.在應用目錄外的composer.json加入(只選一種):
"autoload-dev": {
"classmap": [
"vendor/sexyphp"
]
},
或者:
"autoload": {
"classmap": [
"vendor/sexyphp"
]
},
或者:
"autoload":{
"psr-4": {
"Sexyphp\\" : "vendor/sexyphp/curl-http-request"
}
},
可根據上一篇部落格所說的使用4種載入方式,classmap,psr-0,psr-4,files
6.執行dump-autoload載入
$ composer dump-autoload
7.如果報錯,可能是json檔案的格式沒對.如果沒報錯,那就檢視vendor/composer/autoload_classmap.php或autoload_static.php是否自動載入了你自己開發的包.
eg: autoload_classmap.php
'Sexyphp\\Src\\Api' => $vendorDir . '/sexyphp/curl-http-request/src/Api.php',
'Sexyphp\\Src\\Curl' => $vendorDir . '/sexyphp/curl-http-request/src/Curl.php',
eg: autoload_static.php
'Sexyphp\\Src\\Api' => __DIR__ . '/..' . '/sexyphp/curl-http-request/src/Api.php',
'Sexyphp\\Src\\Curl' => __DIR__ . '/..' . '/sexyphp/curl-http-request/src/Curl.php',
8.在入口目錄中呼叫Api類檢視是否正確載入進來了.
<?php
require "vendor/autoload.php";
$api = new \Sexyphp\Src\Api('http://sexyphp.com/');
$data = $api->getData('index.php?m=Home&c=Article&a=index&id=4');
var_dump($data);
$ php index.php檢視var_dump輸出 或瀏覽器輸入 : localhost檢視
本篇就將到這裡,下一篇將使用Composer建立抽象介面整合元件式開發.