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'),

 

 

 

 

 

 

 

yii2 model 输出sql

我们在使用model进行查询的时候,或者其他,我们想要打印出来model赋值后,在mysql数据库中执行的sql,我们可以使用下面的方法打印sql。

$query = Salesorder::find()  
  ->where(['order_id'=>[1,2,3,4]])  
  ->select(['order_id'])  
;  
// get the AR raw sql in YII2  
$commandQuery = clone $query;  
echo $commandQuery->createCommand()->getRawSql();  
exit;

 

yii2 model 规则验证

YII2的model 在设置值的时候,有很多规则的验证,通过规则的验证,来验证前端传递过来的数据,然后在把数据赋值于model。

下面是model的rule:

[['字段名'],required,'requiredValue'=>'必填值','message'=>'提示信息']; #说明:CRequiredValidator 的别名, 确保了特性不为空.

email : 邮箱验证

['email', 'email'];

match : 正则验证

[['字段名'],match,'pattern'=>'正则表达式','message'=>'提示信息'];      
[['字段名'],match,'not'=>ture,'pattern'=>'正则表达式','message'=>'提示信息']; /*正则取反*/ #说明:CRegularExpressionValidator 的别名, 确保了特性匹配一个正则表达式.

url : 网址

['website', 'url', 'defaultScheme' => 'http'];

captcha : 验证码

['verificationCode', 'captcha'];

safe : 安全

['description', 'safe'];

compare : 比较

['age', 'compare', 'compareValue' => 30, 'operator' => '>=']; #说明:compareValue(比较常量值) - operator(比较操作符)  #说明:CCompareValidator 的别名,确保了特性的值等于另一个特性或常量.

default : 默认值

['age', 'default', 'value' => null]; #说明:CDefaultValueValidator 的别名, 为特性指派了一个默认值.

exist : 存在

['username', 'exist'];

file : 文件

['primaryImage', 'file', 'extensions' => ['png', 'jpg', 'gif'], 'maxSize' => 1024*1024*1024]; #说明:CFileValidator 的别名, 确保了特性包含了一个上传文件的名称.

filter : 滤镜

[['username', 'email'], 'filter', 'filter' => 'trim', 'skipOnArray' => true]; #说明:CFilterValidator 的别名, 使用一个filter转换属性.

in : 范围

['level', 'in', 'range' => [1, 2, 3]];

unique : 唯一性

['username', 'unique']

integer : 整数

['age', 'integer'];

number : 数字

['salary', 'number'];

double : 双精度浮点型

['salary', 'double'];

date : 日期

[['from', 'to'], 'date'];

string : 字符串

['username', 'string', 'length' => [4, 24]];

boolean : 是否为一个布尔值

['字段名', 'boolean', 'trueValue' => true, 'falseValue' => false, 'strict' => true]; #说明:CBooleanValidator 的别名

 

yii2 RESTful 接口 api -3 : 账户验证 和 速度控制

1.

创建数据库表:

sql创建:

CREATE TABLE IF NOT EXISTS `user` (  
  `id` int(20) unsigned NOT NULL AUTO_INCREMENT,  
  `username` varchar(50) DEFAULT NULL COMMENT '用户名',  
  `password_hash` varchar(80) DEFAULT NULL COMMENT '密码',  
  `password_reset_token` varchar(60) DEFAULT NULL COMMENT '密码token',  
  `email` varchar(60) DEFAULT NULL COMMENT '邮箱',  
  `auth_key` varchar(60) DEFAULT NULL,  
  `status` int(5) DEFAULT NULL COMMENT '状态',  
  `created_at` int(18) DEFAULT NULL COMMENT '创建时间',  
  `updated_at` int(18) DEFAULT NULL COMMENT '更新时间',  
  `password` varchar(50) DEFAULT NULL COMMENT '密码',  
  `role` varchar(50) DEFAULT NULL COMMENT 'role',  
  `access_token` varchar(60) DEFAULT NULL,  
  `allowance` int(20) NOT NULL,  
  `allowance_updated_at` int(20) NOT NULL,  
  PRIMARY KEY (`id`),  
  UNIQUE KEY `username` (`username`),  
  UNIQUE KEY `access_token` (`access_token`)  
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;  
  
--  
-- 转存表中的数据 `user`  
--  
  
INSERT INTO `user` (`id`, `username`, `password_hash`, `password_reset_token`, `email`, `auth_key`, `status`, `created_at`, `updated_at`, `password`, `role`, `access_token`, `allowance`, `allowance_updated_at`) VALUES  
(1, 'terry', '$2y$13$EyK1HyJtv4A/19Jb8gB5y.4SQm5y93eMeHjUf35ryLyd2dWPJlh8y', NULL, 'zqy234@126.com', 'pBJi3hyFsLsTuvUM9paFpWjYRatn3qwS', 10, 1441763620, 1447318986, NULL, NULL, 'xxxxxxxxxxxxxxxxxxxx', 0, 1447318986),  
(2, 'terry1', '$2y$13$B0P2T4wEFrxeecSEClo5g.wrapMqG0RmsSL0cJluHJ747M3R0vkMG', NULL, 'zqy2341@126.com', 'wIvJk7dMm6PQ1dJFz8iUqJ1RfH6rsDTW', 10, 1441763906, 1441763906, NULL, NULL, NULL, 0, 0),  
(3, 'zqy', '$2y$13$kcczJRoLGqSWHo7AZloCyeJiMYeM5SA1uXhyUZCNkFirWJuWeC3gO', NULL, 'zqy23114@126.com', 'K-76pcy7gxceemxRI2IeN5g1EhLMaCj8', 10, 1442544183, 1442544183, NULL, 'moderator', NULL, 0, 0),  
(4, 'admin', '$2y$13$w4/PWXvwRUKNSrDTSMhPhOnvxw4v4WWt7GVl2siozPDlmEjP04vJC', NULL, 'zqy2342321@126.com', 'hZWOaamjHEsPtuJJVghFRdE2oTj7Qv8P', 10, 1446524232, 1446524232, NULL, NULL, NULL, 0, 0);  

2.

设置用户组件 yii\web\User ;

'user' => [  
            'identityClass' => 'myapp\code\core\Erp\User\models\User',  
        #   'enableAutoLogin' => true,  
        ],

3.创建User模块,在模块中加入

'user' =>   
        [  
            'class' => 'myapp\code\core\Erp\User\Module',  
        ]

4.编辑 myapp\code\core\Erp\User\Module.php

<?php  
namespace myapp\code\core\Erp\User;  
use Yii;  
class Module extends \yii\base\Module  
{  
    public $controllerNamespace = 'myapp\code\core\Erp\User\controllers';  
  
    public function init()  
    {  
        parent::init();  
        # session 设置无效  
         \Yii::$app->user->enableSession = false;  
         \Yii::$app->user->loginUrl = null;  
        # 加载配置文件  
        if(file_exists(__DIR__ . '/etc/config.php')){  
            Yii::configure($this, ['params'=>(require(__DIR__ . '/etc/config.php'))]);  
        }  
        $this->params['blockDir'] = str_replace("\\controllers","",$this->controllerNamespace);  
    }  
}

主要是 设置:

\Yii::$app->user->enableSession = false;  
\Yii::$app->user->loginUrl = null;

 

5.创建  myapp\code\core\Erp\User\models\User 实现 yii\web\IdentityInterface 接口。

代码如下:

<?php  
namespace myapp\code\core\Erp\User\models;  
  
use Yii;  
use yii\base\NotSupportedException;  
use yii\behaviors\TimestampBehavior;  
use yii\db\ActiveRecord;  
use yii\web\IdentityInterface;  
use yii\filters\RateLimitInterface;  
/**  
 * User model  
 *  
 * @property integer $id  
 * @property string $username  
 * @property string $password_hash  
 * @property string $password_reset_token  
 * @property string $email  
 * @property string $auth_key  
 * @property integer $status  
 * @property integer $created_at  
 * @property integer $updated_at  
 * @property string $password write-only password  
 */  
class User extends ActiveRecord implements IdentityInterface ,RateLimitInterface  
{  
    const STATUS_DELETED = 0;  
    const STATUS_ACTIVE = 10;  
  
      
    # 速度控制  6秒内访问3次,注意,数组的第一个不要设置1,设置1会出问题,一定要  
    #大于2,譬如下面  6秒内只能访问三次  
    # 文档标注:返回允许的请求的最大数目及时间,例如,[100, 600] 表示在600秒内最多100次的API调用。  
    public  function getRateLimit($request, $action){  
         return [3, 6];  
    }  
    # 文档标注: 返回剩余的允许的请求和相应的UNIX时间戳数 当最后一次速率限制检查时。  
    public  function loadAllowance($request, $action){  
        //return [1,strtotime(date("Y-m-d H:i:s"))];  
        //echo $this->allowance;exit;  
         return [$this->allowance, $this->allowance_updated_at];  
    }  
    # allowance 对应user 表的allowance字段  int类型  
    # allowance_updated_at 对应user allowance_updated_at  int类型  
    # 文档标注:保存允许剩余的请求数和当前的UNIX时间戳。  
    public  function saveAllowance($request, $action, $allowance, $timestamp){  
        $this->allowance = $allowance;  
        $this->allowance_updated_at = $timestamp;  
        $this->save();  
    }  
      
      
      
    /**  
     * @inheritdoc  
     */  
    # 设置table  
    public static function tableName()  
    {  
        return 'user';  
    }  
  
    /**  
     * @inheritdoc  
     */  
    public function behaviors()  
    {  
        return [  
            TimestampBehavior::className(),  
        ];  
    }  
  
    /**  
     * @inheritdoc  
     */  
    # 设置 status  默认  ,以及取值的区间  
    public function rules()  
    {  
        return [  
            ['status', 'default', 'value' => self::STATUS_ACTIVE],  
            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],  
        ];  
    }  
  
    /**  
     * @inheritdoc  
     */  
    # 通过id 找到identity  
    public static function findIdentity($id)  
    {  
        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);  
    }  
  
    /**  
     * @inheritdoc  
     */  
    # 通过access_token 找到identity  
    public static function findIdentityByAccessToken($token, $type = null)  
    {  
        return static::findOne(['access_token' => $token, 'status' => self::STATUS_ACTIVE]);  
    }  
    # 生成access_token  
    public function generateAccessToken()  
    {  
        $this->access_token = Yii::$app->security->generateRandomString();  
    }  
  
    /**  
     * Finds user by username  
     *  
     * @param string $username  
     * @return static|null  
     */  
    public static function findByUsername($username)  
    {  
        return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);  
    }  
  
    /**  
     * Finds user by password reset token  
     *  
     * @param string $token password reset token  
     * @return static|null  
     */  
    # 此处是忘记密码所使用的  
    public static function findByPasswordResetToken($token)  
    {  
        if (!static::isPasswordResetTokenValid($token)) {  
            return null;  
        }  
  
        return static::findOne([  
            'password_reset_token' => $token,  
            'status' => self::STATUS_ACTIVE,  
        ]);  
    }  
  
    /**  
     * Finds out if password reset token is valid  
     *  
     * @param string $token password reset token  
     * @return boolean  
     */  
    public static function isPasswordResetTokenValid($token)  
    {  
        if (empty($token)) {  
            return false;  
        }  
  
        $timestamp = (int) substr($token, strrpos($token, '_') + 1);  
        $expire = Yii::$app->params['user.passwordResetTokenExpire'];  
        return $timestamp + $expire >= time();  
    }  
  
    /**  
     * @inheritdoc  
     */  
    public function getId()  
    {  
        return $this->getPrimaryKey();  
    }  
  
    /**  
     * @inheritdoc  
     */  
    public function getAuthKey()  
    {  
        return $this->auth_key;  
    }  
  
    /**  
     * @inheritdoc  
     */  
    public function validateAuthKey($authKey)  
    {  
        return $this->getAuthKey() === $authKey;  
    }  
  
    /**  
     * Validates password  
     *  
     * @param string $password password to validate  
     * @return boolean if password provided is valid for current user  
     */  
    public function validatePassword($password)  
    {  
        return Yii::$app->security->validatePassword($password, $this->password_hash);  
    }  
  
    /**  
     * Generates password hash from password and sets it to the model  
     *  
     * @param string $password  
     */  
    public function setPassword($password)  
    {  
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);  
    }  
  
    /**  
     * Generates "remember me" authentication key  
     */  
    public function generateAuthKey()  
    {  
        $this->auth_key = Yii::$app->security->generateRandomString();  
    }  
  
    /**  
     * Generates new password reset token  
     */  
    public function generatePasswordResetToken()  
    {  
        $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();  
    }  
  
    /**  
     * Removes password reset token  
     */  
    public function removePasswordResetToken()  
    {  
        $this->password_reset_token = null;  
    }  
}

6.控制器:

<?php  
namespace myapp\code\core\Erp\User\controllers;  
  
use Yii;  
use yii\web\Controller;  
use myapp\code\core\Erp\User\models\User;  
use yii\filters\auth\CompositeAuth;  
use yii\filters\auth\HttpBasicAuth;  
use yii\filters\auth\HttpBearerAuth;  
use yii\filters\auth\QueryParamAuth;  
use yii\filters\RateLimiter;  
class IndexController extends Controller  
{  
     
    public function init(){  
            parent::init();  
    }  
      
    # 行为 添加   
    #   验证 :authenticator  
    #   速度控制:rateLimiter  
    public function behaviors()  
    {  
        $behaviors = parent::behaviors();  
        $behaviors['authenticator'] = [  
            'class' => CompositeAuth::className(),  
            'authMethods' => [  
                # 下面是三种验证access_token方式  
                //HttpBasicAuth::className(),  
                //HttpBearerAuth::className(),  
                # 这是GET参数验证的方式  
                # http://10.10.10.252:600/user/index/index?access-token=xxxxxxxxxxxxxxxxxxxx  
                QueryParamAuth::className(),  
            ],  
          
        ];  
          
        # rate limit部分,速度的设置是在  
        #   \myapp\code\core\Erp\User\models\User::getRateLimit($request, $action){  
        /*  官方文档:  
            当速率限制被激活,默认情况下每个响应将包含以下HTTP头发送 目前的速率限制信息:  
            X-Rate-Limit-Limit: 同一个时间段所允许的请求的最大数目;  
            X-Rate-Limit-Remaining: 在当前时间段内剩余的请求的数量;  
            X-Rate-Limit-Reset: 为了得到最大请求数所等待的秒数。  
            你可以禁用这些头信息通过配置 yii\filters\RateLimiter::enableRateLimitHeaders 为false, 就像在上面的代码示例所示。  
  
        */  
        $behaviors['rateLimiter'] = [  
            'class' => RateLimiter::className(),  
            'enableRateLimitHeaders' => true,  
        ];  
        return $behaviors;  
    }  
      
     public function actionIndex()  
    {  
          
        echo Yii::$app->user->id;  
    }  
      
      
}

 

7

然后通过访问:

http://10.10.10.252:900/user/index/index?access-token=nnnnnnnnnnnnnn

就可以访问了,由于我设置的是6秒内访问3次,正常访问,查看head消息头:如下

我设置的是:6秒内最多访问3次的返回结果

X-Rate-Limit-Limit : 3        总次数还剩余3次

X-Rate-Limit-Remaining:2  还剩余2次

yii2 RESTful 接口 api -2 : 自定义函数

yii2 的 restful 接口的默认  是帮写了很多的方法

下面我们需要书写自己的接口方法,譬如搜索方法。

1.更改配置:

'urlManager' => [  
            'class' => 'yii\web\UrlManager',  
            'enablePrettyUrl' => true,  
            'enableStrictParsing' => true,  
            'showScriptName' => false,  
            'rules' => [  
                '' => 'cms/index',  
                  
                  
                ['class' => 'yii\rest\UrlRule', 'controller' => 'customer/api',  
                  
                  'pluralize' => false,  
  
                ],  
                #  定义方法: public function actionSearch($name);   <name> 就是search方法传入的参数  
                'POST customer/api/search/<name>' => 'customer/api/search',  
                //'POST customer' => 'customer/index/create',  
                  
  
            ],  
              
        ],

也就是添加:

'POST customer/api/search/<name>' => 'customer/api/search',

 

name代表的是参数

2.我们需要返回的是json格式:

<?php  
namespace myapp\frontend\code\ECM\Customer\controllers;  
use yii\web\Response;  
use Yii;  
  
use yii\rest\ActiveController;  
use myapp\frontend\code\ECM\User\models\Product;  
class ApiController extends ActiveController  
{  
    public $modelClass = 'myapp\frontend\code\ECM\User\models\Product';  
      
    public function behaviors()  
    {  
        $behaviors = parent::behaviors();  
        #定义返回格式是:JSON  
        $behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON;  
        return $behaviors;  
    }  
      
    public function actionSearch($name){  
        $one = Product::findOne(['name'=>$name]);  
        return $one;  
    }  
}

3. 然后访问:

curl -i -H "Accept:application/json" -H "Content-Type:application/json" -XPOST "http://10.10.10.252:800/customer/api/search/xxxx"

我们发现 name 为xxxx的条目被打印出来了

HTTP/1.1 200 OK  
Server: nginx  
Date: Wed, 18 Nov 2015 02:26:40 GMT  
Content-Type: application/json; charset=UTF-8  
Transfer-Encoding: chunked  
Connection: keep-alive  
X-Powered-By: PHP/5.4.34  
  
{"id":2,"name":"xxxx","description":"ddddd","image":null,"status":null,"created_at":null}

 

yii2 RESTful 接口 api -1 : 接口的基本配置

关于yii2的接口,使用起来是比较方便,配置起来也比较方便,不过按照模块和非模块的配置,在一些地方是不一样的,对于restful api的哲学思想,可以搜索资料,总体来说restfulapi是通过请求类型的不同来决定具体的操作,简略来说,restful api并不是一门技术,而是一种规则,实际当中,很少有人严格的按照restful的哲学思想设计API,一般都是用post类型,好了,下面说下restful api的知识,如何在yii2中使用。

先配置一个普通的restful

我配置的是以模块的方式进行的配置:

1. 配置好模块

2. 定义controller   ,继承于 yii\rest\ActiveController

<?php  
namespace myapp\frontend\code\ECM\Customer\controllers;  
  
use Yii;  
  
use yii\rest\ActiveController;  
  
class IndexController extends ActiveController  
{  
    public $modelClass = 'myapp\frontend\code\ECM\User\models\Product';  
      
}

3.创建资源:

数据库部分:

CREATE TABLE IF NOT EXISTS `restful_product` (  
  `id` int(11) NOT NULL AUTO_INCREMENT,  
  `name` varchar(255) DEFAULT NULL,  
  `description` varchar(255) DEFAULT NULL,  
  `image` varchar(255) DEFAULT NULL,  
  `status` int(5) DEFAULT NULL,  
  `created_at` datetime DEFAULT NULL,  
  PRIMARY KEY (`id`)  
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;  
  
--  
-- 转存表中的数据 `restful_product`  
--  
  
INSERT INTO `restful_product` (`id`, `name`, `description`, `image`, `status`, `created_at`) VALUES  
(1, 'terry', 'terry des', 'terry img', 1, '2015-11-17 15:25:21'),  
(2, 'xxxx', 'ddddd', NULL, NULL, NULL),  
(3, 'xxxx', 'ddddd', NULL, NULL, NULL),  
(4, 'xxxx', 'ddddd', NULL, NULL, NULL),  
(5, 'xxxx', 'ddddd', NULL, NULL, NULL);

创建完数据表  restful_product

剩下的工作就是创建model:

<?php  
  
namespace myapp\frontend\code\ECM\User\models;  
use yii\db\ActiveRecord;  
  
class Product extends ActiveRecord  
{  
    # 定义rule  
    public function rules(){  
        return [  
            [['name','description'],'required'],  
        ];  
    }  
    public static function tableName()  
    {  
        return 'restful_product';  
    }  
      
      
  
}

到这里,资源就建立好了

4.进行配置

在配置的时候,一定要注意,在下面的文件都可以配置

frontend/config/main.php  ,  frontend/config/main-local.php

common/config/main.php , common/config/main-local.php

不要重复,曾经,我配置mailer 的时候,就是因为在两个配置文件配置了mailer组件,导致我的配置没有生效,搞了我半天晕头转向,最后发现是重复配置,

在哲学里面,灵活的东西,对应的就是使用的复杂性,这是无可避免,所以,没有最好,只有更适合,yii2是比较适合架构师玩,定制好规则和example,然后让码农们

填写代码,如果是初学者,玩玩thinkphp,如果玩yii2,则不是很适合,什么都有一个进化的过程(http://blog.csdn.net/terry_water),所以没有最好的框架,只有更适合自己的现状,和公司现状的框架,找女人也是这样吧。

下面要配置的是urlManage:

'urlManager' => [  
            'class' => 'yii\web\UrlManager',  
            'enablePrettyUrl' => true,  
            'enableStrictParsing' => true,  
            'showScriptName' => false,  
            'rules' => [  
                '' => 'cms/index',  
                ['class' => 'yii\rest\UrlRule', 'controller' => 'customer/index',  
                  'pluralize' => false,  
                ],  
                //'POST customer' => 'customer/index/create',  
            ],  
              
        ],  
        'request' => [  
            'class' => '\yii\web\Request',  
            'enableCookieValidation' => false,  
            'parsers' => [  
                'application/json' => 'yii\web\JsonParser',  
            ],  
            'cookieValidationKey' => 'O1d232trde1xww-M97_7QvwPo-5QGdkLMp#@#@',  
        ],

 

在上面,需要配置request  组件    的 parsers子项,这个子项的意思是解析,也就是对于request请求,按照json格式,这样,发送post请求,通过接口插入数据,可以用json格式,而不是用繁琐的xml格式费劲。

对于urlManager组件  的rules子项,

['class' => 'yii\rest\UrlRule', 'controller' => 'customer/index',  
                  'pluralize' => false,  
                ],

class的值是系统默认的, controller的值是您的controller的路径,如果您不使用模块,直接在controller下面建立了一个CustomerController,那么controller的值是customer, 由于我使用的是customer模块,因此controller 是customer/index

pluralize的意思是不使用复数,这样可以不需要加s

5

测试:

get 方式可以直接使用浏览器访问

post请求:

curl -i -H "Accept:application/json" -H "Content-Type:application/json" -XPOST "http://10.10.10.252:800/index.php/customer/index" -d '{"name": "xxxx", "description":"ddddd"}'

官方给予的:

GET /users: 逐页列出所有用户  
HEAD /users: 显示用户列表的概要信息  
POST /users: 创建一个新用户  
GET /users/123: 返回用户 123 的详细信息  
HEAD /users/123: 显示用户 123 的概述信息  
PATCH /users/123 and PUT /users/123: 更新用户123  
DELETE /users/123: 删除用户123  
OPTIONS /users: 显示关于末端 /users 支持的动词  
OPTIONS /users/123: 显示有关末端 /users/123 支持的动词

对应的方法为:

index: list resources page by page;  
view: return the details of a specified resource;  
create: create a new resource;  
update: update an existing resource;  
delete: delete the specified resource;  
options: return the supported HTTP methods.

 

[  
    'PUT,PATCH users/<id>' => 'user/update',  
    'DELETE users/<id>' => 'user/delete',  
    'GET,HEAD users/<id>' => 'user/view',  
    'POST users' => 'user/create',  
    'GET,HEAD users' => 'user/index',  
    'users/<id>' => 'user/options',  
    'users' => 'user/options',  
]

 

为什么可以直接访问,因为在资源建立的时候,activerecord已经把上面的方法都默认建立好,如果您想更改对应的方法

可以在资源model里面新建一个对应的方法即可重写。

YII2 FEC 扩展

github地址为:https://github.com/fancyecommerce/yii2-fec

本插件为一些日常所用的函数类的封装

安装方法:

composer require --prefer-dist fancyecommerce/fec

安装完成后,可以在

/vendor/fancyecommerce/fec文件夹下面看到本插件的文件。

具体的插件信息:

一:基本功能封装部分:

CApi
CCache
CConfig
CCookie
CDate
CDB
CDir
CDoc
CEmail
CExcel
CFile
CFunc
CImage
CLog
CMessage
CModel
CModule
CProfile
CRequest
CSession
CTranslate
CUrl
CUser

 

具体的详细,可以在\fec\helpers里面查看具体的功能要点。这些都是一些帮助类,快速的实现某些功能。

linux设置环境变量 临时设置 和 永久设置

1.临时设置,使用export方法
譬如吧php加入到PATH中:

export PATH=$PATH:/usr/local/php/bin

2.永久方法:

vi /etc/profile

在最后的部分加入

PATH=/usr/local/mysql/bin:$PATH  
PATH=/usr/local/php/bin:$PATH  
export PATH

保存文件,退出
然后在linux命令行中执行:

source /etc/profile

即可