分类 代码分享 下的文章

腾讯云 COS webpack 插件开源

今天想把一个老的 Yii2 项目改成比较时髦的前后端分离的开发模式,于是试用了 webpack,感觉还不错。

项目线上我是想直接把编译后的文件传到带 cdn 的对象存储上,因为服务器用的是腾讯云的 cvm,所以对象存储就顺便选择了 cos。

Github 上搜了下没有现成的 webpack 插件,不过有几个现成的七牛的,比较了一下发现 https://github.com/lyfeyaj/qn-webpack 这个项目的代码最简洁清晰,于是就在这个项目的基础上自己改出了一个 cos 的 webpack 插件并开源了出来:https://github.com/takashiki/cos-webpack

npm 发布包的步骤参考:手把手教你用npm发布一个包

下面是该插件的安装和使用方式:

前提

需要 Node 版本在 v4.0 以上,COS V4 以上(APPID 为 125 开头)

安装

npm i -D cos-webpack

使用方法

支持的配置项:

  • secretId COS SecretId
  • secretKey COS SecretKey
  • bucket COS 存储对象名称,格式为对象名称加应用 ID,如:bucket-1250000000
  • region COS 存储地域,参见官方文档
  • path 存储路径, 默认为 [hash],也可以指定 hash 长度,如: [hash:8]
  • exclude 可选,排除特定文件,正则表达式,如: /index\.html$/
  • include 可选,指定要上传的文件,正则表达式,如: /app\.js$/
  • batch 可选,批量上传文件并发数,默认 20

注: Webpack 的 output.publicPath 要指向 COS(或自定义的)域名地址

// 引入
const CosPlugin = require('cos-webpack');

// 配置 Plugin
const cosPlugin = new CosPlugin({
  secretId: 'my-secret-id',
  secretKey: 'my-secret-key',
  bucket: 'my-125000000',
  region: 'ap-chengdu',
  path: '[hash]/'
});

// Webpack 的配置
module.exports = {
 output: {
    // 此处为 COS 访问域名(bucket-1250000000.file.myqcloud.com) 加上 path([hash]/)
    publicPath: "http://bucket-1250000000.file.myqcloud.com/[hash]/"
    // ...
 },
 plugins: [
   cosPlugin
   // ...
 ]
 // ...
}

在原有的 Yii1.1 项目中使用 Yii2 框架的经验记录

目前公司由于历史原因,之前很多主体项目都是使用 Yii1.1 开发的,Yii1.1 在使用上还是有很多不便,为了使用 Yii2 的一些新特性,我决定在一个规模比较小的项目上尝试 Yii1.1 和 Yii2 共存并逐渐使用 Yii2 替代原有 Yii1.1 代码进行项目升级的方案。

主要的参考文档在 google 上搜了下就只有官方文档的一节 Using Yii 2 with Yii 1

最主要的是创建一个自定义的 Yii 类文件,这个类继承自 Yii2 的 BaseYii 类,而类里面需要手工把 Yii1.1 的 YiiBase 类中的代码复制过来,这样这个类就同时拥有 Yii1.1 和 Yii2 的属性和方法了。
然后最下面三行是为了能在项目中使用 Yii2 的自动加载机制和依赖注入容器,一定不能写错。

$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php'); // Yii 2.x

$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php'); // Yii 1.x

class Yii extends \yii\BaseYii
{
    // 这里要把 Yii1.1 中 YiiBase 类里的代码全部复制过来
}

Yii::$classMap = include($yii2path . '/classes.php');
// 通过 Yii1.1 的方法注册 Yii2 的自动加载器
Yii::registerAutoloader(['yii\BaseYii', 'autoload']);
// 创建依赖注入容器
Yii::$container = new yii\di\Container();

这个文件我们可以放在 components\Yii.php,然后我们就需要修改项目原先的 index.php 入口文件了,修改过后的关键代码如下:

// 引入上一步创建好的自定义 Yii 类文件
require(__DIR__ . '/../components/Yii.php');

// 首先读取 Yii2 的配置,实际配置可能更多,这里只是参考
$yii2Config = require(__DIR__ . '/../config/yii2/web.php');
// 不要调用 run() 方法,Yii2 只作为服务定位器使用
new yii\web\Application($yii2Config);

// 读取 Yii1.1 配置,实例化 Application 并运行
$yii1Config = require(__DIR__ . '/../config/yii1/main.php');
Yii::createWebApplication($yii1Config)->run();

配好这些就可以开始使用了,项目的目录组织的话可以根据实际项目情况而定,在编写 Yii2 代码时,我们可以无视原来的 Yii1.1 的所有代码,将项目作为一个常规的 Yii2 项目来看,这样的话目录结构就很清晰了。

这种方案要求 php 版本至少在 5.4 以上,我建议将 Yii1.1 的框架版本升级到最新的 1.1.19 这个版本可以支持 php7.0 和 php7.1。

总的来说并不困难,不过参考资料较少,实际使用过程中可能会遇到坑点,不过也都比较好解决,老项目这样一配可以说是枯木逢春,写起新功能来要舒服太多了。

分享一个自写的Yii2扩展——Yii2 IDE Helper

虽然github上已经有了几个yii2的ide helper,如:https://github.com/iiifx-production/yii2-autocomplete-helper,不过自己使用下来感觉不是特别好用,于是便自己实现了一个:https://github.com/takashiki/yii2-ide-helper

使用说明:

安装

用以下命令添加 composer 依赖:

composer require mis/yii2-ide-helper --dev

或者在 composer.json 文件的 require-dev 中添加如下内容后执行 composer update

"mis/yii2-ide-helper": "*"

使用

把如下配置加入应用的 console 配置文件中:

'bootstrap' => ['log', 'ideHelper'],
...
'components' => [
    'ideHelper' => [
        'class' => 'Mis\IdeHelper\IdeHelper',
    ],
  ...
],

之后就可以通过如下命令生成 IDE Helper 文件了:

php yii ide-helper/generate

可选配置列表

'ideHelper' => [
    'class' => 'Mis\IdeHelper\IdeHelper',
    'filename' => '_ide_helper',
    'format' => 'php',
    'rootDir' => dirname(__DIR__),
    'configFiles' => [
        'console/config/main.php',
        'console/config/main-local.php',
    ],
],

默认配置文件路径:

protected $defaultConfigFiles = [
    'config/web.php',
    'config/main.php',
    'config/main-local.php',
    'common/config/main.php',
    'common/config/main-local.php',
    'frontend/config/main.php',
    'frontend/config/main-local.php',
    'backend/config/main.php',
    'backend/config/main-local.php',
];

PHP修改apk文件的comment实现

参考链接:
一种动态为apk写入信息的方案

apk文件本身即为zip文件,在PHP中可以使用 ZipArchive 类中的 setArchiveComment 方法方便地设置 apk 的 comment 内容。

也可以使用 fseekfwrite 来参照上述文章原理实现:

$comment = '123测试';

$file = fopen('R:\1.apk', 'r+');
fseek($file, -2, SEEK_END);
fwrite($file, pack('s', mb_strlen($comment, '8bit')));
fwrite($file, $comment);
fclose($file);

$zip = new ZipArchive();

$zip->open('R:\1.apk');
var_dump($zip->getArchiveComment());
//$zip->setArchiveComment($comment);
//var_dump($zip->getArchiveComment());
$zip->close();

PHP in_array、array_key_exists、isset效率测试脚本

<?php
$elemCount = 1000;
$repeatCount = 1000000;

$vArr = range(1, $elemCount);
$kArr = array_flip($vArr);

$start = microtime(true);
for ($i = 0; $i < $repeatCount; $i++) {
    in_array($i, $vArr);
}
$inArrTime = microtime(true) - $start;
echo "in_array:{$inArrTime}<br>";

$start = microtime(true);
for ($i = 0; $i < $repeatCount; $i++) {
    array_key_exists($i, $kArr);
}
$keyTime = microtime(true) - $start;
echo "array_key_exists:{$keyTime}<br>";

$start = microtime(true);
for ($i = 0; $i < $repeatCount; $i++) {
    isset($kArr[$i]);
}
$issetTime = microtime(true) - $start;
echo "isset:{$issetTime}<br>";

测试结果:

in_array:1.6679329872131
array_key_exists:0.23828101158142
isset:0.022069931030273