September, 2008


18
Sep 08

Tạo một Country list (Drop down menu) kèm ảnh quốc kỳ

Chỉ đơn giản dùng CSS dạng như sau:

1
option#AF { background:url(images/flags/vn.png) no-repeat; padding-left:20px; }

Cái “khó” là phải:
- Có đủ ảnh các quốc gia trên thế giới
- File css cũng phải có từng đó định nghĩa option tương ứng

Để download bộ icon ảnh cờ các nước bạn có thể vào http://www.famfamfam.com/lab/icons/flags để tải, icon khá đẹp :)
Continue reading →


15
Sep 08

Một PHP class tạo file ZIP

Tôi đang phải làm  chức năng nén/giải nén trong dự án hiện tại. Giải nén thì đã làm xong rồi, còn nén nữa là xong. Zip library của PHP hỗ trợ chức năng zip hơi bị kém, cái cơ bản nhất là cũng ngại phải viết => search & thấy class này khá nhẹ để nén 1 folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
	require ("zipfile.inc.php");
 
	$zipfile = new zipfile();
 
	rec_listFiles('myFolder');
 
	header("Content-type: application/octet-stream");
	header("Content-disposition: attachment; filename=zipfile.zip");
	echo $zipfile->file();
 
	function rec_listFiles( $from = '.')
	{
		global $zipfile, $filedata;
 
		if(! is_dir($from))
			return false;
 
		if( $dh = opendir($from))
		{
			while( false !== ($file = readdir($dh)))
			{
				// Skip '.' and '..'
				if( $file == '.' || $file == '..')
					continue;
				$path = $from . '/' . $file;
				if( is_dir($path) ) {
					$zipfile->add_dir($path);
					rec_listFiles($path);
				}
				else {
					$filedata = implode("", file($path));
					$zipfile->add_file($filedata, $path);
				}
			}
			closedir($dh);
		}
	}
?>

Tạm đáp ứng yêu cầu :)

Source: http://www.devco.net/archives/2005/05/24/creating_zip_files_with_php.php

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

11
Sep 08

PHP post_max_size issue

Hôm nay tôi gặp phải 1 “tình huống” khá là củ chuối. Phần upload file (thật ra là upload file để update lại các store – khá nhiều, hiện tại là 1500 store) có validate file size, file type. Tôi test “khá kỹ ” ở local & mọi thứ đều ổn. Thông số local của tôi như sau:

  • Windows XP/Vertrigo
  • post_max_size = 100M
  • upload_max_size = 20M

Khi up 1 file có dung lượng quá 20MB (<100MB) thì hệ thống hiện thông báo rất đẹp với nội dung là bạn đã upload quá dung lượng quy định bla bla…:-@

Thế nhưng sau khi request done trên PMS (project management system), bên test report lại là khi upload 1 file lớn hơn 16MB thì chẳng hiện gì cả, không lỗi & giống như tự F5 lại trang.

Xem phpinfo của môi trường trên testing thì như sau:

  • post_max_size = 8M
  • upload_max_size = 16M

Vậy là dung lượng vượt quá post_max_size rồi, và PHP đã làm thế này đối với đoạn code của tôi:

If the size of post data is greater than post_max_size, the $_POST and $_FILES superglobals are empty

Thế cho nên đoạn code:

1
2
3
4
$postMaxSize = int_get('post_max_size');
if($postMaxSize < $userFile['size']) {
//process error
}

chẳng hoạt động gì cả :( (
Trên php.net có 1 trick để xử lý trường hợp này:

This can be tracked in various ways, e.g. by passing the $_GET variable to the script processing the data, i.e.

, and then checking if $_GET['processed'] is set.

Và đây là đoạn code của tôi:

1
2
3
if(isset($_GET['processed']) && !count($_POST)) {
  die('Error message here...');
}

Chạy ngon ;)

Rất cảm ơn anh NBThanh (Nguyễn Bá Thành) đã giúp đỡ em khắc phục vấn đề này :)

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

9
Sep 08

Optimize performance

Dự án e-store tôi đang thực hiện đã sang phase II. Do đã tạo một số lượng không nhỏ các shop demo (khoảng 1500 – mặc dù yêu cầu là 5000 cái :( ) nên chức năng update toàn bộ các shop là chức năng bắt buộc phải có trong phase II này.

Ban đầu cứ nghĩ việc này khó, nhưng đến khi bắt tay vào làm mới thấy chẳng khó tý nào nếu không muốn nói là dễ :p

  1. 1 form để upload file (có validate, cấm các file execute như .sh, .exe…)
  2. File upload lên sẽ được copy vào toàn bộ các shop hiện có.
  3. Nếu file upload lên là dạng zip thì phải cho phép unzip & check như trường hợp 1

Với 3 yêu cầu này, không khó để thực hiện. Tuy vậy tôi vẫn bị vướng 1 chỗ & vẫn chưa nghĩ ra cách giải quyết nào triệt để, đó là vấn đề khi lấy toàn bộ các tên shop (shop code = thư mục) để copy file vào. Nếu trên môi trường Windows, chưa có cách nào khả thi hơn ngoài việc đọc dữ liệu trong DB. Cách này đơn giản nhưng khoảng thời gian để đọc từ DB ra cũng chẳng phải ít :( Còn trên Linux thì có vẻ dễ chịu hơn nếu như safe_mode = off :-” Tôi dùng command để đọc các thư mục shop hiện có, loại trừ đi mấy thư mục hệ thống. Hàm cụ thể như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* get all shop
* @author khanhdn
* @return array
*/
function getAllShop() {
	$shops = array('shop_temp');
 
	if(!isLinuxOS()) {
		$query = db_query("SELECT shop_code FROM {shop_setting} ORDER BY shop_code");
 
		while($rs = db_fetch_array($query)) {
			if(is_dir('../'.$rs['shop_code'])) {
				$shops[] = $rs['shop_code'];
			}
		}
	}
	else {
		$systemFolder = array(
							'system'
							,'sites'
							,'scripts'
							,'profiles'
							,'googlecheckout'
							,'themes'
							,'tmp'
							,'googleerror.log'
							,'googlemessage.log'
							,'index.php'
							,'mysqldumper'
							,'phpinfo.php'
						);
 
		$shopFolder = array();
		exec('cd ../; ls;', $shopFolder);
 
		$shops = array_diff($shopFolder, $systemFolder);
	}
 
	return $shops;
}

Thật ra thì đây chỉ là cách làm đối phó. Nếu hệ thống lớn chắc chắn vẫn không ổn. Chắc là phải làm việc ở mức thấp hơn nữa :-s

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