邵珠庆の日记 生命只有一次,你可以用它来做很多伟大的事情–Make the world a little better and easier


2710月/13

用 Flora_Pac.py 生成自动翻墙的 pac 文件

发布在 邵珠庆

源于人们对自由的向往,翻墙技术已渐趋成熟。愿意花点钱,购买海外 VPN 和 ssh 主机用于自由获取信息是目前比较有效的手段。如我之前文章中提及,这两种方式都有需要筛选出那些网站在墙外,那些网站在墙内,以较节约、高速的方式访问网络。八仙过海,各显神通,不少帮助人们解决这一问题,降低翻墙门槛的小项目出现了。较具代表性的有 chnroutes(http://code.google.com/p/chnroutes/) 项目和 autoproxy-gfwlist(http://code.google.com/p/autoproxy-gfwlist/) 项目。前者修改路由表,配合各种 VPN 使用,后者可以配合 AutoProxy for Firefox(https://addons.mozilla.org/firefox/addon/11009) 或导出(https://autoproxy2pac.appspot.com/)为 pac 文件,配合各种代理服务器,包括 ssh -D 使用。他们的原理稍有差异,chnroutes 只区分国内外 IP 段,让国外地址全部走翻墙路线,autoproxy-gfwlist 项目则精确记录着那些网站被墙。

我以往喜欢 ssh -D 生成 SOCKS 代理后,搭配自己的 pac 文件翻墙。最近由于各种原因转到了 VPN 阵营。感觉 VPN 搭配 chnroutes 的确很舒服,不用再关心那些网站被墙,不会因为 gfwlist 更新延迟而影响访问。于是我在想,有没有办法让使用 ssh -D 或者其他翻墙代理的用户能和使用 VPN 的用户那样省心呢?于是我站在巨人的肩膀上,基于 chnroutes 项目,结合 pac 文件的 dnsResolve() 和 isInNet() 函数,开发了 Flora_Pac 这个小项目。

Flora_Pac 使用 Python 开发,能自动抓取 apnic.net 的 IP 数据,找出所有国内的 IP 地址段,生成能让浏览器自动判断国内外 IP 地址的 pac 文件,让代理用户有等价于 VPN + chnroutes 的翻墙体验。Flora_Pac 使用十分简单,兼容各种平台:

####### 获得帮助:
$ python flora_pac.py -h
usage: flora_pac.py [-h] [-x [PROXY]]
Generate proxy auto-config rules.
optional arguments:
  -h, --help            show this help message and exit
  -x [PROXY], --proxy [PROXY]
                        Proxy Server, examples:
                            SOCKS 127.0.0.1:8964;
                            SOCKS5 127.0.0.1:8964;
                            PROXY 127.0.0.1:8964

####### 生成 pac 文件,国外 IP 通过代理 SOCKS 代理 127.0.0.1:8964 访问:
$ python flora_pac.py -x 'SOCKS 127.0.0.1:8964'
Fetching data from apnic.net, it might take a few minutes, please wait...
Rules: 3460 items.
Usage: Use the newly created flora_pac.pac as your web browser's automatic proxy configuration (.pac) file.

####### 生成 pac 文件,国外 IP 通过代理 HTTP 代理 127.0.0.1:8964 访问:
$ python flora_pac.py -x 'PROXY 127.0.0.1:8964'
Fetching data from apnic.net, it might take a few minutes, please wait...
Rules: 3460 items.
Usage: Use the newly created flora_pac.pac as your web browser's automatic proxy configuration (.pac) file.

程序跑完后,就会在当前目录产生 flora_pac.pac 文件,把它设为浏览器或系统代理设置的 pac 文件即可。

项目代码我放在 github 上开源了:https://github.com/Leask/Flora_Pac,其中 fetch_ip_data 函数 fork 自 chnroutes 项目。

不方便上 github 的朋友,直接复制以下代码保存为 flora_pac.py 就可以跑了:

#!/usr/bin/env python
#
# Flora_Pac by @leaskh
# www.leaskh.com, i@leaskh.com
#
# based on chnroutes project (by Numb.Majority@gmail.com)
#

import re
import urllib2
import argparse
import math

def generate_pac(proxy):
    results  = fetch_ip_data()
    pacfile  = 'flora_pac.pac'
    rfile    = open(pacfile, 'w')
    strLines = (
        "// Flora_Pac by @leaskh"
        "\n// www.leaskh.com, i@leaskh.com"
        "\n"
        "\nfunction FindProxyForURL(url, host)"
        "\n{"
        "\n"
        "\n    var list = ["
    )
    intLines = 0
    for ip,mask,_ in results:
        if intLines > 0:
            strLines = strLines + ','
        intLines = intLines + 1
        strLines = strLines + "\n        ['%s', '%s']"%(ip, mask)
    strLines = strLines + (
        "\n    ];"
        "\n"
        "\n    var ip = dnsResolve(host);"
        "\n"
        "\n    for (var i in list) {"
        "\n        if (isInNet(ip, list[i][0], list[i][1])) {"
        "\n            return 'DIRECT';"
        "\n        }"
        "\n    }"
        "\n"
        "\n    return '%s';"
        "\n"
        "\n}"
        "\n"%(proxy)
    )
    rfile.write(strLines)
    rfile.close()
    print ("Rules: %d items.\n"
           "Usage: Use the newly created %s as your web browser's automatic "
           "proxy configuration (.pac) file."%(intLines, pacfile))

def fetch_ip_data():
    #fetch data from apnic
    print "Fetching data from apnic.net, it might take a few minutes, please wait..."
    url=r'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'
    data=urllib2.urlopen(url).read()

    cnregex=re.compile(r'apnic\|cn\|ipv4\|[0-9\.]+\|[0-9]+\|[0-9]+\|a.*',re.IGNORECASE)
    cndata=cnregex.findall(data)

    results=[]

    for item in cndata:
        unit_items=item.split('|')
        starting_ip=unit_items[3]
        num_ip=int(unit_items[4])

        imask=0xffffffff^(num_ip-1)
        #convert to string
        imask=hex(imask)[2:]
        mask=[0]*4
        mask[0]=imask[0:2]
        mask[1]=imask[2:4]
        mask[2]=imask[4:6]
        mask[3]=imask[6:8]

        #convert str to int
        mask=[ int(i,16 ) for i in mask]
        mask="%d.%d.%d.%d"%tuple(mask)

        #mask in *nix format
        mask2=32-int(math.log(num_ip,2))

        results.append((starting_ip,mask,mask2))

    return results

if __name__=='__main__':
    parser=argparse.ArgumentParser(description="Generate proxy auto-config rules.")
    parser.add_argument('-x', '--proxy',
                        dest = 'proxy',
                        default = 'SOCKS 127.0.0.1:8964',
                        nargs = '?',
                        help = "Proxy Server, examples: "
                               "SOCKS 127.0.0.1:8964; "
                               "SOCKS5 127.0.0.1:8964; "
                               "PROXY 127.0.0.1:8964")

    args = parser.parse_args()

    generate_pac(args.proxy)

我想,应该过不了多久就要解放了。期待着有那么一天:我们能一起呼吸自由的空气,我们不再需要折腾各种翻墙玩意。那时,生活应该会更美好一些吧。

1510月/13

linux 目录结构

发布在 邵珠庆

 linux 目录结构 


/: 根目录,一般根目录下只存放目录,不要存放文件,/etc、/bin、/dev、/lib、/sbin应该和根目录放置在一个分区中
/bin:/usr/bin: 可执行二进制文件的目录,如常用的命令ls、tar、mv、cat等。
/boot: 放置linux系统启动时用到的一些文件。/boot/vmlinuz为linux的内核文件,以及/boot/gurb。建议单独分区,分区大小100M即可
/dev: 存放linux系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,常用的是挂载光驱mount /dev/cdrom /mnt。
/etc: 系统配置文件存放的目录,不建议在此目录下存放可执行文件,重要的配置文件有/etc/inittab、/etc/fstab、/etc/init.d、/etc/X11、/etc/sysconfig、/etc/xinetd.d修改配置文件之前记得备份。注:/etc/X11存放与x windows有关的设置。
/home: 系统默认的用户家目录,新增用户账号时,用户的家目录都存放在此目录下,~表示当前用户的家目录,~test表示用户test的家目录。建议单独分区,并设置较大的磁盘空间,方便用户存放数据
/lib:/usr/lib:/usr/local/lib: 系统使用的函数库的目录,程序在执行过程中,需要调用一些额外的参数时需要函数库的协助,比较重要的目录为/lib/modules。
/lost+fount: 系统异常产生错误时,会将一些遗失的片段放置于此目录下,通常这个目录会自动出现在装置目录下。如加载硬盘于/disk 中,此目录下就会自动产生目录/disk/lost+found
/mnt:/media: 光盘默认挂载点,通常光盘挂载于/mnt/cdrom下,也不一定,可以选择任意位置进行挂载。
/opt: 给主机额外安装软件所摆放的目录。如:FC4使用的Fedora 社群开发软件,如果想要自行安装新的KDE 桌面软件,可以将该软件安装在该目录下。以前的 Linux 系统中,习惯放置在 /usr/local 目录下
/proc: 此目录的数据都在内存中,如系统核心,外部设备,网络状态,由于数据都存放于内存中,所以不占用磁盘空间,比较重要的目录有/proc/cpuinfo、/proc/interrupts、/proc/dma、/proc/ioports、/proc/net/*等
/root: 系统管理员root的家目录,系统第一个启动的分区为/,所以最好将/root和/放置在一个分区下。
/sbin:/usr/sbin:/usr/local/sbin: 放置系统管理员使用的可执行命令,如fdisk、shutdown、mount等。与/bin不同的是,这几个目录是给系统管理员root使用的命令,一般用户只能"查看"而不能设置和使用。
/tmp: 一般用户或正在执行的程序临时存放文件的目录,任何人都可以访问,重要数据不可放置在此目录下
/srv: 服务启动之后需要访问的数据目录,如www服务需要访问的网页数据存放在/srv/www内
/usr: 应用程序存放目录,/usr/bin 存放应用程序, /usr/share 存放共享数据,/usr/lib 存放不能直接运行的,却是许多程序运行所必需的一些函数库文件。/usr/local:存放软件升级包。/usr/share/doc: 系统说明文件存放目录。/usr/share/man: 程序说明文件存放目录,使用 man ls时会查询/usr/share/man/man1/ls.1.gz的内容建议单独分区,设置较大的磁盘空间
/var: 放置系统执行过程中经常变化的文件,如随时更改的日志文件 /var/log,/var/log/message: 所有的登录文件存放目录,/var/spool/mail: 邮件存放的目录, /var/run: 程序或服务启动

后,其PID存放在该目录下。建议单独分区,设置较大的磁盘空间

------------------------------------------ 

/dev: 目录
dev是设备(device)的英文缩写。/dev这个目录对所有的用户都十分重要。因为在这个目录中包含了所有Linux系统中使用的外部设备。但是这里并不是放的外部设备的驱动程序,这一点和

windows,dos操作系统不一样。它实际上是一个访问这些外部设备的端口。我们可以非常方便地去访问这些外部设备,和访问一个文件,一个目录没有任何区别。

Linux沿袭Unix的风格,将所有设备认成是一个文件。

设备文件分为两种:块设备文件(b)和字符设备文件(c)

设备文件一般存放在/dev目录下,对常见设备文件作如下说明:

/dev/hd[a-t]:IDE设备

/dev/sd[a-z]:SCSI设备

/dev/fd[0-7]:标准软驱

/dev/md[0-31]:软raid设备

/dev/loop[0-7]:本地回环设备

/dev/ram[0-15]:内存

/dev/null:无限数据接收设备,相当于黑洞

/dev/zero:无限零资源

/dev/tty[0-63]:虚拟终端

/dev/ttyS[0-3]:串口

/dev/lp[0-3]:并口

/dev/console:控制台

/dev/fb[0-31]:framebuffer

/dev/cdrom => /dev/hdc

/dev/modem => /dev/ttyS[0-9]

/dev/pilot => /dev/ttyS[0-9]

/dev/random:随机数设备

/dev/urandom:随机数设备

(PS:随机数设备,后面我会再写篇博客总结一下)

/dev目录下的节点是怎么创建的?

devf或者udev会自动帮你创建得。

kobject是sysfs文件系统的基础,udev通过监测、检测sysfs来获取新创建的设备的。

------------------------------------------ 

/etc: 目录
包含很多文件.许多网络配置文件也在/etc 中.
/etc/rc   or /etc/rc.d   or /etc/rc*.d    启动、或改变运行级时运行的scripts或scripts的目录.
/etc/passwd  
用户数据库,其中的域给出了用户名、真实姓名、家目录、加密的口令和用户的其他信息.
/etc/fstab  
启动时mount -a命令(在/etc/rc 或等效的启动文件中)自动mount的文件系统列表. Linux下,也包括用swapon -a启用的swap区的信息.
/etc/group 
类似/etc/passwd ,但说明的不是用户而是组.
/etc/inittab  
init 的配置文件.
/etc/issue  
getty 在登录提示符前的输出信息.通常包括系统的一段短说明或欢迎信息.内容由系统管理员确定.
/etc/motd  
Message Of The Day,成功登录后自动输出.内容由系统管理员确定.经常用于通告信息,如计划关机时间的警告.
/etc/mtab  
当前安装的文件系统列表.由scripts初始化,并由mount 命令自动更新.需要一个当前安装的文件系统的列表时使用,例如df 命令.
/etc/shadow  
在安装了影子口令软件的系统上的影子口令文件.影子口令文件将/etc/passwd 文件中的加密口令移动到/etc/shadow 中,而后者只对root可读.这使破译口令更困难.
/etc/login.defs  
login 命令的配置文件.
/etc/printcap  
类似/etc/termcap ,但针对打印机.语法不同.
/etc/profile , /etc/csh.login , /etc/csh.cshrc  
登录或启动时Bourne或C shells执行的文件.这允许系统管理员为所有用户建立全局缺省环境.
/etc/securetty  
确认安全终端,即哪个终端允许root登录.一般只列出虚拟控制台,这样就不可能(至少很困难)通过modem或网络闯入系统并得到超级用户特权.
/etc/shells  
列出可信任的shell.chsh 命令允许用户在本文件指定范围内改变登录shell.提供一台机器FTP服务的服务进程ftpd 检查用户shell是否列在 /etc/shells 文件中,如果不是将不允许该用户登录.
/etc/sysconfig 
网络配置相关目录

------------------------------------------ 

/proc: 目录

档名    文件内容
/proc/cmdline     加载 kernel 时所下达的相关参数!查阅此文件,可了解系统是如何启动的!
/proc/cpuinfo     本机的 CPU 的相关资讯,包含时脉、类型与运算功能等
/proc/devices     这个文件记录了系统各个主要装置的主要装置代号,与 mknod 有关呢!
/proc/filesystems     目前系统已经加载的文件系统罗!
/proc/interrupts     目前系统上面的 IRQ 分配状态。
/proc/ioports     目前系统上面各个装置所配置的 I/O 位址。
/proc/kcore     这个就是内存的大小啦!好大对吧!但是不要读他啦!
/proc/loadavg     还记得 top 以及 uptime 吧?没错!上头的三个平均数值就是记录在此!
/proc/meminfo     使用 free 列出的内存资讯,嘿嘿!在这里也能够查阅到!
/proc/modules     目前我们的 Linux 已经加载的模块列表,也可以想成是驱动程序啦!
/proc/mounts     系统已经挂载的数据,就是用 mount 这个命令呼叫出来的数据啦!
/proc/swaps     到底系统挂加载的内存在哪里?呵呵!使用掉的 partition 就记录在此啦!
/proc/partitions     使用 fdisk -l 会出现目前所有的 partition 吧?在这个文件当中也有纪录喔!
/proc/pci     在 PCI 汇流排上面,每个装置的详细情况!可用 lspci 来查阅!
/proc/uptime     就是用 uptime 的时候,会出现的资讯啦!
/proc/version     核心的版本,就是用 uname -a 显示的内容啦!
/proc/bus/*     一些汇流排的装置,还有 U盘 的装置也记录在此喔!

------------------------------------------ 

/usr: 目录
/usr 文件系统经常很大,因为所有程序安装在这里. /usr 里的所有文件一般来自Linux distribution;本地安装的程序和其他东西在/usr/local 下.这样可能在升级新版系统或新distribution时无须重新安装全部程序.
/usr/etc            存放设置文件
/usr/games      存放游戏和教学文件
/usr/include      存放C开发工具的头文件
/usr/share         存放结构独立的数据
/usr/bin  
几乎所有用户命令.有些命令在/bin 或/usr/local/bin 中.
/usr/sbin  
根文件系统不必要的系统管理命令,例如多数服务程序.
/usr/share/man , /usr/share/info , /usr/share/doc 
手册页、GNU信息文档和各种其他文档文件.
/usr/include  
C编程语言的头文件.为了一致性这实际上应该在/usr/lib 下,但传统上支持这个名字.
/usr/lib  
程序或子系统的不变的数据文件,包括一些site-wide配置文件.名字lib来源于库(library); 编程的原始库存在/usr/lib 里.
/usr/local  
本地安装的软件和其他文件放在这里.
/usr/src             存放程序的源代码


------------------------------------------ 

/var: 目录
/var 包括系统一般运行时要改变的数据.每个系统是特定的,即不通过网络与其他计算机共享.
/var/catman  
当要求格式化时的man页的cache.man页的源文件一般存在/usr/man/man* 中;有些man页可能有预格式化的版本,存在/usr/man/cat* 中.而其他的man页在第一次看时需要格式化,格式化完的版本存在/var/man 中,这样其他人再看相同的页时就无须等待格式化了. (/var/catman 经常被清除,就象清除临时目录一样.)
/var/lib  
系统正常运行时要改变的文件.
/var/local  
/usr/local 中安装的程序的可变数据(即系统管理员安装的程序).注意,如果必要,即使本地安装的程序也会使用其他/var 目录,例如/var/lock .
/var/lock  
锁定文件.许多程序遵循在/var/lock 中产生一个锁定文件的约定,以支持他们正在使用某个特定的设备或文件.其他程序注意到这个锁定文件,将不试图使用这个设备或文件.  
/var/log  

各种程序的Log文件,特别是login  (/var/log/wtmp log所有到系统的登录和注销) 和syslog (/var/log/messages 里存储所有核心和系统程序信息. /var/log 里的文件经常不确定地增长,应该定期清除.  
/var/run  

保存到下次引导前有效的关于系统的信息文件.例如, /var/run/utmp 包含当前登录的用户的信息.
/var/spool  
mail, news, 打印队列和其他队列工作的目录.每个不同的spool在/var/spool 下有自己的子目录,例如,用户的邮箱在/var/spool/mail 中.  
/var/tmp  

比/tmp 允许的大或需要存在较长时间的临时文件. (虽然系统管理员可能不允许/var/tmp 有很旧的文件.) 


------------------------------------------ 

 比较重要的目录 

    在 Linux 系统中,有几个目录是特别需要注意的,以下提供几个需要注意的目录,以及预设相关的用途:
        /etc: 这个目录相当重要,如前所述,你的开机与系统数据文件均在这个目录之下,因此当这个目录被破坏,那你的系统大概也就差不多该死掉了!而在往后的文件中,你会发现我们常常使用这个目录下的 /etc/rc.d/init.d 这个子目录,因为这个 init.d 子目录是开启一些 Linux 系统服务的 scripts (可以想成是批次檔 )的地方。而在 /etc/rc.d/rc.local 这个文件是开机的执行档。
        /bin, /sbin, /usr/bin, /usr/sbin: 这是系统预设的执行文件的放置目录,例如 root 常常使用的 userconf, netconf, perl, gcc, c++ 等等的数据都放在这几个目录中,所以如果你在提示字符下找不到某个执行档时,可以在这四个目录中查一查!其中, /bin, /usr/bin 是给系统使用者使用的指令,而 /sbin, /usr/sbin 则是给系统管理员使用的指令!
        /usr/local: 这是系统预设的让你安装你后来升级的套件的目录。例如,当你发现有更新的 Web 套件(如 Apache )可以安装,而你又不想以 rpm 的方式升级你的套件,则你可以将 apache 这个套件安装在 /usr/local 底下。安装在这里有个好处,因为目前大家的系统都是差不多的,所以如果你的系统要让别人接管的话,也比较容易上手呀!也比较容易找的到数据喔!因此,如果你有需要的话,通常我都会将 /usr/local/bin 这个路径加到我的 path 中。
        /home: 这个是系统将有账号的人口的家目录设置的地方。
        /var: 这个路径就重要了!不论是登入、各类服务的问题发生时的记录、以及常态性的服务记录等等的记录目录,所以当你的系统有问题时,就需要来这个目录记录的文件数据中察看问题的所在啰!而 mail 的预设放置也是在这里,所以他是很重要的
        /usr/share/man, /usr/local/man: 这两个目录为放置各类套件说明档的地方,例如你如果执行 man man,则系统会自动去找这两个目录下的所有说明文件


文件种类: 

谈完了文件格式之后,再来谈谈所谓的文件种类吧!我们在刚刚的属性介绍中提到了最前面的标志 ( d 或 - ) 可以代表目录或文件,那就是不同的文件种类啦!Linux 的文件种类主要有底下

这几种:
    正规文件( regular file ):就是一般类型的文件,在由 ls –al 所显示出来的属性方面,第一个属性为 [ - ]。另外,依照文件的内容,又大略可以分为两种文件种类:
        纯文字文件(ascii) :这是 Unix 系统中最多的一种啰,几乎只要我们可以用来做为设定的文件都属于这一种;
        二进制文件(binary) :通常执行档除了 scripts (文字型批次文件)之外,就是这一种文件格式;
    目录 (directory):就是目录!第一个属性为 [ d ];
    连结档 (link):就是类似 Windows 底下的快捷方式啦!第一个属性为 [ l ];
    设备档 (device):与系统周边相关的一些文件,通常都集中在 /dev 这个目录之下!通常又分为两种:
    区块 (block) 设备档 :就是一些储存数据,以提供系统存取的接口设备,简单的说就是硬盘啦!例如你的一号硬盘的代码是 /dev/hda1 等等的文件啦!第一个属性为 [ b ];
    字符 (character) 设备档 :亦即是一些串行端口的接口设备,例如键盘、鼠标等等!第一个属性为 [ c ]。

1410月/13

常见的软件版本编号及命名

发布在 邵珠庆

1、RC,GA
RC:就是Release Candidate(候选版本)的缩写
GA:就是General Availability,正式发布的版本

 
Alpha:内测版。
Alpha是希腊字母的第一位的英文谐音,就是α,用在软件版本中就是表示最初级的版本。通常情况下Alpha是内部测试版,一般不向外部发布,会有很多Bug。除非你也是测试人员,否则不建议使用。 

Beta:公测版。
Beta是希腊字母的第二位的英文谐音,就是β,是一个比Alpha稍高的版本。Beta也是一个测试版本,在正式版推出之前发布,主要用于面向公众进行测试及Bug收集,这个阶段的版本Bug可能较多,并且可能会加入一些新的功能。

Delux:豪华版。
Plus版和Delux版区别不大,比普通版本多了一些附加功能。

EVAL:体验版或评估版。
功能上和正式版没有区别,但存在一些时间或空间上的限制。

Final:正式版。
软件的正式版本,修正了Alpha版和Beta版的Bug。

Free:免费版。

Full:完全版。

OEM:
是给计算机厂商随着计算机贩卖的,也就是随机版。只能随机器出货,不能零售。如果买笔记型计算机或品牌计算机就会有随机版软件。包装不像零售版精美,通常只有一面CD和说明书(授权书)。

Plus:加强版。

Pro:专业版。
需要注册后才能解除限制,否则为评估版本。

RC(Release Candidate):Candidate是候选人的意思,用在软件上就是候选版本,而Release Candidate 就是发行候选版本,也就是说这还不能算是正式的发布版。。
和Beta版最大的差别在于Beta阶段会一直加入新的功能,但是到了RC版本,几乎就不会加入新的功能了,而主要着重于除错!

RTL(Retail):零售版。
正式上架零售版。

RTM(Release to Manufacture):
程序代码开发完成之后,要将母片送到工厂大量压片,这个版本就叫做 RTM版。所以说,RTM版的程序码一定和正式版一样。

RVL:
不详。

SR:修正版或更新版。
修正了正式版推出后发现的Bug。

Trial:试用版。
软件在功能或时间上有所限制,如果想解除限制,需要购买正式版。

——————————————————————————-
另外:
Build:不是一个发行版本,而是一个内部版本构建标号,用于周期性的生成目标程序,主要目的是构建程序进行测试及版本备份,并可以版本发布时进行选择,类似于RC版本。同一版本可以有多个Build号,通常Build后面的数字越大,软件版本越新。

为了维护软件项目, 我们提出了对版本进行管理控制的要求. 而对于用户来说, 版本直接体现在版本号的命名上. 那么, 如何对版本号进行命名呢? 我查了许多的资料, 希望能解释得比较具体, 同时也希望您在阅读本文的时候, 能够对版本号的命名格式提出自己的见解, 这当然包括一些版本号命名的个例. 下面, 让我们看一下比较普遍的 3 种命名格式. 

GNU 风格的版本号命名格式: 主版本号.子版本号[.修正版本号[.编译版本号]]
英文对照: Major_Version_Number.Minor_Version_Number[.Revision_Number[.Build_Number]]
示例: 1.2.1, 2.0, 5.0.0 build-13124

Windows 风格的版本号命名格式: 主版本号.子版本号[修正版本号[.编译版本号]]
英文对照: Major_Version_Number.Minor_Version_Number[Revision_Number[.Build_Number]]
示例: 1.21, 2.0

.Net Framework 风格的版本号命名格式: 主版本号.子版本号[.编译版本号[.修正版本号]]
英文对照: Major_Version_Number.Minor_Version_Number[.Build_Number[.Revision_Number]]
官方说明参考:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemVersionClassTopic.asp
由于, 有官方解释, 所以本文不做说明.

GNU 风格的版本号管理策略

当项目初版本时, 版本号可以为 0.1 或 0.1.0, 也可以为 1.0 或 1.0.0, 如果你为人很低调, 我想你会选择那个主版本号为 0 的方式;
当项目在进行了局部修改或 bug 修正时, 主版本号和子版本号都不变, 修正版本号加 1;
当项目在原有的基础上增加了部分功能时, 主版本号不变, 子版本号加 1, 修正版本号复位为 0, 因而可以被忽略掉;
当项目在进行了重大修改或局部修正累积较多, 而导致项目整体发生全局变化时, 主版本号加 1;
另外, 编译版本号一般是编译器在编译过程中自动生成的, 我们只定义其格式, 并不进行人为的控制.
Window 下的版本号管理策略

当项目初版时, 版本号为 1.0 或 1.00;
当项目在进行了局部修改或 bug 修正时,主版本号和子版本号都不变, 修正版本号加 1;
当项目在原有的基础上增加了部分功能时, 主版本号不变, 子版本号加 1, 修正版本号复位为 0, 因而可以被忽略掉;
当项目在进行了重大修改或局部修正累积较多, 而导致项目整体发生全局变化时, 主版本号加 1;
另外, 编译版本号一般是编译器在编译过程中自动生成的, 我们只定义其格式, 并不进行人为的控制.
另外, 还可以在版本号后面加入 Alpha, Beta, Gamma, Current, RC (Release Candidate), Release, Stable 等后缀, 在这些后缀后面还可以加入 1 位数字的版本号.

对于用户来说, 如果某个软件的主版本号进行了升级, 用户还想继续那个软件, 则发行软件的公司一般要对用户收取升级费用; 而如果子版本号或修正版本号发生了升级, 一般来说是免费的.

软件版本号总结:

V(Version):即版本,通常用数字表示版本号。(如:EVEREST Ultimate v4.20.1188 Beta )
Build: 用数字或日期标示版本号的一种方式。(如:VeryCD eMule v0.48a Build 071112)
SP: Service Pack,升级包。(如:Windows XP SP2 / Vista SP1)

授权和功能划分:
Trial:试用版,通常都有时间限制,有些试用版软件还在功能上做了一定的限制。可注册或购买成为正式版
Unregistered:未注册版,通常没有时间限制,在功能上相对于正式版做了一定的限制。可注册或购买成为正式版。
Demo: 演示版,仅仅集成了正式版中的几个功能,不能升级成正式版。
Lite: 精简版。
Full version:完整版,属于正式版。

语言划分:
SC: Simplified Chinese简体中文版。
CN: 简体中文版
GBK: 简体中文汉字内码扩展规范版。
TC: Traditional Chinese繁体中文版。
CHT: 繁体中文版
BIG5: 繁体中文大五码版。
EN: 英文版
Multilanguage:多语言版
UTF8: Unicode Transformation Format 8bit,对现有的中文系统不是好的解决方案。

其他版本划分:
Enhance: 增强版或者加强版 属于正式版1
Free:   自由版
Release: 发行版 有时间限制
Upgrade: 升级版
Retail: 零售版
Cardware:属共享软件的一种,只要给作者回复一封电邮或明信片即可。(有的作者并由此提供注册码等),目前这种形式已不多见。
Plus:   属增强版,不过这种大部分是在程序界面及多媒体功能上增强。
Preview: 预览版
Corporation & Enterprise: 企业版
Standard: 标准版
Mini:   迷你版也叫精简版只有最基本的功能
Premium: 贵价版
Professional: 专业版
Express: 特别版
Deluxe: 豪华版
Regged: 已注册版
Rip:是指从原版文件(一般是指光盘或光盘镜像文件)直接将有用的内容(核心内容)分离出来,剔除无用的文档,例如PDF说明文件啊,视频演示啊之类的东西,也可以算做是精简版,但主要内容功能是一点也不能缺少的!另:DVDrip是指将视频和音频直接从DVD光盘里以文件方式分离出来。

RTM 版:这基本就是最终的版本,英文是 Release To Manufactur,意思是发布到生产商。
OEM 版(Original Equipment Manufacturer):OEM软件是给电脑生产厂的版本,无需多说。

FPP 版(Full Packaged Product (FPP)/Retail):零售版(盒装软件),这种产品的光盘的卷标都带有”FPP”字样,比如英文Windows XP Pro 的FPP版本的光盘卷标就是WXPFPP_EN,其中WX表示是Windows XP,P是Professional(H是Home),FPP表明是零售版本,EN是表明是英语。获得途径除了在商店购买之外,某些MSDN用户也可以得到。
VOL版(Volume Licensing for Organizations(VLO)):团体批量许可证(大量采购授权合约),这是为团体购买而制定的一种优惠方式。这种产品的光盘的卷标都带有”VOL”字样,取”Volume”前3个字母,以表明是批量,比如英文WXP Pro的VOL版本的光盘卷标就是WXPVOL_EN,其中WX表示是Windows XP,P是Professional(VOL没有Home版本),VOL表明是团体批量许可证版本,EN是表明是英语。获得途径主要是集团购买,某些MSDN用户也可以得到。

软件开发阶段划分:

1. 软件版本阶段说明

* α(Alpha)版:内测版。此版本表示该软件在此阶段主要是以实现软件功能为主,通常只在软件开发者内部交流,或者专业测试人员测试用,一般而言,该版本软件的Bug较多,需要继续修改。
* β(Beta)版:公测版。该版本相对于α版已有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过多次测试来进一步消除,此版本主要的修改对像是软件的UI,供专业爱好者大规模测试用。

* RC 版:是 Release Candidate 的缩写,意思是发布倒计时,候选版本,该版本已经相当成熟了,完成全部功能并清除大部分的BUG,基本上不存在导致错误的BUG,与即将发行的正式版相差无几。

* Release 版:该版本意味”最终版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下,Release不会以单词形式出现在软件封面上,取而代之的是符号(R)。

2. 版本命名规范

软件版本号由四部分组成,第一个1为主版本号,第二个1为子版本号,第三个1为阶段版本号,第四部分为日期版本号加希腊字母版本号,希腊字母版本号共有5种,分别为:base、alpha、beta、RC、release。例如:1.1.1.051021_beta。

软件版本号怎么命名

 

3. 版本号定修改规则

* 主版本号(1):当功能模块有较大的变动,比如增加多个模块或者整体架构发生变化。此版本号由项目决定是否修改。
* 子版本号(1):当功能有一定的增加或变化,比如增加了对权限控制、增加自定义视图等功能。此版本号由项目决定是否修改。
* 阶段版本号(1):一般是 Bug 修复或是一些小的变动,要经常发布修订版,时间间隔不限,修复一个严重的bug即可发布一个修订版。此版本号由项目经理决定是否修改。
* 日期版本号(051021):用于记录修改项目的当前日期,每天对项目的修改都需要更改日期版本号。此版本号由开发人员决定是否修改。
* 希腊字母版本号(beta):此版本号用于标注当前版本的软件处于哪个开发阶段,当软件进入到另一个阶段时需要修改此版本号。此版本号由项目决定是否修改。

4. 文件命名规范

文件名称由四部分组成:第一部分为项目名称,第二部分为文件的描述,第三部分为当前软件的版本号,第四部分为文件阶段标识加文件后缀,例如:项目外包平台测试报告1.1.1.051021_beta_b.xls,此文件为项目外包平台的测试报告文档,版本号为:1.1.1.051021_beta。

软件版本号怎么命名

 

如果是同一版本同一阶段的文件修改过两次以上,则在阶段标识后面加以数字标识,每次修改数字加1,项目外包平台测试报告1.1.1.051021_beta_b1.xls。

当有多人同时提交同一份文件时,可以在阶段标识的后面加入人名或缩写来区别,例如:项目外包平台测试报告 1.1.1.051021_beta_b_LiuQi.xls。当此文件再次提交时也可以在人名或人名缩写的后面加入序号来区别,例如:项目外包平台测试报告1.1.1.051021_beta_b_LiuQi2.xls。

5. 版本号的阶段标识

软件的每个版本中包括11个阶段,详细阶段描述如下:

阶段名称                            阶段标识
需求控制                               a
设计阶段                               b
编码阶段                               c
单元测试                               d
单元测试修改                        e
集成测试                               f
集成测试修改                        g
系统测试                               h
系统测试修改                        i
验收测试                               j
验收测试修改                        k

1310月/13

mysql数据库数据变化实时监控

发布在 邵珠庆

对于二次开发来说,很大一部分就找找文件和找数据库的变化情况

对于数据库变化。还没有发现比较好用的监控数据库变化监控软件。

今天,我就给大家介绍一个如何使用mysql自带的功能监控数据库变化

1、打开数据库配置文件my.ini (一般在数据库安装目录)(D:\MYSQL)

2、在数据库的最后一行添加 log=log.txt  代码

3、重启mysql数据库

4、去数据库数据目录 我的是(D:\MYSQL\data) 你会发现多了一个log.txt文件

我的是在C:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5.5\data

测试:
1、对数据库操作
2、查看log.txt文件内容 如果发现有变化说明你就可以监控到mysql数据库的变化
数据库的查询 删除 更新 插入都可以查到

希望本篇文章可以帮助大家更快的二次开发 ^_^

日志文件类型概述:
1.错误日志 记录启动、运行或停止mysqld时出现的问题。
My.ini配置信息:
#Enter a name for the error log file. Otherwise a default name will be used.
#log-error=d:/mysql_log_err.txt
2.查询日志 记录建立的客户端连接和执行的语句。
My.ini配置信息:
#Enter a name for the query log file. Otherwise a default name will be used.
#log=d:/mysql_log.txt
3.更新日志 记录更改数据的语句。不赞成使用该日志。
My.ini配置信息:
#Enter a name for the update log file. Otherwise a default name will be used.
#log-update=d:/mysql_log_update.txt
4.二进制日志 记录所有更改数据的语句。还用于复制。
My.ini配置信息:
#Enter a name for the binary log. Otherwise a default name will be used.
#log-bin=d:/mysql_log_bin
5.慢日志 记录所有执行时间超过long_query_time秒的所有查询或不使用索引的查询。
My.ini配置信息:
#Enter a name for the slow query log file. Otherwise a default name will be used.
#long_query_time =1
#log-slow-queries= d:/mysql_log_slow.txt

在linux下:
Sql代码

1. # 在[mysqld] 中輸入
2. #log
3. log-error=/usr/local/mysql/log/error.log
4. log=/usr/local/mysql/log/mysql.log
5. long_query_time=2
6. log-slow-queries= /usr/local/mysql/log/slowquery.log

# 在[mysqld] 中輸入 #log log-error=/usr/local/mysql/log/error.log log=/usr/local/mysql/log/mysql.log long_query_time=2 log-slow-queries= /usr/local/mysql/log/slowquery.log

windows下:
Sql代码

1. # 在[mysqld] 中輸入
2. #log
3. log-error="E:/PROGRA~1/EASYPH~1.0B1/mysql/logs/error.log"
4. log="E:/PROGRA~1/EASYPH~1.0B1/mysql/logs/mysql.log"
5. long_query_time=2
6. log-slow-queries= "E:/PROGRA~1/EASYPH~1.0B1/mysql/logs/slowquery.log"

# 在[mysqld] 中輸入 #log log-error="E:/PROGRA~1/EASYPH~1.0B1/mysql/logs/error.log" log="E:/PROGRA~1/EASYPH~1.0B1/mysql/logs/mysql.log" long_query_time=2 log-slow-queries= "E:/PROGRA~1/EASYPH~1.0B1/mysql/logs/slowquery.log"

开启慢查询
long_query_time =2 --是指执行超过多久的sql会被log下来,这里是2秒
log-slow-queries= /usr/local/mysql/log/slowquery.log --将查询返回较慢的语句进行记录

log-queries-not-using-indexes = nouseindex.log --就是字面意思,log下来没有使用索引的query

log=mylog.log --对所有执行语句进行记录

日志的存放:默认情况下,当开启时,所有的日志都存放在DataDir目录下. 如果没有指定名称的话,它会以后主机名为名称. 如主机名为songcomputer,则相关就的日志为songcomputer.log文件.

Mysql日志的关闭与开启:

使用以下命令查看是否启用了日志 :mysql>show variables like 'log_%’; 

凡Value值为OFF的表示未开启服务,若要开启只需要将上的my.ini配置信息写入(my.ini为mysql安装目录下),然后去掉前面的“#”
号,再重启mysql服务。OK,现在会看到指定的日志文件已创建。相反地,若要停止mysql日志服务,只需要将my.ini中对应的配置信息去掉即
可。

>>>>相应的使用慢日志查询

手动的去读取慢日志以及修改慢日志的时间 show variables like 'long%' 会得到慢日志的时间

进行设置慢日志的值 set long_query_time =2 侧重的二进制文件

二进制日志:

从概述中我可以看到my.ini配置信息的log-bin没有指定文件扩展名,这是因为即使你指定上扩展名它也不使用。当mysql创建二进制日志文件
时,首先创建一个以“mysql_log_bin”为名称,以“.index”为后缀的文件;再创建一个以“mysql_log_bin”为名称,以
“.000001”为后缀的文件。当mysql服务重新启动一次以“.000001”为后缀的文件会增加一个,并且后缀名加1递增;如果日志长度超过了
max_binlog_size的上限(默认是1G)也会创建一个新的日志文件;使用flush
logs(mysql命令符)或者执行mysqladmin –u –p flush-logs(windows命令提示符)也会创建一个新的日志文件。

既然写入的都是二进制数据,用记事本打开文件是看不到正常数据的,那怎么查看呢?

使用BIN目录下mysqlbinlog命令,如:

Bin>mysqlbinlog d:/mysql_log/mysql_bin.000001

Bin>mysqlbinlog d:/mysql_log/mysql_bin.000002

Bin>mysqlbinlog d:/mysql_log/mysql_bin.000003

Bin>mysqlbinlog d:/mysql_log/mysql_bin.000004

Bin>mysqlbinlog d:/mysql_log/mysql_bin.000005

使用SQL语句也可查看mysql创建的二进制的文件目录:Mysql> show master logs; 

查看当前二进制文件状态:mysql> show master status;  

至于准确的看懂日志文件,还需要读者仔细阅读,深深体会,这里就不再奥述了!

1110月/13

互联网广告千亿市场模式演进

发布在 邵珠庆

对于中国互联网广告行业来说,2013年很可能是突破1000亿元市场规模的标志型年份,同时也可能是广告模型演进的重要一年。在大数据概念下,由DSP(需求方平台)开始拓展的一整套互联网广告模式正在中国市场渗透。

其中,以RTB(实时竞价)模式最能体现互联网功能性的改进,然而几位走访的从业者均认为,RTB模式短期内还无法成为国内市场主流。

虽然2012年被成为中国互联网广告市场的DSP元年,但按照艾瑞的估算,2012年中国RTB广告在展示广告中比重为2%,预计2013年将占比3.9%,而2016年才会达到18.8%。

即使是这样,新的模式依然带来了新的市场竞争。除了易传媒、悠易互通、品友互动、MediaV等新兴的第三方公司开始积极崛起外,百度、阿里、腾讯等巨头都开始了新模式下的布局。

广告模式需求下诞生的新模式

互联网广告开始走向技术时代。而这个变化中改变最多的是中间商和广告平台,而对用户相对隐形。

先简单说说互联网广告的发展过程。在最初的时候,一家网站出售自己的某个广告位,需要一个销售人员,直接去游说有宣传需要的企业做投放,然后双方商议价格然后做投放,投放一般是按天来计算。

在多个网站广告位和多个投放需求的情况下,中间的平台机构就有了价值,主要是4A公司这样的公司代理企业来统一投放广告,网站就只需要找投放代理公司来完成销售。这样的中间平台包括好耶等都成为了主流的平台商。

但怎么选网站广告位、选到的位置是否有档期、价格是否合适,这放在以前需要各家报上来,然后一一挑选,但又很容易出错,于是DSP平台和供应方平台SSP开始出现。

将所有潜在的广告位、价格、排期整体放在一个平台上,需求方可以实时投放。这样的平台主要偏向需求方平台即DSP。艾瑞统计数据,2012年中国市场通过DSP投放的互联网广告规模约9.1亿元,预计到2016年DSP市场整体规模将达到245.7亿元。

而在DSP平台的使用中,RTB是更有互联网特性的模式,也更符合大数据的概念。这个2009年诞生在美国的模式,可以让多个广告主通过平台掌握百万个广告位的实时竞价,并通过用户的特性最大化提升广告效果。

打个比方,多数用户喜欢在晚上9点逛淘宝看鞋,那么卖鞋的企业可以在RTB平台上选择这一时间段,选择自己能送货的片区、选择鞋类的广告推荐位,然后根据用户特性推荐不同的鞋。

这是基于IP、cookie等互联网浏览用户数据实现的技术型精准营销。

DSP的火爆和RTB的萌芽

一个来自美国的数据显示,80%广告购买开始向新模式转移,而更多的用户尝试过RTB购买,而这个数字在国内只有8%。这也是由于中国新广告模式还在成长期所致。

从2012年品友拿出DSP平台开始,一批创业公司开始了DSP领域的探索。而在2013年,亿玛、品友互动、传漾科技、新数网络、悠易互通、易传媒等数十家国内广告营销公司先后发布了各自DSP争相进入该领域。

一位从业者表示,DSP的竞争最终取决于技术和资源。在早期,一个平台是否能顺利运行取决于技术,而之前在行业中资源的积累也决定了这个平台是否有价值。

在这样的环境中,各个公司的平台都有自己的积累。亿玛最早的积累就是早期的数据,因为自己之前的广告联盟业务,有着海量的数据。而品友做得早,也一直在不断强调自己的算法、模型分析等技术优势。易传媒则表示,由于公司和4A广告公司的深度合作,更切合需求方。

平台做出来后,投放企业愿意接入平台使用才是整个商业模式成立的闭环。但目前来说,多数广告主还是在实验性的投放,平台本身的质量、技术能力也在接受考验。

与DSP的火爆相比,RTB还在早期的萌芽中。虽然RTB模式更具改革潜力,但大部分接受采访的从业者均表示RTB距离火爆还早。

问题还是之前的两个方面。在技术上,RTB要做到有效提高广告投放的ROI,就需要对海量用户数据进行系统性的分析,但目前鲜有能做到足够细化的技术。另一方面是资源,在RTB以分钟为单位的投放中,中国互联网中最好的一些广告位还没有开始接受新的模式。

在精准广告的定义中还有cookie使用是否符合个人信息安全的问题。这个首先由Google去推动的广告模型在中国的生根发芽需要更好的时机。

移动App潮流加快演进

和传统互联网广告对新模式的接受速度相比,移动平台明显在更快的拥抱新鲜事物,这也让第三方企业更快的拥抱移动时代。

这样的机会除了大量无法直接卖钱的工具性App外,手游的热潮也成了另一个推进器。

好耶产品副总裁徐国洪表示,今年公司成立了移动部门,相对独立做移动DSP平台,这也是广告代理模式向广告技术转变的步伐。而品友、力美科技也是最早在移动DSP中研发的企业之一。

海量Apps的推广位都相对较小,单个销售无法达到大型网站的整体品牌溢价,而移动DSP的推广能更精准送达用户,比如在相同类别游戏中、相似地域和偏好的App中。

除了广告位的模式更容易被认可外,移动广告增长空间也是DSP平台争夺的原因。因为用户在移动端的使用时间超过PC端是一个整体趋势,而三到五年后,移动广告就可能会超过PC,早期布局也是主要目的。

然而移动DSP现阶段对广告主的挑战更大。一方面是移动广告展示位小,对用户体验伤害较大,用户不愿意去点击广告,另一个方面是整个移动广告绝大多数还是横幅模式,非常传统,可操作空间很小。

巨头的跟随演进法

除了投放企业要接入DSP外,优质广告位对DSP的接受才是加快新模式发展的根本动力。而这些优质广告位的拥有者在国内正是多家互联网巨头。

首先是接入。以媒体为主要业务的门户已经开始了对DSP、RTB概念的接受,一些DSP平台也在开始出现主流的广告位,虽然比例还不大。巨头选择接入的原因主要还是看到增长速度,传统卖Banner类的广告业务增长开始放缓,而是否全力支持新模式又要看新模式在整体上是否能带动收入。

同时,一部分有平台型产品的公司在自己做内部平台。这就需要有大量可推荐的广告资源。截至目前,阿里妈妈、腾讯、新浪、百度等互联网企业都已相继推出广告交易平台。从卖流量到卖用户,百度等巨头的前期尝试还是改造传统的联盟业务。

最后是收购。今年以来,百度、京东、阿里等公司与多家广告公司传出收购绯闻,如易传媒、好耶、品友等,这些公司在DSP上的技术、资源积累是巨头看上的主因,虽然目前没有实质动作,但资本运作是巨头的主要优势。

210月/13

MVP,让决策更快

发布在 邵珠庆

彼得·德鲁克有句话很经典:“公司存在唯一的理由是提供价值。”赚钱,是让公司长期发展的必要条件。如何赚钱,需要符合三个条件:第一,公司的存在一定是某种需求的产物;第二,公司一定有方式去解决这个需求;第三,通过解决这个需求能够赚钱,这也就是所谓的商业模式。
    在英文中,Lean(精益)的本义是“很有肌肉,但不胖”。精益创业的核心概念是希望用最高效的资源和最快的时间,去验证产品与需求解决之间是否匹配,其 中最有效的工具是MVP(minimum viable product), 即最小可执行产品。对于创业企业来说,就一些新产品进行小范围的实验并得到可验证的结果,再快速地复制推广,这是很有效的做事哲学和思维方式。

    精益就是做减法

    大众点评网创立至今8年,我曾说自己是非常用户导向的,但真正去跟用户交流的时间并不是特别多。过去人们都说公司战 略要聚焦,功能越少越好,但说起来容易做起来难,很多功能砍不掉,外部多种需求也去不掉。但接触到精益的概念之后,我们用了一年多的时间,将精益的概念导 入到很多产品的技术中。比如,MVP的核心是希望能够用一个最简单的方案去满足最核心的需求,而且希望整个过程花的精力越少越好,这其实是一个做减法的过 程。
    其次,在解决方案上面需要一些创意,MVP往往希望时间短、投入少,所以有些方案并都不一定是很高科技的。譬如苹果的Siri语音系统刚出来的时候,后台 有很多印度人在人工接电话,因为一开始要做到云识别技术的难度挺大,而苹果公司并不知道用户有没有这类需求。在尚未证明需求量的情况下,就开发出一个语音 识别的技术,很可能是一种金钱和时间的浪费,而苹果公司用人工替代,看上去挺初级反而是更有效的。
    所谓解决方案的创新性,就是指这种能让人眼前一亮的做法。与此同时,创业者也要明确对产品阶段MVP的判断,明白究竟想验证什么。比如Siri想验证的就 是用户愿不愿意通过这个界面去交互,量有多大,值不值得后续一系列语音识别技术的投入。通过MVP的实验获得的数据,可以使得后续产品的决策更快一些。

    “不做”与“做”同样重要

    当然,极简和极致绝对不是说MVP等同于简单、粗糙,MVP要求企业做得更加专注、极致,再通过不断的迭代更新和改 进,将产品体验做到完美。就像我刚创办大众点评网时,关心的是有多少用户在写点评,而不是有多少用户在看这个网站。所以我不会一开始就大做营销,也不太关 心流量。因此,了解自己做哪些,不做哪些很重要。
    很多团队都会问老板要资源,我有时候会故意不给,因为资源往往很害人。资源一多,做事就很难专注,更重要的是资源一定得可控。很多创业公司,产品还没做起 来就想做营销,想要用户量,为了用户量马上开始投广告以促进业务增长。但此时产品的核心问题可能都没有解决:用户要不要这个产品、用户的转化率到底怎么 样、对你的产品满意吗……这些问题都还没有答案,这是个挺大的误区。企业应该想清楚资源的用处,是为了让产品体验更好,还是纯粹为了增加用户?两者一定要 分开。
    经过一年多的应用,精益的思想在大众点评网的应用,已经不仅仅限于产品创新,而是慢慢形成了一种“以用户为中心,以需求为中心”的思想。这种思想不仅应用 在职能部门,对待企业内部的客户也特别有效。通过定期检测员工对行政部门的满意度并实施管理改进。一年以来,员工对行政的满意度增加了10%左右,如今, 财务、HR部门对精益的认可度也非常高。
Q&A
    张远(北京梦之窗数码科技有限公司CEO):
    精益创业特别强调数据指导,您怎么看待数据指导和企业文化之间的关系?张涛:我们也曾经从不调研发展为过度依赖调研,以至于感觉不做调 研就无法决策。但实际上,这些都是工具,企业核心目的是要知道用户要什么。工具本身没有好坏,很多情况下企业应该通过数据做决策,但如果任何决策都围绕数 据也是有问题的。数据跟用户体验的关系是不同层面的,只看交易额数据而不看用户体验的决策,与重视用户转化率得出的决策可能就不一样。所以要重视数据跟用 户体验之间的有机关系,活学活用。

    邵羽南(深圳市同益实业股份有限公司董事长):
    在精益创业中,如何评估产品经理的能力对结果的不同影响? 张涛:选人非常重要。产品经理的经验、感觉、做事的方法是不是系统,能不能 接受人家提出的意见,决定了MVP的成败。人的因素甚至占到七八成。精益创业的道理很容易理解,难就难在如何做。作为产品经理,个人的学习能力很重要。我 们用MVP的方式做过很多项目,但结果各有千秋,这与产品经理的个人能力完全相关。

    耿军(深圳市聚橙网络技术有限公司董事长兼CEO):
    作为一个垂直行业里做得非常成功的公司,你会考虑把公司卖掉吗? 张涛:卖公司这件事情跟赚钱一样,没什么对错,该卖的时候就是要卖, 但更多要取决于公司本身该不该卖。比如搜狗,产品非常好,但行业格局决定了它不可能成为老大,在这种情况下兼并就是一种好的出路。卖与不卖不应该是一个感 情问题,而是一个理性思考:企业的行业发展趋势在哪里?创始人应该做自己擅长做的事情,这也是对公司最大的责任。卖和不卖都有各自的道理,但我反对为了出 售企业而创业。

    吴太兵(深圳万兴信息科技股份有限公司董事长兼总裁):
    任何一种管理方法都需要天时、地利、人和。为什么最近精益创业的思想备受关注?二三十年前开发产品时,为什么没有像今天这样去做?张 涛:精益生产源自丰田。当时的汽车竞争越来越激烈,研发速度越来越快。为了应对这种竞争,丰田创造了精益的模式,也就是敏捷。核心的思想是从企业有想法到 让用户拿到产品的时间越短越好。怎么缩短时间?就是不要有浪费。精益创业的出现与互联网时代的竞争速度有关,现在实在是太快了,企业不可能用传统方式去做 流水线式的研发,否则等做出来时却发现市场早已变化了。所以一定要让流程、产品的迭代非常快。

279月/13

Highcharts使用指南

发布在 邵珠庆

摘要

Highcharts图表控件是目前使用最为广泛的图表控件。本文将从零开始逐步为你介绍Highcharts图表控件。通过本文,你将学会如何配置Highcharts以及动态生成Highchart图表。


 

目录


 

一、前言(Preface)

Highcharts是一个非常流行,界面美观的纯Javascript图表库。它主要包括两个部分:Highcharts和Highstock。

Highcharts可以为您的网站或Web应用程序提供直观,互动式的图表。目前支持线,样条,面积,areaspline,柱形图,条形图,饼图和散点图类型。

Highstock可以为您方便地建立股票或一般的时间轴图表。它包括先进的导航选项,预设的日期范围,日期选择器,滚动和平移等等。

如果想要了解更多Highcharts的信息,可以参考官网:http://www.highcharts.com

 

二、安装(Installation)

1.Highcharts沿用jQuery,MooTool以及Prototype等Javascript框架来处理基本的Javascript任务。因此,在使用Highcharts之前,需要在页面头部引用这些脚本文件。如果你使用jQuery作为基本框架,那么你需要在页面头部同时引用jQuery和Hightcharts两个文件。如下:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
<script src="/js/highcharts.js" type="text/javascript"></script>

Highcharts(Highstock)已经内置了jQuery适配器(adapter)(注:可能是jQuery框架最流行的缘故),但是并没有内置MooTool等其他javascript框架的适配器(adapter)。因此,当我们使用MooTool等其他JS框架时,需要单独引用适配器(adapter)脚本文件。如下:

<script src="https://ajax.googleapis.com/ajax/libs/mootools/1.3.0/mootools-yui-compressed.js" type="text/javascript"></script>
<script src="/js/adapters/mootools-adapter.js" type="text/javascript"></script>
<script src="/js/highcharts.js" type="text/javascript"></script>

提示: 安装Highstock过程与上述相同,除了JavaScript文件名称是highstock.js而不是highcharts.js。

 

2.在您的网页头部的脚本标签,或在一个单独的js文件,添加JavaScript代码来初始化图表。renderTo参数用来设置图表渲染的位置,一般来说是一个具有ID的DIV元素(参考第3步)。

复制代码
var chart1; // 全局变量
$(document).ready(function() {
      chart1 = new Highcharts.Chart({
         chart: {
            renderTo: 'container',
            type: 'bar'
         },
         title: {
            text: 'Fruit Consumption'
         },
         xAxis: {
            categories: ['Apples', 'Bananas', 'Oranges']
         },
         yAxis: {
            title: {
               text: 'Fruit eaten'
            }
         },
         series: [{
            name: 'Jane',
            data: [1, 0, 4]
         }, {
            name: 'John',
            data: [5, 7, 3]
         }]
      });
   });
复制代码

上述代码适用于使用jQuery作为基本框架的情况,$(document).ready()函数,表示在文档加载完成后进行相应处理。如果你使用MooTool等其他JS框架,需要使用相对应的代码来替代$(document).ready()函数。

如果你想生成HighStock图表,有一个单独的构造方法调用Highcharts.StockChart。在这些图表中,数据源是一个典型的JavaScript数组数据。其来源可以是一个单独的JavaScript文件,或者是通过Ajax调用远程服务器提供的数据。

复制代码
var chart1; // 全局变量
$(document).ready(function() {
      chart1 = new Highcharts.StockChart({
         chart: {
            renderTo: 'container'
         },
         rangeSelector: {
            selected: 1
         },
         series: [{
            name: 'USD to EUR',
            data: usdtoeur // 数组变量
         }]
      });
   });
复制代码

3.在页面中添加一个DIV元素,作为放置Highcharts图表的容器。需要为其设置ID值,与第2步rendTo参数绑定。设置的宽度和高度将作为Highcharts图表的宽度和高度。

<div id="container" style="width: 100%; height: 400px"></div>

 

4.你可以通过Highcharts.setOptions方法为Highcharts图表设置一个全局的主题(可选的)。下载包含有四个预定义的主题,如果你需要使用从这些主题,只需在 highcharts.js 后引用这些文件。比如:

<script type="text/javascript" src="/js/themes/gray.js"></script>

 

三、如何设置参数(How to set up the options)

Highcharts使用一个JavaScript对象结构来定义参数。选项的值可以是字符串和数字,数组,其他对象,甚至是函数。当您初始化使用新Highcharts.Chart的图表,options对象将作为第一个参数传递。

如果你想在同一个页面上使用一组参数,可以定义一个选项对象(options object)来设置选项。更多内容参考#4预处理选项(Preprocessing the options)。

 

四、预处理参数(Preprocess the options)

了解配置对象(configuration object)的工作原理,以及如何用程序来实现,对于实现高效的Highcharts图表显得十分重要。下面将介绍JavaScript对象的基本知识点:
  • 在上面的例子中,Highcharts options被定义为对象字面值(object literals)。通过这种方法来标记配置,我们可以的到一个清晰的,可读性强的,占用空间低的配置对象。下面这种复杂的代码对于C程序员来说可能比较熟悉:
复制代码
// 不良的风格
var options = new Object();

options.chart = new Object();
options.chart.renderTo = 'container';
options.chart.type = 'bar';

options.series = new Array();
options.series[0] = new Object();
options.series[0].name = 'Jane';
options.series[0].data = new Array(1, 0, 4);
复制代码
对于JavaScript程序员来说,我们更喜欢使用下面的风格。需要注意的是,两种实现方式的结果是完全相同的。
复制代码
// 良好的风格
var options = {
    chart: {
        renderTo: 'container',
        defaultSeriesType: 'bar'
    },
    series: [{
        name: 'Jane',
        data: [1, 0, 4]
    }]
};
复制代码
  • 在创建命名的对象后,我们可以通过.操作符来扩展其成员。假设我们已经定义一个对象(见良好的风格代码)。下面代码代码将添加另一个series。请记住options.series是一个数组,因此我们可以使用push方法。
options.series.push({
    name: 'John',
    data: [3, 4, 2]
})
  • 另外一个可以排上用场的事实是,对于JavsScript对象来说,点符号(.)和方括号[]是等价的。所以,你可以通过名称来访问成员。这意味着:
options.renderTo
等价于
options['renderTo']
 

4.1 案例学习: preprocessing the data from CSV

通过这个简单的例子,我们将学会如何配置基本的参数(options),然后通过一个Ajax调用远程数据以及解析数据,最后通过合适的格式展现出来。在这个例子中,我们使用jQuery来处理Ajax请求。当然,你也可以使用MooTool或者Prototype来实现类似的功能。所有的代码在$(document).ready()函数中处理。你可以在data-from-csv.htm看到这个例子的效果。

(1)创建一个外部的仅包含数据的CSV文件(数据源)。从下面数据文件中,我们可以看到第一行列出了类别的名称(类似于字段名)。后继的行的第一个位置列出了series name(比如:第二行的'John'),随后的位置列出相关的值(value)。在实际开发过程中,我们经常使用PHP或者其他服务器端编程语言(C#,java等)来创建这个文件的内容。或者你会选择其他的标记格式,比较的常见的如XML或者JSON(JSON相对XML更加轻巧)。在这些情况下,jQuery可以解析出数据对象本身。

Categories,Apples,Pears,Oranges,Bananas
John,8,4,6,5
Jane,3,4,2,3
Joe,86,76,79,77
Janet,3,16,13,15

(2)定义基本的初始的参数。注意到,我们为categorys和series对象创建了空数组(empty arrays),稍后我们可以为其添加数据。

复制代码
var options = {
    chart: {
        renderTo: 'container',
        defaultSeriesType: 'column'
    },
    title: {
        text: 'Fruit Consumption'
    },
    xAxis: {
        categories: []
    },
    yAxis: {
        title: {
            text: 'Units'
        }
    },
    series: []
};
复制代码

(3)加载数据。我们通过jQuery的.get方法来获取数据文件.csv的内容。在success回调函数中,我们解析请求返回的字符串,并将结果添加到参数对象(options object)的categories和series成员对象中,最后创建图表。请注意,我们不能在Ajax callback外创建图表,因为我们要等待服务器返回的数据(当请求成功后,返回数据,该过程是异步的)。

复制代码
$.get('data.csv', function(data) {
    // Split the lines
    var lines = data.split('\n');
    
    // Iterate over the lines and add categories or series
    $.each(lines, function(lineNo, line) {
        var items = line.split(',');
        
        // header line containes categories
        if (lineNo == 0) {
            $.each(items, function(itemNo, item) {
                if (itemNo > 0) options.xAxis.categories.push(item);
            });
        }
        
        // the rest of the lines contain data with their name in the first position
        else {
            var series = {
                data: []
            };
            $.each(items, function(itemNo, item) {
                if (itemNo == 0) {
                    series.name = item;
                } else {
                    series.data.push(parseFloat(item));
                }
            });
            
            options.series.push(series);
    
        }
        
    });
    
    // Create the chart
    var chart = new Highcharts.Chart(options);
});
复制代码

4.2 加载XML数据

从XML文件加载数据与加载CSV文件类似。Highcharts不能处理预定义的XML数据(只能处理数组)。因此,整个过程由你来编写XML数据,并为它定义一个解析函数。相对于CSV文件来说,XML的最大缺点是,它增加了一些标记数据(这也是选择JSON的缘故)。使用XML的好处在于,至少对于小量的数据来说,你不必要手动解析返回的数据。你可以使用jQuery现有的DOM解析能力来访问XML数。你可以在data-from-xml.htm看到实例,数据包含在data.xml

 

五、活动图(Live Charts)

尽管我们已经通过配置对象(configuration object)定义图表,然后选择性地预处理(optionally preprocessed),最后通过new Highcharts.Chart()初始化和渲染图表,我们仍然有机会通过API来改变图表。chart,axis,series以及point对象有许多方法,比如update,remove,addSeries,addPoints等等。完整的列表可以查看API参考(the API Reference)下方法和属性。

5.1 案例学习:a live connection to the server

下面的例子将展示怎样构建一个活动的图表(live chart)通过每一秒种从服务器检索的数据。首先,我们要建立自定义函数requestData,它开始在图表加载事件(load event)中调用,随后在Ajax回调函数success中调用。你可以在live-server.htm中看到结果。

1.建立服务器。在这个例子中,我们选择PHP作为服务器脚本语言返回包含时间(time)以及y值(y value)的javascript数组。下列为live-server-data.php文件的代码:

复制代码
 1 <?php
 2 // Set the JSON header
 3 header("Content-type: text/json");
 4 
 5 // The x value is the current JavaScript time, which is the Unix time multiplied by 1000.
 6 $x = time() * 1000;
 7 // The y value is a random number
 8 $y = rand(0, 100);
 9 
10 // Create a PHP array and echo it as JSON
11 $ret = array($x, $y);
12 echo json_encode($ret);
13 ?>
复制代码

2.定义全局变量。需要强调的是,这里必须定义chart全局变量,因为在document ready函数以及requestData函数均要访问。

1 var chart; // global

3.实现requestData函数。在这个例子中使用jQuery中$.ajax函数来处理ajax事务(你也可以用其他ajax框架来替代)。当数据从服务器成功返回后,通过addPoint方法添加点。

复制代码
 1 /**
 2  * Request data from the server, add it to the graph and set a timeout to request again
 3  */
 4 function requestData() {
 5     $.ajax({
 6         url: 'live-server-data.php',
 7         success: function(point) {
 8             var series = chart.series[0],
 9                 shift = series.data.length > 20; // shift if the series is longer than 20
10 
11             // add the point
12             chart.series[0].addPoint(point, true, shift);
13             
14             // call it again after one second
15             setTimeout(requestData, 1000);    
16         },
17         cache: false
18     });
19 }
复制代码

4.创建图表。

复制代码
 1 $(document).ready(function() {
 2     chart = new Highcharts.Chart({
 3         chart: {
 4             renderTo: 'container',
 5             defaultSeriesType: 'spline',
 6             events: {
 7                 load: requestData
 8             }
 9         },
10         title: {
11             text: 'Live random data'
12         },
13         xAxis: {
14             type: 'datetime',
15             tickPixelInterval: 150,
16             maxZoom: 20 * 1000
17         },
18         yAxis: {
19             minPadding: 0.2,
20             maxPadding: 0.2,
21             title: {
22                 text: 'Value',
23                 margin: 80
24             }
25         },
26         series: [{
27             name: 'Random data',
28             data: []
29         }]
30     });        
31 });
复制代码

 

 

来自 http://www.cnblogs.com/liuhaorain/archive/2012/01/24/2311352.html

239月/13

PHP CodeIgniter框架源码解析

发布在 邵珠庆

1.index.php :入口文件
|-->define('ENVIRONMENT')  |主要用于设置errors日志输出级别
|-->$system_path |设置系统路径
|-->设置BASEPATH、FCPATH、SYSDIR、APPPATH等    |设置路径信息变量,为加载相应文件信息准备
|-->require_once BASEPATH.core/CodeIgniter.php | 最后加载CodeIgniter.php作为总控制器

2.CodeIgniter.php加载过程,主要用于加载core核心目录下相应文件

|-->require(BASEPATH.'core/Common.php');  |加载core目录下的Common文件,见2.1解析
|-->require(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); |加载constants目录,与开发环境无关时直接使用config目录下的constants目录
|-->get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));   |设置子文件,扩展类的前缀
|-->$BM =& load_class('Benchmark', 'core');  |加载benchmark类,mark记录当前的时间
|-->$EXT =& load_class('Hooks', 'core');     |加载core目录下的Hooks钩子类
|-->$EXT->_call_hook('pre_system');  |调用_call_hook(pre_system),根据pre_system内部调用_run_hook执行钩子,在系统开始正式工作前作预处理
|-->$CFG =& load_class('Config', 'core');    |继续执行core下的Config配置文件,
|-->$CFG->_assign_to_config($assign_to_config); 
|-->|$this->set_item($key, $val);      |解析指定给config的配置文件,实质为对config[]赋值
|-->$UNI =& load_class('Utf8', 'core');      |加载了UTF-8编码类,CI_Utf8
|-->$URI =& load_class('URI', 'core');       |加载core目录的URI类,CI_URI
|-->$RTR =& load_class('Router', 'core');    |设置route路由及覆盖信息,见2.2解析
|-->_set_routing()
|-->_set_overrides()
|-->$OUT =& load_class('Output', 'core');    |实例化输出类,加载core目录下的output文件
|-->$OUT->_display_cache($CFG, $URI)         |判断是否存在页面缓存,是则输出文件
|-->$SEC =& load_class('Security', 'core');  |加载core目录下的安全处理文件
|-->$IN =& load_class('Input', 'core');      |实例化输入类,加载core目录下的input文件
|-->$LANG =& load_class('Lang', 'core');     |加载语言类
|-->require BASEPATH.'core/Controller.php';  |加载基本控制器类,见2.3解析
|-->require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';  |尝试加载扩展的自定义子类控制器
|-->include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');  |加载自定义控制器下的控制器类
|-->$BM->mark('loading_time:_base_classes_end'); |设定一个benchmark测试点
|-->$class  = $RTR->fetch_class();     |分别获取uri地址的控制器类名和方法名
|-->$method = $RTR->fetch_method();
|-->if ( ! class_exists($class)              |判断方法及类是否合理
OR strncmp($method, '_', 1) == 0
OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
)
|-->$EXT->_call_hook('pre_controller');      |处理器执行前进行预处理,并做benchmark设置
|-->$CI = new $class();                      |获取执行的控制器实例,实例化构造器
|-->$EXT->_call_hook('post_controller_constructor');  |实例化控制器类后的钩子处理
|-->if (method_exists($CI, '_remap'))
|-->$CI->_remap($method, array_slice($URI->rsegments, 2))  |如果控制器存在_remap()方法,则执行, 判断条件$CI为控制器类 
|-->else |判断方法在类当中的存在似,如果不存在,则设置
|-->call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2)); |最终传递参数供调用控制类方法
|-->$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end'); |benchmark标记时间结束点
|-->$EXT->_call_hook('post_controller');     |控制器生存周期,在控制器执行完成后执行后续操作
|-->$OUT->_display();  |输出页面进行展示
|-->$EXT->_call_hook('post_system');         |请求生存周期完成后的终结操作
|-->$CI->db->close();                        |自动关闭数据库资源

2.1 Core/Common.php加载
|-->function is_php($version)                |用于比较版本号的函数
|-->function is_really_writable($file)       |用于判断是否可以写文件,在不同的系统中可靠程度不同,
      W中通过判断is_readonly,U中如果safe_mode为开则不确定性
|-->function load_class($class, $directory = 'libraries', $prefix = 'CI_')   |用于加载目录下的PHP文件的class类
|-->foreach (array(APPPATH, BASEPATH) as $path)    |分别在application和system目录下轮循
|-->file_exists($path.$directory.'/'.$class.'.php' |找到对应的PHP文件
|-->require($path.$directory.'/'.$class.'.php');   |require加载对应的PHP文件内的类,加了前缀,此处可扩展
|-->break;    |如正确加载则退出,否则继续尝试加载文件
|-->file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php')  |自扩展的class类,如My_Test
|-->if ($name === FALSE)   |如果$name不存在,则exit()退出 ,(在自定义类加载时,此处可作为扩展点,增加边际条件)
|-->is_loaded($class);     |确类已经加载
|-->$_classes[$class] = new $name();  |加载至静态的classes数祖中,用于缓存,调用时首先从classes中获取
|-->function is_loaded($class = '')                      
|-->设置$_is_loaded数祖,参数$class不为空,判断是否存在gf $_is_loaded,否则设置
|-->function &get_config($replace = array())|用于获取Config的实例化文件
|-->static $_config;       |定义config类型
|-->$file_path = APPPATH.'config/config.php';      |确定application目录路径下定义的config.php的路径
|-->require($file_path);   |加载application/config/config.php类
|-->count($replace) > 0    |对于config.php中定义的变量,如果有replace,则逐个替代
|-->foreach ($replace as $key => $val)
|-->$config[$key] = $val;
|-->return $_config[0] =& $config;   |最后返回定义的config的结果集
|-->function config_item($item)    |配置选项,从config的数祖对象中返还特殊的配置项
|-->$config =& get_config();
|-->$_config_item[$item] = $config[$item];
|-->function show_error            |用于错误信息输出
|-->$_error =& load_class('Exceptions', 'core');    |加载Exceptions类
|-->echo $_error->show_error($heading, $message, 'error_general', $status_code);  |直接输出错误
|-->function show_404              |用于输出404页面,输出的错误信息页面可配置
|-->function log_message           |用于写日志信息
|-->$_log =& load_class('Log');
|-->$_log->write_log($level, $message, $php_error);

|-->function set_status_header     |用于输出状态的heade信息
|-->function _exception_handler
|-->function remove_invisible_characters
|-->function html_escape           |过滤HTML变量
|-->return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));

2.2Router路由信息设置
|-->_set_routing() 
|-->$segments = array()    |根据目录,控制器,函数的触发器设定segment[]的uri段值,分别fetch()方法去取对象值
|-->include(APPPATH.'config/routes.php');       |加载config下的routes文件
|-->$this->routes          |设置routes数祖值,从config的route中获取
|-->$this->default_controller       |设置routes的控制器值,从config的route中获取
|-->return $this->_validate_request($segments); |验证uri的segment合法性
|-->$this->uri->_remove_url_suffix();$this->uri->_reindex_segments();  |进一步清理解析uri,使segment从1开始x
|-->_set_overrides()  |根据$routing的值,重新设定directory、controller、function参数
|-->$this->set_directory($routing['directory']);
|-->$this->set_class($routing['controller']);
|-->$this->set_method($routing['function']);

2.3 core/Controller.php加载
|-->__construct()                                         |构造函数
|-->self::$instance =& $this;  
|-->foreach (is_loaded() as $var => $class)       |根据is_loaded()的信息加载相应的类
|-->$this->$var =& load_class($class);   
|-->$this->load =& load_class('Loader', 'core');  |加载core/Loader的php文件
|-->$this->load->initialize();                    |主要用于autoload加载信息,如libraries、database等等
|-->function &get_instance                                |返回当前实例
|-->return self::$instance

扩展点:PHP自动加载机制在CodeIgniter中的应用
1.PHP自动加载机制:PHP5后,提供了类的自动加载机制,即类在加载时才被使用,即Lazy loading,共有二种方式
1.1: __autoload()通过扩展可实现,实质为设定规则加载相应路径的PHP文件(require、include方式)
1.2: 将autoload_func指向php文件,这个一般用c语言扩展实现 
  详见:http://blog.csdn.net/flyingpig4/article/details/7286438

2.在CodeIgniter中的应用
根据上述源码分析可知:CodeIgniter中所有的操作都是以Controller为起始,只需在Cotroller加载的过程中,
使__autoload()函数自动加载即可,目前的加载方式为在application/config/config.php中设置__autoload()
函数

139月/13

jquery datepicker 中文汉化方法

发布在 邵珠庆

    <script type="text/javascript">
      jQuery(function(){
        $.datepicker.regional['zh-CN'] = {
          clearText: '清除',
          clearStatus: '清除已选日期',
          closeText: '关闭',
          closeStatus: '不改变当前选择',
          prevText: '<上月',
          prevStatus: '显示上月',
          prevBigText: '<<',
          prevBigStatus: '显示上一年',
          nextText: '下月>',
          nextStatus: '显示下月',
          nextBigText: '>>',
          nextBigStatus: '显示下一年',
          currentText: '今天',
          currentStatus: '显示本月',
          monthNames: ['一月','二月','三月','四月','五月','六月', '七月','八月','九月','十月','十一月','十二月'],
          monthNamesShort: ['一','二','三','四','五','六', '七','八','九','十','十一','十二'],
          monthStatus: '选择月份',
          yearStatus: '选择年份',
          weekHeader: '周',
          weekStatus: '年内周次',
          dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
          dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
          dayNamesMin: ['日','一','二','三','四','五','六'],
          dayStatus: '设置 DD 为一周起始',
          dateStatus: '选择 m月 d日, DD',
          dateFormat: 'yy-mm-dd',
          firstDay: 1,
          initStatus: '请选择日期',
          isRTL: false
        };
        $.datepicker.setDefaults($.datepicker.regional['zh-CN']);
        $('#datepicker').datepicker({changeMonth:true,changeYear:true});
      });
    </script>
29月/13

二十五个精美的后台管理界面模板和布局

发布在 邵珠庆

任何系统都会有一个管理后台,好看的管理后台看起来赏心悦目,管理的时候心情也舒畅,本文给大家推荐 25 个制作精美的后台管理界面的模板和布局,你值得拥有。

Free Admin Template

Web App Theme

Spring Time

Free Admin Template For Web Applications

Free Admin Template

INADMIN

Free admin skin

AdminPraise Lite

Premium Admin HTML Website Templates

MWS Admin – Full Featured Admin Template

Color life – Premium Admin Template

AdminCP

Spina – Premium Admin Template + Tablet Theme

Cupcake – Premium Admin Template + Mobile Theme

xSystem – HTML5 and CSS3 Admin Template

Mandy Lane Premium Admin Template

It’s Brain – premium admin theme

vPad – HTML5+CSS3 App Framework

Adminium – Modern Admin Panel Interface

Peach – Clean & Smooth Admin Template

Lagu Admin Premium Template

Ready Made Admin – Full Featured Admin Theme

Grape – Professional & Flexible Admin Template

Chameleon Circuit – Full Featured Admin Theme

Admin Control Panel v2

White Label – a full featured Admin Skin