常用的 jQuery 插件

自己整理的一些常用的 jQuery 的插件:

http://www.malsup.com/jquery/ [对话框插件/推荐]
http://dev.iceburg.net/jquery/jqModal/ [对话框插件]
http://www.kelvinluck.com/assets/jquery/datePicker/v2/demo/ [日历插件]
http://jquery.bassistance.de/validate/demo/ [表单验证]
http://jquery.com/demo/thickbox/ [图片层/对话框]
http://demos.flesler.com/jquery/scrollTo/ [锚点特效]
http://15daysofjquery.com/examples/jqueryEditInPlace/demo.php [div编辑]
http://www.davehauenstein.com/code/jquery-edit-in-place/example/ [div编辑&保存]
http://www.appelsiini.net/projects/jeditable/default.html [div编辑&保存]
http://www.jdempster.com/category/jquery/disableTextSelect/ [禁止鼠标选取]
http://www.phpletter.com/contents/ajaximageeditor/ajax_image_editor.php [图片放大缩小/加图解]
http://www.phpletter.com/Demo/Jquery-Floating-Box-Plugin/ [页面四角浮停DIV]
http://www.visual-blast.com/javascript/jcrop-jquery-image-crop-plugin/ [图片裁切]
http://stanlemon.net/projects/jgrowl.html [类似 163 BLOG右上角提示信息插件]
http://jquery.lukelutman.com/plugins/flash/ [Flash IE7 无虚框插件]

Posted in JavaScritp, html, jquery | Tagged | Leave a comment

怎样保存 Checkbox 值

预备知识点:

二进制数值:
0的二进制数值是   0
1的二进制数值是   1
2的二进制数值是  10
3的二进制数值是  11
4的二进制数值是 100
5的二进制数值是 101
6的二进制数值是 110
...
在 php 中可以通过 decbin() 函数将十进制数字转换为二进制数字.

位运算符 & (按位与), 什么是 & 运算呢?
以 $c = $a & $b 表达式为例, & 运算是将 $a, $b 的二进制数值相比较, 只要两个二进制数中某位都是1, 则结果的二进制数中该位都为1, 否则结果为 0.

假设:
$a 的值为 2 (十进制), 它的二进制数值为  10
$b 的值为 4 (十进制), 它的二进制数值为 100
那么 $c 为 0 (十进制) 因数 $a & $b 的结果为 000(二进制数值), 转换为十进制数值就为 0

假设:
$a 的值为 2 (十进制), 它的二进制数值为  10
$b 的值为 6 (十进制), 它的二进制数值为 110
那么 $c 为 2 (十进制) 因数 $a & $b 的结果为 010(二进制数值), 转换为十进制数值就为 2

Javascript/php/mysql 都支持 & 运算.

OK. 进入正题:
我们现在要记录用户的兴趣爱好, 兴趣爱好有很多选项, 可以复选, 表现在页面上就是一堆的 checkbox , 它看起来像是这样子的

<input type="checkbox" name="hobby[]" value="aa">爱好1 <br>
<input type="checkbox" name="hobby[]" value="bb">爱好2 <br>
<input type="checkbox" name="hobby[]" value="cc">爱好3 <br>
<input type="checkbox" name="hobby[]" value="dd">爱好4 <br>
<input type="checkbox" name="hobby[]" value="ee">爱好5 <br>
<input type="checkbox" name="hobby[]" value="ff">爱好6 <br>
<input type="checkbox" name="hobby[]" value="gg">爱好7 <br>

假设用户勾选的是 "爱好1", "爱好3", "爱好5", 我们要怎么把用户勾选的值保存到数据库呢?

方法1:

用特定的分隔符(比如,)把用户勾选的 value 值串连起来? 那么保存到数据库中的值应该是 "aa,cc,ee"
还有别的方法吗?

方法2:

保存到数据库的值是 "1010100" , 这个字串是怎么得来的呢? 设计这种方法的思想是这样的: 数据库中保存一个长度与复选框个数一样的字符串, 这个字串中的第一位就表示第一个复选框, 如果第一个复选框的勾选了, 那字串的第一位就是1. 同样的道理所以字串的第3位,第5位值为1, 其它位值为0.
还有别的方法吗?

我用的是方法3:

重新设计 checkbox 的值, 将它们设置成2的N(N>=0)次方. 它看起来像这样子:
<input type="checkbox" name="hobby[]" value="1" >爱好1 <br>
<input type="checkbox" name="hobby[]" value="2" >爱好2 <br>
<input type="checkbox" name="hobby[]" value="4" >爱好3 <br>
<input type="checkbox" name="hobby[]" value="8" >爱好4 <br>
<input type="checkbox" name="hobby[]" value="16">爱好5 <br>
<input type="checkbox" name="hobby[]" value="32">爱好6 <br>
<input type="checkbox" name="hobby[]" value="64">爱好7 <br>
而我要保存到数据库中的值是 21, 没错, 它是一个数字, 它是怎么来的呢? 1+4+16 = 21, 它就是将用户勾选的复选框 value 值累加而以.

为什么是2的N(N>=0)次方? ( 1, 2, 4, 8, 16, 32, ... )

<?php
//我们来看看它们的二进制数值有什么特点.
echo decbin(1)."<br>";   //       1
echo decbin(2)."<br>";   //      10
echo decbin(4)."<br>";   //     100
echo decbin(8)."<br>";   //    1000
echo decbin(16)."<br>";  //   10000
echo decbin(32)."<br>";  //  100000
echo decbin(64)."<br>";  // 1000000

//来看问题: 为什么要把 value 值设置为2的N(N>=0)次方?
//因为2的N(N>=0)次方数字的二进制表示一定是最左边第一位是1, 其它位是0,
//而正是这样的特性, 使得任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况.
//什么意思? 举个例子:
//1+2+4 二进制表示是 1+10+100
//1+2+3 二进制表示是 1+10+11  <-- 这样会使右边第一位,第二位出现进位

//再来看个例子
echo decbin(1+2)."<br>";     //    11
echo decbin(1+2+4)."<br>";   //   111
echo decbin(4+8)."<br>";     //  1100
echo decbin(1+4+16)."<br>";  // 10101
//结合"任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况"的特性, 很容易分析出上面例子中的规律:
//结果值的二进制数值中如果右边第一位是1, 那么结果值的十进制数值一定是 1+***
//结果值的二进制数值中如果右边第二位是1, 那么结果值的十进制数值一定是 2+***
//结果值的二进制数值中如果右边第一位是1,右边第二位也是1, 那么结果值的十进制数值一定是 1+2+***

//我们回到用户勾选爱好复选框保存到数据库中的值 21 (十进制)
//通俗点, 我们可以这样理解:
//2的N(N>=0)次方数字的和(例如21) 的二进制表示(10101), 从右至左如果第n位为1, 那它十进制一定是 2 的 n-1 次方与其它2的N(N>=0)次方数字的和
//所以 21(二进制表示为 10101) 应该是 (2的(1-1)次方)+(2的(3-1)次方)+(2的(5-1)次方) = 1+4+16

//同样根据"任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况"的特性, 结合我们已知的 & 运算, 我们能很方便的判断 任意2的N(N>=0)次方数字相加的和中是否存在一个确定的2的N(N>=0)次方数字
echo (21 & 1)."<br>";   // 1
echo (21 & 2)."<br>";   // 0
echo (21 & 4)."<br>";   // 4
echo (21 & 8)."<br>";   // 0
echo (21 & 16)."<br>";  // 16
echo (21 & 32)."<br>";  // 0
echo (21 & 64)."<br>";  // 0
?>

我们来看看页面前端 javascript 是怎么保存和还原用户勾选的选项的:
在线实例

<input type="button" value="要保存到数据库中的值" onclick="get_save_value('hobby[]')">
<input type="button" value="清除勾选" onclick="clear_all('hobby[]')"> <br>
<br>还原勾选框<br>
<input type="text" name="set_check_value" id="set_check_value"><br>
<input type="button" value='先点击 "清除勾选" 再点我' onclick="set_check('hobby[]', document.getElementById('set_check_value').value)"> <br>

<script language="JavaScript">
/* 重点 */
//还原用户的选取项
function set_check(name, value){
    var obj = document.getElementsByName(name);
    for(var i=0; i<obj.length; i++){
        if( (obj[i].value & value) == obj[i].value ){
            obj[i].checked = true;
        }
    }
}

/* 这不是重点 */
function get_save_value(name){
    var obj = document.getElementsByName(name);
    var saveValue = 0;
    for (var i=0; i<obj.length; i++){
        if (obj[i].checked){
            saveValue += parseInt(obj[i].value);
        }
    }
	document.getElementById("set_check_value").value = saveValue;
    alert(saveValue); //这个就是要存到数据表里的值
}

function clear_all(name){
    var obj = document.getElementsByName(name);
    for (var i=0; i<obj.length; i++){
        obj[i].checked = false;
    }
}
</script>

我们来看看后端数据库是查询用户勾选项的:
假设我们 tableName 中的 hobby 字段是保存用户的兴趣爱好值
一个用户一第记录, 如果前面的例子成功记录到数据库中, 那么 tableName 中应该有一条 hobby==21 的值的记录.

--要查询选择了"爱好1"或者"爱好3"的用户:
--爱好1(value=1)
--爱好3(value=4)
SQL: SELECT * FROM tableName WHERE (hobby&1) OR (hobby&4);

--要查询选择了"爱好1"并且"爱好3"的用户:
--爱好1(value=1)
--爱好3(value=4)
SQL: SELECT * FROM tableName WHERE (hobby&1) AND (hobby&4);

--要查询只选择了"爱好1"和"爱好3"的用户:
--爱好1(value=1)
--爱好3(value=4)
SQL: SELECT * FROM tableName WHERE hobby=(1+4)
Posted in JavaScritp, Mysql, PHP, html | Tagged , , , | Leave a comment

让 Apache 支持 mod_python

mod_pytho 中文文档
http://man.chinaunix.net/develop/python/mod_python/mod_python.html

1, 下载 ModPython-3.3.1 (http://www.apache.org/dist/httpd/modpython/win/3.3.1/), 安装, 安装过程中会讯问 apache 安装目录.
2, 在apache的httpd.conf中加入下面一行:

LoadModule python_module modules/mod_python.so

3, 再加入下面一段

Alias /py/ "d:/PythonCode/"
<Directory "d:/PythonCode/">
    AddHandler mod_python .py
    #PythonHandler mptest
    PythonHandler mod_python.publisher
    PythonDebug On
</Directory>

4, 在 d:/PythonCode/ 目录下新建一名为 mptest.py 的测试文件,内容如下

from mod_python import apache
def handler(req):
   req.content_type = "text/plain"
   req.write("Hello World!")
   return apache.OK

5, 通过 http://127.0.0.1/py/mptest.py 访问测试

可能会遇到的问题:


http://hi.baidu.com/javaway/blog/item/ea7401822bc491aa0cf4d2d8.html

环境:Python:2.5.4 / Apache:2.2
我安装完mod_python之后,在apache的配置文件里httpd.conf,添加了一行:
LoadModule python_module modules/mod_python.so
使得Apache加载mod_python模块
可是在我重新启动Apache时,apache却报错无法启动,看看日志:
[Fri Mar 27 15:07:49 2009] [notice] Parent: Received restart signal -- Restarting the server.
[Fri Mar 27 15:07:49 2009] [notice] Child 948: Exit event signaled. Child process is ending.
httpd.exe: Syntax error on line 127 of D:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf: Cannot load D:/Program Files/Apache Software Foundation/Apache2.2/modules/mod_python.so into server: \xd5\xd2\xb2\xbb\xb5\xbd\xd6\xb8\xb6\xa8\xb5\xc4\xc4\xa3\xbf\xe9\xa1\xa3
[Fri Mar 27 15:07:50 2009] [warn] (OS 995)由于线程退出或应用程序请求,已放弃 I/O 操作。 : winnt_accept: Asynchronous AcceptEx failed.

我又花了很长的时间来查找原因,初始时以为是字符编码问题,然后我又看看mod_python的权限,貌似没有问题。没辙,股沟了一下,在modpython的论坛中有人提出可能是因为Python安装时选择值安装到自己的账户导致的:

Please don't follow up to a different thread with a new question.
Subject now changed.

If you are running Apache as a service, it may be running as a
specific user, not the one which you installed the mod_python code as.
If this is the case, you need to make sure that the user that Apache
is running as has correct access rights to be able to read the module
file.

If this has occurred, you may also have problems with loaded module
then being able to read the installed Python code files.

Generally it is recommended that Apache, Python and mod_python all be
installed as an administrator and not as an individual user.

我不是很确定,但我记得安装Python时的确是选择了单用户,尝试重新安装Python,选择为所有用户安装,重启Apache,OK.
Posted in Apache, Python | Tagged , | Leave a comment

设置 Apache & hosts 本地开发环境

设置本地 Apache 虚拟主机 & 本地 hosts 打造和外网虚拟空间一模一样本地开发环境.

Apache 是全球而署最多的 web server
想全面了解它可以访问官方主页 http://www.apache.org/

Hosts文件是一个用于存储计算机网络中节点信息的文件,它可以将主机名映射到相应的IP地址,实现DNS的功能,它可以由计算机的用户进行控制。
Windows 中它的存放位置是: c:\windows\system32\drivers\etc\hosts
Linux 中它的存放位置是: /etc/hosts

如果你有自己的网站, 但没有自己的本地开发环境, 你想新增一个新功能, 你的操作步骤可能是这样子的:

1, 在本地(本机)把新功能开发好
2, 然后用ftp上传到自己的外网虚拟主机网站目录下
3, 在外网虚拟机空间上测试功能是否正常
4, 如果正常,OK.完成 / 但如果有错, 执行以下步骤:
5, 再修改
6, 再上传
7, 再调试
8, ... <-- 不断循环(4/5/6/7)步骤, 直到功能能正常使用.

显然这样子是费神又费力的, 而且更大的弊端是访问你的网站的用户会有可能看到你调试时的错误信息(如果你的网站有注册用户, 在你调试时十分不凑巧的被他们访问到了你的新功能而引起数据库上错误, 那麻烦就大了)

显然打造本地开发环境是十分有必要的.

前期准备工作:
在本地安装好 Apache+php+mysql , 集成安装包是个不错的选择, 推荐两款集成包:
easyphp(windows) http://www.easyphp.org/
xampp(windows/linux) http://www.apachefriends.org/

假设我们有两个网站 http://dev.kuco , http://wp.kuco 要想打造和我们外网虚拟主机上一模一样的环境
1, 我们要用到的配置 apache 虚拟主机

#将下面内容添加到 Apache 配置文件 httpd.conf 最底端:
#主机ip:端口
NameVirtualHost *:80            

#第一个虚拟主机
<VirtualHost *:80>
ServerAdmin webmaster@dev.kuco
DocumentRoot D:\home\dev.kuco     #指定虚拟主机网站根目录
ServerName dev.kuco               #虚拟主机域名
  <Directory "D:\home\dev.kuco">
  AllowOverride All               #允许rewrite
  </Directory>
</VirtualHost>

#第二个虚拟主机
<VirtualHost *:80>
ServerAdmin kuco@wp.kuco
DocumentRoot D:\home\wp.kuco
ServerName wp.kuco
  <Directory "D:\home\wp.kuco">
  AllowOverride All
  </Directory>
</VirtualHost>

2, 设置本地 hosts

# 如果要访问外网虚拟主机, 在相应的记录行首加上 # 注释掉就可以了
127.0.0.1  dev.kuco   # http://dev.kuco 本地测试环境
127.0.0.1  wp.kuco    # http://wp.kuco  本地测试

3, 将外网虚拟主机网站目录上的程序下载到本地虚拟主机的相应目录
4, 在本地数据库建立好相应的数据库

OK, 我们配置好啦, 现在访问 http://dev.kuco, http://wp.kuco 都会直接访问我们本机上的文件啦.
我们再来看看要新增一个新功能, 我们的操作步骤吧:

1, 在本地(本机)把新功能开发好
2, 直接在本地上测试功能是否正常
3, 如果正常,OK.跳到第*步 / 如果有错, 执行以下步骤:
4, 再修改
5, 再调试
6, ... <-- 不断循环(3/4/5/6)步骤.
*, 将 hosts 中本地测试环境注释掉, 然后再用ftp将程序上传到自己的虚拟主机网站目录下, 完成!
Posted in Apache | Tagged , | Leave a comment

用 jsScrolling 美化你的滚动条

系统自带的滚动条样式设置好像是块硬骨头, 我们只能设定它的边框颜色/背景颜色/3D边框等一些最最最基本的样式, 这对于想要做出一流页面的我们来说简直太简陋了! 做漂亮的页面梦想要破灭了么? NO! jsScrolling 能帮我们来啃掉这块硬骨头~

jsScrolling 能利用 javascript 和 css 来模拟系统滚动条, 达到我们自定义滚动条的目的.
(美中不足的是 jsScrolling 只能模拟垂直滚动条, 暂不支持水平滚动条, 但实际上水平滚动条出现的几率是很小的)

官网地址: http://www.n-son.com/scripts/jsScrolling/index.html
下载地址: http://www.n-son.com/scripts/jsScrolling/jsScrolling.zip
这里面会有简介文件/DEMO/JS文件(压缩&未压缩过的)

jsScrolling 它包括两个部分 jsScroller.js 和 jsScrollbar.js

jsScroller.js 是用来控制内容滚动的, 一个简单的例子
(你可以在这里看到效果 1.html):

<!--
一个最基本的代码结构包括:
1, 默认的样式
2, JS初始化
3, HTML代码格式

注意:
1, 默认css样式必须要有
2, css 样式名不能修改
3, html 代码结构不能修改
-->

<style type="text/css">
.Scroller-Container-Parent{position:relative; width:100px; height:100px; overflow:hidden;}
.Scroller-Container {position: absolute;}
</style>

<script type="text/javascript" src="js/jsScroller.js"></script>
<script type="text/javascript">
var scroller = null;
window.onload = function () {
    scroller = new jsScroller(document.getElementById("div_content"), 350, 100);
}
</script>

<img src="img/up_arrow.gif" onmouseover="scroller.startScroll(0, 5)" onmouseout="scroller.stopScroll()" />
<img src="img/down_arrow.gif" onmouseover="scroller.startScroll(0, -5)" onmouseout="scroller.stopScroll()" />

<div id="div_content" class="Scroller-Container-Parent">
    <div class="Scroller-Container">
        内容...
    </div>
</div>

上面的例子效果似乎没有感觉到滚动条的气息, 那我们来看看 jsScrollbar.js 吧, 一个常见的应用实例
(你可以在这里看到效果 2.html):

<!--
同样要注意的是默认 css 样式和 html 代码结构不能修改. 实例中会有自定义样式, 可以直接在源码里看得到.
(.Scrollbar-Container / .Scroller-Container-Parent 这两个样式是我自己定义的, 这样能更加方便我们去定义自义样式)
-->
<style type="text/css">
.Scrollbar-Container{position:absolute; height:230px; top:0px;}
.Scrollbar-Container .Scrollbar-Up{position:absolute; cursor:pointer; width:30px; height:30px; background-color:#6600FF;}
.Scrollbar-Container .Scrollbar-Down{position: absolute; cursor:pointer; width:30px; height:30px; background-color:#6600FF; top:200px;}
.Scrollbar-Container .Scrollbar-Track{position:absolute; width:30px; height:170px; top:30px;}
.Scrollbar-Container .Scrollbar-Handle{position:absolute; width:30px; height:30px; background-color:#FF0000;}
.Scroller-Container-Parent{position:relative; width:100px; height:100px; overflow:hidden;}
.Scroller-Container {position: absolute;}
</style>

<script type="text/javascript" src="js/jsScroller.js"></script>
<script type="text/javascript" src="js/jsScrollbar.js"></script>

<script type="text/javascript">
var scroller1 = scrollbar1 = scroller2  = scrollbar2 = null;
window.onload = function () {
    //第一个
    scroller1  = new jsScroller(document.getElementById("div_content_1"), 400, 200);
    scrollbar1 = new jsScrollbar(document.getElementById("div_scrollbar_1"), scroller1, false);

    //第二个
    scroller2  = new jsScroller(document.getElementById("div_content_2"), 400, 200);
    scrollbar2 = new jsScrollbar(document.getElementById("div_scrollbar_2"), scroller2, false);
}
</script>

<!-- 1 -->
<div style="position:relative;">
<div id="div_scrollbar_1" class="Scrollbar-Container">
    <div class="Scrollbar-Up"></div>
    <div class="Scrollbar-Down"></div>
    <div class="Scrollbar-Track"><div class="Scrollbar-Handle"></div></div>
</div>
<div id="div_content_1" class="Scroller-Container-Parent">
    <div class="Scroller-Container">
        内容...
    </div>
</div>
</div>
<!--// 1 -->

<!-- 2 -->
<div style="position:relative; margin-top:20px;">
<div id="div_scrollbar_2" class="Scrollbar-Container">
    <div class="Scrollbar-Up"></div>
    <div class="Scrollbar-Down"></div>
    <div class="Scrollbar-Track"><div class="Scrollbar-Handle"></div></div>
</div>
<div id="div_content_2" class="Scroller-Container-Parent">
    <div class="Scroller-Container">
        内容...
    </div>
</div>
</div>
<!--// 2 -->

OK, 看完这些应该足以满足我们日常工作啦, 如果想了解更多, 去官网溜达溜达吧~
赶快去设计属于你自己的滚动条吧~

Posted in Css, JavaScritp, html | Tagged , , | Leave a comment

linux常用命令

部分参考自这里

#[ 目录/文件 ]################################
#切换目录
cd /home/kuco/  #切换到 /home/kuco/ 目录
cd ..           #切换到上一级目录
cd ~            #切换到当前用户的家目录
cd              #切换到当前用户的家目录

#显示目录文件
ls              #显示当前目录文件列表
                # 可带参数:
                # -a 列出全部文件,包括隐藏文件(文件名以.开头的文件)
                # -l 详细列表

#创建目录
mkdir dirname

#删除目录
rm -rf dirname  # -r 递归处理
                # -f 强制删除(不显示确定删除提示对话)
rm -ri dirname  # -i 显示确定删除提示框(推荐带上此参数)

#复制
cp -r dirname1 dirname2   # 将 dirname1 复制到 dirname2 中
                          # 执行结果 ./dirname2/dirname1/*
cp -r dirname1/* dirname2 # 推荐这样写

#移动/重命名
mv filename1 filename2     # 将 filename1 重命令为 filename2
mv -r dirname1/* dirname2/ # 将 dirname1 下面的文件称动到 dirname2 中

#查看文本内容
cat filename     # 显示 filename 全部第1行到第N行的内容
tac filename     # 显示 filename 全部第N行到第1行的内容, 逆向显示
more filename    # 一屏一屏的显示内容, 回车翻页
less filename    # 显示内容, 可用k/j上下翻动, q退出
head -3 filename # 只显示 filename 前3行的内容
tail -3 filename # 只显示 filename 最后3行的内容
tail -f filename # 实时监视 filename 最后10行内容(常用于查看日志)
sed -n '5,10p' filename     #显示 filename 第5行到第10行的内容
head -3 filename | tail -1  #查看 filename 第3行内容

#统计文本文件行数
wc filename      # 行数(-l),字数(-w),字节数(-c)

#查找命令位置
whereis php      # 查找 php 程序目录

#按文件名查找
find /root -name test.* # 在 /root 目录下查找文件名为 test.* 的文件

#在文件内部查找
grep -r "aaaa" /root/*  # 在 /root 目录下查找内容包含有 "aaaa" 字串的文件

#[ 系统 ]################################
top    # 显示,管理执行中的程序
free   # 内存使用和swap空间使用情况
ps     # 查看进程
whoami #查看当前登录用户名

#切换用户
su kuco #切换到 kuco 用户
su      #切换到 root 用户

#新建一个 www 组
groupadd www

#删除 www 分组
groupdel www

#在 www 组里新建一个 wwwuser 用户
adduser -g wwwuser www

#删除用户
userdel username

#修改 username 用户的密码
passwd username

#修改 www 用户密码
passwd www

#修改 dirname 目录下所有文件拥有者改为 www 组下的 wwwuser 用户
chown -R wwwuser:www dirname

#修改 dirname 目录下所有文件权限为可读可写可执行
chmod -R 777 dirname

#[ 管道 ]################################
# 管道:把上一个命令执行的结果交给下一个命令
#      命令1|命令2|命令3......|命令n
ls -Rl /etc | more   #分页(more)显示(ls -Rl /etc)结果
cat /etc/passwd | wc #显示文件结果, 再显示(wc)结果
ls -l | grep "abc"   #只显示 ls 结果只含有 "abc" 的文件/目录

#[ 应用 ]################################
#解压 abc.tar.gz 到 /opt 目录下
tar -xvfz abc.tar.gz -C /opt

#压缩 /home/kuco 为 /root/kuco.tar.gz
tar -zcvf /root/kuco.tar.gz /home/kuco

#将程序运行结果保存到文件中
ls > filename  #将 ls 的执行结果保存到 filename 中
ls >> filename #将 ls 的执行结果追加保存到 filename 中

#[ 其它 ]################################
#系统
uname -a                #查看内核/操作系统/CPU信息
head -n 1 /etc/issue    #查看操作系统版本
cat /proc/cpuinfo       #查看CPU信息
hostname                #查看计算机名
lspci -tv               #列出所有PCI设备
lsusb -tv               #列出所有USB设备
lsmod                   #列出加载的内核模块
env                     #查看环境变量
service network restart #重启网卡命令

#资源
free -m                #查看内存使用量和交换区使用量
df -h                  #查看各分区使用情况
du -sh 目录名           #查看指定目录的大小
grep MemTotal /proc/meminfo   #查看内存总量
grep MemFree /proc/meminfo    #查看空闲内存量
uptime                 #查看系统运行时间、用户数、负载
cat /proc/loadavg      #查看系统负载

#磁盘和分区
mount | column -t      #查看挂接的分区状态
fdisk -l               #查看所有分区
swapon -s              #查看所有交换分区
hdparm -i /dev/hda     #查看磁盘参数(仅适用于IDE设备)
dmesg | grep IDE       #查看启动时IDE设备检测状况

#网络
ifconfig               #查看所有网络接口的属性
iptables -L            #查看防火墙设置
route -n               #查看路由表
netstat -lntp          #查看所有监听端口
netstat -antp          #查看所有已经建立的连接
netstat -s             #查看网络统计信息

#进程
ps -ef                 #查看所有进程
top                    #实时显示进程状态

#用户
w                         #查看活动用户
id 用户名                  #查看指定用户信息
last                      #查看用户登录日志
cut -d: -f1 /etc/passwd   #查看系统所有用户
cut -d: -f1 /etc/group    #查看系统所有组
crontab -l                #查看当前用户的计划任务

#服务
chkconfig --list              #列出所有系统服务
chkconfig --list | grep on    #列出所有启动的系统服务

#程序
rpm -qa                #查看所有安装的软件包
Posted in Linux, Tips, shell | Tagged , | Leave a comment

Mysql 事务简介

什么是事务?
通俗点来说, 事务就是对一组由N条SQL语句(N>=1)组成的逻辑处理单元进行并发控制. 当这组SQL语句都执行成功时才会对数据库构成实际影响. 否则只要有一条SQL语句执行失败, 那么整组SQL都不会执行成功, 都不会对数据库有实际影响. 这样能确保这个事务中的这组SQL操作的统一性, 保证数据一致性.

我们来结合实际的例子来理解事务的概念:

-- 在 phpMyAdmin 中执行下面的操作
-- 1, 建立不支持事务的数据表 tbl_a
CREATE TABLE IF NOT EXISTS `tbl_a` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `val` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 ;

-- 2, 为 tbl_a 插入数据, 将下面 4 条语句全部复制, 用 phpMyAdmin 一并执行
INSERT INTO tbl_a (val) VALUES ('a');
INSERT INTO tbl_a (val) VALUES ('b');
INSERT INTO tbl_a (vals) VALUES ('c'); -- 因为表中没有 vals 这个字段, 执行到这句时会报错.
INSERT INTO tbl_a (val) VALUES ('d');  -- 因为程序已经中断, 这句不执行

-- 3, 我们来看看 tbl_a 中的数据, 会发现有两条数据.
SELECT * FROM tbl_a;
--   +----+-----+
--   | id | val |
--   +----+-----+
--   |  1 | a   |
--   |  2 | b   |
--   +----+-----+
--   很好理解: 因为我们四条语句一并提交, mysql 还是会一条一条的执行:
--   执行第一句, 没有ERROR, 对数据库产生实际影响, 将 'a' 真真实实的插入到 tbl_a 中
--   执行第二句, 没有ERROR, 对数据库产生实际影响, 将 'b' 真真实实的插入到 tbl_a 中
--   执行第三句, 因为没有指定的字段, 抛出ERROR, 程序中断执行.

接下来我们再看看事务是怎么处理的:

-- 在 phpMyAdmin 中执行下面的操作
-- 1, 建立支持事务的数据表 `tbl_b`
CREATE TABLE IF NOT EXISTS `tbl_b` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `val` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 ;

-- 2, 为 tbl_b 插入数据, 将下面 4 条语句全部复制, 用 phpMyAdmin 一并执行
begin; -- 开启一个事务
INSERT INTO tbl_b (val) VALUES ('a');
INSERT INTO tbl_b (val) VALUES ('b');
INSERT INTO tbl_b (vals) VALUES ('c'); -- 报错
INSERT INTO tbl_b (val) VALUES ('d');
commit;

-- 3, 我们来看看 tbl_b 中的数据, 会和 tbl_a 中的数据有什么差别呢?
SELECT * FROM tbl_b;
--   Empty set (0.00 sec)
--   一条数据也没有, 哈. 这就是事务与非事务的区别,
--   因为在事务中遇到了一个错误, 所整个事务中的 SQL 语句都不会对数据库构成实际影响

OK. 现在对事务有了形像的认识之后我们再来结合其它的例子进一步学习事务:

-- 在 phpMyAdmin 中执行下面的操作
-- 1, 清空 tbl_b 记录
TRUNCATE TABLE `tbl_b`

-- 2, 为 tbl_b 插入数据, 将下面 4 条语句全部复制, 用 phpMyAdmin 一并执行
-- begin; -- 注意没有执行 begin
INSERT INTO tbl_b (val) VALUES ('a');
INSERT INTO tbl_b (val) VALUES ('b');
INSERT INTO tbl_b (vals) VALUES ('c'); -- 报错
INSERT INTO tbl_b (val) VALUES ('d');
-- commit;

-- 3, 我们来看看 tbl_b 中的数据, 会和有执行 begin 的效果有什么差别?
SELECT * FROM tbl_b;
--   +----+-----+
--   | id | val |
--   +----+-----+
--   |  1 | a   |
--   |  2 | b   |
--   +----+-----+
--   有两条数据, 这是为什么?
--   因为事务数据表中的事务默认是自动提交的(AUTOCOMMIT), 它的执行过程是:
--   开启一个事务, 执行第一句, 没有ERROR, 提交事务, 对数据库产生实际影响, 将'a'真真实实的插入到 tbl_b 中
--   开启一个事务, 执行第二句, 没有ERROR, 提交事务, 对数据库产生实际影响, 将'b'真真实实的插入到 tbl_b 中
--   开启一个事务, 执行第三句, 因为没有指定的字段, 抛出ERROR, 程序中断执行.
--   这样明白了为什么要使用 begin 了吧, 换句话说,如果事务表中没有 begin,那它和非事务表执行的效果是一样的

下面是一个成功的例子:

-- 在 phpMyAdmin 中执行下面的操作
-- 1, 清空 tbl_b 记录
TRUNCATE TABLE `tbl_b`;

-- 2, 为 tbl_b 插入数据, 将下面 4 条语句全部复制, 用 phpMyAdmin 一并执行
begin;
INSERT INTO tbl_b (val) VALUES ('a');
INSERT INTO tbl_b (val) VALUES ('b');
INSERT INTO tbl_b (val) VALUES ('c');
INSERT INTO tbl_b (val) VALUES ('d');
-- rollback; -- roolback 可以理解为 un-commit, 不提交
commit; -- 注意最后要有 conmmit; 如果这有这一句会怎样? 动手试试吧.

-- 3, 我们来看看 tbl_b 中的数据, 四条数据成功插入.
SELECT * FROM tbl_b;

总结一下:
1, 在 Mysql 中要让数据表支持事务, 必须使用 InnoDB 或 BDB 数据引擎.
2, 事务数据表默认是 autocommit 的, 要开启一个事务应该使用 begin; 或者使用 SET AUTOCOMMIT={1|0} 来设置是否自动提交
3, 事务一定要 commit , 否则没有任何效果

Posted in Mysql | Tagged , | Leave a comment

突破 VPS 上传速度过慢的瓶颈

国外 VPS 优点一大堆, 缺点就一个: 上传速度太慢, 只能用龟速来形容. 家里1M的带宽, 上传文件到 VPS 空间速度竟然小于20K/s, 这真是个致命的弱点, 想想要传几十张照片要几个小时真是让人抓狂.

刚刚说了 VPS 有很多优点, 其中一个就是可以用 ssh 登录, 这可是个令人怦然心动的强大的好功能. 这意味着你能在 VPS 上执行任意 shell 命令, 包括 wget, scp

我们得好好利用 VPS 的这些优点来弥补它唯一的缺点.
如果你能找到一个国内空间做中转, 先把本地文件上传到中转空间上, 然后用用 putty 远程登录 VPS 利用 wget 命令去下载, 那你就自由了. 因为 VPS 服务器都在国外骨干网络上, 所以下载速度是没有上限的, 速度那只能用飞来形容.
你还可以找到一台国内linux服务器做中转, 先把本地文件上传到中转空间上, 然后用用 putty 远程登录 VPS 利用 spc 命令去远程复制, 这样也是 OK 的.

这里我推荐一空免费的, 允许 ssh 登录的国内 linux 空间, 它完全可以胜任我们空间中转站的功能.

Unix体验中心(Unix-Center.Net)
http://www.unix-center.net/
Unix体验中心(Unix-Center.Net)的目标是为研究、学习和使用各种版本的Unix和类Unix操作系统的教师、学生和工程技术人员提供一个体验和测试各种版本的Unix和类Unix系统的软硬件平台。该平台能够为所有注册用户免费提供如下服务:
-- SSH登录(传统字符界面)
-- VNC登录(图形用户界面)
-- AMP服务(Apache, MySQL, PHP开发环境)
-- C/C++,Fortran,Java,Ruby,Python,Perl,Common Lisp等多种语言开发工具
-- MySQL数据库服务
-- 在线日历服务
-- 在线课程服务
-- 开放源代码项目托管服务

首先要做的就是注册帐号 (http://www.unix-center.net/uc/reg.php)
激活帐号后就可以用 ssh 登录 unix-center 服务器了.

开始上传吧:
1, 使用 winSCP 上传本地文件到 unix-center 空间(非正式用户只有 100M 空间), 我的上传速度在 50~70K/s
2, 使用 putty 登录 vps 空间, 再使用 scp 命令复制文件

scp kuco@x4100.unix-center.net:~/test_file.tar.gz .  # unix-center -> vps 速度上百K/s
scp backup.tar.gz kuco@x4100.unix-center.net:~       # vps -> unix-center 速度不是很快

虽然从 VPS 复制文件到 unix-center 速度不是很快, 不过没关系. 我们可以直接将备份文件放到 vps 网站目录下. 然后利用下载工具去下载. 要知道 vps 的下载速度还是很快的哟. 最关键的是我们再也不用去忍受直接上传文件到 VPS 的龟速啦~~~

Posted in Linux, shell | Tagged , | Leave a comment

配置 Mysql 允许远程连接

MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1)来连接访问. 这对于 Web-Server 与 MySql-Server 都在同一台服务器上的网站架构来说是没有问题的. 但随着网站流量的增加, 后期服务器架构可能会将 Web-Server 与 MySql-Server 分别放在独立的服务器上, 以便得到更大性能的提升, 此时 MySql-Server 就要修改成允许 Web-Server 进行远程连接.

假设我们有:
Web-Server : 192.168.1.100 //ubuntu
Mysql-Server : 192.168.1.101 //xp

我们可以按照下面的步骤修改:
1, 登录 Mysql-Server 连接本地 mysql (默认只允许本地连接)

Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

C:\Documents and Settings\kuco>mysql -h localhost -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.1.45-community-log MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

2, 修改 Mysql-Server 用户配置

mysql> USE mysql; -- 切换到 mysql DB
Database changed
mysql> SELECT User, Password, Host FROM user; -- 查看现有用户,密码及允许连接的主机
+------+----------+-----------+
| User | Password | Host      |
+------+----------+-----------+
| root |          | localhost |
+------+----------+-----------+
1 row in set (0.00 sec)

mysql> -- 只有一个默认的 root 用户, 密码为空, 只允许 localhost 连接
mysql> -- 下面我们另外添加一个新的 root 用户, 密码为空, 只允许 192.168.1.100 连接
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.100' IDENTIFIED BY '' WITH GRANT OPTION;

mysql> -- 当然我们也可以直接用 UPDATE 更新 root 用户 Host, 但不推荐, SQL如下:
mysql> -- UPDATE user SET Host='192.168.1.100' WHERE User='root' AND Host='localhost' LIMIT 1;

3, 修改 Mysql 配置文件 my.ini

bind-address = 127.0.0.1
将 bind-address = 127.0.0.1 这一行注释掉, 即修改为:
#bind-address = 127.0.0.1
到此 Mysql-Server 端配置就完成了.

4, 连接 Web-Server , 检查一下是否能连上

kuco@kuco-desktop:/$ /opt/lampp/bin/mysql -h 192.168.1.101 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 23
Server version: 5.1.45-community-log MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> -- 一切OK

当然也可以用 php 程序去验证:

<?php
mysql_connect("192.168.1.101", "root", "") or die("Could not connect: " . mysql_error());
?>
Posted in Mysql, PHP | Tagged , , | Leave a comment

PEAR 之 Cache_Lite

应付网站高流量与大并发的一个好办法就是灵活的运用缓存机制, 各种缓存中最常见的就是内存缓存与文件缓存了, 本文要介绍的的就是大名鼎鼎的小巧的文件缓存类 PEAR::Cache_Lite

官网介绍页面: http://pear.php.net/manual/en/package.caching.cache-lite.intro.php

描述: PEAR::Cache_Lite 是一个小型的缓存系统. 它为高流量网站进行了优化, 所以它是快速和安全的(因为它使用了文件锁 和/或 反讹误测试),
目标和技术细节: 速度, 简单, 安全

安装:

1, 下载 Cache_Lite 包(http://pear.php.net/package/Cache_Lite/download)
   我下载的是 Cache_Lite-1.7.8 (http://download.pear.php.net/package/Cache_Lite-1.7.8.tgz)

2, 下载 PEAR 包(http://pear.php.net/package/PEAR/download)
   我下载的是 PEAR-1.9.1 (http://download.pear.php.net/package/PEAR-1.9.1.tgz)
   下载 PEAR 包是因为 Cache_Lite 类依赖于它(调用了 PEAR 的错误处理机制)

3, 在网站根目录建立 include 目录

4, 在网站根目录建立 cache_dir 目录(也可以建立在其它地方, 注意设置正确的读写权限)

5, 解压两个下载好的压缩包复制以下文件到 include 目录中
   ./PEAR-1.9.1/PEAR.php
   ./PEAR-1.9.1/PEAR5.php
   ./Cache_Lite-1.7.8/Lite.php

6, 最后的文件目录结构看起来像下面这样子
   /include/PEAR.php
   /include/PEAR5.php
   /include/Lite.php
   /cache_dir/
   /test.php   <-- 下面的测试代码可以放在 test.php 文件中

7, OK. 大功告成, 开始享用 PEAR::Cache_Lite 的强大功能吧

实例:

<?php
/*
最基本/最常用的 PEAR::Cache_Lite 使用方法
$cacheId, $cacheOption 是必要的
更多的使用方法可以参照官网介绍
当然您也可以直接查看 Cache_Lite 源代码
*/

require_once('include/Lite.php');
$cacheId = 'test.php';
$cacheOption = array(
    'cacheDir' => 'cache_dir/',
    'lifeTime' => 10
);
$cacheObj = new Cache_Lite($cacheOption);
$cacheData = $cacheObj->get($cacheId);
if (!$cacheData) {
    echo "我要开始创建缓存啦! ";
    $cacheData = "这是一些缓存内容, 当前时间: ".date("Y-m-d H:i:s");
    $cacheFlag = $cacheObj->save($cacheData);
    if(!$cacheFlag) {
        exit("缓存创建失败!");
    }
}

echo $cacheData;
?>

常用方法:

Cache_Lite::Cache_Lite() – 构造函数
Cache_Lite::get() – 测试cache是否存在  并(如果是) 返回它
Cache_Lite::save() – 保存数据到一个cache 文件
Cache_Lite::remove() – 删除一个cache文件
Cache_Lite::clean() – 清除cache
Cache_Lite::setToDebug() –设置为调试模式
Cache_Lite::setLifeTime() – 设置新的生命周期
Cache_Lite::saveMemoryCachingState() --
Cache_Lite::getMemoryCachingState() --
Cache_Lite::lastModified() – 返回cache最后更新时间。
Cache_Lite::raiseError() – 触发一个 PEAR 错误 constructor
Cache_Lite::extendLife() - 重新设定缓存文件修改时间
Posted in PHP, pear | Tagged , , | Leave a comment