最近一年

一年没有更新博客。

一来都是在用自己写的mwiki在vim里面用Markdown来记笔记。没有啥好写。年初的时候计划写2013年的年终总结也没有写。
二来离开matchmove后进入新东家,这一年多又经历一次从感觉太弱到变强大的过程。很多时候都敲代码都敲到手疼, 现在自己对自己的要求是变的有趣就行。
前几天折腾了下jekyll换到了hexo这个nodejs写的静态博客系统上面, 感觉比jekyll友好太多,以后就用这个折腾了。会经常更新。

折腾

  1. 健身, 累计的时间可能也就半年, 收获蛮大, 最近都没有怎麽去, 要多用时间学习, 还有身体比较好,因为天天都在蹬自行车。
  2. 骑行,去年下半年搞了辆捷安特ATX 770, 码表上显示总里程1kkm, Vmax 54km/h。连续时长最长7小时, 120km,被晒的来脱皮了。成都空气太差, 骑行车呼吸不爽。
  3. 炒菜做饭, 马上一个人单独居住两年, 做菜觉得比80%的人好吃。一个人做饭吃饭消化,现在都成为个胖子,75kg,最近看到太多胖子病太多的微博,努力在控制体重。
  4. dotfiles, 各种配置已经被折腾来现在都不知道咋样才能提高效率了, 从firefox(pentadactyl), vim, awesome wm, zsh, emacs, urxvt。把最常用的软件90%的操作都vim化, 总之被其他人看一眼就知道这人在装b。
  5. 语言, Lua, VimL, Golang 主要就折腾这三个, 最后一个是工作需要, 前两个是为了配置。最近从头折腾C。
  6. 其他, Shell(主要是高冷艳的命令),OpenWRT(玩了两下, 发现网络环境和硬件受限没法好好玩). 理发器,寸头自己来。
  7. 追了太多美剧, 太多鸡血,太多的热血。送走了《斯巴达克斯》,《绝命毒师》
    未来一两年都把精力放到算法数据和Linux开发上, 往底层走走。现在做PHP, 前端都找不到新鲜感了。

成长

  1. 工作中踩过一次坑以后, 思考更加全面, 心里再没有有过没有底的感觉。
  2. 半成熟,行为举止越来越接近真实的自己。没有啥解不开心结。至于那些开心的, 不开心的往事都只能放在心底最冷,最热的地方,不会去想, 不去忘记。
    2014-05-17 00:27:13

出来半年啦

缴了半年的房租,缴了一个季度的VPS,又成为穷光蛋了。太久没有更新博客,以后基本上不更新什么技术文章了。因为学的东西都用vimwiki记录去了,除了一些不适合用vimwiki记的。在线的页面在http://blog.h2ero.cn/wiki 。除了语法和markdown不一样因为其他都挺舒服。离开matchmove来到新公司也快两个月了。最近自己也在照着其他的框架写自己的框架。想实现些自己的东西。

主要就这些特点:

* HMVC
* Cascading Filesystem
* Namespace
* i18n
* 代码规范PSR
* 依赖管理Composer 

` 其他的东西都不准备自己写,都用别人写好的。而且很多比自己写的都要好,这也是Composer也是如此流行的原因,PHP会变越好的。除了天天PHP就是天天泡在github上面了,现在已经重度依赖了。不得不感叹github为程序员带来了太多的东西,才两个月vim扩展增加到了40+,其实觉得Vimscript也不是想象中那么不好。自己想写也找不到什么插件可写,Firefox也是。囧敲了一半误删除修改还要优Gundo这个扩展给回退回去。今天才知道CtrlP支持写扩展,觉得自己还是不够认真,所以一直以来都没有发现。今天逛别人的repo才发现。比如你可以用CtrlP弄了搜索分支切换分支的扩展。特别是在团队开发中分支特别多,想CtrlP这样搜索切换岂不是很舒服。具体可以看 https://github.com/kien/ctrlp.vim/tree/extensions 。 重读vim手册也在毕业后的计划中。觉得还是vim-jp活跃,国人都忙着养家糊口去了。不碎碎念了,弄毕业设计去。没有妹子的晚上只能面对电脑。

PHP编码规范及Vim PHP 代码格式化实现

最近对Vim进行各种折腾,现在又上了一层。敲PHP总是有很多地方要空格隔开。所以按照Kohana文档中的编程规范来写了个脚本。写这个脚本把Vim的正则表达式用的非常熟了。功能简单就是加最简单的空格。主要还是用在自己敲代码的时候。基本上的类型就是下面这些了。

格式化类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php 
//判断
if($foo=='bar')     
if ($foo == 'bar')

//赋值
$foo='bar';
$foo = 'bar';

//否定
if (!$foo)
if ( ! $foo)

//三元加其他运算符
$foo=(($bar>5)?($bar+$foo):strlen($bar))?Help::$foo%5:$bar%7;
$foo = (($bar>5) ? ($bar + $foo) : strlen($bar)) ? Hleper::$foo % 5 : $bar % 7;

//强制转换
$foo=(string)$bar;
$foo = (string) $bar;

//判断内有强制转换
if((string)$bar)
if ( (string) $bar)

//括号中有,
preg_replace('/(\d+) dollar/','$1 euro',$str);
preg_replace('/(\d+) dollar/', '$1 euro', $str);

//条件符号
if(($foo&&$bar)||($b&&$c))
if (($foo && $bar) || ($b && $c))

//数组
$arr=array('key'=>array('key'=>'value'+'value2'))
$arr = array('key' => array('key' => 'value' + 'value2'))

//运算符
$a+=$b/$c-$d;
$a += $b / $c - $d;

//逻辑英文操作符
if(1and2or3xor4)
if (1 AND 2 OR 3 XOR 4)

难点

整个脚本用了了10多条正则,用到了正则中的环视和贪婪。不支持这两个特性的正则都是不完美的。

  1. 对于字符串中有转义又有要替换的情况,如“h2ero=h2eros \"##\"##”格式化的时候会将引号中的要替换的类型都给替换掉,如果要排除这些的话需要在10多条正则中都添加,解决是先匹配处是字符串的类型然后替换为STR0,STR1等,并保存到list里面。然后在所有类型替换完后在替换回去,这是最难的地方。
  2. 要格式化是在每一次回车的时候继续格式化,也就是说边敲边格式化。不过vim正则替换完后都是会改变光标的位置,然后回车就失效了。解决是先执行回车保留本来的行为,然后在取上一行进行替换。
  3. 转义’这个是第一个问题中遇到的一个问题。当pattern为’regex’的时候regex里面包含有‘的话需要使用两个’‘进行转义而不是\’。
  4. Vim正则语法比较难,不过正则思想都一样。

使用

没有写为插件的形式,直接复制下面代码保存。然后在.vimrc中添加以下代码:source ~/.vim/script/phpformat.vim 最后一行只会对php文件生效。然后每次敲完一行代码回车就会格式化好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"format code
"http://kohanaframework.org/3.3/guide/kohana/conventions

func! Add_space()
    let now_line = line('.')
    "exec "inoremap <CR> <CR>"
    exec "normal! a\<CR>\<Esc>"
    let n_line = getline(now_line)

    " str replace
    let strlist = []
    let flag = 0
    let index= 0
    while flag == 0
        let replacelist = matchlist(n_line, '\([''"]\)\{1}\(.\{-}\)\\\@<!\1\{1}')
        if len(replacelist) == 0 
            let flag = 1
        else
            let rstr = replacelist[1].replacelist[2].replacelist[1]
            call add(strlist,['STR'.index,rstr])
            let n_line = substitute(n_line,rstr,'STR'.index,'')
            let index+=1
        endif
    endwhile


    " 1.  =+*<-%/ exclude => != !== .= += <= 
    let n_line = substitute(n_line,'\s*\(!\|!=\|+=\|<=\|\.\)\@<!\([%/=*+<-]\+[>]\@!\)\s*',' \2 ','g')

    " 2.  ,                eg : array('a' => 'b', 'c' => 'd')
    let n_line = substitute(n_line,'\s*\([,]\+\)\s*','\1 ','g')

    " 3.  ()               eg : if ( $foo )  exclude define('') 
    let n_line = substitute(n_line,'\(if\|for\|foreach\|switch\)\@<=\s*\([(]\+\)\(.\{-}\)\([)]\+\)\s*',' \2\3\4 ','g')

    " 4.  =>               eg : array('a' => 'b', 'c' => 'd')
    let n_line = substitute(n_line,'\s*\(=>\)\s*',' \1 ','g')

    " 5.  + - * /  exclude ++ --
    "let n_line = substitute(n_line,'\s*\([-]\{2,}\)\s*','\1','g')

    " 6.  != !== += .=     eg : if ($foo !== FALSE)  $a += 5;
    let n_line = substitute(n_line,'\s*\(!=\+\|+=\|\.=\|<=\)\s*',' \1 ','g')

    " 7.  (!               eg : if ( ! $foo)
    let n_line = substitute(n_line,'\s*[(]\@<=\(!\)\s*',' \1 ','g')

    " 8.  || &&            eg : if (($foo && $bar) || ($b && $c))
    let n_line = substitute(n_line,'\s*\(&&\|||\)\s*',' \1 ','g')

    " 9.  (int)            eg : if ( (int) $foo) in up regex will replace it like if((int) $foo), follow will fix it.
    let n_line = substitute(n_line,'\s*(\(int\|bool\|float\|string\|binary\|array\|object\|unset\))\s*',' (\1) ','g')

    " 10.  ?:              eg : $foo = $bar ? $foo : $bar;
    let n_line = substitute(n_line,'\s*\(?\)\s*\(.\{-}\)\s*\(:\)\s*',' \1 \2 \3 ','g')

    " 11. for(;;)          eg : for($i = 0; $i < 100; $i++) 
    let n_line = substitute(n_line,'\(for\s(\)\@<=\([^;]*\)\(;\)\([^;]*\)\(;\)','\2\3 \4\5 ','g')
    
    "let n_line = substitute(n_line,'\s*\(for(\)\@<=.*\s*\(;\).*\s*','\2 ','g')

    "let n_line=substitute(n_line,'\s*\([=+]\+\)\s*',' \1 ','g')

    " str restore
    let index = len(strlist) - 1
    while len(strlist) > 0
        let n_line = substitute(n_line,strlist[index][0],strlist[index][1],'')
        unlet strlist[index]
        let index-=1
    endwhile

    call setline(now_line,n_line)
    "exec now_line."s/\\\s*\\\([=+]\\\+\\\)\\\s*/ \\1 /ge"
    "exec "inoremap <CR> <Esc>:call Add_space()<CR>"

endfunc

func! PHP_space()
    let now_line = line( '.' )
    let n_line = getline(now_line)
    let html = matchstr(n_line, '^\s*[<.#]')
    if empty(html) 
        call Add_space()
    else
        exec "normal! \<ESC>a\<CR>"
        echo "this is html"
        "throw "no url recognized into ``".n_line."''"
    endif
endfunc

":inoremap <CR> <Esc>:call Add_space()<CR>
"inoremap <CR> <Esc>:call Add_space()<CR>
au FileType php inoremap <CR> <Esc>:call PHP_space()<CR>

PHP编程规范

整理来着网上和kohana,zend framework框架的编程约定代码规范。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
//一般变量 形容词_名词,变量范围正则[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
$new_payment

//函数/方法 动词+名词,函数方法空行隔开
get_username()

//多参数加空格
get_message($id, $count, $date)

//语法关键字后加空格
if ($foo)

//函数括号后不加空格
strlen('h2ero')

//花括号
if ($foo)
{
	
}
//SQL关键词大写
$sql = "h2ero"

//类型转换空格
$foo = (string) $foo;


//变量在前,真假在后
if ($foo !== FALSE)

//使用AND,OR代替&& ||
if (($foo AND $bar) OR ($b AND $c))

//实例化
$db = new Database;
//而不是,除了有构造方法的情况。
$db = new Database();

//其他情况
if ( ! $foo)


System Version: OS X 10.8 (12A269) Kernel Version: Darwin 12.0.0
2013-01-29 12:41:08

2012

2012

碎碎念

2012过去快一个月了,说好的总结现在才开始写。2012在学校里面呆了一学期,基本上都是乖乖的去上课,因为不想挂科。上课的时候也差不多是在看借的和买的书,还没有考试就闲不下来出去找工作去了。然后请假考试,因为学校都是要停一个月的课。剩下的7个月都在外边,第一份工作每天回学校第二份在外边租了房子,不过大多数都是一个人呆着。这一年学了很多东西,各种折腾,最近一次折腾下Openwrt折腾了一天没有折腾好,感觉没有以前那种激情了。可能时间不够了。我想这句话比较适合现在的自己吧,too young too simple sometime naive

做好的

  1. 学分修完了。
  2. 搬出学校一个人生活了,当然基本上都是吃自己弄的了。
  3. linux,php,vim,git常用的开发工具软件语言都能用上手了,不枉那些年为戒游戏和QQ装的ubuntu单系统,年尾看正则现在vim里面正则用着那叫一个爽,还看了看vimL,然后看的那本shell的书也给自己带来了很多的东西。
  4. 看了一些书,在学校每周也有去图书馆借新书,学的东西有点点泛。
  5. 认识了很多朋友给自己带来了不少的激情,也让自己很多想法改变了很多。看着同事们都活的蛮开心觉得自己也会有个不错的未来。
  6. PHP单独说下,在MatchMove也算见识到PHP比较NB的用法了,主要是Kohana里面的一些东西,还有譬如namespace等。MatchMove什么都是用的自己熟悉的总之还是蛮享受这四个月的工作时间,不过因为自己太浮躁静不下心来最终决定离开。挺对不住fancy和KJ的。

2013

计划

  1. 锻炼好身体
  2. 消灭完买的书
  3. 多混社区
  4. 待心安静下来了再找份安定的工作
  5. 找个能手牵手一起走女朋友
  6. 把FuelPHP的代码给看了
  7. 弄编译原理和算法
  8. 多参加社会活动
  9. 语言继续python打算学学lua
  10. 认真写部落格,坚决不再删微博。

System Version: OS X 10.8 (12A269) Kernel Version: Darwin 12.0.0 2013-01-24 14:49:46

PHP连接SQL Server 并使用存储过程

标题仅仅是为了SEO凑合着,这1天半都在折腾这个东西了,感觉PHP就是这些好。

freetds

freeTDS全名叫 free [Tabular Data Stream][1],TDS是应用层的协议,最早由Sybase Inc开发,用在自家的数据库,后来被Micrososoft用于MS Server。freeTDS则是TDS的一个开源版本实现。Python,Ruby,PHP,Perl都能够使用。有一个java实现的版本jTDS,freeTDS自身也包含有ODBC库。

安装

ubuntu debain系,sudo apt-get install freetds。mac brew install freetds。或者编译安装。

配置

找到这个文件freetds.conf。然后编辑。

1
2
3
4
5
# A typical Microsoft SQL Server 7.0 configuration      
[MMS]
host = server.h2ero.cn
port = 1433
tds version = 7.0

连接SQL SERVER

使用tsql进行连接,tsql -H server.h2ero.cn -p 1433 -U username -P password。通常显示过去多少秒的数字表示没有连接上。直接上了显示>,然后可以执行SQL了,输入version可以查看当前的freeTDS版本。执行mssql,select @@version 回车,go 回车。然后即可执行。

PHP mssql

安装好了freeTDS后查看phpinfo信息里面有没有mssql,如果有直接就可以使用mssql_connect进行连接,如果没有需要去掉php.ini里面mssql.so或者相关dll的注释,然后重启相关服务查看。如果没有只能重新编译安装讲mmsql扩展添加进来。

php mssql连接

到了这一步直接用使用一下代码进行简单的操作,其实和mysql相关函数一样

1
2
3
4
5
6
7
8
9
10
<?php 

$Server='server.h2ero.cn:1433';
$dbconn = mssql_connect($Server, $User, $Pass) or die("Couldn't connect to SQL Server on $Server");
mssql_select_db($DB, $dbconn);
$version = mssql_query('SELECT @@VERSION');
$row = mssql_fetch_array($version);
echo $row[0];
// Clean up
mssql_free_result($version);

php 使用MSSQL存储过程

1
2
3
4
5
6
7
<?php
$dbconn = mssql_connect('MMS', $User, $Pass) or die("Couldn't connect to SQL Server on $Server");
//init
$stmt=mssql_init('user_del',$dbconn);
mssql_bind($stmt,'@id',$user['id'],SQLINT1,false,false,3);
$res=mssql_execute($stmt);
mssql_free_statement($stmt);

需要注意mssql_connnect的第一个参数使用的是freeTDS里面的配置名。SQLINT1详细到这儿查看MSSQL Predefined Constants

几条MSSQL

1
2
3
4
#查看所有表
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE';
#查看所有存储过程
select * from information_schema.routines where routine_type = 'PROCEDURE;

MSSQL系统自带存储过程

这些可以在tsql里面运行其中sp_helptext,sp_help对了解别人写的存储过程还是作用比较大。MySQL从5.0也开始能使用存储过程了,可以直接把存储过程理解为函数。

1
2
3
4
5
6
7
8
9
10
11
12
exec sp_databases; --查看数据库
exec sp_tables;        --查看表
exec sp_columns student;--查看列
exec sp_helpIndex student;--查看索引
exec sp_helpConstraint student;--约束
exec sp_stored_procedures;
exec sp_helptext 'sp_stored_procedures';--查看存储过程创建、定义语句
exec sp_rename student, stuInfo;--修改表、索引、列的名称
exec sp_renamedb myTempDB, myDB;--更改数据库名称
exec sp_defaultdb 'master', 'myDB';--更改登录名的默认数据库
exec sp_helpdb;--数据库帮助,查询数据库信息
exec sp_helpdb master;


System Version: OS X 10.8 (12A269) Kernel Version: Darwin 12.0.0
2012-12-19 22:00:01

为Youtube播放事件添加Google Analytics统计

Google Analytics太过于强大,才发现国内的什么CNZZ,51la,百度统计等都弱爆。单单是 Dimensions & Metrics就可以满足对网站各种不同的数据分析。以前都不明白为什么很多外国的官方网站都放Youtube的视频,原来Youtube提供的API也非常强大。可惜这些好产品在国内都不能用。不过做个英文站这些都会用到。
要统计Youtube的播放及其他事件需要参照IFrame embeds using the IFrame Player API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//先在页面添加div#player
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var player;
function onYouTubePlayerAPIReady() {
    player = new YT.Player('player', {
        height: '390',
        width: '640',
        videoId: 'zLQFkztsozw',
        events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
        }
    });
}
function onPlayerStateChange(event) {
    if(event.data == YT.PlayerState.PLAYING) {
        _gaq.push(['_trackEvent', 'Videos', 'Play', player.getVideoUrl()]);
    }
    if(event.data == YT.PlayerState.ENDED) {
        _gaq.push(['_trackEvent', 'Videos', 'Watch to End', player.getVideoUrl()]);
    }
}
tag.onload = onYouTubePlayerAPIReady();

然后就可以在Google Analytics里面看到。

Event Category Event Action total event unique event
Videos Play 90 85
Videos Watched to End 30 30

各搜索引擎header信息

整理了一下日志里面的爬虫信息。

  • baidu image: "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; baidu Transcoder;)"
  • soso: "Mozilla/5.0(compatible; Sosospider/2.0; +http://help.soso.com/webspider.htm)"
  • baidu: "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
  • esou: "Mozilla/5.0 (compatible; EasouSpider; +http://www.easou.com/spider.html)"
  • jike: "Mozilla/5.0 (compatible; JikeSpider; +http://shoulu.jike.com/spider.html)"
  • procog: "Mozilla/5.0 (compatible; ProCogBot/1.0; +http://www.procog.com/spider.html)"
  • openindex: "Mozilla/5.0 (compatible; OpenindexSpider; +http://www.openindex.io/en/webmasters/spider.html)"
  • google: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
  • 360: "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.0.11) Gecko/20070312 Firefox/1.5.0.11; 360Spider"
  • bing: "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"

netbeans

jvi

  1. 安装jvi后不能通过右键菜单行号不能显示,:set nu解决
  2. :w 需要回车两次,Menu>Tools>Options>jVi>Platform notice 去掉”:” command completion auto popup. 这项,这个时候没有自动补全需要按Ctrl+space,或者Ctrl+D
  3. zc zo 折叠打开函数。zM zR 全部

    QuickOpener

    show-path-in-title

Mac下配置Postfix使用SMTP

上一次弄过,然后这一次再弄又给忘了,苦逼周末还在弄公司的东西。最近书也没有怎么看,自己的代码也没有怎么敲,现在在的这家公司感觉东西也学的差不多了。
公司用的发送Email用Swift mailer,Mac下SMTP需要用到Postfix这个软件,Mac自带。

配置

sudo vi /System/Library/LaunchDaemons/org.postfix.master.plist
</dict>加入<key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/>

启用

1
2
3
4
5
6
$ sudo launchctl
launchd% start org.postfix.master
#测试运行没有
telnet localhost 25
#停止
launchd% stop org.postfix.master

参考:

  1. Sending emails with PHP using Swiftmailer and SMTP on Mac OSX
  2. How to Enable Local SMTP (Postfix) on OS-X Leopard

fuelphp 备忘

来不起了,不过还是记一下。不然就忘了。FuelPHP主要和Kohana,CodeIgniter相关。很多东西都类似。支持HMVC,Cascading Filesystem,namespace。这些也许就是选他的原因了,如果什么时候kohana支持namespace了一定还是用kohana。不过暂时还不支持,fuelphp看起来还不错,不过很多都不完善,比如Cascading File System就是个悲剧。也有可能是自己没有搞懂,最近都在折腾Kohana和Fuelphp,Kohana中如果有用到module是可以直接通过路由访问的。而且不用设置路由,基于CFS直接冲module里面找。省很多东西,配置文件来说Kohana是merge,而Fuelphp是rewrite,所以有要多弄很多东西。不过各有各的好处。

  1. module直接访问,如果一个Module继承自另外一个Module,相同的Controller/action下,kohana不用再设置,不过带来的坏处就是不需要是的时候需要通过设置url router去屏蔽,其实这样是不可控制的。而Fuelphp需要设置Url router去控制,其实对于一站点或者一module来说就那么点点Controller这样可控制性更强。
  2. Controller_Template,kohana和fuelphp都可以设置$template,不过对于继承的kohana可以通过CFS找到,Fuelphp只能设置的时候添加’NS::template/default’来找到,总是觉得Cascading Filesystem在Fuelphp里面没有体现出来。悲剧,不过实现起来还是比较简单,修改下源码即可实现。
  3. Config合并和覆盖看个人喜欢,比较不喜欢kohana的合并。
  4. Fuelphp的namespace。