王骏的博客 http://blog.okbase.net/JO2000 思途旅游CMS系统简单分析 http://blog.okbase.net/JO2000/archive/56377.html JO2000 2017/9/9 21:41:10 思途旅游CMS系统采用Kohana框架,Kohana是一款纯PHP5的框架,基于MVC模式开发,它的特点是高安全性,轻量级代码,容易使用。

购买的是正版的思途旅游CMS系统,因需要进行二次开发,所以对这个系统进行简单的分析。

 

控制器 Controller

基类:Stourweb_Controller

v5\classes\stourweb\controller.php

其它控制器位于:v5\classes\controller 目录下,
例如首页index控制器 index.php


视图 View

视图基类 Stourweb_View
位于 \v5\classes\stourweb\view.php

 

其它它视图位于:v5\views\default

例如默认的首页模板位于 v5\views\default\index

 

模型 Model

位于 tools\classes\model
基类ORM,实际上是Kohana_ORM,文件位于core\modules\orm\classes\kohana\orm.php

]]>
Excel统计重复内容的数量 http://blog.okbase.net/JO2000/archive/56367.html JO2000 2017/8/24 9:52:58 需要用到公式COUNTIF

格式是:COUNTIF(查找范围,条件)

 

1、返回包含值12的单元格数量
=COUNTIF(DATA,12)
2、返回包含负值的单元格数量
=COUNTIF(DATA,"<0")
3、返回不等于0的单元格数量
=COUNTIF(DATA,"<>0")
4、返回大于5的单元格数量
=COUNTIF(DATA,">5")
5、返回等于单元格A1中内容的单元格数量
=COUNTIF(DATA,A1)
6、返回大于单元格A1中内容的单元格数量
=COUNTIF(DATA,">''&A1)
7、返回包含文本内容的单元格数量
=COUNTIF(DATA,''*'')
8、返回包含三个字符内容的单元格数量
=COUNTIF(DATA,''???'')
9、返回包含单词"GOOD"(不分大小写)内容的单元格数量
=COUNTIF(DATA,''GOOD'')
10、返回在文本中任何位置包含单词"GOOD"字符内容的单元格数量
=COUNTIF(DATA,"*GOOD*")
11(1)、返回包含以单词"AB"(不分大小写)开头内容的单元格数量
=COUNTIF(DATA,"AB*")
11(2)、返回包含以单词"AB"(不分大小写)结尾内容的单元格数量
=COUNTIF(DATA,"*AB")
12、返回包含当前日期的单元格数量
=COUNTIF(DATA,TODAY())
13、返回大于平均值的单元格数量
=COUNTIF(DATA,">"&AVERAGE(DATA))
14、返回平均值上面超过三个标准误差的值的单元格数量
=COUNTIF(DATA,">"&AVERAGE(DATA)+STDEV(DATA)*3)
15、返回包含值为3或-3的单元格数量
=COUNTIF(DATA,3)+COUNIF(DATA,-3)
16、返回包含值;逻辑值为TRUE的单元格数量
=COUNTIF(DATA,TRUE)
17、统计区域中不为空的单元格个数(数值、文本、空格都算)——(上述第3条:文本也算不等于0,空格不算)
=Countif(DATA,"<>")
18、只统计文本单元格数量,不统计数值和空格——(上述第7条统计含空格)
=COUNTIF(DATA,"><")

 

注意:因为只能处理长度小于15的数字,所以对于更长的数字,我们需要用加上"*"这样的方式:

COUNTIF($D$2:$D$5000, D2&"*")

]]>
PHP如何获取文件的扩展名 http://blog.okbase.net/JO2000/archive/56364.html JO2000 2017/8/21 22:55:39 比较常用的方法是使用pathinfo,代码如下:

 

$ext = pathinfo($filename, PATHINFO_EXTENSION);

 

如果需要处理非ASCII字符,需要在此之前:setlocale(LC_ALL,'en_US.UTF-8');

 

另外,对于想获取URL网址的扩展名,例如这个网址:http://example.com/file/okbase.mp3?a=1&b=2
需要用到parse_url,例如:


pathinfo(parse_url($url)['path'], PATHINFO_EXTENSION); // 返回mp3

dirname(parse_url($url)['path']) // 返回 /file
basename(parse_url($url)) // 返回 okbase.mp3

]]>
weex, react native, ionic 技术选型 http://blog.okbase.net/JO2000/archive/56316.html JO2000 2017/8/4 23:22:20

[编者按:为什么在App开发界,没有像曾经的VB,Delphi那样简单易用,又能跨Android,iOS,一统江湖的开发框架呢?现在的框架总是有这样那样的不爽!]

 

目前有一个 APP 项目,需要同时开发 iOS 版和 Android 版,并且每个平台又分为客户端、管理员端,也就是说相当于四个应用。而我们人员有限,工期有明确限制,全部使用 native 语言开发,基本不现实。所以决定采用类 react native 的方案开发。

到了技术选型这里非常纠结!做了一下简单的对比

React Native

如果从成熟度来看,react native 是不二选择。但是,需要维护两套代码,即 iOS,Android 各一套。并且开发调试 iOS 只能使用 Mac 设备。

优势

  • 文档全
  • 社区成熟
  • 组件丰富

劣势

  • 需要维护两套代码
  • 团队没有 React 经验
  • 对开发设备有要求,调试不方便

Weex

而 weex 可以做到 iOS, android, H5 共用一套代码,但是,这个是国内阿里维护的项目,靠谱度存疑,遇到问题估计很难查到资料。而且我们需要使用蓝牙访问硬件设备,而 weex 并没有现成的组件实现,需要我们自己用 native 来实现。

优势

  • 三端共用一套代码
  • 调试简单
  • 团队都有 Vuejs 实战经验

劣势

  • 国内开源项目不太靠谱
  • 社区极度不成熟
  • 文档不全
  • 组件有限,且下载量都在两三百的量,质量无法保证
  • 需要 native 代码扩展蓝牙数据读取

ionic

ionic 这个虽然比较成熟,但是唯一的问题是大家普遍反映体验不够流畅。

优势

  • 文档全
  • 社区成熟
  • 组件丰富

劣势

  • angularjs 不太靠谱
  • 流畅度存疑

结论

决定先硬着头皮上 Weex 了,蓝牙支持准备参考 react native 的实现。

 

来源:http://www.sunzhongwei.com/weex-react-native-ionic-technology-selection

]]>
SFP光模块和SFP+光模块有何区别 http://blog.okbase.net/JO2000/archive/56313.html JO2000 2017/8/3 10:34:16 通俗地讲,最主要的区别是:SFP是千兆(G)SFP+是万兆(10G)

外观基本上差不多,万兆光模块稍显粗壮,拿在手里万兆光模块会感觉重一些。

请看具体的定义:

 

一、SFP的定义

SFP(Small form-factor pluggable)意思是小型可拔插式。就是能够支持千兆以太网、SONET、光纤通道和其他通信标准,插入到交换机SFP端口的可拔插模块。SFP规范是基于IEEE802.3和SFF-8472,它们能够支持速度高达4.25 Gbps。由于其较小的尺寸,SFP取代了以前常见的千兆接口转换器(GBIC),因此也被称为迷你GBIC SFP。通过选择不同的波长和端口的SFP模块,交换机上的相同的电端口可以连接上不同接头和不同波长的光纤。


二、SFP+的定义


由于SFP仅支持4.25 Gbps的传输速率,满足不了人们对网速越来越高的要求,SFP+就在这样的背景下诞生了。SFP+的最高传输速率可达16 Gbps,事实上,SFP+是一个增强版本的SFP。SFP+规范是基于SFF-8431。在今天的大多数应用,SFP+模块通常支持8 Gbit/s光纤通道。SFP+模块凭借其体积小、使用方便的优点,取代了早期万兆以太网中使用比较多的XENPAK和XFP模块,成为了万兆以太网中最受欢迎的光模块。

对上面的SFP和SFP+定义进行分析之后可以得出,SFP和SFP+之间的主要区别是传输速率。而且由于数据速率的不同,应用和传输距离也不同。下面就是它们在应用方面的一些不同。

]]>
nodejs里的异步方案 http://blog.okbase.net/JO2000/archive/56279.html JO2000 2017/7/10 22:28:04 nodejs版本大于v7,可以使用ES7里的async和await,Node运行参数里加上--harmony或者--harmony-async-await

例子:
(async function(){
let db = await MongoClient.connect(url + db_name);
let coll = db.collection('blogs');
let blogs = await coll.find().toArray();
console.log(blogs.length);
db.close();
})().catch(err=> {
console.log(err);
})();

 

nodejs版本小于v7的方案:
ES6原生promise方案,不够爽不想用。

 

async模块方案:


var mysql = require('mysql');
var async = require('async');

var conn = mysql.createConnection({
host: 'localhost',
user: 'nodejs',
password: 'nodejs',
database: 'nodejs',
port: 3306
});

var sqls = {
'insertSQL': 'insert into t_user(name) values("conan"),("fens.me")',
'selectSQL': 'select * from t_user limit 10',
'deleteSQL': 'delete from t_user',
'updateSQL': 'update t_user set name="conan update" where name="conan"'
};

var tasks = ['deleteSQL', 'insertSQL', 'selectSQL', 'updateSQL', 'selectSQL'];
async.eachSeries(tasks, function (item, callback) {
console.log(item + " ==> " + sqls[item]);
conn.query(sqls[item], function (err, res) {
console.log(res);
callback(err, res);
});
}, function (err) {
console.log("err: " + err);
});

 

co方案:

 

const co = require('co');
co(function* (){
let db = yield MongoClient.connect(url + db_name);
let coll = db.collection('blogs');
let blogs = yield coll.find().toArray();
console.log(blogs.length);
db.close();
}).catch(err=> {
console.log(err);
});

]]>
redux-thunk、redux-promise、redux-saga 三个异步方案怎么选择 http://blog.okbase.net/JO2000/archive/56261.html JO2000 2017/6/21 18:35:20 看看github里的获赞次数吧

 

redux-saga (Star:8459)
https://github.com/redux-saga/redux-saga

 

redux-thunk (Star:5580)
https://github.com/gaearon/redux-thunk

 

redux-promise (Star:1629)
https://github.com/acdlite/redux-promise

 

redux-saga在github里获赞次数最多,随大流还是选择redux-saga吧。

]]>
ReactNative新建项目 http://blog.okbase.net/JO2000/archive/56259.html JO2000 2017/6/19 21:51:19 上文 http://blog.okbase.net/JO2000/archive/56035.html 介绍了开发环境的准备,挺折腾人的。折腾好了后,新建项目就很简单了。

 

例如我们新建一个Test1的项目,命令行运行:

react-native init Test1

 

需要一段时间等待,当看到如下文字就OK了:

 

To run your app on iOS:
cd D:\wwwroot\ReactNative\Test1\Test1
react-native run-ios
- or -
Open ios\Test1.xcodeproj in Xcode
Hit the Run button
To run your app on Android:
cd D:\wwwroot\ReactNative\Test1\Test1
Have an Android emulator running (quickest way to get started), or a device connected
react-native run-android

 

 

然后我用Visual Studio Code打开Test1就可以进行具体的开发。

其它IDE环境可以参考此文选择适合自己的IDE:http://www.infoq.com/cn/articles/react-native-ide 

]]>
华为、思科交换机过滤445端口狙击[永恒之蓝]勒索病毒 http://blog.okbase.net/JO2000/archive/56093.html JO2000 2017/5/14 20:52:02 微软的坑,干脆把135-139,445全部封闭

 

思科:

access-list 100 deny tcp any any range 135 139
access-list 100 deny udp any any range 135 139
access-list 100 deny tcp any any eq 445
access-list 100 deny udp any any eq 445
access-list 100 permit ip any any

 

端口
ip access-group 100 in
ip access-group 100 out

 

华为:

acl number 3000
rule 5 deny tcp destination-port range 135 139
rule 10 deny tcp destination-port eq 445
rule 15 deny udp destination-port range 135 netbios-ssn
rule 20 deny udp destination-port eq 445
rule 25 permit ip

 

端口
traffic-filter inbound acl 3000
traffic-filter outbound acl 3000

]]>
JS通过正则表达式提取url里的参数 http://blog.okbase.net/JO2000/archive/56070.html JO2000 2017/5/4 18:34:43 代码如下:

function getParam(url, p) {
	var s = '/'+p+'\\=([^&]+)/ig';
        var re = new RegExp(eval(s));
        var result = re.exec(url);
        if(result && result.length > 0)
            return result[1];
        else
            return 0;
}

document.write(getParam('http://www.sohu.com/test?eid=100&m=abc', 'eid'));
]]>