2008年11月20日
[Web] 連結分享
PHP
- PHP 5 - Online Cheat Sheet
- PHP Bytecode in Binnavi 2.0
- Top 25 PHP template engines
- 3分鐘讓程式透過msn發送訊息,php篇(一)
- image diff
- Making web-pages go faster using PHP
- 深入PHP编译缓存
- 10 Advanced PHP Tips To Improve Your Programming
- PHP Framworks !! Why , when and which ?
Zend Framework
JavaScript
- Render Text With Javascript: Typeface.js
- How I write JavaScript Widgets
- Super Tables - HTML Tables with Fixed Headers and More
- Delaying Javascript Event Execution
- Multi-threading in JavaScript
- 匿名函數遞迴又一章
jQuery
- Hi! I'm trying HARD to be a jQuery Robot
- (jquery plugin)chili 2.2
- 優秀jQuery插件及網站16個,附圖!
- 5 Tips for Better jQuery Code
- Old School Clock with CSS3 and jQuery
- jQuery Delay Plugin
- jQuery & CSS Tooltip Example
CSS
- Equal Height Columns with Cross-Browser CSS & No Hacks
- What Are The Benefits of Using a CSS Framework?
- CSS Browser Selector
- Architecting CSS
- CSS - Contents and compatibility
- CSS Compatibility updated
- Hartija - Css Print Framework
- 10 Técnicas para Reset CSS
- 10 Excellent CSS Tips and Tutorials
- CSS shorthand properties
- 21 ways to streamline your CSS
- Image Mapping with CSS
Web Development
- The Best Cheat Sheets for Web Developers
- The Use of Meta Tags For Search Engine Optimization
- IE 下 href 的 BUG
Database
MySQL
Project
Security
Software
System
- 透過 Samba 在 Windows XP (Host) 與 VMware Ubuntu (Guest) 中共用檔案
- 透過 Samba 在 Windows XP (Host) 與 VMware Ubuntu (Guest) 中共用檔案
Other
2008年11月17日
[JavaScript] 複製物件
前幾天遇到了一個 JavaScript 的小問題,就是物件的複製。
這個問題主要是我先設定了一個全域變數,然後在函式裡去重新定義一個變數,並將全域變數的內容指定給新變數。
我以為這樣就是「複製了 JavaScript 的物件」,但事實上是錯的。
我特地上網找了一下,發現 JavaScript 本身並沒有提供比較方便的 clone 機制,這時我的腦筋就動到 jQuery 上了。
不過這裡我可不是說 jQuery 的 clone 方法,而是 extend 方法。
先來看看例子好了:
<html>
<head>
<script type="text/javascript" src="jquery/1.2.6.js"></script>
<script type="text/javascript">
function w(s) {
document.write(s + '<br />\n');
}
function d(o) {
var s = '';
for (var i in o) {
s += i + ': ' + o[i] + '<br />\n';
}
w(s);
}
</script>
</head>
<body>
<script type="text/javascript">
var o1 = {
a1: '123',
a2: '456'
};
var o2 = o1;
$.extend(o2, { a3: '789' });
var o3 = $.extend({}, o1);
$.extend(o3, { a4: '000' });
w('o1');
d(o1);
w('o2');
d(o2);
w('o3');
d(o3);
</script>
</body>
</html>
在上面的程式中,請將重點放在我強調的部份。
這裡我先定義一個自訂物件 o1 ,然後我將 o2 指定為 o1 ;在 JavaScript 的意義裡, o2 就會是 o1 的「別名」,兩個都指到同一個物件。
因此接下來我對 o2 進行任何操作,都會影響到 o1 ;也就是說如果我們要複製 o1 的話,就不能用等號 (=) 。
jQuery 的 extend 方法可以幫我們這個忙。
原因是 extend 會將第二個參數裡的物件成員,一項一項地複製到第一個參數上。因此我們可以用它來解決 JavaScript 複製物件的問題。
在 o1 複製到 o3 中,很重要的一個關鍵就是我們需要把 $.extend 的第一個參數設為空物件;這是因為 $.extend 會回傳第一個參數,我們就省掉先行定義 o3 為空物件的動作了。
接下來我們不論怎麼對 o3 進行處理,也不會影響到 o1 ;換句話說,我們已經成功達成 clone JavaScript Object 的目標啦。
2008年11月2日
[Web] 連結分享
PHP
- PHPUnit 3.3.2
- [PHP]好用的上傳 pear 模組 HTTP_Upload
- pChart - PHP charting library
- FirePHP 0.2 Released
- Bootstrap PHP code
- PHP Tutorials Utopia: 13 Vital PHP skills for every novice PHP developer and solutions
- 重定向简单么?不,它很复杂!
Zend Framework
- Using Action Helpers in Zend Framework
- ZendFramework performance
- Tinyizing URLs with Zend_Http_Client
JavaScript
- RobotAway線上Demo
- JavaScript OOP: encapsulation, durable objects, parasitic inheritance and the decorator pattern
jQuery
- jQuery plugin: word-counter for textarea
- jQuery plugin - HTML decode and encode
- Create a professional interface for your web applications using jQuery | yensdesign - Tutorials, Web Design and Coding
- jQuery Plugin - Stupid Fixed Header for HTML Table
- jQuery URL Parser
- 使用 jQuery 简化 Ajax 开发
- Creating a jQuery Dashboard
CSS
- How to: CSS Large Background
- What Are The Benefits of Using a CSS Framework?
- The Problem with CSS is ...
- Creating a Virtual jQuery Keyboard
- Why “variables” in CSS are harmful
- CSSHttpRequest
- Uber Round Color Tabs
- Creating easy and useful CSS Sprites
- Peppy - Super Fast CSS 3 Compliant Selector Engine
- 無名版面設計 - css規則限制的迷思(一)
- Cross Browser CSS Fixes, Tools, and Hacks
Web Development
Database
MySQL
- MySQL Master-Master Replication Manager(1) - 簡介
- MySQL Master-Master Replication Manager(2) - 環境建置、架設
- MySQL Master-Master Replication Manager(完) - 問答
- JOIN Performance & Charsets
- Creating a cross tab in MySQL
Security
Service
System
Other
2008年10月20日
[Web] 連結分享
PHP
- phpQuery - PHP 處理 HTML DOM 的好幫手阿!
- PHP 判斷 Header 送出前, 是否有值被送出去: headers_sent()
- [PHP]如何把 Yahoo! BBAuth 加入網站入口認證
- 可怕的 phpmyadmin ,刪除操作要養成看訊息的習慣
- Specifications for PHP5
- Becoming a Kick-ass PHP ninja
- PHP 判斷網址是否正確 / 網頁是否存在
- PHP 設定 session 的過期時間
- HTML2PDF using PHP
- 安裝 PHP bcompile 做 編譯/加密 原始碼
- PHP session 暫存檔過多的注意事項
- PHP Temporary Streams
- PHP负载均衡指南
Zend Framework
- Zend Launches Zend Framework Certification
- Zend Framework and the Twitter API
- Scraping websites with Zend_Dom_Query
JavaScript
- JS Bin - Collaborative JavaScript Debugging
- js.io - JavaScript Network Library
- NiftyPlayer - a small and simple Flash MP3 player!
- Parsing the Querystring
- 50 Excellent AJAX Tutorials
jQuery
- Flip! A jQuery plugin
- jQuery, Microsoft, and Nokia
- jQuery, Microsoft 及 Nokia 的合作
- Content, Presentation, Behavior and Border Layouts
- 10 useful jQuery plugins
- Dynamic Drive CSS Library- jQuery Multi Level CSS Menu #1
- jQuery Progress Indicators
- jQuery & CSS Example - Dropdown Menu
- jQuery Feed Menus
- 20 jQuery Plugins for Unforgettable User Experience
- jQuery: constrain input chars plugin
- Create simple tooltips with CSS and jQuery
- Starting With jQuery - How to Write Custom Validation Rules
- jQuery - sorting DIVs by date
CSS
- How to make CSS Sprites
- Styling Scrollable Areas
- 10 CSS shorthand techniques you’ll use everyday
- Liquid & Color Adjustable CSS Buttons
- CSS Systems for writing maintainable CSS
- Sexy Panels Vertical Menu
- Is There Anything You Wish CSS Could Do? 15 Designer/Developers Sound Off
- NICCAI - Maintainable CSS using IE specific CSS selectors
- The 7 CSS Hacks that we should use
- Purely CSS Callouts
- Animated GIF For CSS Sprites
- Inline 'block' links
Database
MySQL
Design
Web Development
HTML
Browser
- Sample debug session with Google Chrome JavaScript debuger
- Abduction! v2.026 幫你將「整個網頁」全部抓圖下來!(Firefox擴充套件)
- Deviations : Debug Jscript with Internet Explorer 8
- Javascript console in IE
Programming
Project
SCM
Security
Software
System
2008年10月16日
[PHP] Smarty 樣版小技巧整理
在 Smarty 中,我們可以用以下的語法來完成類似 for 迴圈的效果:
{section name="forLoop" start=1 loop=10}
{/section}
其中 start 即為起始值, loop 為小於而不等於的終值。
如果以 PHP 語法來表示,則如下所示:
for ($i = 1; $i < 10; $i ++) {
// ...
}
使用無參數原生 PHP 函式
我們可以在樣版中使用許多原生的 PHP 函式 (但還是有例外) 來當做變數修飾函式,不過如果有些函式不需要參數時,我們可以用以下語法來呼叫:
{''|@time}
當然這裡的空字串對 time 函式來說是沒有意義的,而在函式前加上 @ 號,表示要直接呼叫原生 PHP 函式。
在 assign 設定 default 值
假設當樣版變數不存在或可轉換為 false 值時,我們會希望顯示一個預設值;而 Smarty 剛好就提供了一個 default 變數修飾函式讓我們使用,語法如下:
{$test|default:'NULL'}
而 default 變數修飾函式不僅只有在呈現變數能用,也能在樣版 assign 變數時使用,如下:
{assign var=value2 value=$value1|default:0}
註:當然不只有 default ,幾乎所有變數修飾函式都能在 assign 或其他可接受變數的樣版函式裡使用。
物件導向語法
Smarty 也支援 PHP 的物件導向語法,例如呼叫某物件函式:
{$test->getFakeValue()}
我們也能在樣版函式中,使用物件導向語法,而且後面也能串接變數修飾函式:
{assign var=nullValue value=$test->getNullValue()|default:'NULL'}
利用 config 變數或常數來當做變數修飾函式的參數
通常我們會用到設定值來避免重複設定一些常數值,例如用 PHP 陣列的方式指定給 Smarty :
$config = array(
'date' => '%Y/%m/%d',
'time' => '%H:%M',
);
$smarty->assign($config);
在樣版裡就可以這樣用:
{$date|date_format:$config.date}
我們也可以利用 PHP 的常數來當做設定,在樣版可以用「 $smarty.const.常數名稱」來取得常數內容:
{$date|date_format:$smarty.const.DATE_FORMAT}
當然,我們也可以透過 Smarty 內建的 config 機制;例如我們有個 config.conf ,內容如下:
date = "%Y/%m/%d"
time = "%H:%M"
然後在樣版內改用:
{config_load file="config.conf"}
{$date|date_format:#date#} {$time|date_format:#time#}
其中 #date# 與 #time# 就是從 config.conf 中讀取的。
註:感謝 Smarty 頭號粉絲 - 小魚提供以上技巧。
用 {cycle} 配合 CSS 來做表格列交替變色
我們可以用 cycle 配合 sction 或 foreach ,來做出交替變色的表格,語法如下:
{secion ....}
.....
<tr class="{cycle values="normal,alt"}">
.....
{/secion}
可以看出,它比使用 {if} 來得簡潔許多:
<tr class="{if $smarty.section.forLoop.iteration is odd}normal{else}alt{/if}">
註:感謝 Smarty 頭號粉絲 - 小魚提供以上技巧。
如果還有相關技巧的話,將會陸續再更新。
[PHP] Session 相關文章
身為 PHP 開發者,我其實對 PHP Session 的處理機制還是一知半解。
這次因為有個大案子上線的關係,讓我真的遇到了 Session 過多的問題。
這裡強力推薦宗董寫的一篇好文: PHP session 暫存檔過多的注意事項。
不過基本上在連線數會很高的網站,還是建議使用 MySQL 或 memcache 來當做 Session 的儲存媒體。
如果要使用 MySQL 的話,我們可以利用 session_set_save_handler 來建立資料庫連線並存取 Session 資料。
而使用 memcache 的話,可以參考 PHP 官方提供的方法,程式如下:
<?php
$host = 'localhost';
$port = '11211';
$session_save_path = "tcp://$host:$port?persistent=1&weight=2&timeout=2&retry_interval=10, ,tcp://$host:$port ";
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', $session_save_path);
希望以上的資訊能提供大家對 PHP 處理 Session 有更進一步的瞭解。
2008年09月23日
Bug Tracker 安裝紀錄
我之前介紹過 Trac 這個軟體的安裝及簡略的使用方式,但是 Trac 是一套基於 Python 開發的軟體缺陷追蹤系統,在安裝上有一定的複雜度。
這次,我推薦大家一套國人自行開發的 Bug Tracker ,它是一套以 PHP 所開發的軟體缺陷追蹤系統,相當適合不想安裝複雜開發環境的 PHP 開發者使用。
這裡有 Neo 寫的簡介:國人自製 Bug Tracker 。
下載
網址: http://www.twbsd.org/cht/bug_tracker/index.php?page=download.htm
在「按此下載」的連結上點一下,把 BugTracker-2.x.x.tar.gz 存放到網站根目錄就可以了。
安裝
Bug Tracker 號稱安裝非常容易,但其實在 PHP5 的環境上,還是有一些要特別注意的地方。
解開剛剛的 BugTracker-2.x.x.tar.gz ,然後我們會得到一個 bug 目錄;所以到時候我們可以用 http://localhost/bug 的網址來使用這套系統。
假設你的開發環境是 PHP5 ,那麼 short_open_tag 這個選項預設應該是 Off 。而 Bug Tracker 的程式碼大部份都是以 <? 開頭,因此我們需要把 short_open_tag 設為 On 。
不過因為我個人不喜歡去更動系統預設值,所以我改用 .htaccess 來改變 short_open_tag 的設定。請將以下內容存為 .htaccess 後,存在 bug 資料夾下。
php_flag short_open_tag on
接著我們要修改應用程式的設定,請用文字編輯器開始 bug/include/config.php ,找到:
$GLOBALS['BR_dbtype'] = "postgres";
將它註解掉 (前面加上 //) 。
然後取消以下程式碼開頭的註解:
$GLOBALS['BR_dbtype'] = "mysqlt";
然後往下看到:
$GLOBALS['BR_dbpwd'] = "";
在設定值上寫上 MySQL 的 root 密碼,讓程式可以自動建立資料庫。
最後修改應用程式的路徑:
$GLOBALS["SYS_PROJECT_PATH"] = '/home/synosrc/bug';
將 /home/synosrc/bug 改為你安裝程式的路徑。
現在開啟以下連結,進行安裝動作:
http://localhost/bug/setup/
基本上就是一直按 Next Step 而已,安裝程式會告訴你一切需要的資訊,並自動執行相關的動作。
安裝完後,請記得移除 bug/setup 這個資料夾。
這樣就完成安裝 Bug Tracker 囉~
設定語系
一開始 Bug Tracker 的登入畫面是正體中文:
![]()
但用 admin 登入後,我們會發現預設的語系還是英文的:
![]()
這時我們可以點選上面的 System (系統設定) 功能,然後選擇 Preference (偏好設定) 項目,將 System Language (系統語言) 改為 Chinese Traditional 即可。
搭配 Subversion 使用
Bug Tracker 目前還沒辦法像 Trac 一樣直接支援 Subversion ,也就是說它目前無法直接讓專案回報與源碼相結合。
這裡我找到一篇反過來讓 TortoiseSVN 配合 Bug Tracker 使用的文章:如何設定 TortoiseSVN 整合 Bug Tracker 系統。
依照文章上的解說,我們可以在 Subversion 的 log 上直接連結到 Bug Tracker 回報的畫面。
其實 PHP 是可以支援 Subversion 的,但必須配合 php_svn 這個外掛模組。不過 php_svn 還不支援新版的 Subversion ,這是比較可惜的地方。請參考:安裝php_svn.dll 。
結論
其實不論是團隊合作還是個人開發,一套好的追蹤系統都可以協助我們管理好專案的進度;而 Bug Tracker 可以說是慣用中文的 PHP 開發者一個不錯的選擇。
大家有任何使用上的經驗嗎?也歡迎分享喔~
[jQuery] IE 上的 clone 陷阱
前陣子在處理客戶更改版面的需求時,為了偷懶,結果發現了一個 jQuery 在 IE 上 clone 元素的問題。
先簡單說明一下例子:

如上圖所示,我希望在按下「複製」按鈕後,藍色區塊中的 checkbox 被勾選的項目會被複製到紅色區塊中:

這裡我簡單的使用 jQuery 的 clone 方法來完成它,原始程式如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>測試</title>
<script type="text/javascript" src="jquery/1.2.6.js"></script>
<script type="text/javascript">
$(function () {
$('#copy').click(function () {
$('#target').html('').append($('input.test:checked').clone());
});
});
</script>
</head>
<body>
<div id="source" style="border:1px solid #33F; padding: 20px; width: 200px;">
<input type="checkbox" name="test[]" class="test" value="1" />
<input type="checkbox" name="test[]" class="test" value="2" />
<input type="checkbox" name="test[]" class="test" value="3" />
<input type="checkbox" name="test[]" class="test" value="4" />
</div>
<br />
<div id="target" style="border:1px solid #F33; padding: 20px; width: 200px;">
</div>
<br />
<input type="button" value="複製" id="copy" />
</body>
</html>
在非 IE 的瀏覽器上, jQuery 的 clone 方法可以正確的把已勾選的 checkbox 的 checked 狀態複製下來,但在 IE 上卻不行,如下圖:

所以這裡只好針對 IE 再進行一次特別的處理:
$(function () {
$('#copy').click(function () {
var $checkedValues = $('input.test:checked').clone();
if ($.browser.msie) {
$checkedValues.attr('checked', true);
}
$('#target').html('').append($checkedValues);
});
});
原理很簡單,就是遇到 IE 時,再將複製下來的 checkbox 的 checked 屬性設為 true 即可。
補充:IE6 的逆襲
不過上述程式在 IE6 又會出現問題了,在 IE6 上執行時,會發現 checked 屬性無法正常被設為 true 。
雖然沒有深入去研究,但我猜想是 IE6 在處理 DOM 時的問題,因此我祭出了 setTimeout 大法:
$(function () {
$('#copy').click(function () {
var $checkedValues = $('input.test:checked').clone();
if ($.browser.msie) {
setTimeout(function () { $checkedValues.attr('checked', true); }, 0);
}
$('#target').html('').append($checkedValues);
setTimeout(function () {
// 其他可能會對處理到 checkbox 的動作
}, 0);
});
});
這裡 setTimeout 可以確保程式在 DOM 完全更新後,再執行下一步的動作。
