(PDO::FETCH_ASSOC); foreach ($rows as $row) { if (!empty($row['url_pattern']) && isset($page_type_map[$row['page_type']])) { $route = $page_type_map[$row['page_type']]; // 将url_pattern转换为正则表达式 $pattern = url_pattern_to_regex($row['url_pattern']); if ($pattern) { $url_patterns[$pattern] = array( 'control' => $route['control'], 'action' => $route['action'], 'url_pattern' => $row['url_pattern'] ); // 如果有参数映射,也添加进去 if (isset($route['params'])) { $url_patterns[$pattern]['params'] = $route['params']; } } } } } } } catch (Exception $e) { // 数据库连接失败,使用默认配置 } // 如果没有从数据库读取到配置,使用默认配置 if (empty($url_patterns)) { $url_patterns = array( // 首页 '/^converter\/?$/' => array('control' => 'exchange', 'action' => 'converter', 'url_pattern' => 'converter'), '/^rates\/?$/' => array('control' => 'exchange', 'action' => 'rates', 'url_pattern' => 'rates'), '/^rmb-rate\/?$/' => array('control' => 'exchange', 'action' => 'cnyrate', 'url_pattern' => 'rmb-rate'), '/^bank-rate\/?$/' => array('control' => 'exchange', 'action' => 'bank', 'url_pattern' => 'bank-rate'), '/^forex\/?$/' => array('control' => 'exchange', 'action' => 'forex', 'url_pattern' => 'forex'), '/^currency\/?$/' => array('control' => 'exchange', 'action' => 'currency', 'url_pattern' => 'currency'), '/^daxie\/?$/' => array('control' => 'exchange', 'action' => 'daxie', 'url_pattern' => 'daxie'), '/^article\/?$/' => array('control' => 'exchange', 'action' => 'article', 'url_pattern' => 'article'), // 详情页 - 使用 [a-zA-Z] 支持大小写混合 '/^converter\/([a-zA-Z]{3})-([a-zA-Z]{3})\/?$/' => array('control' => 'exchange', 'action' => 'converter_pair', 'url_pattern' => 'converter/{from}-{to}/', 'params' => array('from' => 1, 'to' => 2)), '/^converter2\/([a-zA-Z]{3})-([a-zA-Z]{3})\/([0-9.]+)\.html$/' => array('control' => 'exchange', 'action' => 'converter_detail', 'url_pattern' => 'converter2/{from}-{to}/{amount}.html', 'params' => array('from' => 1, 'to' => 2, 'amount' => 3)), '/^rmb-rate\/([a-zA-Z]{3})\.html$/' => array('control' => 'exchange', 'action' => 'cnyrate_detail', 'url_pattern' => 'rmb-rate/{code}.html', 'params' => array('code' => 1)), '/^bank-rate\/([a-zA-Z]+)\.html$/' => array('control' => 'exchange', 'action' => 'bank_detail', 'url_pattern' => 'bank-rate/{code}.html', 'params' => array('code' => 1)), '/^forex\/([a-zA-Z0-9_-]+)\.html$/' => array('control' => 'exchange', 'action' => 'forex_detail', 'url_pattern' => 'forex/{code}.html', 'params' => array('code' => 1)), '/^currency\/([a-zA-Z]{3})\.html$/' => array('control' => 'exchange', 'action' => 'currency_detail', 'url_pattern' => 'currency/{code}.html', 'params' => array('code' => 1)), '/^daxie\/([0-9.]+)\.html$/' => array('control' => 'exchange', 'action' => 'daxie_detail', 'url_pattern' => 'daxie/{amount}.html', 'params' => array('amount' => 1)), '/^history\/([a-zA-Z]{3})\.html$/' => array('control' => 'exchange', 'action' => 'history_currency', 'url_pattern' => 'history/{code}.html', 'params' => array('code' => 1)), '/^history\/([a-zA-Z]{3})-([a-zA-Z]{3})\.html$/' => array('control' => 'exchange', 'action' => 'history_pair', 'url_pattern' => 'history/{from}-{to}.html', 'params' => array('from' => 1, 'to' => 2)), '/^trend\/([a-zA-Z]{3})\.html$/' => array('control' => 'exchange', 'action' => 'trend_currency', 'url_pattern' => 'trend/{code}.html', 'params' => array('code' => 1)), '/^trend\/([a-zA-Z]{3})-([a-zA-Z]{3})\.html$/' => array('control' => 'exchange', 'action' => 'trend_pair', 'url_pattern' => 'trend/{from}-{to}.html', 'params' => array('from' => 1, 'to' => 2)), ); } foreach ($url_patterns as $pattern => $route) { if (preg_match($pattern, $rewrite, $matches)) { $_GET['control'] = $route['control']; $_GET['action'] = $route['action']; // 提取参数 if (isset($route['params'])) { foreach ($route['params'] as $param_name => $match_index) { if (isset($matches[$match_index])) { $value = $matches[$match_index]; // 货币代码参数转换为大写 if (in_array($param_name, array('from', 'to', 'code', 'base', 'target'))) { $value = strtoupper($value); } $_GET[$param_name] = $value; } } } // 重要:删除 rewrite 参数,防止后面的代码再次处理 unset($_GET['rewrite']); return; } } } if(empty($_GET)) return; if(!empty($_ENV['_config']['lecms_parseurl']) && isset($_GET['rewrite']) && !empty($_GET['rewrite'])) { if( isset($this->data['cfg']) ) { $cfg = $this->data['cfg']; }else{ $cfg = $this->runtime->xget(); $this->data['cfg'] = $cfg; } $uri = $_GET['rewrite']; unset($_GET['rewrite']); //访问 域名/index.php?rewrite=xx , 直接 301 重定向到 域名/xx $request_uri = isset($_SERVER['REQUEST_URI']) ? strtolower($_SERVER['REQUEST_URI']) : ''; if( $request_uri && strpos($request_uri, '?rewrite=') !== false ){ http_location($cfg['weburl'].$uri, '301'); } $url_suffix = $_ENV['_config']['url_suffix']; $url_suffix_len = strlen($url_suffix); /** * URL重写钩子 - 将首页路由到 exchange 控制器 * 在 parseurl_control 的 index 方法中执行 * 此时 $uri 已经包含了 rewrite 的值,且 $_GET['rewrite'] 已经被 unset */ if (strpos($uri, 'ex_pic/') === 0) { if (!function_exists('imagecreatetruecolor') || !function_exists('imagettftext')) { header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); exit; } if (preg_match('#^ex_pic/history/([a-zA-Z]{3})-([a-zA-Z]{3})/([0-9]+)\.jpg$#', $uri, $m)) { $from = strtoupper($m[1]); $to = strtoupper($m[2]); $days = intval($m[3]); if (!in_array($days, array(7, 30, 90))) $days = 7; $chart_data = array(); try { $model_file_history = PLUGIN_PATH . 'le_exchange/model/exchange_history_model.class.php'; if (file_exists($model_file_history)) { include_once $model_file_history; } $model_file_rate = PLUGIN_PATH . 'le_exchange/model/exchange_rate_model.class.php'; if (file_exists($model_file_rate)) { include_once $model_file_rate; } $exchange_history = new exchange_history(); $exchange_rate = new exchange_rate(); // 使用模型直接获取带交叉汇率计算的历史记录列表 // 由于 $exchange_history->get_history_list() 返回的是从近到远排序的数据 $history_list_raw = $exchange_history->get_history_list($to, $days, $from); $today_date = date('Y-m-d'); $has_today = false; if (!empty($history_list_raw)) { foreach ($history_list_raw as $item) { if ($item['date'] === $today_date) { $has_today = true; break; } } } else { $history_list_raw = array(); } // 如果历史数据里没有今天,则通过实时汇率表补充今天数据 if (!$has_today) { $today_rate = $exchange_rate->get_exchange_rate($from, $to); if ($today_rate > 0) { array_unshift($history_list_raw, array( 'date' => $today_date, 'rate' => $today_rate )); if (count($history_list_raw) > $days) { array_pop($history_list_raw); } } } // 翻转为按时间升序用于画图(从左到右) $history_list_raw = array_reverse($history_list_raw); foreach ($history_list_raw as $item) { $chart_data[] = array( 'date' => substr($item['date'], 5), // 'm-d' 'rate' => round($item['rate'], 6) ); } } catch (Exception $e) {} if (empty($chart_data)) { header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); exit; } $font = PLUGIN_PATH . 'le_exchange/static/msyhbd.ttc'; if (!is_file($font)) { $font = ROOT_PATH . 'lecms/plugin/le_title_pic/static/msyhbd.ttc'; } $ex_draw_center = function ($img, $font, $size, $text, $y, $color, $w) { $bbox = imagettfbbox($size, 0, $font, $text); $min_x = min($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $max_x = max($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $text_w = $max_x - $min_x; $x = intval(($w - $text_w) / 2 - $min_x); imagettftext($img, $size, 0, $x, $y, $color, $font, $text); }; $w = 1200; $h = 630; $scale = 2; $W = $w * $scale; $H = $h * $scale; $S = function ($v) use ($scale) { return intval(round($v * $scale)); }; header("Cache-Control: private, max-age=10800, pre-check=10800"); header("Pragma: private"); header("Expires: " . date(DATE_RFC822, strtotime('+1 day'))); header("Content-type:image/jpeg"); $img = imagecreatetruecolor($W, $H); imagealphablending($img, true); if (function_exists('imageantialias')) imageantialias($img, true); // 背景颜色 $bg_top = array(249, 250, 251); $bg_bottom = array(243, 244, 246); for ($y = 0; $y < $H; $y++) { $t = $y / max(1, ($H - 1)); $r = intval($bg_top[0] + ($bg_bottom[0] - $bg_top[0]) * $t); $g = intval($bg_top[1] + ($bg_bottom[1] - $bg_top[1]) * $t); $b = intval($bg_top[2] + ($bg_bottom[2] - $bg_top[2]) * $t); $c = imagecolorallocate($img, $r, $g, $b); imageline($img, 0, $y, $W - 1, $y, $c); } $text_color = imagecolorallocate($img, 55, 65, 81); $line_color = imagecolorallocate($img, 37, 99, 235); $grid_color = imagecolorallocate($img, 229, 231, 235); $fill_color = imagecolorallocatealpha($img, 37, 99, 235, 110); $margin_left = 140; $margin_right = 60; $margin_top = 80; $margin_bottom = 100; $chart_w = $w - $margin_left - $margin_right; $chart_h = $h - $margin_top - $margin_bottom; $min_rate = $chart_data[0]['rate']; $max_rate = $chart_data[0]['rate']; foreach ($chart_data as $pt) { if ($pt['rate'] < $min_rate) $min_rate = $pt['rate']; if ($pt['rate'] > $max_rate) $max_rate = $pt['rate']; } $diff = $max_rate - $min_rate; if ($diff == 0) $diff = $min_rate * 0.01 ?: 0.01; $min_rate -= $diff * 0.1; $max_rate += $diff * 0.1; $diff = $max_rate - $min_rate; // 绘制标题 $title = "{$from} 兑 {$to} {$days}天趋势图"; $ex_draw_center($img, $font, $S(32), $title, $S(60), $text_color, $W); // 绘制网格与Y轴标签 $y_ticks = 5; for ($i = 0; $i <= $y_ticks; $i++) { $val = $min_rate + ($diff * $i / $y_ticks); $y = $margin_top + $chart_h - ($chart_h * $i / $y_ticks); imageline($img, $S($margin_left), $S($y), $S($margin_left + $chart_w), $S($y), $grid_color); $label = number_format($val, 4); $bbox = imagettfbbox($S(16), 0, $font, $label); $lw = max($bbox[2], $bbox[4]) - min($bbox[0], $bbox[6]); imagettftext($img, $S(16), 0, $S($margin_left - 20) - $lw, $S($y + 6), $text_color, $font, $label); } // 绘制折线和X轴标签 $pts_count = count($chart_data); if ($pts_count > 1) { $step_x = $chart_w / ($pts_count - 1); $poly = array(); $poly[] = $S($margin_left); $poly[] = $S($margin_top + $chart_h); $prev_x = null; $prev_y = null; imagesetthickness($img, $S(4)); // X轴标签密度控制 $x_label_step = ceil($pts_count / 7); foreach ($chart_data as $i => $pt) { $x = $margin_left + $i * $step_x; $y = $margin_top + $chart_h - (($pt['rate'] - $min_rate) / $diff * $chart_h); $poly[] = $S($x); $poly[] = $S($y); if ($prev_x !== null) { imageline($img, $S($prev_x), $S($prev_y), $S($x), $S($y), $line_color); } // 绘制X轴刻度及文字 if ($i % $x_label_step == 0 || $i == $pts_count - 1) { imageline($img, $S($x), $S($margin_top + $chart_h), $S($x), $S($margin_top + $chart_h + 10), $grid_color); $bbox = imagettfbbox($S(14), 0, $font, $pt['date']); $lw = max($bbox[2], $bbox[4]) - min($bbox[0], $bbox[6]); imagettftext($img, $S(14), 0, $S($x) - $lw / 2, $S($margin_top + $chart_h + 30), $text_color, $font, $pt['date']); } $prev_x = $x; $prev_y = $y; } imagesetthickness($img, 1); $poly[] = $S($margin_left + $chart_w); $poly[] = $S($margin_top + $chart_h); imagefilledpolygon($img, $poly, count($poly) / 2, $fill_color); } $out = imagecreatetruecolor($w, $h); imagecopyresampled($out, $img, 0, 0, 0, 0, $w, $h, $W, $H); imagejpeg($out, null, 90); imagedestroy($out); imagedestroy($img); exit; } header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); exit; } $font = PLUGIN_PATH . 'le_exchange/static/msyhbd.ttc'; if (!is_file($font)) { $font = ROOT_PATH . 'lecms/plugin/le_title_pic/static/msyhbd.ttc'; } $ex_tt_bbox_w = function ($font, $size, $text) { $bbox = imagettfbbox($size, 0, $font, $text); $min_x = min($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $max_x = max($bbox[0], $bbox[2], $bbox[4], $bbox[6]); return $max_x - $min_x; }; $ex_fit_size = function ($font, $text, $max_width, $start_size, $min_size) use ($ex_tt_bbox_w) { $size = $start_size; while ($size > $min_size) { $w = $ex_tt_bbox_w($font, $size, $text); if ($w <= $max_width) break; $size -= 2; } return max($size, $min_size); }; $ex_wrap = function ($font, $size, $text, $max_width, $max_lines) use ($ex_tt_bbox_w) { $chars = preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY); $lines = array(); $line = ''; foreach ($chars as $ch) { $try = $line . $ch; if ($line !== '' && $ex_tt_bbox_w($font, $size, $try) > $max_width) { $lines[] = $line; $line = $ch; if (count($lines) >= $max_lines) break; } else { $line = $try; } } if (count($lines) < $max_lines && $line !== '') $lines[] = $line; if (count($lines) > $max_lines) $lines = array_slice($lines, 0, $max_lines); return $lines; }; $ex_draw_center = function ($img, $font, $size, $text, $y, $color, $w) { $bbox = imagettfbbox($size, 0, $font, $text); $min_x = min($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $max_x = max($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $text_w = $max_x - $min_x; $x = intval(($w - $text_w) / 2 - $min_x); imagettftext($img, $size, 0, $x, $y, $color, $font, $text); }; $ex_draw_center_box = function ($img, $font, $size, $text, $y, $color, $box_left, $box_width) { $bbox = imagettfbbox($size, 0, $font, $text); $min_x = min($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $max_x = max($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $text_w = $max_x - $min_x; $x = intval($box_left + ($box_width - $text_w) / 2 - $min_x); imagettftext($img, $size, 0, $x, $y, $color, $font, $text); }; $ex_draw_center_rect = function ($img, $font, $size, $text, $x1, $y1, $x2, $y2, $color) { $bbox = imagettfbbox($size, 0, $font, $text); $min_x = min($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $max_x = max($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $min_y = min($bbox[1], $bbox[3], $bbox[5], $bbox[7]); $max_y = max($bbox[1], $bbox[3], $bbox[5], $bbox[7]); $text_w = $max_x - $min_x; $text_h = $max_y - $min_y; $rect_w = $x2 - $x1; $rect_h = $y2 - $y1; $tx = intval($x1 + ($rect_w - $text_w) / 2 - $min_x); $ty_top = $y1 + ($rect_h - $text_h) / 2; $ty = intval($ty_top - $min_y); imagettftext($img, $size, 0, $tx, $ty, $color, $font, $text); }; $ex_round_rect_fill = function ($img, $x1, $y1, $x2, $y2, $r, $color) { $r = max(0, intval($r)); if ($r === 0) { imagefilledrectangle($img, $x1, $y1, $x2, $y2, $color); return; } imagefilledrectangle($img, $x1 + $r, $y1, $x2 - $r, $y2, $color); imagefilledrectangle($img, $x1, $y1 + $r, $x2, $y2 - $r, $color); imagefilledellipse($img, $x1 + $r, $y1 + $r, $r * 2, $r * 2, $color); imagefilledellipse($img, $x2 - $r, $y1 + $r, $r * 2, $r * 2, $color); imagefilledellipse($img, $x1 + $r, $y2 - $r, $r * 2, $r * 2, $color); imagefilledellipse($img, $x2 - $r, $y2 - $r, $r * 2, $r * 2, $color); }; $ex_round_rect_border = function ($img, $x1, $y1, $x2, $y2, $r, $color, $thickness) { $r = max(0, intval($r)); $thickness = max(1, intval($thickness)); imagesetthickness($img, $thickness); if ($r === 0) { imagerectangle($img, $x1, $y1, $x2, $y2, $color); imagesetthickness($img, 1); return; } imagearc($img, $x1 + $r, $y1 + $r, $r * 2, $r * 2, 180, 270, $color); imagearc($img, $x2 - $r, $y1 + $r, $r * 2, $r * 2, 270, 360, $color); imagearc($img, $x2 - $r, $y2 - $r, $r * 2, $r * 2, 0, 90, $color); imagearc($img, $x1 + $r, $y2 - $r, $r * 2, $r * 2, 90, 180, $color); imageline($img, $x1 + $r, $y1, $x2 - $r, $y1, $color); imageline($img, $x1 + $r, $y2, $x2 - $r, $y2, $color); imageline($img, $x1, $y1 + $r, $x1, $y2 - $r, $color); imageline($img, $x2, $y1 + $r, $x2, $y2 - $r, $color); imagesetthickness($img, 1); }; $ex_wrap_ellipsis = function ($font, $size, $text, $max_width, $max_lines) use ($ex_tt_bbox_w) { $chars = preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY); $lines = array(); $line = ''; $i = 0; $n = count($chars); for (; $i < $n; $i++) { $ch = $chars[$i]; $try = $line . $ch; if ($line !== '' && $ex_tt_bbox_w($font, $size, $try) > $max_width) { $lines[] = $line; $line = $ch; if (count($lines) >= $max_lines) break; } else { $line = $try; } } if (count($lines) < $max_lines && $line !== '') $lines[] = $line; $truncated = ($i < $n - 1); if ($truncated && !empty($lines)) { $last = array_pop($lines); $ellipsis = '…'; while ($last !== '' && $ex_tt_bbox_w($font, $size, $last . $ellipsis) > $max_width) { $tmp = preg_split('//u', $last, -1, PREG_SPLIT_NO_EMPTY); array_pop($tmp); $last = implode('', $tmp); } $lines[] = $last . $ellipsis; } if (count($lines) > $max_lines) $lines = array_slice($lines, 0, $max_lines); return $lines; }; $ex_trim_decimal_zeros = function ($s) { $s = (string)$s; if (strpos($s, '.') === false) return $s; $s = rtrim($s, '0'); $s = rtrim($s, '.'); return $s; }; $ex_output_converter_jpg = function ($left_big, $left_name, $left_code, $right_big, $right_name, $right_code) use ($font, $ex_tt_bbox_w, $ex_wrap_ellipsis, $ex_trim_decimal_zeros, $ex_draw_center_rect, $ex_round_rect_fill, $ex_round_rect_border) { $w = 1200; $h = 630; $scale = 2; $W = $w * $scale; $H = $h * $scale; $S = function ($v) use ($scale) { return intval(round($v * $scale)); }; if (empty($font) || !is_file($font)) { header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); exit; } if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { header('Last-Modified: ' . $_SERVER['HTTP_IF_MODIFIED_SINCE'], true, 304); exit; } header("Cache-Control: private, max-age=10800, pre-check=10800"); header("Pragma: private"); header("Expires: " . date(DATE_RFC822, strtotime('+7 day'))); header("Content-type:image/jpeg"); $left_big = $ex_trim_decimal_zeros($left_big); $right_big = $ex_trim_decimal_zeros($right_big); if (strlen($left_big) > 12) $left_big = str_replace(',', '', $left_big); if (strlen($right_big) > 12) $right_big = str_replace(',', '', $right_big); $img = imagecreatetruecolor($W, $H); imagealphablending($img, true); if (function_exists('imageantialias')) imageantialias($img, true); // 背景渐变 - 更柔和的现代蓝紫渐变 $bg_top = array(59, 130, 246); $bg_bottom = array(30, 58, 138); for ($y = 0; $y < $H; $y++) { $t = $y / max(1, ($H - 1)); $r = intval($bg_top[0] + ($bg_bottom[0] - $bg_top[0]) * $t); $g = intval($bg_top[1] + ($bg_bottom[1] - $bg_top[1]) * $t); $b = intval($bg_top[2] + ($bg_bottom[2] - $bg_top[2]) * $t); $c = imagecolorallocate($img, $r, $g, $b); imageline($img, 0, $y, $W - 1, $y, $c); } $white = imagecolorallocate($img, 255, 255, 255); $white_soft = imagecolorallocatealpha($img, 255, 255, 255, 30); $blue_text = imagecolorallocate($img, 30, 58, 138); $light_blue_box = imagecolorallocate($img, 239, 246, 255); $shadow = imagecolorallocatealpha($img, 0, 0, 0, 110); $gray_text = imagecolorallocate($img, 107, 114, 128); $margin = 80; $gap = 140; $box_width = intval(($w - $margin * 2 - $gap) / 2); $left_box_left = $margin; $right_box_left = $margin + $box_width + $gap; $card_top = 120; $card_bottom = 510; $card_r = 32; // 阴影与卡片 $ex_round_rect_fill($img, $S($left_box_left + 12), $S($card_top + 16), $S($left_box_left + $box_width + 12), $S($card_bottom + 16), $S($card_r), $shadow); $ex_round_rect_fill($img, $S($right_box_left + 12), $S($card_top + 16), $S($right_box_left + $box_width + 12), $S($card_bottom + 16), $S($card_r), $shadow); $ex_round_rect_fill($img, $S($left_box_left), $S($card_top), $S($left_box_left + $box_width), $S($card_bottom), $S($card_r), $white); $ex_round_rect_fill($img, $S($right_box_left), $S($card_top), $S($right_box_left + $box_width), $S($card_bottom), $S($card_r), $white); // 货币缩写与名称 (上方) $name_size = 52; $code_size = 36; $ex_draw_center_rect($img, $font, $code_size * $scale, strtoupper($left_code), $S($left_box_left), $S($card_top + 40), $S($left_box_left + $box_width), $S($card_top + 100), $gray_text); $ex_draw_center_rect($img, $font, $code_size * $scale, strtoupper($right_code), $S($right_box_left), $S($card_top + 40), $S($right_box_left + $box_width), $S($card_top + 100), $gray_text); $ex_draw_center_rect($img, $font, $name_size * $scale, $left_name, $S($left_box_left), $S($card_top + 110), $S($left_box_left + $box_width), $S($card_top + 190), $blue_text); $ex_draw_center_rect($img, $font, $name_size * $scale, $right_name, $S($right_box_left), $S($card_top + 110), $S($right_box_left + $box_width), $S($card_top + 190), $blue_text); // 浅蓝色数据底框 $num_box_top = $card_top + 220; $num_box_bottom = $card_bottom - 40; $num_box_pad = 30; $ex_round_rect_fill($img, $S($left_box_left + $num_box_pad), $S($num_box_top), $S($left_box_left + $box_width - $num_box_pad), $S($num_box_bottom), $S(20), $light_blue_box); $ex_round_rect_fill($img, $S($right_box_left + $num_box_pad), $S($num_box_top), $S($right_box_left + $box_width - $num_box_pad), $S($num_box_bottom), $S(20), $light_blue_box); $big_size = 80; while ($big_size > 40) { $lw = $ex_tt_bbox_w($font, $big_size * $scale, $left_big); $rw = $ex_tt_bbox_w($font, $big_size * $scale, $right_big); if ($lw <= ($box_width - $num_box_pad * 2 - 20) * $scale && $rw <= ($box_width - $num_box_pad * 2 - 20) * $scale) break; $big_size -= 2; } $ex_draw_center_rect($img, $font, $big_size * $scale, $left_big, $S($left_box_left + $num_box_pad), $S($num_box_top), $S($left_box_left + $box_width - $num_box_pad), $S($num_box_bottom), $blue_text); $ex_draw_center_rect($img, $font, $big_size * $scale, $right_big, $S($right_box_left + $num_box_pad), $S($num_box_top), $S($right_box_left + $box_width - $num_box_pad), $S($num_box_bottom), $blue_text); // 中间箭头图标 $btn_r = 48; $btn_cx = intval($margin + $box_width + $gap / 2); $btn_cy = intval(($card_top + $card_bottom) / 2); imagefilledellipse($img, $S($btn_cx + 8), $S($btn_cy + 10), $S($btn_r * 2), $S($btn_r * 2), $shadow); imagefilledellipse($img, $S($btn_cx), $S($btn_cy), $S($btn_r * 2), $S($btn_r * 2), $white); $arrow_c = $blue_text; imagesetthickness($img, $S(6)); $ax1 = $btn_cx - 20; $ax2 = $btn_cx + 20; $ay1 = $btn_cy - 12; $ay2 = $btn_cy + 12; imageline($img, $S($ax1), $S($ay1), $S($ax2), $S($ay1), $arrow_c); imagefilledpolygon($img, array($S($ax2), $S($ay1), $S($ax2 - 12), $S($ay1 - 10), $S($ax2 - 12), $S($ay1 + 10)), 3, $arrow_c); imageline($img, $S($ax2), $S($ay2), $S($ax1), $S($ay2), $arrow_c); imagefilledpolygon($img, array($S($ax1), $S($ay2), $S($ax1 + 12), $S($ay2 - 10), $S($ax1 + 12), $S($ay2 + 10)), 3, $arrow_c); imagesetthickness($img, 1); // 顶部标题和说明 $title_text = "实时汇率换算"; $ex_draw_center_rect($img, $font, $S(40), $title_text, 0, $S(20), $W, $S(100), $white); $out = imagecreatetruecolor($w, $h); imagecopyresampled($out, $img, 0, 0, 0, 0, $w, $h, $W, $H); imagejpeg($out, null, 90); imagedestroy($out); imagedestroy($img); exit; }; $ex_output_jpg = function ($line1, $line2_lines) use ($font, $ex_fit_size, $ex_wrap, $ex_draw_center) { $w = 1200; $h = 630; if (empty($font) || !is_file($font)) { header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); exit; } if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { header('Last-Modified: ' . $_SERVER['HTTP_IF_MODIFIED_SINCE'], true, 304); exit; } header("Cache-Control: private, max-age=10800, pre-check=10800"); header("Pragma: private"); header("Expires: " . date(DATE_RFC822, strtotime('+7 day'))); header("Content-type:image/jpeg"); $img = imagecreatetruecolor($w, $h); $bg = imagecolorallocate($img, 37, 99, 235); imagefilledrectangle($img, 0, 0, $w, $h, $bg); $white = imagecolorallocate($img, 255, 255, 255); $line1_size = $ex_fit_size($font, $line1, $w - 140, 56, 28); $ex_draw_center($img, $font, $line1_size, $line1, 250, $white, $w); $line2_text = implode('', $line2_lines); $line2_size = $ex_fit_size($font, $line2_text, $w - 140, 44, 22); $line2_lines_fit = $ex_wrap($font, $line2_size, $line2_text, $w - 140, 2); $y = 340; foreach ($line2_lines_fit as $i => $t) { $ex_draw_center($img, $font, $line2_size, $t, $y + $i * 60, $white, $w); } imagejpeg($img, null, 90); imagedestroy($img); exit; }; if (preg_match('#^ex_pic/converter/([a-zA-Z]{3})-([a-zA-Z]{3})/([0-9]+(?:_[0-9]{1,6})?)\.jpg$#', $uri, $m)) { $from = strtoupper($m[1]); $to = strtoupper($m[2]); $amount_str = str_replace('_', '.', $m[3]); $amount = floatval($amount_str); if ($amount <= 0) $amount = 1; $from_name = $this->exchange_currency->get_name($from); $to_name = $this->exchange_currency->get_name($to); $rate = $this->exchange_rate->get_exchange_rate($from, $to); if ($rate <= 0) exit; $result = $amount * $rate; $amount_formatted = (abs($amount - intval($amount)) < 0.000001) ? number_format(intval($amount)) : number_format($amount, 2); $result_formatted = number_format($result, 2); $ex_output_converter_jpg($amount_formatted, $from_name, $from, $result_formatted, $to_name, $to); } if (preg_match('#^ex_pic/daxie/([0-9]+(?:_[0-9]{1,2})?)\.jpg$#', $uri, $m)) { $number_str = str_replace('_', '.', $m[1]); if (!is_numeric($number_str)) { header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); exit; } $number = floatval($number_str); $ex_number_to_chinese = function ($number) { $number = floatval($number); $negative = false; if ($number < 0) { $negative = true; $number = abs($number); } $num_cn = array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'); $unit_cn = array('', '拾', '佰', '仟'); $big_unit_cn = array('', '万', '亿', '万亿'); $integer_part = floor($number); $decimal_part = round(($number - $integer_part) * 100); $result = ''; if ($integer_part == 0) { $result = '零元'; } else { $integer_str = strval($integer_part); $integer_len = strlen($integer_str); $groups = ceil($integer_len / 4); $integer_str = str_pad($integer_str, $groups * 4, '0', STR_PAD_LEFT); $group_results = array(); for ($i = 0; $i < $groups; $i++) { $group = substr($integer_str, $i * 4, 4); $group_result = ''; $zero_flag = false; for ($j = 0; $j < 4; $j++) { $digit = intval($group[$j]); if ($digit == 0) { if (!$zero_flag && $group_result != '') { $group_result .= '零'; $zero_flag = true; } } else { $group_result .= $num_cn[$digit] . $unit_cn[3 - $j]; $zero_flag = false; } } $group_result = rtrim($group_result, '零'); if ($group_result != '') { $group_result .= $big_unit_cn[$groups - $i - 1]; $group_results[] = $group_result; } } $result = implode('', $group_results) . '元'; } $jiao = floor($decimal_part / 10); $fen = $decimal_part % 10; if ($jiao == 0 && $fen == 0) { $result .= '整'; } else { if ($jiao > 0) { $result .= $num_cn[$jiao] . '角'; } elseif ($integer_part > 0) { $result .= '零'; } if ($fen > 0) { $result .= $num_cn[$fen] . '分'; } } if ($negative) $result = '负' . $result; return $result; }; $result_cn = $ex_number_to_chinese($number); $w = 1200; $h = 630; $scale = 2; $W = $w * $scale; $H = $h * $scale; $S = function ($v) use ($scale) { return intval(round($v * $scale)); }; if (empty($font) || !is_file($font)) { header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); exit; } if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { header('Last-Modified: ' . $_SERVER['HTTP_IF_MODIFIED_SINCE'], true, 304); exit; } header("Cache-Control: private, max-age=10800, pre-check=10800"); header("Pragma: private"); header("Expires: " . date(DATE_RFC822, strtotime('+7 day'))); header("Content-type:image/jpeg"); $img = imagecreatetruecolor($W, $H); imagealphablending($img, true); if (function_exists('imageantialias')) imageantialias($img, true); // 背景渐变 - 柔和的橙红暖色调(匹配人民币相关大写概念) $bg_top = array(249, 115, 22); $bg_bottom = array(194, 65, 12); for ($y = 0; $y < $H; $y++) { $t = $y / max(1, ($H - 1)); $r = intval($bg_top[0] + ($bg_bottom[0] - $bg_top[0]) * $t); $g = intval($bg_top[1] + ($bg_bottom[1] - $bg_top[1]) * $t); $b = intval($bg_top[2] + ($bg_bottom[2] - $bg_top[2]) * $t); $c = imagecolorallocate($img, $r, $g, $b); imageline($img, 0, $y, $W - 1, $y, $c); } $white = imagecolorallocate($img, 255, 255, 255); $shadow = imagecolorallocatealpha($img, 0, 0, 0, 112); $orange_text = imagecolorallocate($img, 194, 65, 12); $light_orange_box = imagecolorallocate($img, 255, 237, 213); $border = imagecolorallocatealpha($img, 255, 255, 255, 90); $gray_text = imagecolorallocate($img, 31, 41, 55); $card_w = 1000; $card_h = 460; $card_x1 = intval(($w - $card_w) / 2); $card_y1 = 110; $card_x2 = $card_x1 + $card_w; $card_y2 = $card_y1 + $card_h; $card_r = 32; $ex_round_rect_fill($img, $S($card_x1 + 12), $S($card_y1 + 16), $S($card_x2 + 12), $S($card_y2 + 16), $S($card_r), $shadow); $ex_round_rect_fill($img, $S($card_x1), $S($card_y1), $S($card_x2), $S($card_y2), $S($card_r), $white); $pill_w = 260; $pill_h = 60; $pill_x1 = intval($card_x1 + 60); $pill_y1 = intval($card_y1 + 50); $pill_x2 = $pill_x1 + $pill_w; $pill_y2 = $pill_y1 + $pill_h; $ex_round_rect_fill($img, $S($pill_x1), $S($pill_y1), $S($pill_x2), $S($pill_y2), $S(30), $light_orange_box); $ex_draw_center_rect($img, $font, 32 * $scale, '人民币大写转换', $S($pill_x1), $S($pill_y1), $S($pill_x2), $S($pill_y2), $orange_text); $title = $number_str . ' 大写'; $title_size = 56; while ($title_size > 30) { if ($ex_tt_bbox_w($font, $title_size * $scale, $title) <= ($card_w - 380) * $scale) break; $title_size -= 2; } $ex_draw_center_rect($img, $font, $title_size * $scale, $title, $S($card_x1 + 340), $S($card_y1 + 50), $S($card_x2 - 60), $S($pill_y2), $gray_text); $grid_x1 = $card_x1 + 60; $grid_y1 = $card_y1 + 160; $grid_x2 = $card_x2 - 60; $grid_y2 = $card_y2 - 60; $grid_w = $grid_x2 - $grid_x1; $grid_h = $grid_y2 - $grid_y1; $grid_bg = imagecolorallocatealpha($img, 255, 255, 255, 127); $grid_line = imagecolorallocatealpha($img, 253, 186, 116, 70); // 橙色网格线 $grid_diag = imagecolorallocatealpha($img, 253, 186, 116, 90); $chars = preg_split('//u', $result_cn, -1, PREG_SPLIT_NO_EMPTY); $n = count($chars); if ($n < 1) { $chars = array(' '); $n = 1; } $wrap_cols = 8; $rows = intval(ceil($n / $wrap_cols)); if ($rows < 1) $rows = 1; $cols_for_width = $rows == 1 ? min($wrap_cols, $n) : $wrap_cols; $min_cell = 64; $max_cell = 100; if ($n <= 4) $max_cell = 130; if ($n <= 2) $max_cell = 150; $cell_w = intval($grid_w / $cols_for_width); if ($cell_w > $max_cell) $cell_w = $max_cell; if ($cell_w < $min_cell) $cell_w = $min_cell; $cell_h = intval($grid_h / $rows); if ($cell_h > $max_cell) $cell_h = $max_cell; if ($cell_h < $min_cell) $cell_h = $min_cell; $cell = min($cell_w, $cell_h); $max_rows = intval(floor($grid_h / $cell)); if ($max_rows < 1) $max_rows = 1; if ($rows > $max_rows) $rows = $max_rows; $max_chars = $wrap_cols * $rows; if ($n > $max_chars) { $chars = array_slice($chars, 0, $max_chars - 1); $chars[] = '…'; $n = count($chars); } $last_row_count = $n - ($rows - 1) * $wrap_cols; if ($last_row_count < 1) $last_row_count = 1; $grid_w_used = $cell * ($rows == 1 ? $cols_for_width : $wrap_cols); $grid_h_used = $cell * $rows; $gx = intval($grid_x1 + ($grid_w - $grid_w_used) / 2); $gy = intval($grid_y1 + ($grid_h - $grid_h_used) / 2); $ex_dashed_line = function ($img, $x1, $y1, $x2, $y2, $color, $dash_len, $gap_len) { $dx = $x2 - $x1; $dy = $y2 - $y1; $dist = sqrt($dx * $dx + $dy * $dy); if ($dist <= 0) return; $step = $dash_len + $gap_len; $count = intval($dist / $step) + 1; for ($i = 0; $i < $count; $i++) { $start = $i * $step; $end = $start + $dash_len; if ($start > $dist) break; if ($end > $dist) $end = $dist; $sx = $x1 + $dx * ($start / $dist); $sy = $y1 + $dy * ($start / $dist); $ex = $x1 + $dx * ($end / $dist); $ey = $y1 + $dy * ($end / $dist); imageline($img, intval($sx), intval($sy), intval($ex), intval($ey), $color); } }; $char_color = imagecolorallocate($img, 194, 65, 12); $char_factor = 0.78; $char_max = 70; if ($n <= 2) { $char_factor = 0.92; $char_max = 96; } elseif ($n <= 4) { $char_factor = 0.88; $char_max = 90; } elseif ($n <= 6) { $char_factor = 0.82; $char_max = 78; } $char_size = intval($cell * $char_factor); if ($char_size < 34) $char_size = 34; if ($char_size > $char_max) $char_size = $char_max; for ($i = 0; $i < $n; $i++) { $r = intval(floor($i / $wrap_cols)); $c = $i % $wrap_cols; $row_cols = ($r == $rows - 1) ? $last_row_count : $wrap_cols; $row_offset_x = intval($gx + ($grid_w_used - $cell * $row_cols) / 2); $x1 = $row_offset_x + $c * $cell; $y1 = $gy + $r * $cell; $x2 = $x1 + $cell; $y2 = $y1 + $cell; imagerectangle($img, $S($x1), $S($y1), $S($x2), $S($y2), $grid_line); $mx = intval(($x1 + $x2) / 2); $my = intval(($y1 + $y2) / 2); $ex_dashed_line($img, $S($x1), $S($y1), $S($x2), $S($y2), $grid_diag, $S(6), $S(6)); $ex_dashed_line($img, $S($x1), $S($y2), $S($x2), $S($y1), $grid_diag, $S(6), $S(6)); $ex_dashed_line($img, $S($mx), $S($y1), $S($mx), $S($y2), $grid_diag, $S(6), $S(6)); $ex_dashed_line($img, $S($x1), $S($my), $S($x2), $S($my), $grid_diag, $S(6), $S(6)); $ch = $chars[$i]; $s = $char_size; while ($s > 18 && $ex_tt_bbox_w($font, $s * $scale, $ch) > (($cell - 18) * $scale)) { $s -= 2; } $ex_draw_center_rect($img, $font, $s * $scale, $ch, $S($x1 + 4), $S($y1 + 4), $S($x2 - 4), $S($y2 - 4), $char_color); } $title_text = "金额大写生成器"; $ex_draw_center_rect($img, $font, $S(40), $title_text, 0, $S(20), $W, $S(90), $white); $out = imagecreatetruecolor($w, $h); imagecopyresampled($out, $img, 0, 0, 0, 0, $w, $h, $W, $H); imagejpeg($out, null, 90); imagedestroy($out); imagedestroy($img); exit; } } // 处理AJAX请求(如 /exchange/ajax_rate) if (strpos($uri, 'exchange/ajax') === 0) { // 将 /exchange/ajax_rate 解析为 control=exchange&action=ajax_rate $parts = explode('/', $uri); if (count($parts) >= 2) { $_GET['control'] = 'exchange'; $_GET['action'] = $parts[1]; return; } } // 如果URI不是汇率相关的,不处理,让lecms默认路由处理 $exchange_patterns = array('converter', 'rates', 'rmb-rate', 'bank-rate', 'forex', 'currency', 'daxie', 'article', 'history', 'trend', 'rate/', 'bank/', 'forex/', 'daxie/', 'currency/', 'history/', 'trend/'); $is_exchange_url = false; foreach ($exchange_patterns as $pattern) { if (strpos($uri, $pattern) === 0 || $uri === $pattern || $uri === $pattern . '/') { $is_exchange_url = true; break; } } // 如果URI为空(首页),也处理 if (empty($uri)) { $is_exchange_url = true; } // 如果不是汇率相关的URL,不处理,让lecms继续执行category_url等方法 if (!$is_exchange_url) { // 不要return,让parseurl_control继续执行category_url等方法 // 但我们需要跳过下面的汇率URL处理代码 } else { // 获取数据库实例 $db = &$_ENV['_db']; $tableprefix = $_ENV['_config']['db']['tablepre']; // 从SEO表获取所有启用的URL规则 $seo_patterns = array(); try { $result = $db->query("SELECT * FROM `{$tableprefix}exchange_seo` WHERE `is_show` = 1 ORDER BY `sort` ASC"); if ($result) { while ($row = $db->fetch_array($result)) { $seo_patterns[$row['page_type']] = $row; } } } catch (Exception $e) { // 如果表不存在或查询失败,使用空数组 } // 辅助函数:获取URI路径(去掉后缀) function _get_uri_path($uri, $url_suffix) { $suffix_len = strlen($url_suffix); if (substr($uri, -$suffix_len) === $url_suffix) { return substr($uri, 0, -$suffix_len); } return $uri; } $url_suffix = isset($_ENV['_config']['url_suffix']) ? $_ENV['_config']['url_suffix'] : '.html'; // 处理首页URL(从SEO表读取) $index_patterns = array( 'converter_index' => array('control' => 'exchange', 'action' => 'converter'), 'rates_index' => array('control' => 'exchange', 'action' => 'rates'), 'rmbrate_index' => array('control' => 'exchange', 'action' => 'cnyrate'), 'bankrate_index' => array('control' => 'exchange', 'action' => 'bank'), 'forex_index' => array('control' => 'exchange', 'action' => 'forex'), 'currency_index' => array('control' => 'exchange', 'action' => 'currency'), 'daxie_index' => array('control' => 'exchange', 'action' => 'daxie'), 'article_index' => array('control' => 'exchange', 'action' => 'article'), ); foreach ($index_patterns as $page_type => $route) { if (isset($seo_patterns[$page_type])) { // 使用SEO表中的url_pattern $pattern = $seo_patterns[$page_type]['url_pattern']; // 去掉末尾的.html(如果有)用于匹配 $pattern_without_suffix = _get_uri_path($pattern, $url_suffix); $uri_path = _get_uri_path($uri, $url_suffix); if ($uri_path === $pattern_without_suffix) { $_GET['control'] = $route['control']; $_GET['action'] = $route['action']; return; } } } // 处理 converter 货币对页(如 /converter/USD-CNY/) // 支持大小写混合的货币代码,路径从SEO表读取 $converter_pair_pattern = isset($seo_patterns['converter_pair']) ? $seo_patterns['converter_pair']['url_pattern'] : 'converter/{from}-{to}/'; // 将 url_pattern 转换为正则表达式 // converter/{from}-{to}/ => converter/([a-zA-Z]{3})-([a-zA-Z]{3})/ $converter_pair_regex = preg_replace('/\{from\}/', '([a-zA-Z]{3})', $converter_pair_pattern); $converter_pair_regex = preg_replace('/\{to\}/', '([a-zA-Z]{3})', $converter_pair_regex); // 去掉末尾的斜杠,让斜杠可选 $converter_pair_regex = rtrim($converter_pair_regex, '/'); $converter_pair_regex = '#^' . preg_replace('/\./', '\\.', $converter_pair_regex) . '/?$#'; if (preg_match($converter_pair_regex, $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'converter_pair'; $_GET['from'] = strtoupper($matches[1]); $_GET['to'] = strtoupper($matches[2]); return; } // 处理 converter 详情页(如 /converter/USD-CNY/10000.html 或 /converter2/usd-cny/1.html) // 支持大小写混合的货币代码,路径从SEO表读取 $converter_pattern = isset($seo_patterns['converter_result']) ? $seo_patterns['converter_result']['url_pattern'] : 'converter/{from}-{to}/{amount}.html'; // 将 url_pattern 转换为正则表达式 // converter/{from}-{to}/{amount}.html => converter/([a-zA-Z]{3})-([a-zA-Z]{3})/(\d+)\.html $converter_regex = preg_replace('/\{from\}/', '([a-zA-Z]{3})', $converter_pattern); $converter_regex = preg_replace('/\{to\}/', '([a-zA-Z]{3})', $converter_regex); $converter_regex = preg_replace('/\{amount\}/', '(\d+)', $converter_regex); $converter_regex = '#^' . preg_replace('/\./', '\\.', $converter_regex) . '$#'; if (preg_match($converter_regex, $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'converter_detail'; $_GET['from'] = strtoupper($matches[1]); $_GET['to'] = strtoupper($matches[2]); $_GET['amount'] = intval($matches[3]); return; } $history_pair_pattern = isset($seo_patterns['history_pair']) ? $seo_patterns['history_pair']['url_pattern'] : 'history/{from}-{to}.html'; $history_pair_regex = preg_replace('/\{from\}/', '([a-zA-Z]{3})', $history_pair_pattern); $history_pair_regex = preg_replace('/\{to\}/', '([a-zA-Z]{3})', $history_pair_regex); $history_pair_regex = rtrim($history_pair_regex, '/'); $history_pair_regex = '#^' . preg_replace('/\./', '\\.', $history_pair_regex) . '$#'; if (preg_match($history_pair_regex, $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'history_pair'; $_GET['from'] = strtoupper($matches[1]); $_GET['to'] = strtoupper($matches[2]); return; } $history_currency_pattern = isset($seo_patterns['history_currency']) ? $seo_patterns['history_currency']['url_pattern'] : 'history/{code}.html'; $history_currency_regex = preg_replace('/\{code\}/', '([a-zA-Z]{3})', $history_currency_pattern); $history_currency_regex = rtrim($history_currency_regex, '/'); $history_currency_regex = '#^' . preg_replace('/\./', '\\.', $history_currency_regex) . '$#'; if (preg_match($history_currency_regex, $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'history_currency'; $_GET['code'] = strtoupper($matches[1]); return; } $trend_pair_pattern = isset($seo_patterns['trend_pair']) ? $seo_patterns['trend_pair']['url_pattern'] : 'trend/{from}-{to}.html'; $trend_pair_regex = preg_replace('/\{from\}/', '([a-zA-Z]{3})', $trend_pair_pattern); $trend_pair_regex = preg_replace('/\{to\}/', '([a-zA-Z]{3})', $trend_pair_regex); $trend_pair_regex = rtrim($trend_pair_regex, '/'); $trend_pair_regex = '#^' . preg_replace('/\./', '\\.', $trend_pair_regex) . '$#'; if (preg_match($trend_pair_regex, $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'trend_pair'; $_GET['from'] = strtoupper($matches[1]); $_GET['to'] = strtoupper($matches[2]); return; } $trend_currency_pattern = isset($seo_patterns['trend_currency']) ? $seo_patterns['trend_currency']['url_pattern'] : 'trend/{code}.html'; $trend_currency_regex = preg_replace('/\{code\}/', '([a-zA-Z]{3})', $trend_currency_pattern); $trend_currency_regex = rtrim($trend_currency_regex, '/'); $trend_currency_regex = '#^' . preg_replace('/\./', '\\.', $trend_currency_regex) . '$#'; if (preg_match($trend_currency_regex, $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'trend_currency'; $_GET['code'] = strtoupper($matches[1]); return; } // 处理 /rate/USD.html 页面(人民币牌价内容页) if (preg_match('#^rate/([a-zA-Z]{3})\.html$#', $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'cnyrate_detail'; $_GET['code'] = strtoupper($matches[1]); return; } // 处理 /bank/boc.html 页面(银行牌价内容页) if (preg_match('#^bank/([a-zA-Z]+)\.html$#', $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'bank_detail'; $_GET['code'] = strtoupper($matches[1]); return; } // 处理 /forex/USD-EUR.html 页面(外汇牌价内容页) if (preg_match('#^forex/([a-zA-Z]{3})-([a-zA-Z]{3})\.html$#', $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'forex_detail'; $_GET['base'] = strtoupper($matches[1]); $_GET['target'] = strtoupper($matches[2]); return; } // 处理 /daxie/100.html 页面(大写转换内容页) if (preg_match('#^daxie/(\d+)\.html$#', $uri, $matches)) { $_GET['control'] = 'exchange'; $_GET['action'] = 'daxie_detail'; $_GET['number'] = $matches[1]; return; } // 处理 /article.html 页面(文章资讯栏目页) if (isset($seo_patterns['article_index'])) { $pattern = _get_uri_path($seo_patterns['article_index']['url_pattern'], $url_suffix); if (_get_uri_path($uri, $url_suffix) === $pattern) { $_GET['control'] = 'exchange_article'; $_GET['action'] = 'index'; return; } } // 处理 /article/XXX.html 页面(文章资讯内容页) if (preg_match('#^article/(\d+)\.html$#', $uri, $matches)) { $_GET['control'] = 'exchange_article'; $_GET['action'] = 'detail'; $_GET['id'] = intval($matches[1]); return; } // 处理 /article/category/XXX.html 页面(文章分类页) if (preg_match('#^article/category/(\d+)\.html$#', $uri, $matches)) { $_GET['control'] = 'exchange_article'; $_GET['action'] = 'index'; $_GET['category_id'] = intval($matches[1]); return; } // 处理 /article/category/XXX/2.html 页面(文章分类分页) if (preg_match('#^article/category/(\d+)/(\d+)\.html$#', $uri, $matches)) { $_GET['control'] = 'exchange_article'; $_GET['action'] = 'index'; $_GET['category_id'] = intval($matches[1]); $_GET['page'] = intval($matches[2]); return; } // 处理 /article/2.html 页面(文章列表分页) if (preg_match('#^article/(\d+)\.html$#', $uri, $matches)) { $_GET['control'] = 'exchange_article'; $_GET['action'] = 'index'; $_GET['page'] = intval($matches[1]); return; } }//标题缩略图伪静态 cid_id.jpg if( preg_match('/pic\/(\d+)_(\d+)\.jpg/i', $uri, $match) ){ $title = ''; if( isset($match[1]) && isset($match[2]) ){ $cid = $match[1]; $id = $match[2]; $category = $this->category->get_cache($cid); if($category){ // 初始模型表名 $this->cms_content->table = 'cms_'.$category['table']; // 读取内容 $_show = $this->cms_content->read($id); if($_show){ $title = $_show['title']; } } } if( empty($title) ){ exit(); } //$title = $match[1]; //如果浏览器对当前页面已经有缓存,那么就直接使用它 if (isset($_SERVER['http_IF_MODIFIED_SINCE'])) { header('Last-Modified: '.$_SERVER['HTTP_IF_MODIFIED_SINCE'],true,304); exit(); } //随机取一个背景图 $bgimgdir = PLUGIN_PATH.'le_title_pic/bg_img/'; if( !is_dir($bgimgdir) ){exit();} $all_image_files = _scandir($bgimgdir);//背景图存放文件夹的jpg图片 foreach ($all_image_files as $k=>$file){ if($file == '.' || $file == '..'){ unset($all_image_files[$k]); } } if( empty($all_image_files) ){ exit(); } shuffle($all_image_files); $backgroundFile = array_slice($all_image_files, 0, 1); $backgroundPath = $bgimgdir.$backgroundFile[0]; $font = PLUGIN_PATH."le_title_pic/static/msyhbd.ttc"; //字体 $size = 20; //默认字体大小 $oneline = 10; preg_match_all("/./u", $title, $t_arr);//将所有字符转成单个数组 $tarr = $t_arr[0]; $t_total = count($tarr); //标题长度 if($t_total > 30){ $t_total = 30; } $cha = 30 - $t_total; $size = $size + $cha; if($size > 36 ){ $size = 36; }elseif($size < 24){ $size = 24; } $text = ''; if($t_total > $oneline){ $line = 2; $bnum = $t_total/2; $snum = 0; for ($x = 0; $x < $t_total; $x++) { $snum++; if($snum >= $bnum){ $snum = 0; $text .= $tarr[$x].PHP_EOL; }else{ if($x > 27){ $text .= "..."; break; }else{ $text .= $tarr[$x]; } } } }else{ $text = $title; $line = 1; } //创建图片 $img = imagecreatefromjpeg($backgroundPath); $width = imagesx($img); $height = imagesy($img); if($line > 1){ $a = imagettfbbox($size, 0, $font, $text); //得到字符串虚拟方框四个点的坐标 $len = $a[2] - $a[0]; $x = ($width-$len)/2; $h = $size/10; $y = ($height/2)-15+$h; }else{ $a = imagettfbbox($size, 0, $font, $text); //得到字符串虚拟方框四个点的坐标 $len = $a[2] - $a[0]; $x = ($width-$len)/2; $h = $size/10; $y = ($height/2)+10+$h; } $color = imagecolorallocate($img, 255, 255, 255); // 0 0 0 表示黑色 $setting = $this->kv->get('le_title_pic_setting'); $cache_day = $setting['cache_day'].' day'; //缓存天数 //将规定当前页面缓存的时间(两天),并在下一次访问中使用这个缓存时间节点。接下来判断是否已经有缓存,如果有,就使用缓存。 header("Cache-Control: private, max-age=10800, pre-check=10800"); header("Pragma: private"); header("Expires: " . date(DATE_RFC822, strtotime($cache_day))); header("Content-type:image/jpeg"); imagettftext($img, $size, 0, $x, $y, $color, $font, $text); imagejpeg($img); imagedestroy($img); exit(); } //站点地图 $sitemap_uri = array('sitemap.xml', 'sitemap.html', 'sitemap.txt'); if(in_array($uri, $sitemap_uri)){ $u_arr = explode('.', $uri); $_GET['control'] = 'sitemap'; $_GET['action'] = $u_arr[1]; return; } /** * 分类URL解析前钩子 * 在 category_url 方法之前执行 * 如果URI不是汇率相关的,让lecms处理 */ // 如果URI不是汇率相关的,不拦截,让lecms的category_url处理 $exchange_patterns = array('converter', 'rates', 'rmb-rate', 'bank-rate', 'forex', 'currency', 'daxie', 'article', 'rate/', 'bank/', 'forex/', 'daxie/', 'currency/'); $is_exchange_url = false; foreach ($exchange_patterns as $pattern) { if (strpos($uri, $pattern) === 0 || $uri === $pattern || $uri === $pattern . '/') { $is_exchange_url = true; break; } } // 如果URI为空(首页),也处理 if (empty($uri)) { $is_exchange_url = true; } // 如果不是汇率相关的URL,不拦截,让category_url处理 if (!$is_exchange_url) { // 不要return,让category_url继续执行 } $r = $this->category_url($cfg, $uri); if($r){return;} $r = $this->content_url($cfg, $uri); if($r){return;} $r = $this->tag_url($cfg, $uri); if($r){return;} $r = $this->search_url($cfg, $uri); if($r){return;} $r = $this->comment_url($cfg, $uri); if($r){return;} $r = $this->index_page_url($cfg, $uri); if($r){return;} $r = $this->tag_like_url($cfg, $uri); if($r){return;} $r = $this->user_url($cfg, $uri); if($r){return;} $r = $this->model_url($cfg, $uri); if($r){return;} $r = $this->flags_url($cfg, $uri); if($r){return;} $r = $this->space_url($cfg, $uri); if($r){return;} } //伪静态结束------------------------------------------------------------------------------------------------------ // 伪静态时,如果 $uri 有值,但没有解析到相关 $_GET 时,就提示404 if(empty($_GET) && isset($uri) && !empty($uri)) { core::error404(); } if( !isset($_GET['control']) ) { $r = $this->other_url(); if($r){return;} } } //---------------------------------------------------------------------- 以下是各模块URL解析的具体函数实现 //模型页URL解析 protected function model_url($cfg = array(), $uri = ''){ //模型信息 table=>mid $model_arr = array_flip($cfg['table_arr']); // 模型URL未设置后缀/的情况,301重定向到已设置后缀的URL if( isset($model_arr[$uri]) ) { http_location($cfg['weburl'].$uri.'/', '301'); } $_GET['control'] = 'model'; $_GET['action'] = 'index'; if(substr($uri, -1) == '/'){ $newurl = substr($uri, 0, -1); }else{ $newurl = $uri; } //模型首页URL if( isset($model_arr[$newurl]) ) { $_GET['mid'] = (int)$model_arr[$newurl]; return true; } //模型分页URL $u_arr = explode('/', $newurl); if( isset($model_arr[$u_arr[0]]) ) { $_GET['mid'] = (int)$model_arr[$u_arr[0]]; //分页 if( isset($u_arr[1]) ){ if($page = $this->page_check($u_arr[1])){ $_GET['page'] = $page; }else{ core::error404(); } } return true; } unset($_GET['control']); unset($_GET['action']); return false; } //分类URL解析 protected function category_url($cfg = array(), $uri = ''){ /** * 分类URL解析前钩子 */ //分类信息 alias=>cid $cate_arr = array_flip($cfg['cate_arr']); // 分类URL未设置后缀的情况,301重定向到已设置后缀的URL if( isset($cate_arr[$uri]) ) { http_location($cfg['weburl'].$uri.$cfg['link_cate_end'], '301'); } $_GET['control'] = 'cate'; $_GET['action'] = 'index'; $len = strlen($cfg['link_cate_end']); //分页首页URL if(substr($uri, -$len) == $cfg['link_cate_end']) { $newurl = substr($uri, 0, -$len); if( isset($cate_arr[$newurl]) ) { $_GET['cid'] = (int)$cate_arr[$newurl]; return true; } } //分类URL分页的情况 if(strpos($uri, $cfg['link_cate_page_pre']) !== FALSE) { $len = strlen($cfg['link_cate_page_end']); if(substr($uri, -$len) == $cfg['link_cate_page_end']) { $newurl = substr($uri, 0, -$len); $u_arr = explode($cfg['link_cate_page_pre'], $newurl); if( isset($cate_arr[$u_arr[0]]) ) { $_GET['cid'] = (int)$cate_arr[$u_arr[0]]; //分页 if( isset($u_arr[1]) ){ if($this->integer_check($u_arr[1])){ $_GET['page'] = $u_arr[1]; }else{ core::error404(); } } return true; } } } /** * 分类URL解析后钩子 * 如果category_url返回false,尝试直接匹配分类别名 */ // 如果前面的方法没有匹配到,尝试直接匹配分类别名(无后缀) if (!isset($_GET['cid']) && !empty($uri)) { // 移除尾部斜杠 $alias = rtrim($uri, '/'); // 检查是否是分类别名 if (isset($cate_arr[$alias])) { $_GET['control'] = 'cate'; $_GET['action'] = 'index'; $_GET['cid'] = (int)$cate_arr[$alias]; // 直接return,让category_url方法返回true return true; } } unset($_GET['control']); unset($_GET['action']); return false; } //内容URL解析 protected function content_url($cfg = array(), $uri = ''){ $link_show_end = $cfg['link_show_end']; $link_show_end_len = strlen($link_show_end); $cate_arr = array_flip($cfg['cate_arr']); $newurl = $link_show_end_len ? substr($uri, 0, -$link_show_end_len) : $uri; $_GET['control'] = 'show'; $_GET['action'] = 'index'; switch ($cfg['link_show_type']){ case 1: //数字型 preg_match("/^(\d+)\/(\d+)$/i", $newurl, $mat); if( isset($mat[2]) ){ $_GET['cid'] = $mat[1]; $_GET['id'] = $mat[2]; return true; } break; case 2: //推荐型 preg_match("/^(\w+)\/(\d+)$/i", $newurl, $mat); if( isset($mat[2]) && isset($cate_arr[$mat[1]]) ){ $_GET['cid'] = $cate_arr[$mat[1]]; $_GET['id'] = $mat[2]; return true; } break; case 3: //别名型 preg_match("/^(\d+)\_(\d+)$/i", $newurl, $mat); //没有设置别名,将用 cid_id 组合 if( isset($mat[2]) ) { $_GET['cid'] = $mat[1]; $_GET['id'] = $mat[2]; return true; }elseif( preg_match('/^[a-zA-Z0-9-_]+$/i', $newurl) ) { $row = $this->only_alias->get($newurl); if( !empty($row) ) { $_GET['cid'] = $row['cid']; $_GET['id'] = $row['id']; return true; } } break; case 4: //加密型 $newurl = decrypt($newurl);//解密得到 cid_id preg_match("/^(\d+)\_(\d+)$/i", $newurl, $mat); if( isset($mat[2]) ) { $_GET['cid'] = $mat[1]; $_GET['id'] = $mat[2]; return true; } break; case 5: //ID型 if($this->integer_check($newurl)){ $_GET['mid'] = 2; $_GET['id'] = $newurl; return true; } preg_match("/^(\d+)\_(\d+)$/i", $newurl, $mat); if( isset($mat[2]) ) { if( !$this->mid_check($mat[1], $cfg) ){core::error404();} $_GET['mid'] = $mat[1]; $_GET['id'] = $mat[2]; return true; } break; case 6: //别名组合型 $u_arr = explode('/', $newurl); if( isset($u_arr[1]) && isset($cate_arr[$u_arr[0]]) ){ $cid = (int)$cate_arr[$u_arr[0]]; // 如果没有设置别名,将用 cid_id 组合 preg_match("/^(\d+)\_(\d+)$/i", $u_arr[1], $mat); if(isset($mat[2]) && $mat[1] == $cid) { $_GET['cid'] = $mat[1]; $_GET['id'] = $mat[2]; return true; }elseif(preg_match('/^[a-zA-Z0-9-_]+$/i', $u_arr[1])) { $row = $this->only_alias->get($u_arr[1]); if(!empty($row) && $row['cid'] == $cid) { $_GET['cid'] = $row['cid']; $_GET['id'] = $row['id']; return true; } } } break; case 7: //灵活型 $quote = preg_quote($cfg['link_show'], '#'); $quote = strtr($quote, array( '\{cid\}' => '(?\d+)', '\{mid\}' => '(?\d+)', '\{id\}' => '(?\d+)', '\{alias\}' => '(?\w+)', '\{cate_alias\}' => '(?\w+)', '\{password\}' => '(?\w+)', '\{ymd\}' => '(?\d{8})', '\{y\}' => '(?\d{4})', '\{m\}' => '(?\d{2})', '\{d\}' => '(?\d{2})', '\{auth_key\}' => '(?\w+)', '\{hashids\}' => '(?\w+)' )); preg_match('#'.$quote.'#', $uri, $mat); if($mat){ //用于control验证日期 isset($mat['ymd']) AND $_GET['date_ymd'] = $mat['ymd']; isset($mat['y']) AND $_GET['date_y'] = $mat['y']; isset($mat['m']) AND $_GET['date_m'] = $mat['m']; isset($mat['d']) AND $_GET['date_d'] = $mat['d']; $auth_key = $_ENV['_config']['auth_key']; if( isset($mat['auth_key']) && $mat['auth_key'] != substr(md5($auth_key), 0, 6) ){ core::error404(); } if( isset($mat['cid']) && isset($mat['id']) ) { // {cid} {id} 合组 $_GET['cid'] = $mat['cid']; $_GET['id'] = $mat['id']; return true; }elseif( isset($mat['mid']) && isset($mat['id']) && $this->mid_check($mat['mid'], $cfg) ) { // {mid} {id} 合组 $_GET['mid'] = $mat['mid']; $_GET['id'] = $mat['id']; return true; }elseif( isset($mat['cate_alias']) && isset($mat['id']) ) { // {cate_alias} {id} 合组 $_GET['cid'] = isset($cate_arr[$mat['cate_alias']]) ? $cate_arr[$mat['cate_alias']] : 0; empty($_GET['cid']) && core::error404(); $_GET['id'] = $mat['id']; return true; }elseif( isset($mat['password']) ) { // {password} $newurl = decrypt($mat['password']);//解密得到 cid_id preg_match("/^(\d+)\_(\d+)$/i", $newurl, $mat); if( isset($mat[2]) ) { $_GET['cid'] = $mat[1]; $_GET['id'] = $mat[2]; return true; } }elseif( isset($mat['alias']) ) { // {alias} preg_match("/^(\d+)\_(\d+)$/i", $mat['alias'], $mat2); //没有设置别名,将用 cid_id 组合 if( isset($mat2[2]) ) { $_GET['cid'] = $mat2[1]; $_GET['id'] = $mat2[2]; return true; } $row = $this->only_alias->get($mat['alias']); if(!empty($row)) { $_GET['cid'] = $row['cid']; $_GET['id'] = $row['id']; return true; } }elseif( isset($mat['hashids']) ) { // {hashids} $newurl = hashids_decrypt($mat['hashids']);//解密得到 cid id 数组 if(is_array($newurl) && isset($newurl[1])){ $_GET['cid'] = $newurl[0]; $_GET['id'] = $newurl[1]; return true; } } // 比如article/id.html,只能一个文章模型(多模型的不行,没法区分id属于那个模型的),因此丢到最后 if ( isset($mat['id']) && $this->integer_check($mat['id']) ){ $u_arr = explode('/', $uri); if( substr($cfg['link_show'], 0, strlen($u_arr[0])) == $u_arr[0] ){ $_GET['mid'] = 2; $_GET['id'] = $mat['id']; return true; } } } break; case 8: //HashIDS $newurl = hashids_decrypt($newurl);//解密得到 cid id 数组 if(is_array($newurl) && isset($newurl[1])){ $_GET['cid'] = $newurl[0]; $_GET['id'] = $newurl[1]; return true; } break; } unset($_GET['control']); unset($_GET['action']); return false; } //标签URL解析 protected function tag_url($cfg = array(), $uri = ''){ $len = strlen($cfg['link_tag_pre']); if(substr($uri, 0, $len) == $cfg['link_tag_pre']) { $len2 = strlen($cfg['link_tag_end']); if(substr($uri, -$len2) == $cfg['link_tag_end']) { $_GET['control'] = 'tag'; $_GET['action'] = 'index'; $newurl = substr($uri, $len, -$len2); $u_arr = explode('/', $newurl); $u_arr_count = count($u_arr); if($u_arr_count > 2){ core::error404(); } //分页 if( isset($u_arr[1]) ){ $page = $this->page_check($u_arr[1]); if($page){ $_GET['page'] = $page; }else{ core::error404(); } } switch ($cfg['link_tag_type']){ case 0: preg_match('/^(\d+)\_(.+)$/i', $u_arr[0], $mat); if( isset($mat[2]) ) { if( !$this->mid_check($mat[1], $cfg) ){core::error404();} $_GET['mid'] = $mat[1]; $_GET['name'] = $mat[2]; return true; }else{ $_GET['mid'] = 2; $_GET['name'] = $u_arr[0]; return true; } break; case 1: preg_match("/^(\d+)\_(\d+)$/i", $u_arr[0], $mat); if( isset($mat[2]) ) { if( !$this->mid_check($mat[1], $cfg) ){core::error404();} $_GET['mid'] = $mat[1]; $_GET['tagid'] = $mat[2]; return true; }elseif( $this->integer_check($u_arr[0]) ){ $_GET['mid'] = 2; $_GET['tagid'] = $u_arr[0]; return true; } break; case 2: $newurl = decrypt($u_arr[0]);//解密得到 mid_tagid preg_match("/^(\d+)\_(\d+)$/i", $newurl, $mat); if( isset($mat[2]) ){ if( !$this->mid_check($mat[1], $cfg) ){core::error404();} $_GET['mid'] = (int)$mat[1]; $_GET['tagid'] = (int)$mat[2]; return true; } break; case 3: $newurl = hashids_decrypt($u_arr[0]);//解密得到 mid tagid 数组 if(is_array($newurl) && isset($newurl[1])){ $_GET['mid'] = (int)$newurl[0]; $_GET['tagid'] = (int)$newurl[1]; return true; } break; } }else{ //尝试301跳转到带后缀的链接试试看~ http_location($cfg['weburl'].$uri.$cfg['link_tag_end'], '301'); } } unset($_GET['control']); unset($_GET['action']); return false; } //搜索URL解析 protected function search_url($cfg = array(), $uri = ''){ if(substr($uri, 0, 7) == 'search/') { if(substr($uri, -1) != '/'){$uri .= '/';} $newurl = substr($uri, 7, -1); $uarr = explode('/', $newurl); //模型ID if(isset($uarr[0]) && substr($uarr[0], 0 ,4) == 'mid_'){ $mid = substr($uarr[0], 4); if($this->mid_check($mid, $cfg)){ $_GET['mid'] = $mid; array_shift($uarr); }else{ core::error404(); } }else{ $_GET['mid'] = 2; } //排除多余的参数 if(count($uarr) > 2){core::error404();} //关键词 $_GET['keyword'] = $uarr[0]; //分页 if( isset($uarr[1]) ){ $page = $this->page_check($uarr[1]); if($page){ $_GET['page'] = $page; }else{ core::error404(); } } $_GET['control'] = 'search'; $_GET['action'] = 'index'; return true; } //搜索页面链接解析 $url_suffix = isset($_ENV['_config']['url_suffix']) ? $_ENV['_config']['url_suffix'] : '.html'; $url_suffix_len = strlen($url_suffix); if(substr($uri, -$url_suffix_len) == $url_suffix && substr($uri, 0, -$url_suffix_len) == 'so') { $_GET['control'] = 'search'; $_GET['action'] = 'so'; return true; } return false; } //评论URL解析 protected function comment_url($cfg = array(), $uri = ''){ $len = strlen($cfg['link_comment_pre']); if(substr($uri, 0, $len) == $cfg['link_comment_pre']) { $url_suffix = isset($_ENV['_config']['url_suffix']) ? $_ENV['_config']['url_suffix'] : '.html'; $url_suffix_len = strlen($url_suffix); if(substr($uri, -$url_suffix_len) == $url_suffix) { $newurl = substr($uri, $len, -$url_suffix_len); $u_arr = explode('_', $newurl); if(count($u_arr) > 1) { $_GET['control'] = 'comment'; $_GET['action'] = 'index'; $_GET['cid'] = $u_arr[0]; $_GET['id'] = $u_arr[1]; //分页 if(isset($u_arr[2])){ if($this->integer_check($u_arr[2])){ $_GET['page'] = $u_arr[2]; }else{ core::error404(); } } return true; } } } return false; } //首页分页URL解析 protected function index_page_url($cfg = array(), $uri = ''){ $url_suffix = isset($_ENV['_config']['url_suffix']) ? $_ENV['_config']['url_suffix'] : '.html'; $url_suffix_len = strlen($url_suffix); if(substr($uri, 0, 6) == 'index_' && substr($uri, -$url_suffix_len) == $url_suffix) { $newurl = substr($uri, 0, -$url_suffix_len); preg_match("/^index_(\d+)$/i", $newurl, $mat); if( isset($mat[1]) ){ if(!$this->integer_check($mat[1])){core::error404();} $_GET['control'] = 'index'; $_GET['action'] = 'index'; $_GET['mid'] = 2; $_GET['page'] = $mat[1]; return true; } preg_match("/^index_(\d+)_(\d+)$/i", $newurl, $mat); if( isset($mat[2]) ){ if(!$this->mid_check($mat[1], $cfg)){core::error404();} if(!$this->integer_check($mat[2])){core::error404();} $_GET['control'] = 'index'; $_GET['action'] = 'index'; $_GET['mid'] = $mat[1]; $_GET['page'] = $mat[2]; return true; } } return false; } //热门标签 全部标签 URL解析 protected function tag_like_url($cfg = array(), $uri = ''){ // 热门标签 if($uri == $cfg['link_tag_top'] || $uri == $cfg['link_tag_top'].'/') { if($uri == $cfg['link_tag_top']){ http_location($cfg['weburl'].$uri.'/', '301'); } $_GET['control'] = 'tag'; $_GET['action'] = 'top'; return true; } //全部标签 if(substr($uri, 0, 8) == 'tag_all/' || substr($uri, 0, 7) == 'tag_all'){ if(substr($uri, -1) != '/'){ http_location($cfg['weburl'].$uri.'/', '301'); } $u_arr = explode('/', $uri); if($u_arr[0] != 'tag_all'){ core::error404(); }else{ unset($u_arr); } $_GET['control'] = 'tag'; $_GET['action'] = 'all'; $newurl = substr($uri, 8, -1); if($newurl){ if(is_numeric($newurl) && $newurl > 0){ $_GET['mid'] = 2; $_GET['page'] = $newurl; }else{ $u_arr = explode('_', $newurl); if(count($u_arr) > 2){core::error404();} if(!$this->mid_check($u_arr[0], $cfg)){core::error404();} $_GET['mid'] = $u_arr[0]; if(is_numeric($u_arr[1]) && $u_arr[1] > 0){ $_GET['page'] = $u_arr[1]; }else{ core::error404(); } } } return true; } return false; } //用户中心URL解析 protected function user_url($cfg = array(), $uri = ''){ $url_suffix = isset($_ENV['_config']['url_suffix']) ? $_ENV['_config']['url_suffix'] : '.html'; $url_suffix_len = strlen($url_suffix); $newurl = substr($uri, 0, -$url_suffix_len); if( preg_match('/^user-[a-z0-9-]+$/i', $newurl) || preg_match('/^my-[a-z0-9-]+$/i', $newurl) ){ $u_arr = explode('-', $newurl); if(count($u_arr) > 1) { $_GET['control'] = $u_arr[0]; array_shift($u_arr); $_GET['action'] = $u_arr[0]; array_shift($u_arr); $num = count($u_arr); for($i=0; $i<$num; $i+=2){ isset($u_arr[$i+1]) && $_GET[$u_arr[$i]] = $u_arr[$i+1]; } return true; } } return false; } //属性内容URL解析 protected function flags_url($cfg = array(), $uri = ''){ if(substr($uri, 0, 6) == 'flags/'){ if(substr($uri, -1) == '/'){$uri = substr($uri, 0,-1);} $u_arr = explode('/', $uri); if( isset($u_arr[1]) ){ $_GET['control'] = 'flags'; $_GET['action'] = 'index'; $u_arr_1 = explode('_', $u_arr[1]); if(isset($u_arr_1[1])){ $_GET['mid'] = $u_arr_1[0]; if(!$this->mid_check($_GET['mid'], $cfg)){core::error404();} $_GET['flag'] = $u_arr_1[1]; }else{ $_GET['mid'] = 2; $_GET['flag'] = $u_arr[1]; } if(!isset($this->cms_content->flag_arr[$_GET['flag']])){core::error404();} //分页 if( isset($u_arr[2]) ){ $page = $this->page_check($u_arr[2]); if($page){ $_GET['page'] = $page; }else{ core::error404(); } } return true; } } return false; } //个人空间URL解析 protected function space_url($cfg = array(), $uri = ''){ $len = strlen($cfg['link_space_pre']); if(substr($uri, 0, $len) == $cfg['link_space_pre']) { $len2 = strlen($cfg['link_space_end']); if(substr($uri, -$len2) == $cfg['link_space_end']) { $newurl = substr($uri, $len, -$len2); $u_arr = explode('/', $newurl); if( $this->integer_check($u_arr[0]) ){ $_GET['control'] = 'space'; $_GET['action'] = 'index'; $_GET['uid'] = $u_arr[0]; //分页 if( isset($u_arr[1]) ){ $page = $this->page_check($u_arr[1]); if($page){ $_GET['page'] = $page; }else{ core::error404(); } } } } } return false; } //动态URL解析 protected function other_url(){ if(isset($_GET['u'])) { $u = $_GET['u']; unset($_GET['u']); }elseif(!empty($_SERVER['PATH_INFO'])) { $u = R('PATH_INFO', 'S'); }else{ $_GET = array(); $u = R('QUERY_STRING', 'S'); } //清除URL后缀 $url_suffix = C('url_suffix'); if($url_suffix) { $suf_len = strlen($url_suffix); if(substr($u, -($suf_len)) == $url_suffix) $u = substr($u, 0, -($suf_len)); } $uarr = explode('&', $u); $u = $uarr[0]; if(count($uarr) > 1){ array_shift($uarr); foreach ($uarr as $v){ $varr = explode('=', $v); $_GET[$varr[0]] = isset($varr[1]) ? urldecode($varr[1]) : ''; } } unset($uarr); $uarr = explode('-', $u); if(count($uarr) < 2) {core::error404();} //控制器 if(isset($uarr[0])) { $_GET['control'] = empty($uarr[0]) ? 'index': strtolower($uarr[0]); array_shift($uarr); } //方法 if(isset($uarr[0])) { $_GET['action'] = empty($uarr[0]) ? 'index': strtolower($uarr[0]); array_shift($uarr); } //伪静态下 访问动态首页、内容页URL、分类URL、标签URL 则进入404页面 $dis_control = array('index', 'show', 'cate', 'tag'); if( in_array($_GET['control'], $dis_control) && $_GET['action'] == 'index'){ core::error404(); } //参数 $num = count($uarr); for($i=0; $i<$num; $i+=2){ isset($uarr[$i+1]) && $_GET[$uarr[$i]] = $uarr[$i+1]; } return false; } //分页参数验证 private function page_check($param){ if(empty($param)){ return false; }else{ preg_match('/^page_([1-9]\d*)$/', $param, $mat); if(isset($mat[1])){ return $mat[1]; }else{ return false; } } } //正整数参数验证 private function integer_check($param){ if(empty($param)){ return false; }elseif( preg_match($this->integer_pattern, $param) ){ return true; }else{ return false; } } //模型ID验证(不含单页) private function mid_check($mid, $cfg){ if($mid > 1 && isset($cfg['table_arr'][$mid])){ return true; }else{ return false; } } } Lecms 3.0.3 错误

错误信息

  • 消息: [程序异常] : 类 parseurl_control 不存在
  • 文件: /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/core.class.php
  • 位置: 第115行

错误位置

    #111        }elseif(is_file(FRAMEWORK_PATH.'ext/network/'.$classname.'.php')) {
    #112            include FRAMEWORK_PATH.'ext/network/'.$classname.'.php';
    #113        }else{
    #114            if(!defined('VENDOR')){
    #115                throw new Exception("类 $classname 不存在");
    #116            }
    #117        }
    #118        DEBUG && $_ENV['_include'][] = $classname.' 类';
    #119        return class_exists($classname, false);
    #120    }

基本信息

  • 模型: /www/wwwroot/www.chawaihui.com/lecms/model/
  • 视图: /www/wwwroot/www.chawaihui.com/view/default/
  • 控制器: /www/wwwroot/www.chawaihui.com/lecms/control/_control.class.php
  • 日志目录: /www/wwwroot/www.chawaihui.com/runcache/logs/

程序流程

  • #0 [internal function]: core::autoload_handler()
  • #1 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/core.class.php(240): spl_autoload_call()
  • #2 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/core.class.php(149): core::parseurl_control()
  • #3 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/core.class.php(10): core::init_get()
  • #4 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/xiunophp.php(101): core::init_start()
  • #5 /www/wwwroot/www.chawaihui.com/index.php(20): require('/www/wwwroot/ww...')
  • #6 {main}

SQL

    $_GET

    • #rewrite => ex_pic/converter/CUP-CNY/742444.jpg

    $_POST

      $_COOKIE

        包含文件

        • #0 /www/wwwroot/www.chawaihui.com/index.php
        • #1 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/xiunophp.php
        • #2 /www/wwwroot/www.chawaihui.com/lecms/config/config.inc.php
        • #3 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/base.func.php
        • #4 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/core.class.php
        • #5 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/debug.class.php
        • #6 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/log.class.php
        • #7 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/model.class.php
        • #8 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/view.class.php
        • #9 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/lib/control.class.php
        • #10 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/db/db.interface.php
        • #11 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/db/db_pdo_mysql.class.php
        • #12 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/cache/cache.interface.php
        • #13 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/cache/cache_memcache.class.php
        • #14 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/ext/network/Network__interface.php
        • #15 /www/wwwroot/www.chawaihui.com/lecms/config/plugin.inc.php
        • #16 /www/wwwroot/www.chawaihui.com/lecms/plugin/editor_um/conf.php
        • #17 /www/wwwroot/www.chawaihui.com/lecms/plugin/le_deepseek/conf.php
        • #18 /www/wwwroot/www.chawaihui.com/lecms/plugin/le_drafts/conf.php
        • #19 /www/wwwroot/www.chawaihui.com/lecms/plugin/le_exchange/conf.php
        • #20 /www/wwwroot/www.chawaihui.com/lecms/plugin/le_links/conf.php
        • #21 /www/wwwroot/www.chawaihui.com/lecms/plugin/le_sitemaps_pro_v303/conf.php
        • #22 /www/wwwroot/www.chawaihui.com/lecms/plugin/le_spider/conf.php
        • #23 /www/wwwroot/www.chawaihui.com/lecms/plugin/le_tag_links/conf.php
        • #24 /www/wwwroot/www.chawaihui.com/lecms/plugin/le_title_pic/conf.php
        • #25 /www/wwwroot/www.chawaihui.com/runcache/misc.func.php
        • #26 /www/wwwroot/www.chawaihui.com/runcache/core_lang/zh-cn.php
        • #27 /www/wwwroot/www.chawaihui.com/runcache/lang/zh-cn.php
        • #28 /www/wwwroot/www.chawaihui.com/runcache/lecms_control/parseurl_control.class.php
        • #29 /www/wwwroot/www.chawaihui.com/lecms/xiunophp/tpl/exception.php

        其他信息

        • 请求路径: /ex_pic/converter/CUP-CNY/742444.jpg
        • 当前时间: 2026-04-11 02:28:02
        • 当前网协: 216.73.216.24
        • 运行时间: 0.1240
        • 内存开销: 180.89 KB
          Lecms 3.0.3