1. Trang chủ
  2. » Công Nghệ Thông Tin

Thuật toán xoay vòng với quản lý dữ liệu chuỗi thời gian và ứng dụng trong quản trị mạng máy tính

95 353 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 95
Dung lượng 1,28 MB

Nội dung

i ĐẠI HỌC THÁI NGUYÊN TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN & TRUYỀN THÔNG NGUYỄN THỊ MỸ HẠNH THUẬT TOÁN XOAY VÒNG VỚI QUẢN LÝ DỮ LIỆU CHUỖI THỜI GIAN VÀ ỨNG DỤNG TRONG QUẢN TRỊ MẠNG MÁY TÍNH LUẬN VĂN THẠC SỸ CÔNG NGHỆ THÔNG TIN Thái Nguyên - 2016 ii ĐẠI HỌC THÁI NGUYÊN TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN & TRUYỀN THÔNG NGUYỄN THỊ MỸ HẠNH THUẬT TOÁN XOAY VÒNG VỚI QUẢN LÝ DỮ LIỆU CHUỖI THỜI GIAN VÀ ỨNG DỤNG TRONG QUẢN TRỊ MẠNG MÁY TÍNH Chuyên ngành: Khoa học máy tính Mã số: 60480101 LUẬN VĂN THẠC SỸ CÔNG NGHỆ THÔNG TIN NGƯỜI HƯỚNG DẪN KHOA HỌC PGS.TS NGUYỄN VĂN TAM Thái Nguyên – 2016 i LỜI CAM ĐOAN Tôi xin cam đoan rằng: Số lượng kết nghiên cứu luận văn hoàn toàn trung thực chưa sử dụng công bố công trình khác Mọi giúp đỡ cho việc thực luận văn cảm ơn thông tin trích dẫn luận văn ghi rõ nguồn gốc Tác giả luận văn Nguyễn Thị Mỹ Hạnh ii LỜI CẢM ƠN Lời học viên xin gửi lời cảm ơn trân thành tới Thầy, Cô giáo trường Đại học Công nghệ thông tin Truyền thông, Đại học Thái Nguyên, thầy cô tận tình dạy bảo, truyền đạt kiến thức quý báu cho học viên suốt trình học tập Xin trân trọng cảm ơn Khoa, Phòng, Ban cán tạo điều kiện tốt cho học viên học tập hoàn thành đề tài tốt nghiệp Đặc biệt, học viên xin gửi lời cảm ơn sâu sắc đến Thầy giáo hướng dẫn học viên PGS TS Nguyễn Văn Tam, Thầy tận tình bảo giúp đỡ học viên suốt trình nghiên cứu để hoàn thành luận văn Cuối học viên xin gửi lời cảm ơn gia đình, bạn bè, đồng nghiệp giúp đỡ, động viên ủng hộ học viên nhiều toàn trình học tập nghiên cứu để hoàn thành luận văn Trân trọng cảm ơn! iii MỤC LỤC LỜI CAM ĐOAN ………… ………………………………………….i LỜI CẢM ƠN ……………………………………………………………….ii MỤC LỤC …… ………………………………………………………… iii DANH MỤC CHỮ VIẾT TẮT ………………………………… …………v DANH MỤC HÌNH VẼ ………………………………… ……………… vi MỞ ĐẦU 1 Đặt vấn đề: Ý nghĩa khoa học, thực tiễn đề tài: Phương pháp nghiên cứu: Bố cục luận văn: CHƯƠNG I: MÔ HÌNH QUẢN LÝ LUỒNG DỮ LIỆU CHUỖI THỜI GIAN 1.1 Kiến trúc tổng quát hệ thống quản lý luồng liệu chuỗi thời gian 1.1.1 Giới thiệu chung 1.1.2 Khái niệm chuỗi thời gian 1.1.3 Kiến trúc tổng quát 1.2 Mô hình liệu truy vấn 1.2.1 Mô hình liệu 1.2.2 Ngữ nghĩa truy vấn liên tục 1.3 Một số ứng dụng hệ quản lý luồng liệu 10 1.3.1 Ứng dụng mạng cảm biến (Sensor Networks) 10 1.3.2 Ứng dụng phân tích lưu lượng mạng 11 1.3.3 Ứng dụng phân tích nhật ký giao dịch 12 CHƯƠNG II :THUẬT TOÁN XOAY VÒNG VỚI CƠ SỞ DỮ LIỆU CHUỖI THỜI GIAN TRONG QUẢN TRỊ MẠNG 14 2.1 Thuật toán xoay vòng với sở liệu chuỗi thời gian 14 iv 2.1.1 Nguyên lý thuật toán xoay vòng RR( Round Robin) 14 2.1.2 Thuật toán xoay vòng với sở liệu chuỗi thời gian RRD 17 2.1.2.1 Nguyên lý RRD 17 2.1.2.2 Dữ liệu RRD 18 2.2 RRD quản trị mạng[1] 23 2.2.1 RRD thu thập liệu hiển thị kết 24 2.2.2 RRD phát bất thường 26 CHƯƠNG : CHƯƠNG TRÌNH THỬ NGHIỆM 37 3.1 Bài toán thử nghiệm 37 3.2 Bộ công cụ phục vụ xây dựng sở liệu chuỗi thời gian RRDtool 38 3.2.1 Tập hàm thư viện RRDtool 38 3.2.2 Hoạt động RRDtool 39 3.2.3 Giám sát liệu bất thường 42 3.3 Kỹ thuật tích hợp RRDTool vào hệ quản trị mạng CACTI 45 3.4 Một số kết thử nghiệm 47 3.4.1 Mô hình thử nghiệm 47 3.4.2 Triển khai mô hình thử nghiệm 48 3.4.3 Kết thử nghiệm …………………………… ………………… 61 3.4.4 Đánh giá …………………………………………………………… 61 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN 63 TÀI LIỆU THAM KHẢO 65 PHỤ LỤC 66 v DANH MỤC CÁC KÝ HIỆU, CÁC CHỮ VIẾT TẮT Từ viết tắt ATM Tiếng anh Automated Teller Machine CF Consolidation Function CPU Central Processing Unit IAP Internet Access Provider IP Internet Protocol ISP Internet Service Provider LAN Local Area NetWork PC Personal Computer PDP Primary Data Point PHP Personal Hompe Page RR Round Robin RRA Round Robin Archives RRD Round Robin Database SNMP Simple Network Managerment Protocol SQL Structured Query Language TCL Tool Command Language TCP Tranfer Control Protocol TSD Time Series Database URL Uniform Resource Locator XML Extensible Markup Language vi DANH MỤC CÁC HÌNH VẼ Hình 1.1 - Kiến trúc tổng thể hệ quản lý luồng Dữ liệu Hình 2.1 - Nguyên lý sở liệu RRD 18 Hình 2.2 - Vấn đề tỷ lệ thời gian 19 Hình 2.3 - Vấn đề tỷ lệ thời gian 21 Hình 2.4 - Hợp Cơ sở liệu RRD 23 Hình 2.5 - Sơ đồ khối hệ quản trị mạng 23 Hình 2.6 - Biểu diễn đồ thị RRD 25 Hình 3.1 - Lưu đồ chung Chương trình tích hợp RRDTool vào Cacti 47 Hình 3.2 - Chạy lệnh tích hợp RRDTool 48 Hình 3.3 - Mô hình thử nghiệm 49 Hình 3.4 - Màn hình đăng nhập hệ thống 52 Hình 3.5 - Giao diện Cacti 52 Hình 3.6 - Cài đặt dịch vụ SNMP cho thiết bị 53 Hình 3.7 - Tìm file SNMP Services 54 Hình 3.8 - Đặt cấu hình SNMP Services 55 Hình 3.9 - Cài đặt thiết bị vào Cacti 55 Hình 3.10 - Danh sách nội dung cần giám sát 56 Hình 3.11 - Trạng thái kết nối thiết bị Cacti 56 Hình 3.12 - Thể việc lựa chọn thiết bị cần tạo đồ thị 57 Hình 3.13 - Danh sách máy có đồ thị 58 vii Hình 3.14 - Biểu đồ tình trạng thiết bị 59 Hình 3.15 - Import Templates 60 Hình 3.16 - Import Templates data cacti 60 Hình 3.17 - Thông tin quản lý thiết bị hệ thống mạng 61 Hình 3.18 - Quản lý theo lịch thời gian 61 Hình 3.19 - Thông tin giới hạn hệ thống 62 MỞ ĐẦU Đặt vấn đề: Vấn đề quản lý luồng liệu chuỗi thời gian quan tâm nhiều, ứng dụng đời sống xã hội nói chung ứng dụng quản trị mạng máy tính nói riêng Thuật toán xoay vòng với quản lý liệu chuỗi thời gian RRD (Round Robin Database) giải pháp nhằm tối ưu hóa hệ thống, tránh tốn tài nguyên giảm độ phức tạp Trong sở liệu Round - Robin (RR) thường liệu chuỗi thời gian như: băng thông mạng, nhiệt độ, giá cổ phiếu … vv, nhiều ứng dụng gần yêu cầu hỗ trợ cho việc phân tích trực tuyến thay đổi nhanh chóng dòng liệu như: thống kê lưu lượng truy cập internet, đấu giá mạng [4], [6] Trong Quản trị mạng, tần suất trích mẫu thu thập thông tin lớn việc chẩn đoán hoạt động mạng xác (Ví dụ: chẩn đoán lỗi), việc xử lý lưu trữ liệu theo thời gian cực lớn, giải pháp sở liệu truyền thống không đáp ứng được, thuật toán RRD giải pháp hữu hiệu Do đó, học viên lựa chọn đề tài luận văn Thạc sỹ “ Thuật toán xoay vòng với quản lý liệu chuỗi thời gian ứng dụng quản trị mạng máy tính” Trong đề tài học viên thực thu thập liệu mạng để biểu diễn dạng đồ thị trạng thái hoạt động thiết bị cần giám sát, sử dụng RRDtool để lưu trữ liệu hiển thị liệu theo chuỗi thời gian Để thực điều học viên tiến hành nghiên cứu mô hình quản lý luồng liệu chuỗi thời gian, thuật toán xoay vòng với liệu chuỗi 72 $data_source["rrd_maximum"] = "U"; } elseif (strpos($data_source["rrd_maximum"], "|query_") !== false) { /* in case a query variable is given, evaluate it */ $data_local = db_fetch_row("SELECT * FROM data_local WHERE id=" $local_data_id); if ($data_source["rrd_maximum"] == "|query_ifSpeed|" || $data_source["rrd_maximum"] == "|query_ifHighSpeed|") { $highSpeed = db_fetch_cell("SELECT field_value FROM host_snmp_cache WHERE host_id=" $data_local["host_id"] " AND snmp_query_id=" $data_local["snmp_query_id"] " AND snmp_index='" $data_local["snmp_index"] "' AND field_name='ifHighSpeed'"); if (!empty($highSpeed)) { $data_source["rrd_maximum"] = $highSpeed * 1000000; }else{ $data_source["rrd_maximum"] = substitute_snmp_query_data("|query_ifSpeed|",$data_local["hos t_id"], $data_local["snmp_query_id"], $data_local["snmp_index"]); } }else{ $data_source["rrd_maximum"] = substitute_snmp_query_data($data_source["rrd_maximum"],$data_ local["host_id"], $data_local["snmp_query_id"], $data_local["snmp_index"]); } } elseif (($data_source["rrd_maximum"] != "U") && (int)$data_source["rrd_maximum"] required, but take care of an "Undef" value */ 73 $data_source["rrd_maximum"] = (int)$data_source["rrd_minimum"]+1; } /* min==max==0 won't work with rrdtool */ if ($data_source["rrd_minimum"] == && $data_source["rrd_maximum"] == 0) { $data_source["rrd_maximum"] = "U"; } $create_ds = "DS:$data_source_name:" $data_source_types{$data_source["data_source_type_id"]} ":" $data_source["rrd_heartbeat"] ":" $data_source["rrd_minimum"] ":" $data_source["rrd_maximum"] RRD_NL; } } $create_rra = ""; /* loop through each available RRA for this DS */ foreach ($rras as $rra) { $create_rra = "RRA:" $consolidation_functions{$rra["consolidation_function_id"]} ":" $rra["x_files_factor"] ":" $rra["steps"] ":" $rra["rows"] RRD_NL; } /* check for structured path configuration, if in place verify directory exists and if not create it */ if (read_config_option("extended_paths") == "on") { if (!is_dir(dirname($data_source_path))) { if (mkdir(dirname($data_source_path), 0775)) { if ($config["cacti_server_os"] != "win32") { $owner_id = fileowner($config["rra_path"]); $group_id = filegroup($config["rra_path"]); 74 if ((chown(dirname($data_source_path), $owner_id)) && (chgrp(dirname($data_source_path), $group_id))) { /* permissions set ok */ }else{ cacti_log("ERROR: Unable to set directory permissions for '" dirname($data_source_path) "'", FALSE); } } }else{ cacti_log("ERROR: Unable to create directory '" dirname($data_source_path) "'", FALSE); } } } if ($show_source == true) { return read_config_option("path_rrdtool") " create" RRD_NL "$data_source_path$create_ds$create_rra"; }else{ rrdtool_execute("create $data_source_path $create_ds$create_rra", true, RRDTOOL_OUTPUT_STDOUT, $rrdtool_pipe, "POLLER"); } } function rrdtool_function_update($update_cache_array, $rrdtool_pipe = "") { /* lets count the number of rrd files processed */ $rrds_processed = 0; while (list($rrd_path, $rrd_fields) = each($update_cache_array)) { $create_rrd_file = false; /* create the rrd if one does not already exist */ if (!file_exists($rrd_path)) { rrdtool_function_create($rrd_fields["local_data_id"], false, $rrdtool_pipe); 75 $create_rrd_file = true; } if ((is_array($rrd_fields["times"])) && (sizeof($rrd_fields["times"]) > 0)) { ksort($rrd_fields["times"]); while (list($update_time, $field_array) = each($rrd_fields["times"])) { if (empty($update_time)) { /* default the rrdupdate time to now */ $current_rrd_update_time = "N"; }else if ($create_rrd_file == true) { /* for some reason rrdtool will not let you update using times less than the rrd create time */ $current_rrd_update_time = "N"; }else{ $current_rrd_update_time = $update_time; } $i = 0; $rrd_update_template = ""; $rrd_update_values = $current_rrd_update_time ":"; while (list($field_name, $value) = each($field_array)) { $rrd_update_template = $field_name; /* if we have "invalid data", give rrdtool an Unknown (U) */ if ((!isset($value)) || (!is_numeric($value))) { $value = "U"; } $rrd_update_values = $value; if (($i+1) < count($field_array)) { $rrd_update_template = ":"; $rrd_update_values = ":"; 76 } $i++; } rrdtool_execute("update $rrd_path -template $rrd_update_template $rrd_update_values", true, RRDTOOL_OUTPUT_STDOUT, $rrdtool_pipe, "POLLER"); $rrds_processed++; } } } return $rrds_processed; } function rrdtool_function_tune($rrd_tune_array) { global $config; include($config["include_path"] "/global_arrays.php"); $data_source_name = get_data_source_item_name($rrd_tune_array["data_source_id"]); $data_source_type = $data_source_types{$rrd_tune_array["data-source-type"]}; $data_source_path = get_data_source_path($rrd_tune_array["data_source_id"], true); if ($rrd_tune_array["heartbeat"] != "") { $rrd_tune = " heartbeat $data_source_name:" $rrd_tune_array["heartbeat"]; } if ($rrd_tune_array["minimum"] != "") { $rrd_tune = " minimum $data_source_name:" $rrd_tune_array["minimum"]; } if ($rrd_tune_array["maximum"] != "") { 77 $rrd_tune = " maximum $data_source_name:" $rrd_tune_array["maximum"]; } if ($rrd_tune_array["data-source-type"] != "") { $rrd_tune = " data-source-type $data_source_name:" $data_source_type; } if ($rrd_tune_array["data-source-rename"] != "") { $rrd_tune = " data-source-rename $data_source_name:" $rrd_tune_array["data-source-rename"]; } if ($rrd_tune != "") { if (file_exists($data_source_path) == true) { $fp = popen(read_config_option("path_rrdtool") " tune $data_source_path $rrd_tune", "r"); pclose($fp); if (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG) { cacti_log("CACTI2RRD: " read_config_option("path_rrdtool") " tune $data_source_path $rrd_tune"); } } } } $rrd_fetch_cache = array(); function rrdtool_function_fetch($local_data_id, $start_time, $end_time, $resolution = 0, $show_unknown = false, $rrdtool_file = null) { global $rrd_fetch_cache; /* validate local data id */ if (empty($local_data_id) && is_null($rrdtool_file)) { 78 return array(); } /* the cache hash is used to identify unique items in the cache */ $current_hash_cache = md5($local_data_id $start_time $end_time $resolution $show_unknown $rrdtool_file); /* return the cached entry if available */ if (isset($rrd_fetch_cache[$current_hash_cache])) { return $rrd_fetch_cache[$current_hash_cache]; } /* initialize fetch array */ $fetch_array = array(); /* check if we have been passed a file instead of lodal data source to look up */ if (is_null($rrdtool_file)) { $data_source_path = get_data_source_path($local_data_id, true); }else{ $data_source_path = $rrdtool_file; } /* build and run the rrdtool fetch command with all of our data */ $cmd_line = "fetch $data_source_path AVERAGE -s $start_time -e $end_time"; if ($resolution > 0) { $cmd_line = " -r $resolution"; } $output = rrdtool_execute($cmd_line, false, RRDTOOL_OUTPUT_STDOUT); /* grab the first line of the output which contains a list of data sources in this rrd output */ $line_one_eol = strpos($output, "\n"); $line_one = substr($output, 0, $line_one_eol); $output = substr($output, $line_one_eol); 79 /* split the output into an array */ $output = preg_split('/[\r\n]{1,2}/', $output, null, PREG_SPLIT_NO_EMPTY); /* find the data sources in the rrdtool output */ if (preg_match_all('/\S+/', $line_one, $data_source_names)) { /* version 1.0.49 changed the output slightly, remove the timestamp label if present */ if (preg_match('/^timestamp/', $line_one)) { array_shift($data_source_names[0]); } $fetch_array["data_source_names"] = $data_source_names[0]; /* build a regular expression to match each data source value in the rrdtool output line */ $regex = '/[0-9]+:\s+'; for ($i=0; $i < count($fetch_array["data_source_names"]); $i++) { $regex = '([\-]?[0-9]{1}[.,][0-9]+e[\+-][09]{2,3}|-?[Nn][Aa][Nn])'; if ($i < count($fetch_array["data_source_names"]) - 1) { $regex = '\s+'; } } $regex = '/'; } /* loop through each line of the output */ $fetch_array["values"] = array(); for ($j = 0; $j < count($output); $j++) { $matches = array(); $max_array = array(); /* match the output line */ if (preg_match($regex, $output[$j], $matches)) { 80 /* only process the output line if we have the correct number of matches */ if (count($matches) - == count($fetch_array["data_source_names"])) { /* get all values from the line and set them to the appropriate data source */ for ($i=1; $i 0) { $fetch_array["values"][count($fetch_array["data_source_n ames"])][$j] = max($max_array); } } } 81 } /* add nth percentile maximum data source */ if (isset($fetch_array["values"][count($fetch_array["data_source _names"])])) { $fetch_array["data_source_names"][count($fetch_array["da ta_source_names"])] = "nth_percentile_maximum"; } /* clear the cache if it gets too big */ if (sizeof($rrd_fetch_cache) >= MAX_FETCH_CACHE_SIZE) { $rrd_fetch_cache = array(); } /* update the cache */ if (MAX_FETCH_CACHE_SIZE > 0) { $rrd_fetch_cache[$current_hash_cache] = $fetch_array; } return $fetch_array; } 82 Phần II Các hàm RRA tích hợp vào cacti: include("./include/auth.php"); /* set default action */ if (!isset($_REQUEST["action"])) { $_REQUEST["action"] = ""; } switch ($_REQUEST["action"]) { case 'save': form_save(); break; case 'remove': rra_remove(); header("Location: rra.php"); break; case 'edit': include_once("./include/top_header.php"); rra_edit(); include_once("./include/bottom_footer.php"); break; default: include_once("./include/top_header.php"); rra(); include_once("./include/bottom_footer.php"); break; } /* The Save Function */ function form_save() { if (isset($_POST["save_component_rra"])) { $save["id"] = $_POST["id"]; $save["hash"] = get_hash_round_robin_archive($_POST["id"]); $save["name"] = form_input_validate($_POST["name"], "name", "", false, 3); 83 $dummy = form_input_validate(count($_POST["consolidation_function_id"] ), "consolidation_function_id", "^[0-9]*$", false, 3); $save["x_files_factor"] = form_input_validate($_POST["x_files_factor"], "x_files_factor", "^[01]?(\.[0-9]+)?$", false, 3); $save["steps"] = form_input_validate($_POST["steps"], "steps", "^[0-9]*$", false, 3); $save["rows"] = form_input_validate($_POST["rows"], "rows", "^[0-9]*$", false, 3); $save["timespan"] = form_input_validate($_POST["timespan"], "timespan", "^[09]*$", false, 3); if (!is_error_message()) { $rra_id = sql_save($save, "rra"); if ($rra_id) { raise_message(1); db_execute("delete from rra_cf where rra_id=$rra_id"); if (isset($_POST["consolidation_function_id"])) { for ($i=0; ($i < count($_POST["consolidation_function_id"])); $i++) { /* ================= input validation ================= */ input_validate_input_number($_POST["consolidation_functi on_id"][$i]); /* ==================================================== */ db_execute("insert into rra_cf (rra_id,consolidation_function_id) values ($rra_id," $_POST["consolidation_function_id"][$i] ")"); } }else{ raise_message(2); } }else{ raise_message(2); } } if (is_error_message()) { 84 header("Location: rra.php?action=edit&id=" (empty($rra_id) ? $_POST["id"] : $rra_id)); }else{ header("Location: rra.php"); } } } /* - RRA Functions - */ function rra_remove() { /* ================= input validation ================= */ input_validate_input_number(get_request_var("id")); /* ==================================================== */ if ((read_config_option("deletion_verification") == "on") && (!isset($_GET["confirm"]))) { include_once("./include/top_header.php"); form_confirm("Are You Sure?", "Are you sure you want to delete the round robin archive '" htmlspecialchars(db_fetch_cell("select name from rra where id=" $_GET["id"])) "'?", htmlspecialchars("rra.php"), htmlspecialchars("rra.php?action=remove&id=" $_GET["id"])); exit; } if ((read_config_option("deletion_verification") == "") || (isset($_GET["confirm"]))) { db_execute("delete from rra where id=" $_GET["id"]); db_execute("delete from rra_cf where rra_id=" $_GET["id"]); } } function rra_edit() { global $colors, $fields_rra_edit; /* ================= input validation ================= */ input_validate_input_number(get_request_var("id")); /* ==================================================== */ if (!empty($_GET["id"])) { $rra = db_fetch_row("select * from rra where id=" $_GET["id"]); $header_label = "[edit: " htmlspecialchars($rra["name"]) "]"; }else{ 85 $header_label = "[new]"; } html_start_box("Round Robin Archives $header_label", "100%", $colors["header"], "3", "center", ""); draw_edit_form(array( "config" => array(), "fields" => inject_form_variables($fields_rra_edit, (isset($rra) ? $rra : array())) )); html_end_box(); form_save_button("rra.php"); } function rra() { global $colors; /* clean up sort_column */ if (isset($_REQUEST["sort_column"])) { $_REQUEST["sort_column"] = sanitize_search_string(get_request_var("sort_column")); } /* clean up search string */ if (isset($_REQUEST["sort_direction"])) { $_REQUEST["sort_direction"] = sanitize_search_string(get_request_var("sort_direction")); } /* remember these search fields in session vars so we don't have to keep passing them around */ load_current_session_value("sort_column", "sess_rra_sort_column", "timespan"); load_current_session_value("sort_direction", "sess_rra_sort_direction", "ASC"); html_start_box("Round Robin Archives", "100%", $colors["header"], "3", "center", "rra.php?action=edit"); $display_text = array( "name" => array("Name", "ASC"), "steps" => array("Steps", "ASC"), "rows" => array("Rows", "ASC"), "timespan" => array("Timespan", "ASC")); 86 html_header_sort($display_text, $_REQUEST["sort_column"], $_REQUEST["sort_direction"], 4); $rras = db_fetch_assoc("SELECT id, name, rows, steps, timespan FROM rra ORDER BY " $_REQUEST['sort_column'] " " $_REQUEST['sort_direction']); $i = 0; if (sizeof($rras) > 0) { foreach ($rras as $rra) { form_alternate_row_color($colors["alternate"],$colors["l ight"],$i); $i++; ?>

Ngày đăng: 16/04/2017, 17:26

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w