Windows 7 工具列增加快速啟動
許多網友一定記得在 Windows 7 之前的 Windows 系統都有個快速啟動(quick launch)區域。比如 IE 瀏覽器、Windows Media Player 程序可以在裡面快速啟動。
Windows 7 全新的任務欄其實,Windows 7 裡面雖然取消了快速啟動,但是快速啟動的功能仍然存在。你可以把常用的程序放在任務欄裡,要用的時候一樣可以方便打開。
你可以把你想要的程序加到任務欄中:
(右鍵點這個程序或者是快捷方式,選鎖定到任務欄。也可以把程序拖到任務欄。)
如何找回 Windows XP 樣式的快速啟動欄
1. 在任務欄上右鍵 -> 工具欄 -> 新建工具欄。
2.在文件夾裡面輸入這個路徑,然後點選著資料夾: %userprofile%\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch
3.在任務欄上空白處右鍵,把鎖定任務欄的勾去掉。然後在 Quick Launch 的位置右鍵,把顯示文本和顯示標題的勾全部去掉。
4.. 現在任務欄已經解鎖。我們可以自由的拖動上面的東西。稍微用點力,需要乾坤大挪移一下。把快速啟動欄往左拖到不能再拖的位置。然後把任務欄往右拖,快速啟動欄自動就到了最左邊。
5.把任務攔拉到左邊以後 登登登登~~xp原本的快速啟動又出現了!!!!
摘自:http://jack66112211.pixnet.net/blog/post/26227279
2010年8月31日 星期二
2010年8月17日 星期二
Python Framework
Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design.
Developed four years ago by a fast-moving online-news operation, Django was designed to handle two challenges: the intensive deadlines of a newsroom and the stringent requirements of the experienced Web developers who wrote it. It lets you build high-performing, elegant Web applications quickly.
官方網站:http://www.djangoproject.com/
Developed four years ago by a fast-moving online-news operation, Django was designed to handle two challenges: the intensive deadlines of a newsroom and the stringent requirements of the experienced Web developers who wrote it. It lets you build high-performing, elegant Web applications quickly.
官方網站:http://www.djangoproject.com/
Synergy 教學 用一組鍵盤、滑鼠,同時控制兩台電腦PC和MAC~
先跟你說一下 Synergy 這個軟體最重要的使用條件,
就是要操控的這兩台電腦的 IP 四碼裡前三碼要一樣,第一碼必需是192 或 10 (i.e. 專業講法:位於同一個區域網路內),
有線或無線網路都可以。
如果是公司環境,要確認兩台電腦是連在同一台ip分享器上,
不然有可能會出現前三碼一樣, 但仍不在同一區域網路的狀況。
然後,兩台電腦都要裝 Synergy 軟體才能用,但是 MAC 環境下要裝的軟體名字不太一下,
for Windows 叫 Synergy
網址:http://sourceforge.net/projects/synergy2/files/
for MAC 叫 SynergyKM
網址:http://sourceforge.net/projects/synergykm/
確認 OK 以後,
我要知道你是要
1.用 PC 的鍵盤同時控制 PC、MAC (以PC為 Server 端)
還是
2.用 MAC 的鍵盤同時控制兩台 (以 MAC 為 Server )
我自己是用 PC 鍵盤控制兩台電腦啦,一台PC 裝 Windows 7 x64,一台 iMac,OS 是 10.5.8 (Leopard)
居然連64位元的Windows都可以用是我最高興的地方!
所以先講 狀況 1 的設定方法。
假設你兩台電腦都已經裝好 Synergy 而且 位於同一個區域網路底下。
我的 PC 端 IP 是 192.168.1.1 (可以打開 Synergy 後,點左下 info 的按鍵看到)
MAC ip 是 192.168.1.3 (系統偏好設定-->網路 再找一下就看到了)。
打開 PC 上 Synergy,
點 Share this computer's keyboard and mouse (server) --> 以 PC 為 server 端。
按 Screens 下面的 "+"
Screen Name 可以隨便打,認得出來就可以,我輸入 PC
Aliases 不能隨便打,打錯就抓不到電腦!
Aliases 要跟你電腦的"網路名稱"完全一樣!!!! --> 第一個最容易設錯不能用的地方。
網路名稱:控制台-->系統-->完整電腦名稱,ex: Twinkle-PC
改網路名稱:
(XP) 控制台-->系統-->變更
(Win 7) 控制台-->系統-->進階系統設定-->變更
(MAC) 系統偏好設定-->共享-->編輯
輸入完 Screen Name 和 Aliases 按 OK。
同樣的動作再做一次,但這次輸入 MAC 的 Aliases,Screen Name 可以隨便打,我輸入 MAC。
接著,是設定下面 Links (螢幕位置) 的部份:
這邊是讓我搞很久,第二個最容易出問題的地方,不過點破就沒什麼稀奇了。
我的螢幕擺的位置是 PC 在左,MAC 在右,同高。
把下拉選單拉成: 0 to 100 % of the right of PC goes to 0 to 100% of MAC
然後按 "+" --> 出現 PC is left of MAC.
我原本以為這樣就好了,結果是,我滑鼠往右移到MAC上之後就移不回 PC 了 ^o^"
沒想到還要設讓遊標移回來的位置:
把下拉選單拉成: 0 to 100 % of the left of MAC goes to 0 to 100% of PC
然後按 "+" --> 出現 MAC is left of PC.
兩個 Links 都出現在框框裡之後按 OK.
註:要是螢幕不同高,就調整 0 to 100 的選項,但我沒調過,可以自己試試看。
如此 Server端 就設定完成了。
轉戰到 MAC 吧...
打開 系統偏好設定-->最下面 SynergyKM
點上面 Location 的選單,選 New Location,打入一個名稱後ok
在 General 標籤下,選 Connect to a shared keyboard and mouse,
到 Client Configuration 標籤,輸入 Server 端 IP, ex: 192.168.1.1
回到 General ,按 Turn Synergy On
Status 出現 Connected 表示連接成功! 可以移動滑鼠過去囉!
移過去之後打字也ok。
預設按鍵 Alt (PC) = Command (MAC)
我碰到另一個問題是,
我滑鼠可以在 PC 和 MAC 同時用沒有問題,
但是打字的話,
切換到 MAC 的注音後,還是出現英文字……不能打注音。
但是裝了 嘸蝦米輸入法之後就沒這個問題。
目前我還是不能在 MAC 上用 PC 鍵盤打注音。
成功的話就跟我分享一下喜悅吧!
^^
摘自:http://dj1020.posterous.com/synergy-pcmac
Synergy Mac to Window Configuring Mac as Server! Easy!
http://www.youtube.com/watch?v=uydwhv20qnI&feature=channel
就是要操控的這兩台電腦的 IP 四碼裡前三碼要一樣,第一碼必需是192 或 10 (i.e. 專業講法:位於同一個區域網路內),
有線或無線網路都可以。
如果是公司環境,要確認兩台電腦是連在同一台ip分享器上,
不然有可能會出現前三碼一樣, 但仍不在同一區域網路的狀況。
然後,兩台電腦都要裝 Synergy 軟體才能用,但是 MAC 環境下要裝的軟體名字不太一下,
for Windows 叫 Synergy
網址:http://sourceforge.net/projects/synergy2/files/
for MAC 叫 SynergyKM
網址:http://sourceforge.net/projects/synergykm/
確認 OK 以後,
我要知道你是要
1.用 PC 的鍵盤同時控制 PC、MAC (以PC為 Server 端)
還是
2.用 MAC 的鍵盤同時控制兩台 (以 MAC 為 Server )
我自己是用 PC 鍵盤控制兩台電腦啦,一台PC 裝 Windows 7 x64,一台 iMac,OS 是 10.5.8 (Leopard)
居然連64位元的Windows都可以用是我最高興的地方!
所以先講 狀況 1 的設定方法。
假設你兩台電腦都已經裝好 Synergy 而且 位於同一個區域網路底下。
我的 PC 端 IP 是 192.168.1.1 (可以打開 Synergy 後,點左下 info 的按鍵看到)
MAC ip 是 192.168.1.3 (系統偏好設定-->網路 再找一下就看到了)。
打開 PC 上 Synergy,
點 Share this computer's keyboard and mouse (server) --> 以 PC 為 server 端。
按 Screens 下面的 "+"
Screen Name 可以隨便打,認得出來就可以,我輸入 PC
Aliases 不能隨便打,打錯就抓不到電腦!
Aliases 要跟你電腦的"網路名稱"完全一樣!!!! --> 第一個最容易設錯不能用的地方。
網路名稱:控制台-->系統-->完整電腦名稱,ex: Twinkle-PC
改網路名稱:
(XP) 控制台-->系統-->變更
(Win 7) 控制台-->系統-->進階系統設定-->變更
(MAC) 系統偏好設定-->共享-->編輯
輸入完 Screen Name 和 Aliases 按 OK。
同樣的動作再做一次,但這次輸入 MAC 的 Aliases,Screen Name 可以隨便打,我輸入 MAC。
接著,是設定下面 Links (螢幕位置) 的部份:
這邊是讓我搞很久,第二個最容易出問題的地方,不過點破就沒什麼稀奇了。
我的螢幕擺的位置是 PC 在左,MAC 在右,同高。
把下拉選單拉成: 0 to 100 % of the right of PC goes to 0 to 100% of MAC
然後按 "+" --> 出現 PC is left of MAC.
我原本以為這樣就好了,結果是,我滑鼠往右移到MAC上之後就移不回 PC 了 ^o^"
沒想到還要設讓遊標移回來的位置:
把下拉選單拉成: 0 to 100 % of the left of MAC goes to 0 to 100% of PC
然後按 "+" --> 出現 MAC is left of PC.
兩個 Links 都出現在框框裡之後按 OK.
註:要是螢幕不同高,就調整 0 to 100 的選項,但我沒調過,可以自己試試看。
如此 Server端 就設定完成了。
轉戰到 MAC 吧...
打開 系統偏好設定-->最下面 SynergyKM
點上面 Location 的選單,選 New Location,打入一個名稱後ok
在 General 標籤下,選 Connect to a shared keyboard and mouse,
到 Client Configuration 標籤,輸入 Server 端 IP, ex: 192.168.1.1
回到 General ,按 Turn Synergy On
Status 出現 Connected 表示連接成功! 可以移動滑鼠過去囉!
移過去之後打字也ok。
預設按鍵 Alt (PC) = Command (MAC)
我碰到另一個問題是,
我滑鼠可以在 PC 和 MAC 同時用沒有問題,
但是打字的話,
切換到 MAC 的注音後,還是出現英文字……不能打注音。
但是裝了 嘸蝦米輸入法之後就沒這個問題。
目前我還是不能在 MAC 上用 PC 鍵盤打注音。
成功的話就跟我分享一下喜悅吧!
^^
摘自:http://dj1020.posterous.com/synergy-pcmac
Synergy Mac to Window Configuring Mac as Server! Easy!
http://www.youtube.com/watch?v=uydwhv20qnI&feature=channel
多台電腦共享一組鍵盤滑鼠-SynergyKM
假設你的工作桌上有好幾台電腦,好幾個螢幕,但是只有一組鍵盤滑鼠,可是又不想花錢買"KM切換器",Synergy是一套可以用軟體達到共享鍵盤滑鼠的軟體,而這邊介紹給你的SynergyKM是在Mac平台下的圖像介面,讓你使用Synergy起來比較容易。Synergy這套軟體也是免費開源碼的軟體,支援多平台,所以說如果你有一台PC+螢幕、一台Mac+螢幕,只要兩台電腦在同一個網路子網域下,分別裝上windows版的Synergy和Mac版的SynergyKM,一樣也可以共享一組鍵盤滑鼠,相當好用,推薦給你。
2010年8月16日 星期一
Develop JQuery Plugin
Adding a new global function
另一種寫法 jQuery.extend
Add namespace
Creating a utility method
Creating a jQuery Object method
Method chaining
Design Pattern
//自訂 globalFunction
jQuery.globalFunction = function(){
alert('This is a global function!');
};
//呼叫寫好的 globalFunction
$.globalFunction();
另一種寫法 jQuery.extend
//自訂 globalFunction
jQuery.extend({
globalFunction: function(){
alert('This is a global function!');
}
});
//呼叫寫好的 globalFunction
$.globalFunction();
Add namespace
//自訂 Rex's plugin
jQuery.Rex = {
globalFunction: function(){
alert("This is a Rex's function!");
}
};
//呼叫寫好的 plugin
$.Rex.globalFunction();
Creating a utility method
//自訂 sum utility
jQuery.Rex = {
sum: function(array){
var total = 0;
jQuery.each(array, function(index, value){
total += value;
});
return total;
}
};
//呼叫寫好的 utility
var myArray = [1,3,5,7,9];
alert($.Rex.sum(myArray));
Creating a jQuery Object method
//自訂 object method "swapClass"
jQuery.fn.swapClass = function(classA, classB){
this.each(function(){
var element = jQuery(this);
if(element.hasClass(classA)){
element.removeClass(classA).addClass(classB);
}
else if(element.hasClass(classB)){
element.removeClass(classB).addClass(classA);
}
});
};
$(document).ready(function(){
$('#btnSwap').click(function(){
//呼叫"swapClass"
$('li').swapClass('red', 'yellow');
return false;
});
});
Method chaining
//自訂 object method "swapClass"
jQuery.fn.swapClass = function(classA, classB){
return this.each(function(){
var element = jQuery(this);
if(element.hasClass(classA)){
element.removeClass(classA).addClass(classB);
}
else if(element.hasClass(classB)){
element.removeClass(classB).addClass(classA);
}
});
};
$(document).ready(function(){
$('#btnSwap').click(function(){
//呼叫"swapClass"
$('li').swapClass('red', 'yellow').css('text-decoration','underline');
return false;
});
});
Design Pattern
//javascript class design pattern
var People = function(name){
this.name = name;
};
People.prototype = {
constructor: People,
sayHi: function(){
alert('hello! I am ' + this.name );
}
};
var Rex = new People('Rex');
Rex.sayHi();
//jQuery plugin design pattern (Object method)
(function($){
$.fn.setColor = function(color){
return this.each(function(){
var element = jQuery(this);
element.css('background-color',color);
});
};
})(jQuery);
$(document).ready(function(){
$('a').setColor('red').css('font-size','36px');
$('a:eq(0)').css('background','yellow');
});
2010年8月14日 星期六
Subversion With Mac OS X Tutorial
Subversion is a version control system that allows you to work with other people on a project and switch back easily to every version ever made. It can be used for all kinds of projects like application source code, web sites, even images or just simple text documents. Once you have it all set up and followed all the steps described below, it is easy to handle and a very useful thing – not just for computer geeks.
About This Tuturial
This tutorial explains the basics from installing subversion and getting started to working with other people on the same project. It is written primarly for Mac OS X users, but since Subversion itself works the same on all platforms, most of this tutorial should apply to Linux or Windows users, too.
The Concept of Subversion
Subversion works by setting up a central repository on a server or local computer that every user connects to and downloads a personal working copy from. When changes are made to the working copy, they can be uploaded to the repository. If these changes conflict with changes other people may have uploaded since the last time you updated your working copy, subversion tries to merge these files and solve the conflicts.
Downloading and Installing Subversion
I recommend downloading the Subversion Mac OS X package from Collabnet
Download and run the installer. Note that Subversion itself doesn't feature a graphical user interface, so you won't find any new files in your application directory after installation. Instead it installs some command line commands into the directory /opt/subversion/bin* on your hard drive. *Note: For other Subversion packages this path is usually /usr/local/bin.
To be able to call the Subversion commands from every directory, you must add it to your path. If you don't know what that means, don't worry. Just follow the instructions.
Open the Terminal application. It can be found in the /Applications/Utilities folder. Whenever you see below a line starting with a dollar sign, you should type the text after the dollar sign in your terminal and hit return.
Start by creating a new text file called '.bash_profile', i.e. with the command line text editor pico:
$ pico .bash_profile
Add the following line to the text file:
export PATH=/opt/subversion/bin/:$PATH
Now hit Control-X, then confirm saving the file with 'y', followed by return.
You have just added Subversions's location to your path. Let Terminal read this file to know the path has changed (there's an empty space between the dots):
$ . .bash_profile
Creating a Sample Subversion Project
First we will need to set up a Subversion repository on our local computer. That is the place to store all versions of our project. Now create your repository like this:
$ svnadmin create SVNrep
This will create a repository named 'SVNrep' in your your home directory, although svnadmin won't give you any feedback. If you don't trust me on this, you can check the existence of this folder by typing 'ls' in the terminal or looking for it in the Finder.
Next we create our sample project. Create a new folder and an empty file named 'test.txt' inside this folder:
$ mkdir test
$ touch test/test.txt
Let's import this project into the repository. Type in your terminal, by replacing 'sara' with your own user name:
$ svn import test file:///Users/sara/SVNrep/test -m "Initial import"
This will output:
Adding test.txt
Committed revision 1.
We have just imported the folder 'test' into the repository 'SVNrep'. Each version in the repository is called a "revision" and is identified by a unique number. Always provide a short message ('-m') of the changes you made to the repository like we just did!
Retrieving Files From Subversion
Now we get a copy to work on from the repository. This process is called "check out":
$ svn checkout file:///Users/your_user_name/SVNrep/test test-copy
The output will show all files added ('A') to our working copy:
A test-copy/test.txt
Checked out revision 1.
Change into the working copy directory by typing:
$ cd test-copy
Next check the content of our working copy in the terminal:
$ ls -a1
This will output the directory including hidden files:
.
..
.svn
test.txt
Note the hidden directory '.svn'. This holds some subversion info like the name of the repository, so you don't have to type that in the future. If you would like a copy of your repository without this hidden directory in every folder, you have to export a copy:
$ svn export file:///Users/your_user_name/SVNrep/test test-copy
This copy is now safe to deploy on the web. It is not a working copy though, so you can't commit changes back to the repository from this folder.
Time For Changes
It is time to make some changes to our file and save it back to the repository. Open 'test.txt' from the working copy with your favourite text editor and type "Hello world" or whatever you are up to, then save the file.
You can then query Subversion to find out the differences between the repository and your copy:
$ svn status
This will state that our file has been modified ('M'):
M test.txt
Now we want to update the repository with the changes we made. This process is called "committing":
$ svn commit -m "Added some text"
This will output:
Sending test.txt
Transmitting file data .
Committed revision 2.
Dealing With All These Versions
Let's assume, that someone else working on your project made changes to the repository. You will want to update your local working copy to incorporate the changes:
$ svn update
Because in our example nobody else made changes to the repository, this will do nothing and output:
At revision 2.
To list all revisions in the repository, type:
$ svn log
This will output a list of all revisions with it's messages:
------------------------------------------------------------------------
r2 | sara | 2006-10-08 16:41:46 +0200 (Sun, 08 Oct 2006) | 1 line
Added some text
------------------------------------------------------------------------
r1 | sara | 2006-10-08 16:10:36 +0200 (Sun, 08 Oct 2006) | 1 line
Initial import
------------------------------------------------------------------------
If you would like to see the exact differing lines to a specific revision, i.e. revision 1, just type:
$ svn diff -r 1
The output states that the line "Hello world" has been added ("+"):
Index: test.txt ===================================================================
--- test.txt (revision 1)
+++ test.txt (working copy)
@@ -0,0 +1 @@
+Hello world
Maybe you would then rather like to switch back to an older revision:
$ svn update -r 1
This will update ('U') your copy back to revision 1 and output:
U test.txt
Updated to revision 1.
Note that all commands are used on the whole current working directory. You could also provide a single filename for each of these commands, i.e. 'svn update test.txt'.
Renaming, Adding And Deleting Files From The Repository
Sometimes you may add new files to your working copy.
$ touch test2.txt
They will not be included in the repository though, unless you manually add them to the repository:
$ svn add test2.txt
$ svn commit -m "added new file"
If you later would like to remove a file from the repository, type likewise:
$ svn delete test2.txt
$ svn commit -m "deleted file"
Note that you should never delete or rename files from your working copy without Subversion knowing. You can modify inside your files as much as you like. But if you just rename files or move them to another folder, Subversion will loose track of them. Always use 'svn' commands for those operations.
This is how you move a file accordingly:
$ svn move oldfilename newfilename
$ svn commit -m "moved file"
All of these commands will not only affect the repository, but your working copy as well. So you should never have to delete or rename a file with your Finder.
If you are working alone on a project, this is it! Well, basicly. The next chapter will explain dealing with multiple users.
Working With Other People
To act as if someone else was working on your project, you could now check out a second working copy named i.e. 'test-copy2' into your home directory and make some more changes to it. Then commit it to the repository following the steps from above.
Now think of a possible conflict: two people have downloaded their working copy and started working on the same file. When Sara commits her files before Michael does, Michael will get an error message when committing because his copy is not up to date any more:
$ svn commit -m "Some change by Michael"
Sending test.txt
svn: Commit failed (details follow):
svn: Out of date: '/test/test.txt' in transaction '3-1'
Michael will then first have to update his working copy by typing 'svn update'. This will merge Sara's earlier changes into Michael's working copy, line by line.
Michael can now commit the merged copy to the repository. In some rare cases however, there my be a conflict that Subversion cannot solve itself. It will then create three files in Michael's working copy:
test.txt.mine
test.txt.r2
test.txt.r3
Michael now has to manually put the pieces together in the file 'test.txt', deciding which changes to keep. Only when this is made and the three extra files are deleted, Subversion will allow Michael to commit his files.
Now go play around with it to get used to it. Of course there is more to Subversion. You could type "svn help" in the terminal to list all commands or read the freely available SVNbook at http://svnbook.red-bean.com
Graphical User Interfaces
Many people don't like working with the terminal. They find it complicated to remember the text commands, as opposed to clicking on buttons in applications. There is a couple of free or commercial apps available on the internet, that provide a graphical user interface for Subversion commands. I think it's best practice to learn Subversion from the terminal first, before you use a graphical client, to understand the way subversion works better.
A nice and free GUI for Mac OS X is svnX. To manage your working copies from the same application that you write your code with, the text editor TextMate is a good choice. TextMate includes a Subversion bundle that allows you to easily invoke most Subversion commands from the menu. Only once for setting up the repository and checking out the first working copy, you will have to use the terminal. After that, just press Shift-Control-A to open the Subversion bundle menu.
摘自:http://www.rubyrobot.org/tutorial/subversion-with-mac-os-x
About This Tuturial
This tutorial explains the basics from installing subversion and getting started to working with other people on the same project. It is written primarly for Mac OS X users, but since Subversion itself works the same on all platforms, most of this tutorial should apply to Linux or Windows users, too.
The Concept of Subversion
Subversion works by setting up a central repository on a server or local computer that every user connects to and downloads a personal working copy from. When changes are made to the working copy, they can be uploaded to the repository. If these changes conflict with changes other people may have uploaded since the last time you updated your working copy, subversion tries to merge these files and solve the conflicts.
Downloading and Installing Subversion
I recommend downloading the Subversion Mac OS X package from Collabnet
Download and run the installer. Note that Subversion itself doesn't feature a graphical user interface, so you won't find any new files in your application directory after installation. Instead it installs some command line commands into the directory /opt/subversion/bin* on your hard drive. *Note: For other Subversion packages this path is usually /usr/local/bin.
To be able to call the Subversion commands from every directory, you must add it to your path. If you don't know what that means, don't worry. Just follow the instructions.
Open the Terminal application. It can be found in the /Applications/Utilities folder. Whenever you see below a line starting with a dollar sign, you should type the text after the dollar sign in your terminal and hit return.
Start by creating a new text file called '.bash_profile', i.e. with the command line text editor pico:
$ pico .bash_profile
Add the following line to the text file:
export PATH=/opt/subversion/bin/:$PATH
Now hit Control-X, then confirm saving the file with 'y', followed by return.
You have just added Subversions's location to your path. Let Terminal read this file to know the path has changed (there's an empty space between the dots):
$ . .bash_profile
Creating a Sample Subversion Project
First we will need to set up a Subversion repository on our local computer. That is the place to store all versions of our project. Now create your repository like this:
$ svnadmin create SVNrep
This will create a repository named 'SVNrep' in your your home directory, although svnadmin won't give you any feedback. If you don't trust me on this, you can check the existence of this folder by typing 'ls' in the terminal or looking for it in the Finder.
Next we create our sample project. Create a new folder and an empty file named 'test.txt' inside this folder:
$ mkdir test
$ touch test/test.txt
Let's import this project into the repository. Type in your terminal, by replacing 'sara' with your own user name:
$ svn import test file:///Users/sara/SVNrep/test -m "Initial import"
This will output:
Adding test.txt
Committed revision 1.
We have just imported the folder 'test' into the repository 'SVNrep'. Each version in the repository is called a "revision" and is identified by a unique number. Always provide a short message ('-m') of the changes you made to the repository like we just did!
Retrieving Files From Subversion
Now we get a copy to work on from the repository. This process is called "check out":
$ svn checkout file:///Users/your_user_name/SVNrep/test test-copy
The output will show all files added ('A') to our working copy:
A test-copy/test.txt
Checked out revision 1.
Change into the working copy directory by typing:
$ cd test-copy
Next check the content of our working copy in the terminal:
$ ls -a1
This will output the directory including hidden files:
.
..
.svn
test.txt
Note the hidden directory '.svn'. This holds some subversion info like the name of the repository, so you don't have to type that in the future. If you would like a copy of your repository without this hidden directory in every folder, you have to export a copy:
$ svn export file:///Users/your_user_name/SVNrep/test test-copy
This copy is now safe to deploy on the web. It is not a working copy though, so you can't commit changes back to the repository from this folder.
Time For Changes
It is time to make some changes to our file and save it back to the repository. Open 'test.txt' from the working copy with your favourite text editor and type "Hello world" or whatever you are up to, then save the file.
You can then query Subversion to find out the differences between the repository and your copy:
$ svn status
This will state that our file has been modified ('M'):
M test.txt
Now we want to update the repository with the changes we made. This process is called "committing":
$ svn commit -m "Added some text"
This will output:
Sending test.txt
Transmitting file data .
Committed revision 2.
Dealing With All These Versions
Let's assume, that someone else working on your project made changes to the repository. You will want to update your local working copy to incorporate the changes:
$ svn update
Because in our example nobody else made changes to the repository, this will do nothing and output:
At revision 2.
To list all revisions in the repository, type:
$ svn log
This will output a list of all revisions with it's messages:
------------------------------------------------------------------------
r2 | sara | 2006-10-08 16:41:46 +0200 (Sun, 08 Oct 2006) | 1 line
Added some text
------------------------------------------------------------------------
r1 | sara | 2006-10-08 16:10:36 +0200 (Sun, 08 Oct 2006) | 1 line
Initial import
------------------------------------------------------------------------
If you would like to see the exact differing lines to a specific revision, i.e. revision 1, just type:
$ svn diff -r 1
The output states that the line "Hello world" has been added ("+"):
Index: test.txt ===================================================================
--- test.txt (revision 1)
+++ test.txt (working copy)
@@ -0,0 +1 @@
+Hello world
Maybe you would then rather like to switch back to an older revision:
$ svn update -r 1
This will update ('U') your copy back to revision 1 and output:
U test.txt
Updated to revision 1.
Note that all commands are used on the whole current working directory. You could also provide a single filename for each of these commands, i.e. 'svn update test.txt'.
Renaming, Adding And Deleting Files From The Repository
Sometimes you may add new files to your working copy.
$ touch test2.txt
They will not be included in the repository though, unless you manually add them to the repository:
$ svn add test2.txt
$ svn commit -m "added new file"
If you later would like to remove a file from the repository, type likewise:
$ svn delete test2.txt
$ svn commit -m "deleted file"
Note that you should never delete or rename files from your working copy without Subversion knowing. You can modify inside your files as much as you like. But if you just rename files or move them to another folder, Subversion will loose track of them. Always use 'svn' commands for those operations.
This is how you move a file accordingly:
$ svn move oldfilename newfilename
$ svn commit -m "moved file"
All of these commands will not only affect the repository, but your working copy as well. So you should never have to delete or rename a file with your Finder.
If you are working alone on a project, this is it! Well, basicly. The next chapter will explain dealing with multiple users.
Working With Other People
To act as if someone else was working on your project, you could now check out a second working copy named i.e. 'test-copy2' into your home directory and make some more changes to it. Then commit it to the repository following the steps from above.
Now think of a possible conflict: two people have downloaded their working copy and started working on the same file. When Sara commits her files before Michael does, Michael will get an error message when committing because his copy is not up to date any more:
$ svn commit -m "Some change by Michael"
Sending test.txt
svn: Commit failed (details follow):
svn: Out of date: '/test/test.txt' in transaction '3-1'
Michael will then first have to update his working copy by typing 'svn update'. This will merge Sara's earlier changes into Michael's working copy, line by line.
Michael can now commit the merged copy to the repository. In some rare cases however, there my be a conflict that Subversion cannot solve itself. It will then create three files in Michael's working copy:
test.txt.mine
test.txt.r2
test.txt.r3
Michael now has to manually put the pieces together in the file 'test.txt', deciding which changes to keep. Only when this is made and the three extra files are deleted, Subversion will allow Michael to commit his files.
Now go play around with it to get used to it. Of course there is more to Subversion. You could type "svn help" in the terminal to list all commands or read the freely available SVNbook at http://svnbook.red-bean.com
Graphical User Interfaces
Many people don't like working with the terminal. They find it complicated to remember the text commands, as opposed to clicking on buttons in applications. There is a couple of free or commercial apps available on the internet, that provide a graphical user interface for Subversion commands. I think it's best practice to learn Subversion from the terminal first, before you use a graphical client, to understand the way subversion works better.
A nice and free GUI for Mac OS X is svnX. To manage your working copies from the same application that you write your code with, the text editor TextMate is a good choice. TextMate includes a Subversion bundle that allows you to easily invoke most Subversion commands from the menu. Only once for setting up the repository and checking out the first working copy, you will have to use the terminal. After that, just press Shift-Control-A to open the Subversion bundle menu.
摘自:http://www.rubyrobot.org/tutorial/subversion-with-mac-os-x
Git autocomplete in Mac OS X
I always liked that my Git installations on Unix and Linux comes with the contrib/complete/git-completion.bash script activated or easily activated. But its harder if you use the pre-built binaries for Mac OS X.
To get autocompletion to work on Mac OS X when installing the pre-built binaries do this.
UPDATE: Instead of step 1 and 2 below you can get the completion script directly from Github. Thanks to Fredric.
curl http://github.com/git/git/raw/master/contrib/completion/git-completion.bash -O
1. Download the Git source from git-scm.com.
2. Unpack and copy the completion script git-completion.bash found in contrib/completion to your home directory.
3. Add the following to your ~/.profile or ~/.bash_profile
source ~/git-completion.bash
alias gco='git co'
alias gci='git ci'
alias grb='git rb'
4. Add the following to your ~/.gitconfig
[alias]
co = checkout
ci = commit
rb = rebase
摘自:http://www.codethatmatters.com/2010/01/git-autocomplete-in-mac-os-x/
To get autocompletion to work on Mac OS X when installing the pre-built binaries do this.
UPDATE: Instead of step 1 and 2 below you can get the completion script directly from Github. Thanks to Fredric.
curl http://github.com/git/git/raw/master/contrib/completion/git-completion.bash -O
1. Download the Git source from git-scm.com.
2. Unpack and copy the completion script git-completion.bash found in contrib/completion to your home directory.
3. Add the following to your ~/.profile or ~/.bash_profile
source ~/git-completion.bash
alias gco='git co'
alias gci='git ci'
alias grb='git rb'
4. Add the following to your ~/.gitconfig
[alias]
co = checkout
ci = commit
rb = rebase
摘自:http://www.codethatmatters.com/2010/01/git-autocomplete-in-mac-os-x/
[how-to] Mac上如何安裝 git
方法一(使用macports, 我使用這種方法):
打開終端機:
$ sudo port selfupdate
$ sudo port install git-core +svn
方法二(直接使用 Git for OS X Installer):
http://code.google.com/p/git-osx-installer/
git的更多介紹:
http://ihower.idv.tw/blog/archives/2591
摘自:http://izero.pixnet.net/blog/post/27303111
打開終端機:
$ sudo port selfupdate
$ sudo port install git-core +svn
方法二(直接使用 Git for OS X Installer):
http://code.google.com/p/git-osx-installer/
git的更多介紹:
http://ihower.idv.tw/blog/archives/2591
摘自:http://izero.pixnet.net/blog/post/27303111
2010年8月11日 星期三
HTML5 Boilerplate
HTML5 Boilerplate is the professional badass's base HTML/CSS/JS template for a fast, robust and future-proof site.
After more than two years in iterative development, you get the best of the best practices baked in: cross-browser normalization, performance optimizations, even optional features like cross-domain ajax and flash. A starter apache .htaccess config file hooks you the eff up with caching rules and preps your site to serve HTML5 video, use @font-face, and get your gzip zipple on.
Boilerplate is not a framework, nor does it prescribe any philosophy of development, it's just got some tricks to get your project off the ground quickly and right-footed.
...
摘自:http://html5boilerplate.com/
After more than two years in iterative development, you get the best of the best practices baked in: cross-browser normalization, performance optimizations, even optional features like cross-domain ajax and flash. A starter apache .htaccess config file hooks you the eff up with caching rules and preps your site to serve HTML5 video, use @font-face, and get your gzip zipple on.
Boilerplate is not a framework, nor does it prescribe any philosophy of development, it's just got some tricks to get your project off the ground quickly and right-footed.
...
摘自:http://html5boilerplate.com/
log() - A lightweight wrapper for console.log
There are a few things that a console.log wrapper can and should do:
Prevent errors if a console isn't around (i.e. IE)
Maintain a history of logs, so you can look in the past if your console is added afterwards (e.g. firebug lite)
Normalize the browser differences in console integration (e.g. when passing multiple arguments into console.log())
For something you type regularly, make it quicker to type for the lazy among us.
But there are a few considerations…
Console.log.apply doesn't handle multiple arguments in Safari 3 or Chrome 1.1
Firebug, Chrome, and Safari have a clearer presentation for strings when inside an array:
More details on how firebug and webkit inspector visually view these things here: http://gist.github.com/466188
Extra features
A reverse-chronological history, accessible as an array at log.history
I have also included (I removed it) a shorthand logargs() function that is useful when you're inside a function and want to know the context and arguments passed in. I use it a lot in ajax callbacks. Worth noting that it uses arguments.callee.caller, which will be deprecated in ECMAScript 5 Strict mode. :( I killed off logargs cuz nobody lurved it like I did. If you want it… pastie.org/1033665
The code:
// usage: log('inside coolFunc',this,arguments);
// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
log.history = log.history || []; // store logs to an array for reference
log.history.push(arguments);
if(this.console){
console.log( Array.prototype.slice.call(arguments) );
}
};
And if you'd like it minified:
window.log=function(){log.history=log.history||[];log.history.push(arguments);if(this.console){console.log(Array.prototype.slice.call(arguments))}};
Interestingly, the minified version of this script is smaller (262 148 bytes), and arguably more useful, than the minified firebugx.js, which I've covered before. Plus it has one more feature.
Plus Firebug lite?
You got it. This bookmarklet will add firebug lite, and then output the logged history when it's ready:
>>> Fbug Lite+log <<<
Want more power?
After writing this, I worked with Ben Alman on a more comprehensive and robust logging script. It's excellent if you take full advantage of the console API. And you should be aware that Safari 4 and Chrome 2 have most of that API supported. Make full use of it and don't you dare type another alert()!
摘自:http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
Prevent errors if a console isn't around (i.e. IE)
Maintain a history of logs, so you can look in the past if your console is added afterwards (e.g. firebug lite)
Normalize the browser differences in console integration (e.g. when passing multiple arguments into console.log())
For something you type regularly, make it quicker to type for the lazy among us.
But there are a few considerations…
Console.log.apply doesn't handle multiple arguments in Safari 3 or Chrome 1.1
Firebug, Chrome, and Safari have a clearer presentation for strings when inside an array:
More details on how firebug and webkit inspector visually view these things here: http://gist.github.com/466188
Extra features
A reverse-chronological history, accessible as an array at log.history
I have also included (I removed it) a shorthand logargs() function that is useful when you're inside a function and want to know the context and arguments passed in. I use it a lot in ajax callbacks. Worth noting that it uses arguments.callee.caller, which will be deprecated in ECMAScript 5 Strict mode. :( I killed off logargs cuz nobody lurved it like I did. If you want it… pastie.org/1033665
The code:
// usage: log('inside coolFunc',this,arguments);
// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
log.history = log.history || []; // store logs to an array for reference
log.history.push(arguments);
if(this.console){
console.log( Array.prototype.slice.call(arguments) );
}
};
And if you'd like it minified:
window.log=function(){log.history=log.history||[];log.history.push(arguments);if(this.console){console.log(Array.prototype.slice.call(arguments))}};
Interestingly, the minified version of this script is smaller (262 148 bytes), and arguably more useful, than the minified firebugx.js, which I've covered before. Plus it has one more feature.
Plus Firebug lite?
You got it. This bookmarklet will add firebug lite, and then output the logged history when it's ready:
>>> Fbug Lite+log <<<
Want more power?
After writing this, I worked with Ben Alman on a more comprehensive and robust logging script. It's excellent if you take full advantage of the console API. And you should be aware that Safari 4 and Chrome 2 have most of that API supported. Make full use of it and don't you dare type another alert()!
摘自:http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
2010年8月10日 星期二
Javscript form serialize
function serialize(form){
var parts = new Array();
var field = null;
for (var i=0, len=form.elements.length; i < len; i++){
field = form.elements[i];
switch(field.type){
case "select-one":
case "select-multiple":
for (var j=0, optLen = field.options.length; j < optLen; j++){
var option = field.options[j];
if (option.selected){
var optValue = "";
if (option.hasAttribute){
optValue = (option.hasAttribute("value") ? option.value : option.text);
} else {
optValue = (option.attributes["value"].specified ? option.value : option.text);
}
parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue));
}
}
break;
case undefined: //fieldset
case "file": //file input
case "submit": //submit button
case "reset": //reset button
case "button": //custom button
break;
case "radio": //radio button
case "checkbox": //checkbox
if (!field.checked){
break;
}
/* falls through */
default:
parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));
}
}
return parts.join("&");
}
2010年8月9日 星期一
javascript detect popup blocker
var blocked = false;
try {
var wroxWin = window.open("http://www.wrox.com","_blank");
if(wroxWin == null){
blocked = true;
}
}catch(ex){
block = true;
}
if(blocked){
alert("The popup was blocked!");
}
2010年8月4日 星期三
Thickbox3.1彈出層關閉再打開,文本框不能輸入,即無法聚焦
症狀:關閉彈出層後,原來頁面上的文本框無法聚焦,即文本框變成readyonly(只讀)了
原因和解決方法:這個的原因不好說,很多人都認為是ie本身的bug。 是由於iframe沒有移除,即使移除了。 內存上也麼有清除造成的。 這也是我猜的。 哈哈。 解決方法是在tb_remove()中先手動移除iframe然後,在強製做垃圾回收,至少我是可以啦。 哈哈。 代碼如下:
function tb_remove() {
$("#TB_imageOff").unbind("click");
$("#TB_closeWindowButton").unbind("click");
$("#TB_window").fadeOut("fast",function(){
if(navigator.userAgent.indexOf("MSIE")>0) { //如果是IE
//手動移除iframe,IE的一個bug
$('#TB_iframeContent').remove();
}
$('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();
if(navigator.userAgent.indexOf("MSIE")>0) { //如果是IE
//自己調用垃圾回收,強制清楚iframe內存,解決文本框無法輸入問題。
CollectGarbage();
}
});
$("#TB_load").remove();
if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
$("body","html").css({
height: "auto",
width: "auto"
});
$("html").css("overflow","");
}
document.onkeydown = "";
document.onkeyup = "";
return false;
}
摘自:http://www.kukaka.org/home/showonews/210
原因和解決方法:這個的原因不好說,很多人都認為是ie本身的bug。 是由於iframe沒有移除,即使移除了。 內存上也麼有清除造成的。 這也是我猜的。 哈哈。 解決方法是在tb_remove()中先手動移除iframe然後,在強製做垃圾回收,至少我是可以啦。 哈哈。 代碼如下:
function tb_remove() {
$("#TB_imageOff").unbind("click");
$("#TB_closeWindowButton").unbind("click");
$("#TB_window").fadeOut("fast",function(){
if(navigator.userAgent.indexOf("MSIE")>0) { //如果是IE
//手動移除iframe,IE的一個bug
$('#TB_iframeContent').remove();
}
$('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();
if(navigator.userAgent.indexOf("MSIE")>0) { //如果是IE
//自己調用垃圾回收,強制清楚iframe內存,解決文本框無法輸入問題。
CollectGarbage();
}
});
$("#TB_load").remove();
if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
$("body","html").css({
height: "auto",
width: "auto"
});
$("html").css("overflow","");
}
document.onkeydown = "";
document.onkeyup = "";
return false;
}
摘自:http://www.kukaka.org/home/showonews/210
2010年8月3日 星期二
Use spket For mootools aptana plugin
安裝步驟如下:
1.下載安裝包含有Eclipse的Aptana Studio;
2.啟動Aptana,然後菜單:Help → Software Updates → Find and Install… → Search for new features to install → New remote site…
3.名稱可以輸入: “Spket”,URL是http://www.spket.com/update/
4.會提示重啟Aptana,重啟之;
5.Window → Preferences → Spket → JavaScript Profiles → New ;
6.輸入“ExtJS”點擊OK;
7.選擇“ExtJS”並點擊“Add Library”然後在下拉條中選取“ExtJS”;
8.選擇“ExtJS”並點擊“Add File”,然後在你的./ext-3.x/source目錄中選取“ext.jsb”文件;
(ext3.0正式版中不包含ext.jsb文件,需要手動Google一下找到rc版3.0中的ext.jsb,同樣可以使用)
9.設置新的ExtJS Profile,選中並點擊“JavaScript Profiles”對話框右手邊的“Defalut”按鈕;
10.重啟Aptana;
Create MooTools profile
Select the menu item Window > Preferences... to open the workbench preferences.
Select the Spket > JavaScript Profile preference page to display the installed JavaScript Profiles.
Click the New.. button. In the Name field, type MooTools as the name for the new profile. Then click OK.
Click the Add Library button. From the Library drop-down list, select MooTools. Then click OK.
Click the Add File button, choose mootools-xxx.js download from mootools.net (When choose compression type, No Compression is recommend)
Choose the MooTools profile created in step 3, click the Default button make it the default profile for all project. The default profile can also be configured per project by using Configure Project Specific Settings... link.
Click on OK to save the preferences.
摘自:
http://home.phpchina.com/space.php?uid=71776&do=blog&id=181715
http://www.spket.com/mootools-editor.html
1.下載安裝包含有Eclipse的Aptana Studio;
2.啟動Aptana,然後菜單:Help → Software Updates → Find and Install… → Search for new features to install → New remote site…
3.名稱可以輸入: “Spket”,URL是http://www.spket.com/update/
4.會提示重啟Aptana,重啟之;
5.Window → Preferences → Spket → JavaScript Profiles → New ;
6.輸入“ExtJS”點擊OK;
7.選擇“ExtJS”並點擊“Add Library”然後在下拉條中選取“ExtJS”;
8.選擇“ExtJS”並點擊“Add File”,然後在你的./ext-3.x/source目錄中選取“ext.jsb”文件;
(ext3.0正式版中不包含ext.jsb文件,需要手動Google一下找到rc版3.0中的ext.jsb,同樣可以使用)
9.設置新的ExtJS Profile,選中並點擊“JavaScript Profiles”對話框右手邊的“Defalut”按鈕;
10.重啟Aptana;
Create MooTools profile
Select the menu item Window > Preferences... to open the workbench preferences.
Select the Spket > JavaScript Profile preference page to display the installed JavaScript Profiles.
Click the New.. button. In the Name field, type MooTools as the name for the new profile. Then click OK.
Click the Add Library button. From the Library drop-down list, select MooTools. Then click OK.
Click the Add File button, choose mootools-xxx.js download from mootools.net (When choose compression type, No Compression is recommend)
Choose the MooTools profile created in step 3, click the Default button make it the default profile for all project. The default profile can also be configured per project by using Configure Project Specific Settings... link.
Click on OK to save the preferences.
摘自:
http://home.phpchina.com/space.php?uid=71776&do=blog&id=181715
http://www.spket.com/mootools-editor.html
用memcache來存儲session
PECL :: Package :: memcache 2.1.1 版本的Changelog 中有一條:
- Added experimental session storage support. You can use memcached as session storage.
也就是可以直接用memcache 來作PHP 的session.save_handler。
1. 安裝memcached
還是那套./configure; make; make install,注意memcached 用libevent 來作事件驅動,所以要先安裝有libevent。
2. 安裝pecl::memcache,用pecl 命令行工具安裝:
pecl install memcache
或直接從源碼安裝:
phpize
./configure
make
make install
將php.ini 中extension=memcache.so 打開,重啟一下apache,查看phpinfo 中的“Registered save handlers” 會有“files user memcache” 這3個可用。
3. 修改配置文件,在php.ini 中全局設置:
session.save_handler = memcache
session.save_path = “tcp://127.0.0.1:11211″
或者某個目錄下的.htaccess :
php_value session.save_handler “memcache”
php_value session.save_path “tcp://127.0.0.1:11211″
再或者在某個一個應用中:
ini_set(“session.save_handler”, “memcache”);
ini_set(“session.save_path”, “tcp://127.0.0.1:11211″);
使用多個memcached server 時用逗號”,”隔開,並且和Memcache::addServer() 文檔中說明的一樣,可以帶額外的參數”persistent”、”weight”、”timeout”、”retry_interval” 等等,類似這樣的:”tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2″ 。
4. 啟動memcached:
memcached -d -l 127.0.0.1 -p 11212 -m 128
5. 在程序中使用memcache 來作session 存儲,用例子測試一下:
session_start();
if (!isset($_SESSION['TEST'])) {
$_SESSION['TEST'] = time();
}
$_SESSION['TEST3'] = time();
print $_SESSION['TEST'];
print “
”;
print $_SESSION['TEST3'];
print “
”;
print session_id();
6. 用sessionid 去memcached 裡查詢一下:
$memcache = memcache_connect('localhost', 11211);
var_dump($memcache->get('19216821213c65cedec65b0883238c278eeb573e077′));
會有看到
string(37) “TEST|i:1177556731;TEST3|i:1177556881;”
這樣的輸出,證明session 正常工作。
用memcache 來存儲session 在讀寫速度上會比files 時快很多,而且在多個服務器需要共用session 時會比較方便,將這些服務器都配置成使用同一組memcached 服務器就可以,減少了額外的工作量。 缺點是session 數據都保存在memory 中,持久化方面有所欠缺,但對session 數據來說也不是很大的問題。
另外,WS Memcached Session Handler for PHP 提供一種用session_set_save_handler 來利用memcached 的方法。
- Added experimental session storage support. You can use memcached as session storage.
也就是可以直接用memcache 來作PHP 的session.save_handler。
1. 安裝memcached
還是那套./configure; make; make install,注意memcached 用libevent 來作事件驅動,所以要先安裝有libevent。
2. 安裝pecl::memcache,用pecl 命令行工具安裝:
pecl install memcache
或直接從源碼安裝:
phpize
./configure
make
make install
將php.ini 中extension=memcache.so 打開,重啟一下apache,查看phpinfo 中的“Registered save handlers” 會有“files user memcache” 這3個可用。
3. 修改配置文件,在php.ini 中全局設置:
session.save_handler = memcache
session.save_path = “tcp://127.0.0.1:11211″
或者某個目錄下的.htaccess :
php_value session.save_handler “memcache”
php_value session.save_path “tcp://127.0.0.1:11211″
再或者在某個一個應用中:
ini_set(“session.save_handler”, “memcache”);
ini_set(“session.save_path”, “tcp://127.0.0.1:11211″);
使用多個memcached server 時用逗號”,”隔開,並且和Memcache::addServer() 文檔中說明的一樣,可以帶額外的參數”persistent”、”weight”、”timeout”、”retry_interval” 等等,類似這樣的:”tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2″ 。
4. 啟動memcached:
memcached -d -l 127.0.0.1 -p 11212 -m 128
5. 在程序中使用memcache 來作session 存儲,用例子測試一下:
session_start();
if (!isset($_SESSION['TEST'])) {
$_SESSION['TEST'] = time();
}
$_SESSION['TEST3'] = time();
print $_SESSION['TEST'];
print “
”;
print $_SESSION['TEST3'];
print “
”;
print session_id();
6. 用sessionid 去memcached 裡查詢一下:
$memcache = memcache_connect('localhost', 11211);
var_dump($memcache->get('19216821213c65cedec65b0883238c278eeb573e077′));
會有看到
string(37) “TEST|i:1177556731;TEST3|i:1177556881;”
這樣的輸出,證明session 正常工作。
用memcache 來存儲session 在讀寫速度上會比files 時快很多,而且在多個服務器需要共用session 時會比較方便,將這些服務器都配置成使用同一組memcached 服務器就可以,減少了額外的工作量。 缺點是session 數據都保存在memory 中,持久化方面有所欠缺,但對session 數據來說也不是很大的問題。
另外,WS Memcached Session Handler for PHP 提供一種用session_set_save_handler 來利用memcached 的方法。
跨服務器Session共享
伴隨網站業務規模和訪問量的逐步發展,原本由單台服務器、單個域名的迷你網站架構已經無法滿足發展需要。
此時我們可能會購買更多服務器,並且啟用多個二級子域名以頻道化的方式,根據業務功能將網站分佈部署在獨立的服務器上;或通過負載均衡技術(如:DNS輪詢、Radware 、F5、LVS等)讓多個頻道共享一組服務器。
OK,頭腦中我們已經構思了這樣的解決方案,不過進入深入開發後新的技術問題又隨之而來:
我們把網站程序分佈部署到多台服務器上,而且獨立為幾個二級域名,由於Session受實現原理的局限(PHP中Session默認以文件的形式保 存在本地服務器的硬盤),使得我們的網站用戶不得不經常在幾個頻道間來回輸入用戶名、密碼登入,導致用戶體驗大打折扣;另外,原本程序可以直接從用戶 Session變量中讀取的資料(如:暱稱、積分、登入時間等) ,因為無法跨服務器同步更新Session變量,迫使開發人員必須實時讀寫數據庫,從而增 加了數據庫的負擔。
於是,解決網站跨服務器之間的Session共享方案需求變得迫切起來,最終催生了多種解決方案,下面列舉4種較為可行的方案進行對比探討:
1. 基於NFS的Session共享
NFS是Net FileSystem的簡稱,最早由Sun公司為解決Unix網絡主機間的目錄共享而研發。
這個方案實現最為簡單,無需做過多的二次開發,僅需將共享目錄服務器mount到各頻道服務器的本地session目錄即可,缺點是NFS依託於复 雜的安全機制和文件系統,因此並發效率不高,尤其對於session這類高並發讀寫的小文件, 會由於共享目錄服務器的io-wait過高,最終拖累前端WEB應用程序的執行效率。
2. 基於數據庫的Session共享
首選當然是大名鼎鼎的Mysql數據庫,並且建議使用內存表Heap,提高session操作的讀寫效率。 這個方案的實用性比較強,相信大家普遍在 使用,它的缺點在於session的並發讀寫能力取決於Mysql數據庫的性能,同時需要自己實現session淘汰邏輯,以便定時從數據表中更新、刪除 session記錄,當並發過高時容易出現表鎖,雖然我們可以選擇行級鎖的表引擎,但不得不否認使用數據庫存儲Session還是有些殺雞用牛刀的架勢。
3. 基於Cookie的Session共享
這個方案我們可能比較陌生,但它在大型網站中還是比較普遍被使用。 原理是將全站用戶的Session信息加密、序列化後以Cookie的方式,統一 種植在根域名下(如:.host.com),利用瀏覽器訪問該根域名下的所有二級域名站點時,會傳遞與之域名對應的所有Cookie內容的特性,從而實現 用戶的Cookie化Session 在多服務間的共享訪問。
這個方案的優點無需額外的服務器資源;缺點是由於受http協議頭信心長度的限制,僅能夠存儲小部分的用戶信息,同時Cookie化的 Session內容需要進行安全加解密(如:採用DES、RSA等進行明文加解密;再由MD5、SHA-1等算法進行防偽認證),另外它也會佔用一定的帶 寬資源,因為瀏覽器會在請求當前域名下任何資源時將本地Cookie附加在http頭中傳遞到服務器。
4. 基於Memcache的Session共享
Memcache由於是一款基於Libevent多路異步I/O技術的內存共享系統,簡單的Key + Value數據存儲模式使得代碼邏輯小巧高效,因此在並發處理能力上佔據了絕對優勢。
另外值得一提的是Memcache的內存hash表所特有的Expires數據過期淘汰機制,正好和Session的過期機制不謀而合,降低了過期Session數據刪除的代碼複雜度,對比“基於數據庫的存儲方案” ,僅這塊邏輯就給數據表產生巨大的查詢壓力。
基於Memcache 的存儲是這幾個方案中推薦選用的!
其它方案依然有其使用的場合,具體選用哪套需要開發人員的根據當前的服務器資源、網站並發壓力等綜合評估。
摘自:http://www.jiunile.com/?p=345
此時我們可能會購買更多服務器,並且啟用多個二級子域名以頻道化的方式,根據業務功能將網站分佈部署在獨立的服務器上;或通過負載均衡技術(如:DNS輪詢、Radware 、F5、LVS等)讓多個頻道共享一組服務器。
OK,頭腦中我們已經構思了這樣的解決方案,不過進入深入開發後新的技術問題又隨之而來:
我們把網站程序分佈部署到多台服務器上,而且獨立為幾個二級域名,由於Session受實現原理的局限(PHP中Session默認以文件的形式保 存在本地服務器的硬盤),使得我們的網站用戶不得不經常在幾個頻道間來回輸入用戶名、密碼登入,導致用戶體驗大打折扣;另外,原本程序可以直接從用戶 Session變量中讀取的資料(如:暱稱、積分、登入時間等) ,因為無法跨服務器同步更新Session變量,迫使開發人員必須實時讀寫數據庫,從而增 加了數據庫的負擔。
於是,解決網站跨服務器之間的Session共享方案需求變得迫切起來,最終催生了多種解決方案,下面列舉4種較為可行的方案進行對比探討:
1. 基於NFS的Session共享
NFS是Net FileSystem的簡稱,最早由Sun公司為解決Unix網絡主機間的目錄共享而研發。
這個方案實現最為簡單,無需做過多的二次開發,僅需將共享目錄服務器mount到各頻道服務器的本地session目錄即可,缺點是NFS依託於复 雜的安全機制和文件系統,因此並發效率不高,尤其對於session這類高並發讀寫的小文件, 會由於共享目錄服務器的io-wait過高,最終拖累前端WEB應用程序的執行效率。
2. 基於數據庫的Session共享
首選當然是大名鼎鼎的Mysql數據庫,並且建議使用內存表Heap,提高session操作的讀寫效率。 這個方案的實用性比較強,相信大家普遍在 使用,它的缺點在於session的並發讀寫能力取決於Mysql數據庫的性能,同時需要自己實現session淘汰邏輯,以便定時從數據表中更新、刪除 session記錄,當並發過高時容易出現表鎖,雖然我們可以選擇行級鎖的表引擎,但不得不否認使用數據庫存儲Session還是有些殺雞用牛刀的架勢。
3. 基於Cookie的Session共享
這個方案我們可能比較陌生,但它在大型網站中還是比較普遍被使用。 原理是將全站用戶的Session信息加密、序列化後以Cookie的方式,統一 種植在根域名下(如:.host.com),利用瀏覽器訪問該根域名下的所有二級域名站點時,會傳遞與之域名對應的所有Cookie內容的特性,從而實現 用戶的Cookie化Session 在多服務間的共享訪問。
這個方案的優點無需額外的服務器資源;缺點是由於受http協議頭信心長度的限制,僅能夠存儲小部分的用戶信息,同時Cookie化的 Session內容需要進行安全加解密(如:採用DES、RSA等進行明文加解密;再由MD5、SHA-1等算法進行防偽認證),另外它也會佔用一定的帶 寬資源,因為瀏覽器會在請求當前域名下任何資源時將本地Cookie附加在http頭中傳遞到服務器。
4. 基於Memcache的Session共享
Memcache由於是一款基於Libevent多路異步I/O技術的內存共享系統,簡單的Key + Value數據存儲模式使得代碼邏輯小巧高效,因此在並發處理能力上佔據了絕對優勢。
另外值得一提的是Memcache的內存hash表所特有的Expires數據過期淘汰機制,正好和Session的過期機制不謀而合,降低了過期Session數據刪除的代碼複雜度,對比“基於數據庫的存儲方案” ,僅這塊邏輯就給數據表產生巨大的查詢壓力。
基於Memcache 的存儲是這幾個方案中推薦選用的!
其它方案依然有其使用的場合,具體選用哪套需要開發人員的根據當前的服務器資源、網站並發壓力等綜合評估。
摘自:http://www.jiunile.com/?p=345
2010年8月1日 星期日
膜拜Redis
Redis的介紹
數據庫主要類型有對像數據庫,關係數據庫,鍵值數據庫等等,對像數據庫太超前了,現階段不提也罷;關係數據庫就是平常說的MySQL,PostgreSQL這些熟的不能再熟的東西,至於鍵值數據庫則是本文要著重說的,其代表主要有MemcacheDB,Tokyo Cabinet等等。
Redis本質上也是一種鍵值數據庫的,但它在保持鍵值數據庫簡單快捷特點的同時,又吸收了部分關係數據庫的優點。 從而使它的位置處於關係數據庫和鍵值數據庫之間。 Redis不僅能保存Strings類型的數據,還能保存Lists類型(有序)和Sets類型(無序)的數據,而且還能完成排序(SORT)等高級功能,在實現INCR,SETNX等功能的時候,保證了其操作的原子性,除此以外,還支持主從復制等功能。
詳細描述參見官方手冊,同時,官方提供了一個名為Retwis的項目的源代碼,可以對照著官方介紹學習,注意其中關於Data Layout的描述,其他沒什麼。
項目實踐中,多以關係數據庫為主,不過合理的使用Redis這樣的鍵值數據庫,往往能揚長避短,比如說實現一個類似消息隊列的功能,對MySQL來說,除非使用Q4M,否則很難滿足高並發請求,不過對Redis來說,通過內建的Lists支持,消息隊列就是小菜一碟。
Redis的安裝
tar zxvf redis-version.tar.gz
cd redis-version
make
由於沒有make install,所以得把源代碼目錄裡的關鍵文件手動複製到適當的位置:
cp redis.conf /etc/
cp redis-benchmark redis-cli redis-server /usr/bin/
如果內存情況比較緊張的話,需要設定內核參數:
echo 1 > /proc/sys/vm/overcommit_memory
然後編輯redis.conf配置文件(/etc/redis.conf),按需求做出適當調整,比如:
daemonize yes
logfile /dev/null
如果要記錄日誌的話,最好先調整loglevel到一個合適的級別,然後設定logfile,如果不需要,則可以像上面這樣直接把日子丟棄到/dev/null裡,還有一點,缺省情況下,數據文件dump.rdb會被生成到當前目錄,可以通過dir參數設定合適的目錄。
此外,如果你決定把Redis用於產品環境,還要注意maxmemory選項,因為Redis在啟動時會把所有數據加載到內存中,所以設定maxmemory相對安全。
接下來直接啟動服務就可以了,只有配置文件一個參數:
redis-server /etc/redis.conf
確認運行了之後,可以用redis-benchmark命令測試看看,還可以通過redis-cli命令實際操作一下,比如:
redis-cli set foo bar
OK
redis-cli get foo
bar
在設置鍵對應的值的時候,按照協議的規定是要提供數據大小這個參數的,上面的redis-cli命令之所以沒有提供這個參數是因為redis-cli本身進行了封裝。
可以通過telnet來驗證一點:
telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
set foo 3
bar
+OK
get foo
$3
bar
^]
telnet> quit
Connection closed.
更多命令介紹參考文檔介紹。
Redis源代碼裡附帶了多種客戶端的擴展,比如說php(client-libraries/php),這是一個純PHP的實現方案,也有二進製版本的實現(phpredis)。 其他語言即便沒有現成的擴展實現,也可以自己按照協議規範寫一個擴展,應該不是什麼難事。
Redis內存要求很高,如果你的數據量很大的話,可能會導致系統使用swap,這會使性能急劇下降。 此時更好的方法是通過consistent hashing把數據分佈到多個服務器上,文檔上給出了簡單的例子解釋:
For example imagine to have N Redis servers, server-0, server-1, ..., server-N. You want to store the key "foo", what's the right server where to put "foo" in order to distribute keys evenly among different servers? Just perform the crc = CRC32("foo"), then servernum = crc % N (the rest of the division for N). This will give a number between 0 and N-1 for every key. Connect to this server and store the key.
在線演示:
http://try.redis-db.com/
參考鏈接:
http://redis.io/
http://github.com/jdp/redisent/tree/master
http://github.com/owlient/phpredis
http://rediska.geometria-lab.net/javascript:void(0)
數據庫主要類型有對像數據庫,關係數據庫,鍵值數據庫等等,對像數據庫太超前了,現階段不提也罷;關係數據庫就是平常說的MySQL,PostgreSQL這些熟的不能再熟的東西,至於鍵值數據庫則是本文要著重說的,其代表主要有MemcacheDB,Tokyo Cabinet等等。
Redis本質上也是一種鍵值數據庫的,但它在保持鍵值數據庫簡單快捷特點的同時,又吸收了部分關係數據庫的優點。 從而使它的位置處於關係數據庫和鍵值數據庫之間。 Redis不僅能保存Strings類型的數據,還能保存Lists類型(有序)和Sets類型(無序)的數據,而且還能完成排序(SORT)等高級功能,在實現INCR,SETNX等功能的時候,保證了其操作的原子性,除此以外,還支持主從復制等功能。
詳細描述參見官方手冊,同時,官方提供了一個名為Retwis的項目的源代碼,可以對照著官方介紹學習,注意其中關於Data Layout的描述,其他沒什麼。
項目實踐中,多以關係數據庫為主,不過合理的使用Redis這樣的鍵值數據庫,往往能揚長避短,比如說實現一個類似消息隊列的功能,對MySQL來說,除非使用Q4M,否則很難滿足高並發請求,不過對Redis來說,通過內建的Lists支持,消息隊列就是小菜一碟。
Redis的安裝
tar zxvf redis-version.tar.gz
cd redis-version
make
由於沒有make install,所以得把源代碼目錄裡的關鍵文件手動複製到適當的位置:
cp redis.conf /etc/
cp redis-benchmark redis-cli redis-server /usr/bin/
如果內存情況比較緊張的話,需要設定內核參數:
echo 1 > /proc/sys/vm/overcommit_memory
然後編輯redis.conf配置文件(/etc/redis.conf),按需求做出適當調整,比如:
daemonize yes
logfile /dev/null
如果要記錄日誌的話,最好先調整loglevel到一個合適的級別,然後設定logfile,如果不需要,則可以像上面這樣直接把日子丟棄到/dev/null裡,還有一點,缺省情況下,數據文件dump.rdb會被生成到當前目錄,可以通過dir參數設定合適的目錄。
此外,如果你決定把Redis用於產品環境,還要注意maxmemory選項,因為Redis在啟動時會把所有數據加載到內存中,所以設定maxmemory相對安全。
接下來直接啟動服務就可以了,只有配置文件一個參數:
redis-server /etc/redis.conf
確認運行了之後,可以用redis-benchmark命令測試看看,還可以通過redis-cli命令實際操作一下,比如:
redis-cli set foo bar
OK
redis-cli get foo
bar
在設置鍵對應的值的時候,按照協議的規定是要提供數據大小這個參數的,上面的redis-cli命令之所以沒有提供這個參數是因為redis-cli本身進行了封裝。
可以通過telnet來驗證一點:
telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
set foo 3
bar
+OK
get foo
$3
bar
^]
telnet> quit
Connection closed.
更多命令介紹參考文檔介紹。
Redis源代碼裡附帶了多種客戶端的擴展,比如說php(client-libraries/php),這是一個純PHP的實現方案,也有二進製版本的實現(phpredis)。 其他語言即便沒有現成的擴展實現,也可以自己按照協議規範寫一個擴展,應該不是什麼難事。
Redis內存要求很高,如果你的數據量很大的話,可能會導致系統使用swap,這會使性能急劇下降。 此時更好的方法是通過consistent hashing把數據分佈到多個服務器上,文檔上給出了簡單的例子解釋:
For example imagine to have N Redis servers, server-0, server-1, ..., server-N. You want to store the key "foo", what's the right server where to put "foo" in order to distribute keys evenly among different servers? Just perform the crc = CRC32("foo"), then servernum = crc % N (the rest of the division for N). This will give a number between 0 and N-1 for every key. Connect to this server and store the key.
在線演示:
http://try.redis-db.com/
參考鏈接:
http://redis.io/
http://github.com/jdp/redisent/tree/master
http://github.com/owlient/phpredis
http://rediska.geometria-lab.net/javascript:void(0)
訂閱:
文章 (Atom)