Author Archives


11
Feb 10

Cache Zend_Db_Table MetaData with Zend_Cache

In this afternoon, my boss asked me to improving performance of project to release to client before we have Lunar new year holidays. The problem has too many DESCRIBE queries on every page load. I Google-ed & found the Lysender’s solution, simple & easy to fix this problem:

When you are using Zend_Db_Table (I sometimes only used Zend_Db) you will notice that when you try to retrieve data from the database, the first query called is to DESCRIBE the table. Zend_Db_Table uses the information on DESCRIBE query to do its magic on SELECT.

As I have profiled my queries, I noticed that DESCRIBE query is the longest query (in most cases) which mean a big overhead over you retrieval operation. You have two options:

  1. Don’t use Zend_Db_Table (go for Zend_Db)
  2. Cache the MetaData

On this post, I’ll use the caching of MetaData. On your bootstrap file, put this piece of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
	//Caching
	$frontendOptions = array(
					'lifetime'				 => 25200,
	    				'automatic_serialization' => true
	    				);
	$backendOptions  = array(
	   					 'cache_dir'  => APPLICATION_PATH . '/tmp'
	    				);
	$cache = Zend_Cache::factory(
				'Core',
	                        'File',
	                        $frontendOptions,
	                        $backendOptions
	                    );
	//Cache table metadata
	Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);

The code simply instructs Zend_Db_Table_Abstract to cache the result of DESCRIBE statement so that next time you retrieve data, the cache is used instead of repeatedly describing tables over and over again.

(But I noticed that INSERT and UPDATE statements don’t have DESCRIBE…)

After several tries with this caching, you will see files on the tmp folder like this: zend_cache—internal-metadatas—5e7576e3cd79114d46850714e998a3b0.

Still there is an overhead on reading the cache file. If you want better caching, use memory based caching like MemCache.

Source: http://lysender.co.cc/2009/03/zend-framework-optimization-tips

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

1
Feb 10

Overtime

Lâu rồi mới phải làm overtime (OT) thế này. Hôm thứ 7 vừa rồi phải ngồi lại cty đến hơn 12h đêm mới về :( Rồi lại đưa chị Thủy “tét” (vs với con dở Thủy top :D ) về nhà cho an tòan, về đến nhà cũng hơn 1h sáng rồi. Log effort 14h mới kinh :”>

Nói chung là nếu hạn chế được overtime là tốt nhất, dĩ nhiên rồi. Nhưng thỉnh thoảng có 1 vài hôm phải OT cũng hay, vì nó phần nào cũng chỉ thêm được cho chúng ta biết, team chúng ta làm việc với nhau như thế nào, hỗ trợ nhau ra sao…

Tự nhiên thấy mệt mỏi, mệt mỏi vì cứ phải gặp những kẻ lưỡi dẻo & dài, những kẻ khoái “nổ”, những kẻ ăn có nói không… haizz…

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

18
Nov 09

IE message: Operation aborted

Few days ago, I assigned a task to fix a problem: IE showed an error message box and crashed when load a heavy page (it took about 40-50s to load completly) .

I thought, maybe cause of problem is Javascript (syntax error) and I checked whole the page. Hix, nothing happened :( After I Googled, I found the main reason are:

  1. The HTML file is being parsed
  2. Script is executing
  3. The executing script attempts to add, or remove an element from an unclosed ancestor in the markup tree (not including the script block’s immediate parent element).

So I refactored code by move all JS function call into $(document).ready( … ) (I used jQuery) to make sure the script will be excute after the page loaded successful. whew, the problem has been resolved :)

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

1
Nov 09

Determining the Number of Days in a Month with Javascript

Cuối tuần vừa rồi, bác Cảnh (my leader) có triển khai 1 task cho tôi với nội dung là: “chỉnh lại core của con calendar.js để ngày mặc định khi hiệp popup calendar sẽ là ngày hiện tại cộng một” (dĩ nhiên nếu đã nhập ngày trước đó rồi thì vẫn phải focus đúng).

Rất may là con calendar của tác giả Alf Magne Kalleland đã xử lý việc focus ngày nếu text field đã có giá trị nên việc của tôi lúc này khá nhàn hạ:

- Nếu textfield đã có giá trị rồi thì ko làm gì cả
- Nếu chưa có:
+ Lấy ngày hiện tại & cộng thêm 1 đơn vị
+ Nếu giá trị vừa cộng > tổng số ngày trong tháng hiện tại thì tăng tháng lên 1 đơn vị & ngày hiện tại = 1
+ Nếu tháng vừa cộng > 12 thì tăng năm hiện tại lên 1, ngày & tháng hiện tại = 1

Cái khó ở đây chính việc xác định tổng số ngày trong tháng bằng Javascript. Khó ở đây không phải thuật toán, khó ở đây chỉ đơn giản là làm thế nào để viết…càng ngắn càng tốt.

Nếu làm theo kiểu như trong các sách họp lập trình hoặc trong trường học thì sẽ phải if else (switch case) các tháng 30 ngày (4, 6, 9, 11), tháng có 31 ngày (1, 3, 5, 7, 8, 10, 12) và tháng 2 có 28 ngày (năm nhuận sẽ là 29). Ở đây lại phải xác định năm nhuận là năm như thế nào (chia hết cho 400), dài dòng ghê :p

Đối tượng Date của Javascript cho quá tải tham số date truyền vào & sẽ tự động tính toán số dư ngày thừa ra đó theo ngày hiện tại. Do đó để tính số ngày trong 1 tháng bằng Javascript chỉ cần dùng 1 dòng sau:

[-]?View Code JAVASCRIPT
1
2
3
4
function daysInMonth(iMonth, iYear)
{
    return 32 - new Date(iYear, iMonth, 32).getDate();
}

Keke… vậy là task 1 giờ đã được giải quyết trong vòng chưa đầy 5′. Suỵt, bí mật :D

Source: http://snippets.dzone.com/posts/show/2099

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

31
Oct 09

Use synchronous request in jQuery.ajax

Đã bao giờ bạn sử dụng AJAX (jQuery) để check username tồn tại như sau chưa?

[-]?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function checkUser(u) {
    var isExist = false;
    $.post(
        'index.php',
        {'username': u},
        function(ret) {
            isExist = ret;
        }
    );
 
    return isExist;
}
 
if( checkUser('donamkhanh') ) {
    alert('donamkhanh already exist');
}
else {
    alert('donamkhanh does not exist');
}

Theo bạn, nếu chạy đoạn mã trên thì sẽ ra kết quả nào (giả sử rằng server script hoàn toàn chạy chính xác, trả về giá trị true/false hay 1/0 gì đó & username donamkhanh đã tồn tại)?

Do mặc định trong jQuery tất cả các request đều được sent asynchronous nên trong quá trình send request thì hàm checkUser đã return luôn giá trị lúc khởi tạo biến isExist = 0 rồi. Vậy nên kết quả luôn thông báo là username donamkhanh chưa tồn tại :)

Cách fix rất đơn giản, sử dụng thuộc tính async của $.ajax. Các hàm $.post hay $.get không có thuộc tính này vì

This is jQuery’s low-level AJAX implementation. See $.get, $.post etc. for higher-level abstractions that are often easier to understand and use, but don’t offer as much functionality (such as error callbacks).

Code ở trên sẽ sửa lại như sau:

[-]?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function checkUser(u) {
    var isExist = false;
    $.ajax({
        async: false,
        type: "POST",
	url: "ajax.php",
	data: "username=" + u,
	success: function(msg){
	     isExist = msg;
	}
    });
 
    return isExist;
}

Nếu set async = false, jQuery sẽ sử dụng synchronous cho các request. Ở ví dụ này bạn có thể thấy nó chưa thực sự cần thiết (vì có thể nhét đoạn check vào luôn trong callback function của $.post, $.get hay bất cứ ajax method nào của jQuery), tuy nhiên nếu bạn phải viết nhiều hàm (ajax) và các hàm này lấy kết quả của nhau để tính toán thì việc set synchronous là bắt buộc. Nếu không thì sẽ xảy ra tình trạng nhiều biến nhiều hàm lon ton cầm đèn dầu chạy trước ô tô ^^

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

9
Oct 09

Enable windows Vista Aero glass transparency effect

Nếu như phần cứng đáp ứng đủ yêu cầu tối thiểu để sử dụng hiệu ứng Aero glass transparency mà Windows vẫn không chịu enable hiệu ứng đấy lên thì làm như sau:

  1. Go to Start button, then click on Run.
  2. Run “regedit”.
  3. Browse and navigate to HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ registry branch.
  4. On the following registry subkeys, edit and change the default value:Composition to 1
    CompositionPolicy to 2
  5. Exit registry editor.
  6. Go to Start and click on Run again.
  7. Execute and run the following commands one by one:

net stop uxsms
net start uxsms

Source: http://www.mydigitallife.info

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

19
Sep 09

UnitTest???

  • Khó có thể viết Unit Test để bắt tất cả các lỗi của 1 chương trình.
  • Chỉ kiểm tra được lỗi của những unit nhỏ nhất của chương trình do đó không thể nào lường trước những vấn đề có thể xảy ra khi kết hợp các module với nhau.
  • Chỉ có thể kiểm tra được những lỗi đã biết chứ không thể sử dụng nó để tìm ra các lỗi tiềm ẩn của chương trình.
  • Viết Unit Test ít ra cũng giúp cho việc refactor code sau này dễ dàng hơn.

Sưu tầm + nghĩ linh tinh :(

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

8
Sep 09

Parse single Javascript object in Jquery by $.ajax method

Chưa thử test với Jquery phiên bản mới nhất, mới chạy trên bản 1.2.1 (dự án hiện tại đang dùng :( ). Khi sử dụng $.ajax như bên dưới thì phát sinh lỗi:

[-]?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$.ajax({
	type: "POST",
	url: document.location.href,
	data: "card_type=" + cardType + "&card_number=" + cardNumber,
	dataType: 'JSON',
	cache: false,
	success: function(responses){
	    if(!responses.has_error)
	    {
	 	alert("Please enter valid Card Number.");
	 	return false;
	    }
       }
});

thì bị lỗi. Mặc dù response là {‘has_error’: false;} nhưng lại không nhảy vào khối lệnh IF.
Cách khắc phục rất đơn giản:

[-]?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
...
success: function(responses){
    var obj = eval('('+responses+')');
    if(!obj .has_error)
    {
	alert("Please enter valid Card Number.");
	return false;
    }
}

Lưu ý: Chỉ xảy ra lỗi này nếu response là single object, nếu nó là mảng các object thì cứ $.each rồi get theo key, val thì lại ko sao :(

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

13
Jul 09

Library vs Framework

Hôm trước có hỏi ở trên Twitter (mặc dù cái list của mình chả có mấy người :”>):

web framework or library framework :( Ai cho em lời khuyên :(

Hôm nay nhận được reply của anh Định:

Phân biệt nhé: library là you call me, framework là I call you ;)

Do trình độ mình có hạn nên đọc hơi mơ hồ :”>  Search thêm 1 chút thì nó là thế này:

A library is about reusable functionalities, but a framework is about reusable behaviors.
A library is something you call/inherit from your code, but framework is something that calls your code or provide services for your code.
A library is a collection of components and classes, where framwork is how abstract classes and components interact with each others.

Cái đoạn bôi đậm chính là cái anh Định nói đến :-x Rất cám ơn anh

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

3
Jul 09

Stupid IE???

Today, a colleague asked me: “how to download file with docx extension (MS Word 2007) in IE6?” because IE automatic changes the .docx to .zip. I thought to solve this problem very easy by directly link download but I’m wrong :( It seems a IE bug??? So I recommend him that he should use PHP header to output binary content of file.

IE handle stupid or smart in this case?

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]