1、私有组件

大多数时候我们使用的都是公开可用的开源组件,但有时候如果公司使用内部开发的PHP组件,而基于许可证和安全方面的问题不能将其开源,就需要使用私有组件。对Composer而言,这是小菜一碟。

Composer可用管理放在需要认证的仓库中的私有PHP组件,执行composer installcomposer update命令时,如果组件的仓库需要认证凭据,Composer会提醒你需要输入认证信息,此外,Composer还会询问是否把仓库的认证凭据保存在本地的auth.json文件(和composer.json放在同一级)。下面是auth.json的内容示例:

{
    “http-basic”: {
        “laravelacademy.org”: {
            “username”: “your-username”,
            “password”: “your-password"
        }
    }
}

auth.json最好不要放到版本控制中,我们要让项目的开发者自己创建auth.json文件,保存他们自己的认证凭据。

如果不想傻傻的等待Composer向你询问认证凭据,可以使用下述命令手动告诉Composer远程设备的认证凭据:

composer config http-basic.laravelacademy.org your-username your-password

在这个示例中,http-basic告诉Composer我们要为指定的域名添加认证信息。laravelacademy.org是主机名,用于识别存储私有组件仓库的设备,最后两个参数是用户名和密码。默认情况下,这个命令会在当前项目中的auth.json文件里保存凭据。

你还可以使用--global标记在系统全局中保存认证凭据。使用这个标记设定认证凭据后,Composer会在本地设备中的所有项目里使用这个凭据。

composer config --global http-basic.laravelacademy.org your-username your-password

全局凭据保存在~/.composer/auth.json中,如果你使用的是Windows系统,相应全局凭据保存在APPDATA%/Composer文件夹中。

2、创建组件

现在你应该知道怎么查找和使用PHP组件了,下面我们来讨论如何创建PHP组件。创建PHP组件是把工作成果分享给PHP社区成员的好方式,PHP社区乐于分享和帮助他人,如果你在应用中使用了开源组件,那么投桃报李,创建有创意的新开源组件是回报社区最好的方式。

注:别重新编写已经存在的组件,如果是改进现有组件,可以在拉取请求中把改进发送给原本的组件,否则,PHP生态系统将充斥重复的组件。

命名空间

在设置命名空间之前,先要确定厂商名称和包名,即形如laravel/framework这样,要确保其全局唯一性,在Packagist中不存在。

每个组件都有自己的命名空间,说到这里,人们常常误以为组件的命名空间必须与组件的厂商名和包名一致,其实不然,组件使用的命名空间与组件的厂商名和包名无关,厂商名和包名只是为了让Packagist和Composer识别组件,而组件的命名空间是为了在PHP代码中使用组件。

文件系统结构

PHP组件的文件系统结构基本上是确定的:

  • src:这个目录用于存放组件的源代码
  • tests:存放组件的测试代码
  • composer.json:Composer配置文件,用于描述组件,声明组件依赖以及自动加载配置等
  • README.md:这个Markdown文件提供关于组件的相关信息、使用文档说明、软件许可证等
  • CONTRIBUTING.md:这个Markdown文件告知别人如何为这个组件做贡献
  • LICENSE:纯文本文件,声明组件的软件许可证
  • CHANGELOG.md:Markdown文件,列出组件在每个版本中引入的改动

composer.json

PHP组件中必须包含composer.json文件,而且这个文件的内容必须是有效的JSON,Composer会使用这个文件中的信息查找、安装和自动加载PHP组件。composer.json文件还包含组件在Packagist目录中的信息。

我们新建一个组件目录(~/Packages/urlscanner),然后在urlscanner目录下通过如下命令生成composer.json文件:

composer init

然后在终端会让我们按照提示向导一步步填写composer.json内容:

最后回车,会生成相应的composer.json文件,我们对该文件作如下修改:

{
    "name": "laravelacademy/urlscanner",
    "description": "Scan URLs FROM A CSV FILE AND REPORT INACCESSIBLE URLs",
    "keywords": ["url", "scanner", "csv"],
    "homepage": "http://laravelacademy.org",
    "license": "MIT",
    "authors": [
        {
            "name": "sunqiang",
            "email": "yaojinbu@163.com"
        }
    ],
    "support": {
        "email": "yaojinbu@163.com"
    },
    "minimum-stability": "dev",
    "require": {
        "php": ">=5.4.0",
        "guzzlehttp/guzzle": "~5.0"
    },
    "require-dev": {
        "phpunit/phpunit": "~4.3"
    },
    "suggest": {
        "league/csv": "~6.0"
    },
    "autoload": {
        "psr-4": {
            "LaravelAcademy\\UrlScanner\\": "src/"
        }
    }
}

我们来仔细研究一下这个文件,看看每个部分究竟是什么意思:

  • name:组件的厂商名和包名,也是Packagist中的组件名
  • description:简要说明组件
  • keywords:描述属性的关键字
  • homepage:组件网站URL
  • license:PHP组件采用的软件许可证(更多软件许可证参考:http://choosealicense.com/
  • authors:作者信息数组
  • support:组件用户获取技术支持的方式
  • require:组件自身依赖的组件
  • require-dev:开发这个组件所需的依赖
  • suggest:建议安装的组件
  • autoload:告诉Composer自动加载器如何自动加载这个组件

READEME.md

通常这个是用户最先阅读的文件,对托管在Github和Bitbucket中的组件来说,更是如此。标准的READEME.md文件至少提供以下信息:

  • 组件的名称和描述
  • 安装说明
  • 使用说明
  • 测试说明
  • 贡献方式
  • 支持资源
  • 作者信息
  • 软件许可证

实现组件

开始之前我们使用如下命令安装依赖:

composer install

该命令会把依赖组件安装到vendor目录并生成自动加载器。

现在我们要来实现组件的具体功能了。这一步我们要编写组成PHP组件的类、接口和Trait,编写什么类以及编写多少类完全取决于PHP组件的作用。不过组件中的所有类、接口和Trait都要放到src目录下。

对这个组件来说我只需要创建一个类Scanner,位于子命名空间Url中,这个子命名空间位于composer.json文件中设定的LaravelAcademy/UrlScanner命名空间下,Scanner类保存在src/Url/Scanner.php文件。Scanner类实现的逻辑和上一节的URL扫描器示例应用相同,只不过现在我们要把扫描URL的功能封装在一个PHP类中:

<?php
namespace LaravelAcademy\UrlScanner\Url; use GuzzleHttp\Client; class Scanner
{
protected $urls; protected $httpClient; public function __construct(array $urls)
{
$this->urls = $urls;
$this->httpClient = new Client();
} /**
* 获取访问指定URL的HTTP状态码
*
* @param $url
* @return int
*/
public function getStatusCodeForUrl($url)
{
$httpResponse = $this->httpClient->get($url);
return $httpResponse->getStatusCode();
} /**
* 获取死链
*
* @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;
} }

我们没有解析并迭代处理一个CSV文件,而是把一个URL数组传递给Scanner类的构造函数,因为我们要尽量让这个扫描URL的类通用。如果直接处理CSV文件就限制了这个组件的用途。我们把获取URL的来源开放给用户,让他们自己从文件、数组亦或是CSV文件中获取。所以回到上面的composer.json,我们在suggest中声明了league/csv组件,只是建议安装,并不是必须安装。

提交到Packagist

我们先将代码提交到GitHub(注意将vendor目录添加到.gitignore)仓库(我的是nonfu/urlscanner):

涉及到的git命令如下:

git init
git remote add origin https://github.com/nonfu/urlscanner.git
git add .
git commit -m “urlscanner"
git pull origin master
git push origin master

这样就将本地组件提交到GitHub仓库:

然后在Packagist中通过GitHub账户登录,通过https://packagist.org/packages/submit提交组件,在输入框中输入刚刚提交的GitHub仓库地址:

check成功后点击submit即可将组件提交到Packagist:

其中红色的警告的意思是需要我们通过GitHub Service Hook去GitHub中创建一个钩子,以后每次更新组件的GitHub仓库时通知Packagist。

3、使用组件

至此,我们已经成功将自己的组件提交到Packagist,现在任何人都可以使用Composer安装这个URL扫描器组件,然后在自己的PHP应用中使用。在终端执行如下命令安装这个组件:

composer require laravelacademy/urlsanner dev-master

然后在我们的代码中使用:

<?php
require “vendor/autoload.php”; $urls = [
    “http://laravelacademy.org”,
    “http://laravel-academy.org”,
    “https://packagist.org"
]; $scanner =  new \LaravelAcademy\UrlScanner\Url\Scanner($urls);
print_r($scanner->getInvalidUrls()); 参考文档:https://laravelacademy.org/post/4545.html

聊聊 PHP 私有组件以及如何创建自己的 PHP 组件 (转)的更多相关文章

  1. Qt Quick 组件和动态创建的对象具体的解释

    在<Qt Quick 事件处理之信号与槽>一文中介绍自己定义信号时,举了一个简单的样例.定义了一个颜色选择组件,当用户在组建内点击鼠标时,该组件会发出一个携带颜色值的信号,当时我使用 Co ...

  2. Android开发10.1:UI组件适配器AdapterView(创建ListView,Adapter接口)

    @version:Android4.3 API18 @author:liuxinming 概述               AdapterView继承了ViewGroup,它的本质是容器       ...

  3. Vue:如何在vue-cli中创建并引入自定义组件

    一.创建并引入一个组件 1.创建组件 vue-cli中的所有组件都是存放在components文件夹下面的,所以在components文件夹下面创建一个名为First.vue的自定义组件: <t ...

  4. C#创建和使用ActiveX组件

    开发基于.Net平台上的程序员是很难从本质上把Visual C#和ActiveX组件联起来,虽然在使用Visual C#开发应用程序时,有时为了快速开发或者由于.Net FrameWork SDK的不 ...

  5. Ionic 2 中的创建一个闪视卡片组件

    闪视卡片是记忆信息的重要工具,它的使用可以追溯到19世纪.我们将要创建一个很酷的短暂动画来实现它.看起来像是这个样子的: 闪视卡片示例 Ionic 2 实例开发 新增章节将为你介绍如何在Ionic 2 ...

  6. unity编辑器扩展_03(在组件中右击创建一个选项,并通过该选项修改该组件下面的字段的值)

    在组件中右击创建一个选项代码: [MenuItem("CONTEXT/PlayerHealth/InitHealth")]    static void Test5()    {  ...

  7. ReactNative: 创建自定义List列表组件

    一.介绍 在App中,很多数据消息显示都是一行行动态展示的,例如新闻标题,其实每一条新闻标题都可以独立成一个简单的列表组件,之前我们使用Text组件将数据都写死了,为了提高组件的灵活性,我们可以使用T ...

  8. 如何创建一个前端 React 组件并发布到 NPM

    首先npm文档摆在这里: https://www.npmjs.cn/ 参考组件 https://github.com/rakuten-rex/rex-dropdownhttps://www.npmjs ...

  9. 多对多第三张表的创建方式 和 forms组件的使用

    目录 一.多对多第三张表的创建 1. 全自动方式 (1)实现代码 (2)优点和不足 2. 纯手撸方式(了解) (1)实现代码 (2)优点和不足 3. 半自动方式(推荐使用) (1)实现代码 (2)优点 ...

随机推荐

  1. python下载网页视频

    因网站不同需要修改. 下载 mp4 连接 from bs4 import BeautifulSoup import requests import urllib import re import js ...

  2. 审核被拒:1. 1 Safety: Objectionable Content ;3. 1.1 Business: Payments - In-App Purchase ;4. 3 Design: Spam ;5. 1.1 Legal: Privacy - Data Collection and Storage

    1. 1 Safety: Objectionable Content                          有人民币符号—隐藏收费课程 3. 1.1 Business: Payments ...

  3. 【Python全栈-JavaScript】JavaScript的window.onload()与jQuery 的ready()的区别

    JavaScript的window.onload()与jQuery 的ready()的区别 做web开发时常用Jquery中$(document).ready()和JavaScript中的window ...

  4. Python3学习之路~5.9 xml处理模块

    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,以前在json还没诞生的时候,大家只能选择用xml,至今很多传统公司如金融行业的很多系统的接口还主要 ...

  5. 转载的web server实例

    asp.net—web server模拟网上购物 2014-05-08     我来说两句   来源:asp.net—web server模拟网上购物   收藏    我要投稿 在学vb的时候学到了a ...

  6. Python使用中错误(持续更新.....)

    1.在使用requests发送请求,响应数据转成json提示,没有可解码的json 解决办法: 这是由于,发送请求的数据,存在错误,响应出错比如404 400,所以找不到可以解码的json 示例如下: ...

  7. Archlinux软件包管理pacman基本使用说明

    熟悉APT和YUM包管理的应该都知道,这两个包管理的使用命令都是采用"主命令+参数"的格式,比如"sudo apt-get install --reinstall pac ...

  8. jdk1.8新特性之lambda表达式及在Android Studio中的使用举例

    Jdk1.8已经出很久了但是很多同学对它的特性在android studio 中的应用可能还不是很熟悉,今天我们就来对这个新特性在AS中做它的应用实践. 一.首先在有JDK1.8的情况下我们要在AS的 ...

  9. dubbo框架整合常见问题

    逆向工程常见问题总结 tomcat7插件启动项目卡在:log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for ...

  10. Ubuntu16.04 appstreamcli错误

    解决方案:https://askubuntu.com/questions/774986/appstreamcli-hanging-with-100-cpu-usage-during-update 搬运 ...