1. 程式人生 > >Composer構建現代PHP帝國(二)——編寫自己的Composer包

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建立抽象介面整合元件式開發.

問題:你理解composer如何實現自動載入第三方元件了嗎?