小叮当的肚兜 2022-08-31 12:09:46 2697次浏览 0条评论 0 0 0

关于Yii2优化的几点建议 可先阅读此链接内容Yiichina

  1. 写法优化

    • 查询条件尽量多写数组,若写入字符串会进行正则匹配.
       ->select(['id','name'])
       ->orderBy(['id' => SORT_DESC])
       ->groupBy(['id'])
      
    • model类查询尽量多使用数组
       $data = DemoModel::find()->asArray()->all();
       //或者(此处from写数组与上一点原理相同)
       $data = (new \yii\db\Query())->from([DemoModel::tableName()])->all();
      
    • 字符串加密,如不是特别强求尽量使用encryptByKey而不是encryptByPassword,本人用xhprof性能工具分析时发现encryptByPassword要比encryptByKey慢很多
       Yii::$app->security->encryptByKey($string, $key);
      
    • 自己写的Asset类,里面的静态文件放在web目录下直接访问,不在复制静态文件到web/asset目录,如果更新静态文件可添加静态文件版本号,减少文件读取次数.
       <?php
       namespace app\assets;
       use yii\web\AssetBundle;
       class DemoAssets extends AssetBundle
       {
        public $basePath = '@webroot';
        public $baseUrl = '@web';
        public $js = [
            'js/demo.min.js?v=1',
        ];
       }
      
  2. 配置优化

    • 静态文件assetManager不要添加时间戳减少访问文件次数
       $config['components']['assetManager'] =[
        'appendTimestamp' => false, //默认为false
       ]
      
    • 数据库缓存表结构
       $config['db'] =[
        'class' => 'yii\db\Connection',
        'enableSchemaCache' => true,
       ];
      
    • session配置保存在内存中(可选)
       $config['components']['session'] = [
        'class' => 'yii\redis\Session',
        'keyPrefix'=>'user_',
        'redis' => [
            'hostname' => '127.0.0.1',
            'port' => 6379,
            'database' => 11,
            'password' => 'password',
        ]
       ];
      
  3. 扩展优化

    • 修改日志组件为seaslog

       $config['components']['log'] = [
        'traceLevel' => YII_DEBUG ? 3 : 0,
        'flushInterval' => 1,
        'targets' => [
            [
                'class' => 'app\components\log\SeasLogTarget',
                'exportInterval' => 1,
                'levels' => ['error'],//,'warning', 'info'
                'maxFileSize' => 1024 * 2,
                'maxLogFiles' => 20,
            ],
        ],
       ],
       //seaslog类
       <?php
       namespace app\components\log;
       use Yii;
       use yii\helpers\VarDumper;
       use yii\log\FileTarget;
       use yii\log\Logger;
       class SeasLogTarget extends FileTarget
       {
        public $logPath;
        private $levelName;
        /**
         * @var \SeasLog
         */
        protected $seasLog;
        /**
         * init
         * @throws \yii\base\InvalidConfigException
         */
        public function init()
        {
            if (empty($this->logPath)) {
                $this->logPath = Yii::$app->getRuntimePath().DIRECTORY_SEPARATOR;
            } else {
                $this->logPath = Yii::getAlias($this->logPath);
            }
          
            $this->logFile = $this->logPath.DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.date('Ymd').'.log';
            $this->seasLog = Yii::createObject('SeasLog');
            $this->seasLog->setBasePath($this->logPath);
            $this->seasLog->setLogger('logs');
            parent::init();
        }
          
        public function export()
        {
            if ($this->enableRotation && @filesize($this->logFile) > $this->maxFileSize * 1024) {
                $this->rotateFiles();
            }
            foreach ($this->messages as $text) {
                $text = $this->formatMessage($text);
                $this->seasLog->log($this->levelName, $text);
            }
        }
          
        /**
         * formatMessage
         * @param array $message
         * @return string
         */
        public function formatMessage($message)
        {
            list($text, $level, $category) = $message;
            $this->levelName = Logger::getLevelName($level);
            if (!is_string($text)) {
                if ($text instanceof \Throwable || $text instanceof \Exception) {
                    $text = (string) $text;
                } else {
                    $text = VarDumper::export($text);
                }
            }
            $traces = [];
            if (isset($message[4])) {
                foreach ($message[4] as $trace) {
                    $traces[] = "in {$trace['file']}:{$trace['line']}";
                }
            }
            $prefix = $this->getMessagePrefix($message);
            return "{$prefix}[$this->levelName][$category] $text"
                .(empty($traces) ? '' : "\n    ".implode("\n    ", $traces));
        }
       }
      
    • 修改cache组件为内存

       //MemCache 详细配置源码内有注释
       $config['components']['cache'] = [
        'class' => 'yii\caching\MemCache'
       ];
       //yii2-redis包(https://packagist.org/packages/yiisoft/yii2-redis)
       $config['components']['cache'] = [
        'class' => 'yii\redis\Connection',
            'hostname' => '127.0.0.1',
            'port' => 6379,
            'database' => 0,
       ];
       //yac(https://github.com/laruence/yac)鸟哥写的PHP共享和无锁内存用户数据缓存
       $config['components']['cache'] = [
        'class' => 'app\components\cache\YacCache',
        'prefix' => 'yii2'
       ];
       //yac cache组件代码
       <?php
       namespace app\components\cache;
       use Yii;
       use Yac;
       use yii\caching\Cache;
       class YacCache extends Cache
       {
        /**
         * @var Yac
         */
        private $yac;
        /**
         * @var string
         */
        public $prefix='';
          
        public function init()
        {
            parent::init();
            $this->yac = new Yac($this->prefix);
        }
      
        /**
         * @param mixed $key
         * @return bool
         */
        public function exists($key)
        {
            $key = $this->buildKey($key);
            $value = $this->getValue($key);
            return $value !== false;
        }
      
        /**
         * @param string $key
         * @return string|bool
         */
        protected function getValue($key)
        {
            return $this->yac->get($key);
        }
      
        /**
         * @param array $keys
         * @return array
         */
        protected function getValues($keys)
        {
            return $this->yac->get($keys);
        }
      
        /**
         * @param string $key
         * it could be something else.
         * @param int $duration
         * @return bool
         */
        protected function setValue($key, $value, $duration)
        {
            return $this->yac->set($key, $value, $duration);
        }
          
        /**
         * @param array $data
         * @param int $duration
         * @return array
         */
        protected function setValues($data, $duration)
        {
            return $this->yac->set($data,$duration);
        }
          
        /**
         * @param string $key
         * @param mixed $value
         * @param int $duration
         * @return bool
         */
        protected function addValue($key, $value, $duration)
        {
            return $this->yac->set($key, $value, $duration);
        }
          
        /**
         * @param array $data
         * @param int $duration
         * @return array
         */
        protected function addValues($data, $duration)
        {
            return $this->yac->set($data, $duration);
        }
          
        /**
         * @param string $key
         * @return bool
         */
        protected function deleteValue($key)
        {
            return $this->yac->delete($key);
        }
          
        /**
         * @return bool
         */
        protected function flushValues()
        {
            return $this->yac->flush();
        }
       }
      
    • 使用yaconf扩展配置文件
       // web/index.php
       //此处配置文件里不要写回调函数
       function getAppConfig(){
        //高级版
        return yii\helpers\ArrayHelper::merge(
            require(__DIR__ . '/../../common/config/main.php'),
            require(__DIR__ . '/../../common/config/main-local.php'),
            require(__DIR__ . '/../config/main.php'),
            require(__DIR__ . '/../config/main-local.php')
        );
        //基础版
        //return require __DIR__ . '/../config/web.php';
       }
       if(extension_loaded('yaconf')){
        /**
        * 使用此函数把index.php的配置数组转yaconf配置文件
        * arr2ini
        * @param array  $config
        * @param string $parent
        * @param int    $level
        * @return string
        */
        function arr2ini(array $config, $parent = '',$level=0){
            $out = '';
            foreach ($config as $key => $value) {
                if (is_array($value)) {
                    $level++;
                    if($level==0){
                        $out .= '[' . $key . ']' . PHP_EOL;
                        $sec='';
                    }else{
                        if(empty($parent)){
                            $sec = $key.'.';
                        }else{
                            $sec = $parent.$key.'.';
                        }
                    }
                    $out .= arr2ini($value, $sec,$level);
                } else {
                    if(is_numeric($value)){
                        $out .= $parent."$key=$value" . PHP_EOL;
                    }elseif(is_bool($value)){
                        $out .= $parent."$key=".($value?1:0) . PHP_EOL;
                    }else{
                        $out .= $parent."$key='$value'" . PHP_EOL;
                    }
                    $level=0;
                }
            }
            return $out;
        }
        if(empty($config = Yaconf::get("demo"))){
            $config = getAppConfig();
            file_put_contents('PATH/demo.ini',arr2ini($config));
        }
       }
       if(empty($config)){
        $config = getAppConfig();
       }
       (new yii\web\Application($config))->run();
      
  4. composer.json配置镜像仓库加速下载
    • 修改repositories配置
      "repositories": {
        "0": {
            "type": "composer",
            "url": "https://asset-packagist.cn"
        },
        "packagist": {
            "type": "composer",
            "url": "https://mirrors.aliyun.com/composer/"
        }
      }
      
    没有找到数据。
您需要登录后才可以评论。登录 | 立即注册