模板户:专注于dede模板,织梦源码,织梦模板,网站模板,dedecms模板,网站源码,dedecms教程以及各类手机网站模板和企业网站模板分享.

织梦模板

VIP

CMS教程

站长学院

随机织梦教程

最新织梦教程

织梦模板随机Tags

关键词排名 原创 用户体验 玩具外贸网站源码 关键词优化 搜索引擎 汽车配件织梦模板 网站title 太阳能光伏网站源码 网站 财务会计网站源码 餐饮管理织梦模板 餐饮加盟网站源码 关键词 汽车润滑油网站源码 蜘蛛 优化 织梦伪静态 高亮 个人网站

利用 PHP 名称空间编写可读且可维护的代码

www.mobanhu.com / 2017-09-18 16:59:25

“Conan 是我榜样。” 如果我在餐桌上说这句话,我儿子会以为我说的是游戏 “野蛮人柯南”,而我妻子会以为我说的是脱口秀主持人 Conan O'Brien。这种上下文混淆在 IT 中称为名称冲突。许多语言都有防止名称冲突的战略,PHP V5.3 也是这样。PHP 使用新的名称空间特性解决名称冲突问题。当然,PHP 要解决的冲突的名称并不是人名,而是类、函数和常量的名称。

本文解释为什么应该考虑在项目中使用名称空间。本文概述名称空间的语义,介绍最佳实践,并提供一个使用名称空间的简单的 Model-View-Controller 应用程序。还讨论 Eclipse、NetBeans 和 Zend Studio 中的名称空间支持,特别是在 Eclipse 中使用名称空间的方法。

我需要名称空间吗?

PHP 语言的优点之一是简单。如果您是 PHP 新手,名称空间只是您需要了解的一个概念。但是如果出现以下任何一种情况,就应该考虑使用名称空间:

  • 您正在开发一个包含数百个 PHP 文件的大型应用程序。

  • 您的应用程序由程序员团队编写。

  • 您打算使用的框架使用 V5.3 和名称空间。

  • 您在其他语言中使用过名称空间(或包等相似的功能),比如 Java™、Ruby 或 Python 语言。

如果您独自开发一个相当小的应用程序,可能不需要名称空间。但是对于其他情况,名称空间提供了组织类结构和防止名称冲突的简便方法。这就是许多框架开发人员使用名称空间的原因。例如,强大的 PHP 框架 Zend Framework V2.0 就使用了名称空间。

概述

名称空间为名称提供上下文。清单 1 中的两个类有名称冲突。

清单 1. 在没有名称空间的情况下,同名的两个类会导致冲突
class Conan {
	var $bodyBuild = "extremely muscular";
	var $birthDate = 'before history';
	var $skill = 'fighting';
}

class Conan {
	var $bodyBuild = "very skinny";
	var $birthDate = '1963';
	var $skill = 'comedy';
}

要想指定名称空间,只需作为源代码的第一个语句添加名称空间声明。

清单 2. 两个类同名,但是名称空间解决了冲突
<?php
namespace barbarian;
class Conan {
	var $bodyBuild = "extremely muscular";
	var $birthDate = 'before history';
	var $skill = 'fighting';
}
namespace obrien;
class Conan {
	var $bodyBuild = "very skinny";
	var $birthDate = '1963';
	var $skill = 'comedy';
}
$conan = new arbarianConan();
assert('extremely muscular born: before history' == 
   "$conan->bodyBuild born: $conan->birthDate");

$conan = new obrienConan();
assert('very skinny born: 1963' == "$conan->bodyBuild born: $conan->birthDate");
?>

上面的代码可以顺利运行。在解释两个都名为 Conan 的类为什么可以同时存在之前,先要指出两点。首先,我使用断言证实代码符合预期。第二,我做了您绝对不应该做的事情:在一个源代码文件中声明多个名称空间。

名称空间为两个 Conan 类提供惟一的限定符。代码能够明确地区分要引用的是野蛮人柯南,还是脱口秀主持人。注意,实例化语法使用反斜杠 (),后面跟着名称空间名称:

$conan = new arbarianConan();

和:

$conan = new obrienConan();

这些限定符看起来像 Windows® 的目录限定符,这样看待它们是有意义的,因为名称空间支持相对和绝对引用(就像目录一样),而且最好把类文件的源代码放在与名称空间匹配的目录中。

使用名称空间

更现实的做法是把两个 Conan 类分别放在称为 barbarian 和 obrien 的目录中,然后从其他 PHP 文件引用这些类。有三种引用 PHP 名称空间的方法:

  • 在类名前面加上名称空间

  • 导入名称空间

  • 给名称空间指定别名

要想使用第一种方法,只需在类名前面加上名称空间(当然是在包含源代码文件之后):

include "barbarian/Conan.php";
$conan = new arbarianConan();

这非常简单,但是对于大型应用程序,这种方法的问题是必须反复输入名称空间。除了输入量大之外,还会不必要地弄乱代码。对于第二种方法,使用 PHP V5.3 保留字 use 导入名称空间:

include "barbarian/Conan.php";
use barbarianConan;  
$conan = new Conan();

第三种方法允许为名称空间指定别名:

include "barbarian/Conan.php";
use arbarianConan as Cimmerian;
$conan = new Cimmerian();

(顺便说一句,Cimmerian 是野蛮人柯南的绰号。)

以上三个示例都有的一个问题是要使用 include 语句。可以通过使用 __autoload 函数避免使用 include。每当引用源代码文件中还不包含的类时,调用 __autoload 函数。把清单 3 中的代码放在名为 autoload.php 的文件中。

清单 3. __autoload 函数动态地包含源代码文件
<?php
function __autoload($classname) {
  $classname = ltrim($classname, '\');
  $filename  = '';
  $namespace = '';
  if ($lastnspos = strripos($classname, '\')) {
    $namespace = substr($classname, 0, $lastnspos);
    $classname = substr($classname, $lastnspos + 1);
    $filename  = str_replace('\', '/', $namespace) . '/';
  }
  $filename .= str_replace('_', '/', $classname) . '.php';
  require $filename;
}
?>

然后把 autoload.php 导入源代码:

require_once "autoload.php"; 
use arbarianConan as Cimmerian;

自动装载器的主要好处是不必为每个类创建 include 语句。注意,尽管可以对函数、常量和类使用 PHP 名称空间,但是自动装载器技术只适用于类。自动装载器非常方便,所以可以不编写函数,而是在适当命名的实用程序类中创建方法并把常量放在不可变的类中。

通过 MVC 应用程序了解实际用法

把 O'Brien 和野蛮人柯南这个示例放在一边,我们来看一个简单的 MVC 示例应用程序。为了有效地使用名称空间,应该在编写代码之前设计自己的命名约定。常用的最佳实践是使用名称空间树。名称空间分为高层名称空间和子名称空间。如果您的公司有多个应用程序,采用公司名作为高层名称空间可能很方便。然后,使用子名称空间表示应用程序。接下来,用一个级别表示目录,进而用名称指定其中包含的 PHP 类的应用程序功能。例如,假设高层名称空间是公司名 denoncourt,第一个子级别是 retail,第二个子级别是功能名称,见清单 4。

清单 4. 名称空间的设计可以包含嵌套的子名称空间
/denoncourt
	/retail
		/common
		/controller
		/model
		/utility
		/view

controllermodel 和 view 子名称空间显然代表 MVC 架构,而 utility 和 common 子名称空间用于表示不属于其他子名称空间的一般性的类。

现在看看这个简单的 MVC 应用程序的代码。清单 5 给出 index.php 的代码,这个文件放在根文件夹中。

清单 5. MVC 应用程序的 index PHP 使用 controller 类
<?php
require "autoload.php";
use denoncourt
etailcontroller as Control;
$controller = new ControlController();
$controller->execute();
?>

注意,名称空间比较长,所以使用别名 Control。由于两个原因,我喜欢对名称空间使用别名:首先,如果以后要改变名称空间,在每个源代码文件中只有一行需要修改。第二,由于在实例化类时最好完全限定名称空间,使用 ControlController() 实际上就等于denoncourt etailcontrollerController()。注意,也可以只为高层名称空间创建别名,然后使用子名称空间的名称进行类实例化:

use denoncourt
etail as Retail;
$controller = new retailcontrollerController();

当在同一源代码文件中引用名称空间的多个级别时,这个特性很方便。我在 denoncourt/retail/controller 目录中创建了 Controller.php,见清单 6。

清单 6. MVC Controller 类根据用户输入决定操作
<?php
namespace denoncourt
etailcontroller;
use denoncourt
etail as retail;

class Controller {
  public function execute() {
    switch ($_GET['action']) {
    case 'showItem' :
      $item = new retailmodelItem();
      require "denoncourt/retail/utils/format.php";
      require "denoncourt/retail/view/item.php";
      break;
    }
  }
}
?>

我在 denoncourt/retail/model 中创建了 Item.php。清单 7 给出代码。

清单 7. MVC Item 类在 model 子名称空间中
<?php
namespace denoncourt
etailmodel;
class Item {
  public $itemNo = '123';
  public $price = 2.45;
  public $qtyOnHand = 87;
}
?>

我在 denoncourt/retail/utils 中创建了 format.php,见清单 8。

清单 8. dollar PHP 函数说明如何对函数使用名称空间
<?php
namespace denoncourt
etail;
function dollar($dollar) {
    return "$$dollar";
}
?>

注意,正如前面提到的,我喜欢把格式化函数放在实用程序类中(这样自动装载器就会处理代码的导入,我不需要为 format.php 编写 require 语句)。

最后,在 denoncourt/retail/views 中创建视图页面 item.php。清单 9 给出代码。

清单 9. item 页面显示在控制器中实例化的模型
<html>
<head>
<style>
dt {
  float:left; clear:left;
  font-weight:bold;
  margin-right:10px;
  width:15%;
  text-align: right;
}
dd { text-align:left; }
</style>
</head>
<body>
<dl>
  <dt>Item No:</dt><dd><?php echo "$item->itemNo"; ?></dd>
  <dt>Price:</dt><dd>
       <?php echo denoncourt
etaildollar($item->price); ?>
       </dd>
  <dt>Quantity On Hand:</dt><dd><?php echo "$item->qtyOnHand"; ?></dd>
</dl>
</body>
</html>

注意 item 页面如何用 denoncourt etail 名称空间限定 dollar 函数。

后退

如果源代码文件中有名称空间声明,那么对类、函数和常量的所有引用都使用名称空间语义。当 PHP 遇到未限定的类、函数或常量时,它会执行后退 (fallback)。用户类上的后退会让编译器假设使用当前的名称空间。要想引用没有名称空间的类,需要加上一个反斜杠。例如,要想引用 PHP Exception 类,应该使用 $error = new Exception();。在使用任何 Standard PHP Library 类(比如 ArrayObjectFindFile 和KeyFilter)时要记住这一点。

对于函数和常量,如果当前的名称空间不包含这个函数或常量,PHP 的后退机制会后退到标准的 PHP 函数。例如,如果您编写了自己的strlen 函数,PHP 会解析出您的函数。但是,如果也希望使用标准的 PHP strlen 函数(比如在自己的 strlen 实现内部),就需要在函数调用前面加上反斜杠,见清单 10。

清单 10. 可以用反斜杠限定 PHP 标准函数以表示全局名称空间
<?php
namespace denoncourt
etail;
function strlen($str) {
    return strlen();
}
?>

名称空间全局变量和字符串

如果您喜欢编写动态的方法,可能想把名称空间放在带双引号的字符串中:"denoncourt etailcontroller"。但是要记住,需要对反斜杠进行转义:"denoncourt\retail\controller"。一种解决方法是使用单引号:'denoncourt etailcontroller'

在进行动态编程时,要记住 PHP V5.3 有一个新的全局变量 __NAMESPACE__。可以考虑使用这个全局变量而不是输入名称空间:

$echo 'I am using this namespace:'.__NAMESPACE__;


投诉
本文由AB模板网:织梦模板整理发布, 转载请说明出处:https://www.mobanhu.com
随机站长资讯
高级精美的家私企业网站源码 家私家纺类网
农业绿色生态水果企业dede源码
驾校类企业网站源码 驾校网站模板
绿色LED灯管类织梦源码 照明企业网站模板
蓝色通用织梦博客模板 资讯文章类网站源码
红色大气装饰公司织梦源码 建筑装修装潢企
网站建设企业模板 互联网网络营销类网站源
html5响应式手机自适应网站模板(兼容手机
黑色HTML5工作室网络公司网站整站模板(适
简洁大气网站建设网络设计类企业织梦模板
html5+css3高端网站建设工作室源码 酷炫的h
红灰色大气网络工作室织梦模板
织梦dedecms幻灯片模糊解决办法
织梦dedecms巧用标签实现图片自动Alt功能,
织梦dedecms文章列表循环标签增加notypeid
织梦dedecms专题模板应用分析及使用案例
dedecms织梦让二级栏目标题去除“/”斜杠和
关于出现“对不起,您安装的不是正版应用..
Discuz(Can not write to cache files)有关
Discuz通过修改文章标题更好的实现SEO的方
DiscuzX中存在不合法的文件被上传的修复方
关于Discuz x3.1页面空白解决方法
通用营销工业机械展示型企业织梦模板 电子
简洁外贸公司电子科技产品网站源码 白色织
蓝色大气的通信类电子科技企业通用网站源码
娱乐多媒体类企业公司织梦模板 娱乐设备网
高端大气数码产品电子类企业源码模板
高级精美的家私企业网站源码 家私家纺类网
农业绿色生态水果企业dede源码
驾校类企业网站源码 驾校网站模板
绿色LED灯管类织梦源码 照明企业网站模板
蓝色通用织梦博客模板 资讯文章类网站源码
红色大气装饰公司织梦源码 建筑装修装潢企
网站建设企业模板 互联网网络营销类网站源
html5响应式手机自适应网站模板(兼容手机
黑色HTML5工作室网络公司网站整站模板(适
简洁大气网站建设网络设计类企业织梦模板
html5+css3高端网站建设工作室源码 酷炫的h
红灰色大气网络工作室织梦模板
织梦dedecms幻灯片模糊解决办法
织梦dedecms巧用标签实现图片自动Alt功能,
织梦dedecms文章列表循环标签增加notypeid
织梦dedecms专题模板应用分析及使用案例
dedecms织梦让二级栏目标题去除“/”斜杠和
最新站长资讯
高级精美的家私企业网站源码 家私家纺类网
农业绿色生态水果企业dede源码
驾校类企业网站源码 驾校网站模板
绿色LED灯管类织梦源码 照明企业网站模板
蓝色通用织梦博客模板 资讯文章类网站源码
红色大气装饰公司织梦源码 建筑装修装潢企
网站建设企业模板 互联网网络营销类网站源
html5响应式手机自适应网站模板(兼容手机
黑色HTML5工作室网络公司网站整站模板(适
简洁大气网站建设网络设计类企业织梦模板
html5+css3高端网站建设工作室源码 酷炫的h
红灰色大气网络工作室织梦模板
织梦dedecms幻灯片模糊解决办法
织梦dedecms巧用标签实现图片自动Alt功能,
织梦dedecms文章列表循环标签增加notypeid
织梦dedecms专题模板应用分析及使用案例
dedecms织梦让二级栏目标题去除“/”斜杠和
关于出现“对不起,您安装的不是正版应用..
Discuz(Can not write to cache files)有关
Discuz通过修改文章标题更好的实现SEO的方
DiscuzX中存在不合法的文件被上传的修复方
关于Discuz x3.1页面空白解决方法
通用营销工业机械展示型企业织梦模板 电子
简洁外贸公司电子科技产品网站源码 白色织
蓝色大气的通信类电子科技企业通用网站源码
娱乐多媒体类企业公司织梦模板 娱乐设备网
高端大气数码产品电子类企业源码模板
高级精美的家私企业网站源码 家私家纺类网
农业绿色生态水果企业dede源码
驾校类企业网站源码 驾校网站模板
绿色LED灯管类织梦源码 照明企业网站模板
蓝色通用织梦博客模板 资讯文章类网站源码
红色大气装饰公司织梦源码 建筑装修装潢企
网站建设企业模板 互联网网络营销类网站源
html5响应式手机自适应网站模板(兼容手机
黑色HTML5工作室网络公司网站整站模板(适
简洁大气网站建设网络设计类企业织梦模板
html5+css3高端网站建设工作室源码 酷炫的h
红灰色大气网络工作室织梦模板
织梦dedecms幻灯片模糊解决办法
织梦dedecms巧用标签实现图片自动Alt功能,
织梦dedecms文章列表循环标签增加notypeid
织梦dedecms专题模板应用分析及使用案例
dedecms织梦让二级栏目标题去除“/”斜杠和
关于出现“对不起,您安装的不是正版应用..
Discuz(Can not write to cache files)有关
Discuz通过修改文章标题更好的实现SEO的方
DiscuzX中存在不合法的文件被上传的修复方
关于Discuz x3.1页面空白解决方法
首页 免费源码 VIP专区 会员中心
收缩