关于URL路由的一些事儿

虽然有人抱怨使用Apache的mod_rewrite在访问量大的时候经常会出现CPU的占用率为 100%的情况,但是对于一些中小型网站来说,这样做毕竟会美化URL,有益于搜索引擎的收录。

因此CMSPAD 1.1的最后一个特性就是支持URL路由(或URL Rewrite?),以下称URLR。那么,CMSPAD是如何支持URLR的呢?下面我们来分析一下URL路径的一些特性。

一个URL由协议、主机、端口、访问路径组成,前三者忽略,说说访问路径吧,它是一个由“/”分隔的一个字符串,用来定位文件位置。正常的一个网站的URL模式为:
[code]http://www.yourcompany.com/index.php[/code]
其中“/index.php”就是其访问路径(或叫URI?不知道,自己查查吧)。而好多网站为了隐藏整站程序的实现技术,一般都隐藏了文件后缀,例如:
[code]http://www.yourcompany.com/hello/world/2007/12/20[/code]
通过某些URLR技术来进行路径重写到指定脚本文件中。Servlet路径模式匹配和RoR都是这样干的。

因此,如何使用CMSPAD把路径给优化成很不错的感觉呢?其实很简单。

1. 建立一个Dispatcher文件,是PHP的。
[code]<?php
require_once('kernel/global.php'); //包含CMSPAD核心文件
import('Dispatcher'); //导入Dispatcher包
$dispatcher = new Dispatcher('default'); //创建Dispatcher实例,这里使用默认的URLR解析器
$dispatcher->dispatch(isset($_SERVER['PATH_INFO'])?$_SERVER['PATH_INFO']:''); //使用PATH_INFO作为参数进行URLR转换。
?>[/code]当然,如果你不想使用PATH_INFO作为路径转换,可以使用其他的数据,例如GET参数。将文件保存在网站目录下,例如 /index.php。

2. 增加 .htaccess 文件:就是写Apache的URL Rewrite规则,这里就不提了。

3. 新建一个Portlet,如果不知道什么叫Portlet,那就看看偶本博客中以前的文章。
[code]class DefaultPortal extends Portlet{
public function pageDefaultPortal($params){
return 'This is home page: '.$params[0];
}
public function pageHelloWorld($params){
return 'This is hello world page: '.print_r($params);
}
}[/code][b]看到了没有,所有的URLR方法都是以“page”开头的,并且有个类型为单项数组的参数($params),并返回输出的内容[/b],将代码保存到Portlet主目录下的DefaultPortal.php文件中。

4. 本节就三个字:搞定鸟。

在测试之前,大家需要了解一下CMSPAD URLR的一些路径处理规则:

1. default: 默认的路径处理方法,格式为 /[PortletName]/[PageName]/[Param1[/Param2[...]]]

2. statics: 伪静态页的路径处理方法,格式为:/[PortletName]/[PageName]/[Param1[,Param2[...]]].html

在这里如果没有PageName,那么CMSPAD将自动匹配到与PortletName同名的方法,例如使用默认模式的路径 /SimplePortlet/100/200/300 将被转换为 /SimplePortlet/SimplePortlet/100/200/300。

如果连PortletName也没有,没事儿,CMSPAD可以通过配置信息变量 $_CONFIG['DISPATCH']['PORTAL'] 来作为默认的Portlet使用;如果连 $_CONFIG['DISPATCH']['PORTAL'] 变量都没有定义,也没事儿,系统会自动使用 DefaultPortal 作为Portlet名字来使用;如果连 DefaultPortal 也没定义,那没办法了,系统会返回404错误。

下面就开始测试了:

把Apache服务器打开,假设以上程序在web根目录下,在浏览器中敲入下列地址 http://localhost/index.php/DefaultPortal/100000,你将会看到以下内容:[code]This is home page: 100000[/code],而敲入 http://localhost/index.php/DefaultPortal/helloWorld/100/200,则会看到:[code]This is hello world page: Array([0] => 100, [1] => 200)[/code]

而如果使用statics模式,则路径分别为:http://localhost/index.php/DefaultPortal/100000.html 和 http://localhost/index.php/DefaultPortal/helloWorld/100,200.html

这就有个问题了,如果可以任意转换URLR处理器,那么在模板中使用路径时怎么样动态转换路径呢?答案当然是有的啦,哈哈

在模板中,使用hyperlink函数即可实现,例如:[code]<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>URL Router Portal Test</title>
</head>
<body>
<!-- 完整的使用方法 1-->
<a href="<{hyperlink portlet="DefaultPortal" page="DefaultPortal" arg1="100" arg2="200"}>">Portal Link 1</a><br/>
<!-- 完整的使用方法 2-->
<a href="<{hyperlink portlet="DefaultPortal" page="helloworld" arg1="100" arg2="200"}>">Portal Link 2</a><br/>
<!-- 最简使用方法,使用当前Portlet的名字,如果没有在Portlet中使用则使用默认的DefaultPortal,方法名与Portlet名字相同 -->
<a href="<{hyperlink arg1="100" arg2="200"}>">Portal Link 3</a><br/>
<!-- 简便使用方法 1,方法名与Portlet名相同 -->
<a href="<{hyperlink portlet="DefaultPortal" arg1="100" arg2="200"}>">Portal Link 4</a><br/>
<!-- 简便使用方法 2,使用当前Portlet的名字,如果没有在Portlet中使用则使用默认的DefaultPortal-->
<a href="<{hyperlink page="helloworld" arg1="100" arg2="200"}>">Portal Link 5</a><br/>
</body>
</html>[/code]这样,当在后台转换URLR路径处理了方法时,则模板中自动应用了新的路径。

使用默认URLR处理器时输出为:[code]<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>URL Router Portal Test</title>
</head>
<body>
<a href="/index.php/DefaultPortal/100/200">Portal Link 1</a><br/>
<a href="/index.php/DefaultPortal/helloworld/100/200">Portal Link 2</a><br/>
<a href="/index.php/DefaultPortal/100/200">Portal Link 3</a><br/>
<a href="/index.php/DefaultPortal/100/200">Portal Link 4</a><br/>
<a href="/index.php/DefaultPortal/helloworld/100/200">Portal Link 5</a><br/>
</body>
</html>[/code]而使用statics处理器时输出为:[code]<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>URL Router Portal Test</title>
</head>
<body>
<a href="/index.php/DefaultPortal/100,200.html">Portal Link 1</a><br/>
<a href="/index.php/DefaultPortal/helloworld/100,200.html">Portal Link 2</a><br/>
<a href="/index.php/DefaultPortal/100,200.html">Portal Link 3</a><br/>
<a href="/index.php/DefaultPortal/100,200.html">Portal Link 4</a><br/>
<a href="/index.php/DefaultPortal/helloworld/100,200.html">Portal Link 5</a><br/>
</body>
</html>[/code]

下面来看看如何开发URLR路径处理器吧:

创建一个名字为 cmspad_router_<文件名字>的类,实现 URLRouter接口,并实现接口里的两个函数:
[code]class cmspad_router_myrule implements URLRouter{
public function route($pathinfo){
// 处理并输出路径所对应的内容。
}

public function hyperlink($portlet = null, $method = null, $parameters = array()){
// 生成并返回该规则的URL路径。
}
}[/code]将以上代码保存到 inc/urlrouters/myrule.php 文件中。然后在创建Dispatcher文件的代码中将[code]$dispatcher = new Dispatcher('default'); [/code]改成[code]$dispatcher = new Dispatcher('myrule'); [/code]这样,你写的规则就应用上去了。

下面给出当前默认实现(default)的源代码:[code]<?php
cmspad_import('util.PortletUtil');
class cmspad_router_default implements URLRouter{

private $portal;

public function __construct($portal = 'DefaultPortal'){
$this->portal = $portal;
}

public function route($pathinfo){
while(strpos($pathinfo,'//') !== false){
$pathinfo = str_replace('//','/',$pathinfo);
}
$pathinfo = trim($pathinfo,' /');
if(empty($pathinfo)){
$pathinfo = $this->portal . '/' . $this->portal;
}
$arr = explode('/',$pathinfo);
if(count($arr) > 0){
$portlet = $arr[0];
$portletObj = PortletUtil::newObject($portlet);
if($portletObj === null || $portletObj === false){
$portletObj = PortletUtil::newObject($portlet = $this->portal);
}else{
array_shift($arr);
}
}
if($portletObj === null || $portletObj === false){
return false;
}
if(count($arr) > 0){
$portletArr = PortletUtil::newMethod($portletObj,'page' . ucfirst($arr[0]));
if($portletArr === null || $portletArr === false){
$portletArr = PortletUtil::newMethod($portletObj,'page' . ucfirst($portlet));
}else{
array_shift($arr);
}
$portletArg = $arr;
}else{
$portletArr = PortletUtil::newMethod($portletObj,'page' . ucfirst($portlet));
$portletArg = array();
}
if($portletArr === null || $portletArr === false){
return false;
}

$contents = call_user_func($portletArr,$portletArg);
if($contents){
echo $contents;
}
return true;
}

public function hyperlink($portlet = null,$method = null,$params = null){
global $_CONFIG;
if(isset($_CONFIG['DISPATCH']['SCRIPT'])){
$url = $_CONFIG['DISPATCH']['SCRIPT'];
}else{
$url = $_SERVER['SCRIPT_NAME'];
}
if(!$portlet){
$portlet = $this->portal;
}
if($portlet){
$url .= ($portlet == $this->portal?'':'/' . $portlet);
if($method){
$url .= ($method == $portlet?'':'/' . $method);
}
if($params){
$url .= '/' . implode('/',$params);
}
}
return $url;
}
}
?>[/code]此代码保存在 inc/urlrouters/default.php 中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值