Yii2 – 如何写一个插件 , 如何做一个扩展

1.在github申请账户,申请完成就可以创建项目了

2.创建一个composer.json文件:内容如下:

{  
  "name": "zqy234/terrytest",  
  "description": "Yii2 zqy234 terrytest",  
  "keywords": [  
    "yii2",  
    "terrytest"  
  ],  
  "homepage": "https://github.com/zqy234/terrytest",  
  "type": "yii2-extension",  
  "license": "MIT",  
  "support": {  
    "source": "https://github.com/zqy234/terrytest"  
  },  
  "authors": [  
    {  
      "name": "terry water",  
      "email": "zqy234@126.com"  
    }  
  ],  
  "minimum-stability": "stable",  
  "require": {  
    "php": ">=5.4.0",  
    "yiisoft/yii2": ">=2.0.6"  
     
  },  
  "autoload": {  
    "psr-4": {  
      "terry\\": ""  
    }  
  },  
  "config": {  
    "process-timeout": 1800  
  }  
}

我的扩展的地址为:https://github.com/zqy234/terrytest

上面的信息大致核对自己的地址填写,比较重要的为下面

2.1.require 这个是当前插件需要的库包

2.2.autoload:为在aotuload自动加载的信息,psr-4:所在部分加入自动加载的信息,当访问terry\开头的,都会到这个插件的路径下面找文件。

在插件安装的时候,上面psr-4的信息会安装到文件/vendor/composer/autoload_psr4.php 中,具体信息,可以到这个文件夹中查看详细。

3.搞完上面的,我们需要在包管理里面添加。

打开:https://packagist.org/packages/submit

把github的地址提交,提交成功后的界面:

4.到这里就提交成功了,您可以使用composer下载了:

[root@iZ942k2d5ezZ cc]# composer require  zqy234/terrytest:dev-master  
./composer.json has been updated  
Loading composer repositories with package information  
Updating dependencies (including require-dev)  
  - Installing zqy234/terrytest (dev-master c80914f)  
    Cloning c80914fc7dedc2f464f16fb0af5d3a843326bddb  
  
Writing lock file  
Generating autoload files

5.使用正式版本号(稳定版本号)

首先去github中:

然后再packagist中更新:

然后就可以更新了:

[root@iZ942k2d5ezZ cc]# composer require --prefer-dist zqy234/terrytest  
Using version ^1.0 for zqy234/terrytest  
./composer.json has been created  
Loading composer repositories with package information  
Updating dependencies (including require-dev)  
  - Installing yiisoft/yii2-composer (2.0.3)                 
    Loading from cache  
  
  - Installing bower-asset/jquery (2.1.4)  
    Loading from cache  
  
  - Installing bower-asset/yii2-pjax (v2.0.5)  
    Loading from cache  
  
  - Installing bower-asset/punycode (v1.3.2)  
    Loading from cache  
  
  - Installing bower-asset/jquery.inputmask (3.1.63)  
    Loading from cache  
  
  - Installing cebe/markdown (1.1.0)  
    Loading from cache  
  
  - Installing ezyang/htmlpurifier (v4.6.0)  
    Loading from cache  
  
  - Installing yiisoft/yii2 (2.0.6)  
    Loading from cache  
  
  - Installing zqy234/terrytest (1.0.0)  
    Downloading: 100%           
  
Writing lock file  
Generating autoload files  
[root@iZ942k2d5ezZ cc]#

这样就安装成功了。

6.版本号自动更新(github和packagist之间)

访问:https://packagist.org/profile/

获取api token

详细说明地址:https://packagist.org/about

填写的url的格式:https://packagist.org/api/bitbucket?username=USERNAME&apiToken=API_TOKEN

可以用:

curl -XPOST -H'content-type:application/json' 'https://packagist.org/api/update-package?username=USERNAME&apiToken=API_TOKEN' -d'{"repository":{"url":"PACKAGIST_PACKAGE_URL"}}'

来检测。

测试:

在github那边增加一个稳定版本号

然后再 https://packagist.org/packages/zqy234/terrytest#1.0.1

发现:1.0.1出来了。

基本的详细大致使用就这些

总之,可以快乐的,让别人下载自己的库包了

composer require --prefer-dist zqy234/terrytest

 

Yii2 安装 – composer

yii2的框架的安装,以及扩展的安装,都是用composer,下面是安装composer的具体方法:

  1. 查看php是否存在
    php --version

    如果不存在,将安装的php设置下快捷方式,这样,就可以直接用php执行。

  2. 我当前的php的安装路径为/usr/local/php/bin/php 我设置了下快捷方式:
  3. ln -s /usr/local/php/bin/php  /usr/local/bin/php
  4. 安装composer
    curl -sS https://getcomposer.org/installer | php
    mv composer.phar /usr/local/bin/composer
  5. 到这里就安装完成了,譬如,我可以用下面的方式安装asset
    composer global require "fxp/composer-asset-plugin:~1.1.1"

    上面如果报错:参看:http://stackoverflow.com/questions/36579559/updating-composer-throws-exception-class-fxp-composer-assetplugin-repository-npm

    try to update your fxp/composer-asset-plugin:

    php composer.phar global update fxp/composer-asset-plugin --no-plugins

    PS: If after update it still not working, try also following:

    composer global require fxp/composer-asset-plugin --no-plugins

    如果上面的方法还是有问题,譬如我曾经的报错:

    我采取的办法是清空composer global存放的文件夹。我的composer我使用的是root账户,我清空命令如下:

    rm -rf /root/.composer

    然后重新安装:

    composer global require "fxp/composer-asset-plugin:^1.2.0"

    文章参考:

    https://getcomposer.org/doc/03-cli.md#global

https://getcomposer.org/doc/03-cli.md#composer-home

yii2 redis 使用 unixSocket 的方式连接 以及配置

yii2 官方除了一个redis连接的扩展,默认的情况下连接redis,并不是最高效,用unixSocket的方式,速度至少提高一半,配置的方式如下:

1.配置如下:

'redis' => [  
            'class' => 'yii\redis\Connection',  
            'hostname' => 'localhost',  
            'port' => 6379,  
            'database' => 0,  
            'password'  => 'rdsFD',  
            'unixSocket' => '/tmp/redis.sock',  
        ],

也就是在unixSocket 项,配置redis.sock的路径。具体的路径,按照redis unixSocket的路径进行设置。

总之:’unixSocket’ => ‘/tmp/redis.sock’,  是配置 unix Socket的链接方式,速度要比TCP的要快一半。

2.配置redis

vim /etc/redis/6379.conf   (在redis的配置文件中进行修改。)

unixsocket /tmp/redis.sock  
unixsocketperm 700

保存,重启redis。

3.这样,redis就配置好了,使用unixSocket速度比较快一些,用默认的方式,对于一般的Yii2网站来说,也没有太多的问题。

yii2初始化详解 – 深究yii2 autoload机制

yii2采用的基于namespace的autoload机制,我们从初始化来参看yii2的autoload机制的整个过程,详解yii的初始化过程

1.在入口文件index.php我们可以看到代码:

require(__DIR__ . '/../../vendor/autoload.php');

2.我们打开这个文件:

<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer' . '/autoload_real.php';

return ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88::getLoader();

可以看到加载了文件/vendor/composer/autoload_real.php,打开这个文件,我们可以发现,里面定义了一个php的class类:

ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88

也就是调用了这个类的getLoader()方法。

3.找到这个方法getLoader()方法:下面是所有的代码:

<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        spl_autoload_register(array('ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
        spl_autoload_unregister(array('ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88', 'loadClassLoader'));

        $map = require __DIR__ . '/autoload_namespaces.php';
        foreach ($map as $namespace => $path) {
            $loader->set($namespace, $path);
        }

        $map = require __DIR__ . '/autoload_psr4.php';
        foreach ($map as $namespace => $path) {
            $loader->setPsr4($namespace, $path);
        }

        $classMap = require __DIR__ . '/autoload_classmap.php';
        if ($classMap) {
            $loader->addClassMap($classMap);
        }

        $loader->register(true);

        $includeFiles = require __DIR__ . '/autoload_files.php';
        foreach ($includeFiles as $file) {
            composerRequire90def245ed1c6f870abec3fefcc03f88($file);
        }

        return $loader;
    }
}

function composerRequire90def245ed1c6f870abec3fefcc03f88($file)
{
    require $file;
}

首先我们看到的是spl_autoload_register这个方法,这个方法的作用是,在找不到类的情况下,通过这个函数定义的类方法去找,通过传递的参数,返回加载的类的路径。也就是说,当找不到类的时候,就通过这个方法找:

public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

因此这段代码  self::$loader = $loader = new \Composer\Autoload\ClassLoader();

加载的文件是vendor/composer/ClassLoader.php

4.然后通过这个类的方法,加载很多初始路径:

$map = require __DIR__ . '/autoload_namespaces.php';
       foreach ($map as $namespace => $path) {
           $loader->set($namespace, $path);
       }

       $map = require __DIR__ . '/autoload_psr4.php';
       foreach ($map as $namespace => $path) {
           $loader->setPsr4($namespace, $path);
       }

       $classMap = require __DIR__ . '/autoload_classmap.php';
       if ($classMap) {
           $loader->addClassMap($classMap);
       }

       $loader->register(true);

       $includeFiles = require __DIR__ . '/autoload_files.php';
       foreach ($includeFiles as $file) {
           composerRequire90def245ed1c6f870abec3fefcc03f88($file);
       }

       return $loader;

4.1通过set  setPsr4  addClassMap等方法进行namespace路径初始化。 这个对应的文件是/autoload_psr4.php , 这个文件里面是对yii2的插件的namespace的定义:

<?php

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'yii\\swiftmailer\\' => array($vendorDir . '/yiisoft/yii2-swiftmailer'),
    'yii\\redis\\' => array($vendorDir . '/yiisoft/yii2-redis'),
    'yii\\gii\\' => array($vendorDir . '/yiisoft/yii2-gii'),
    'yii\\faker\\' => array($vendorDir . '/yiisoft/yii2-faker'),
    'yii\\debug\\' => array($vendorDir . '/yiisoft/yii2-debug'),
    'yii\\composer\\' => array($vendorDir . '/yiisoft/yii2-composer'),
    'yii\\codeception\\' => array($vendorDir . '/yiisoft/yii2-codeception'),
    'yii\\bootstrap\\' => array($vendorDir . '/yiisoft/yii2-bootstrap'),
    'yii\\' => array($vendorDir . '/yiisoft/yii2'),
    'fecadmin\\' => array($vendorDir . '/fancyecommerce/fec_admin'),
    'fec\\' => array($vendorDir . '/fancyecommerce/fec'),
    'cebe\\markdown\\' => array($vendorDir . '/cebe/markdown'),
    'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),
);

定义各个插件的根路径。

4.2autoload_classmap.php 这个目前为空,没有细致研究具体内部的存放

4.3/autoload_files.php

<?php

// autoload_files.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
    '2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
);

4.4  这是非yii2插件的包库 autoload_namespaces.php

<?php

// autoload_namespaces.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'PHPExcel' => array($vendorDir . '/phpoffice/phpexcel/Classes'),
    'Imagine' => array($vendorDir . '/imagine/imagine/lib'),
    'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),
    'Diff' => array($vendorDir . '/phpspec/php-diff/lib'),
);

譬如我的yii2 – fec 插件中加入的PHPExcel 和Imagine 库包,就会在这里被标注namespace的对应关系。

对于composer安装的库包,有的是include的方式加入的,譬如Excel,安装库包后,不需要再程序中require,包管理器在autoload_namespaces.php  会加入路径,自动加载进来。

还有的是基于namespaces的,譬如Imagine。

5. 通过上面的配置,去找到对应文件路径,加载文件。

也就是说,对于 https://packagist.org/ 这里的php的库包,我们都可以通过composer加载到我们的系统中,在线安装。

譬如:我的fec插件的   composer.json的配置。

"require": {
      "php": ">=5.4.0",
      "yiisoft/yii2": ">=2.0.6",
      "imagine/imagine": "0.5.*",
      "phpoffice/phpexcel": "1.8.*"
},
"autoload": {
  "psr-4": {
    "fec\\": ""
  }
},

其中require代表的需要下载的包

autoload  psr-4 里面添加了信息后,会在 vendor/yiisoft/extensions.php 文件中加入别名。

'fancyecommerce/fec' =>
 array (
   'name' => 'fancyecommerce/fec',
   'version' => '1.1.2.4',
   'alias' =>
   array (
     '@fec' => $vendorDir . '/fancyecommerce/fec',
   ),
 ),

 

vendor/composer/autoload_psr4.php 中加入namespace信息:

'fecadmin\\' => array($vendorDir . '/fancyecommerce/fec_admin'),
    'fec\\' => array($vendorDir . '/fancyecommerce/fec'),