php中常用的全局变量有,在PHP中如何使用全局变量的方法详解

但是你可以使用你自己的全局变量。使用关键字“global”你就可以把全局数据导入到一个函数的局部范围内。如果你不明白“变量使用范围”,请你自己参考PHP手册上的相关说明。

下面是一个使用“global”关键字的演示例子:

代码如下:

正如你在上面的例子中看到的一样,“global”关键字是用来导入全局变量的。看起来它工作的很好,而且很简单,那么为什么我们还要担心使用“global”关键字来定义全局数据呢?

下面是三个很好的理由:

1、代码重用几乎是不可能的。

如果一个函数依赖于全局变量,那么想在不同的环境中使用这个函数几乎是不可能的。另外一个问题就是你不能提取出这个函数,然后在其他的代码中使用。

2、调试并解决问题是非常困难的。

跟踪一个全局变量比跟踪一个非全局变量困难的多。一个全局变量可能会在一些不明显的包含文件中被重新定义,即使你有一个非常好的程序编辑器(或者IDE)来帮助你,你也得花了几个小时才能发现这个问题所在。

3、理解这些代码将是非常难的事情。

你很难弄清楚一个全局变量是从哪里来得,它是用来做什么的。在开发的过程中,你可能会知道知道每一个全局变量,但大概一年之后,你可能会忘记其中至少一般的全局变量,这个时候你会为自己使用那么多全局变量而懊悔不已。

那么如果我们不使用全局变量,我们该使用什么呢?下面让我们看看一些解决方案。

使用函数参数

停止使用全局变量的一种方法就是简单的把变量作为函数的参数传递过去,如同下面所示:

代码如下:

如果你仅仅只需要传递一个全局变量,那么这是一种非常优秀甚至可以说是杰出的解决方案,但是如果你要传递很多个值,那该怎么办呢?

比如说,假如我们要使用一个数据库类,一个程序设置类和一个用户类。在我们代码中,这三个类在所有组件中都要用到,所以必须传递给每一个组件。如果我们使用函数参数的方法,我们不得不这样:

代码如下:

显然,这是不值得的,而且一旦我们有新的对象需要加入,我们不得不为每一个函数增加多一个函数参数。因此我们需要用采用另外一种方式来解决。

使用单件(Singletons)解决函数参数问题的一种方法就是采用单件(Singletons)来代替函数参数。单件是一类特殊的对象,它们只能实例化一次,而且含有一个静态方法来返回对象的接口。下面的例子演示了如何构建一个简单的单件:

代码如下:

user = 'sa';// Set second variable (which points to the same instance)$second =& DBConnection::getInstance();// Should print 'sa'echo $second>user;Class DBConnection { var $user; function &getInstance() { static $me; if (is_object($me) == true) { return $me; } $me = new DBConnection; return $me; } function connect() { // TODO } function query() { // TODO }}?>

上面例子中最重要的部分是函数getInstance()。这个函数通过使用一个静态变量$me来返回这个类的实例,从而确保了只有一个DBConnection类的实例。

使用单件的好处就是我们不需要明确的传递一个对象,而是简单的使用getInstance()方法来获取到这个对象,就好像下面这样:

代码如下:

然而使用单件也存在一系列的不足。首先,如果我们如何在一个类需要全局化多个对象呢?因为我们使用单件,所以这个不可能的(正如它的名字是单件一样)。另外一个问题,单件不能使用个体测试来测试的,而且这也是完全不可能的,除非你引入所有的堆栈,而这显然是你不想看到的。这也是为什么单件不是我们理想中的解决方法的主要原因。

注册模式

让一些对象能够被我们代码中所有的组件使用到(译者注:全局化对象或者数据)的最好的方法就是使用一个中央容器对象,用它来包含我们所有的对象。通常这种容器对象被人们称为一个注册器。它非常的灵活而且也非常的简单。一个简单的注册器对象就如下所示:

代码如下:

_objects[$name] =& $object; } function &get($name) { return $this>_objects[$name]; }}?>

使用注册器对象的第一步就是使用方法set()来注册一个对象:

代码如下:

set ('db', $db);$registry>set ('settings', $settings);$registry>set ('user', $user);?>

现在我们的寄存器对象容纳了我们所有的对象,我们指需要把这个注册器对象传递给一个函数(而不是分别传递三个对象)。看下面的例子:

代码如下:

get('db'); $settings =& $registry>get('settings'); $user =& $registry>get('user'); // Do something with the objects}?>

注册器相比其他的方法来说,它的一个很大的改进就是当我们需要在我们的代码中新增加一个对象的时候,我们不再需要改变所有的东西(译者注:指程序中所有用到全局对象的代码),我们只需要在注册器里面新注册一个对象,然后它(译者注:新注册的对象)就立即可以在所有的组件中调用。

为了更加容易的使用注册器,我们把它的调用改成单件模式(译者注:不使用前面提到的函数传递)。因为在我们的程序中只需要使用一个注册器,所以单件模式使非常适合这种任务的。在注册器类里面增加一个新的方法,如下所示:

代码如下:

这样它就可以作为一个单件来使用,比如:

代码如下:

set ('db', $db);$registry>set ('settings', $settings);$registry>set ('user', $user);function test() { $registry =& Registry::getInstance(); $db =& $registry>get('db'); $settings =& $registry>get('settings'); $user =& $registry>get('user'); // Do something with the objects}?>

正如你看到的,我们不需要把私有的东西都传递到一个函数,也不需要使用“global”关键字。所以注册器模式是这个问题的理想解决方案,而且它非常的灵活。

请求封装器

虽然我们的注册器已经使“global”关键字完全多余了,在我们的代码中还是存在一种类型的全局变量:超级全局变量,比如变量$_POST,$_GET。虽然这些变量都非常标准,而且在你使用中也不会出什么问题,但是在某些情况下,你可能同样需要使用注册器来封装它们。

一个简单的解决方法就是写一个类来提供获取这些变量的接口。这通常被称为“请求封装器”,下面是一个简单的例子:

代码如下:

_request = $_REQUEST; } function get($name) { return $this>_request[$name]; }}?>

上面的例子是一个简单的演示,当然在请求封装器(request wrapper)里面你还可以做很多其他的事情(比如:自动过滤数据,提供默认值等等)。

下面的代码演示了如何调用一个请求封装器:

代码如下:

set ('request', &$request);test();function test() { $registry =& Registry::getInstance(); $request =& $registry>get ('request'); // Print the 'name' querystring, normally it'd be $_GET['name'] echo htmlentities($request>get('name'));}?>

正如你看到的,现在我们不再依靠任何全局变量了,而且我们完全让这些函数远离了全局变量。

结论

在本文中,我们演示了如何从根本上移除代码中的全局变量,而相应的用合适的函数和变量来替代。注册模式是我最喜欢的设计模式之一,因为它是非常的灵活,而且它能够防止你的代码变得一塌糊涂。

另外,我推荐使用函数参数而不是单件模式来传递注册器对象。虽然使用单件更加轻松,但是它可能会在以后出现一些问题,而且使用函数参数来传递也更加容易被人理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java实现图像处理高通滤波,图像处理入门——滤波 - leo_de_macondo的个人页面 - OSCHINA - 中文开源技术交流社区...

模糊图像模糊的方法可以将每个像素的rgb值用周围像素的加权平均值来代替。比如用周围的9个像素来计算加权平均值,权值可以用一个3x3的矩阵来表示:| 1 2 1 || 2 4 2 | * (1/16)| 1 2 1 |中间的像素是要处理的像素,越靠近中间权…

java激光图,java-OpenCV Android跟踪激光点

我正在尝试在Android设备上使用OpenCV跟踪激光点.我想使用此激光点在我的cameraview上的画布上绘制.我已经将我的camerapreview转换为HSV色彩空间,并使用阈值过滤(仅在H和V通道上)来分离我的Laserdot.这相当健壮.public Mat onCameraFrame(CvCameraViewFrame cvf) {// Grab the…

matlab数据接口技术,matlab接口技术与应用

matlab接口技术与应用来源:mamingkeda作者:华仔浏览:1070时间:2016-08-10 14:18标签:摘要:matlab接口技术与应用应用程序接口的使用方法。全书分为10章,第1章是matlab环境和编程语言的概述&…

php iframe 上传文件,php+iframe 实现上传文件功能示例

本文实例讲述了phpiframe 实现上传文件功能。分享给大家供大家参考,具体如下:我们通过动态的创建iframe,修改form的target,来实现无跳转的文件上传。具体的实现步骤1.捕捉表单提交事件2.创建一个iframe3.修改表单的target,指向ifr…

break是python合法标识符,Python笔记——break的注意事项

ajax状态ajax的几个状态 Uninitialized 初始化状态.XMLHttpRequest 对象已创建或已被 abort() 方法重置. Open open() 方法已调用,但是 send() 方法未调 ...使用Npoi向Excel中插入图片先把数据库中的数据都导入到Excel表格中,把图片地址的路径全部转成绝对路径. 使用Npoi读取刚…

bulk Java提交数据,性能优化 – bulk提交 - ELK Stack 中文指南

在 CRUD 章节,我们已经知道 ES 的数据写入是如何操作的了。喜欢自己动手的读者可能已经迫不及待的自己写了程序开始往 ES 里写数据做测试。这时候大家会发现:程序的运行速度非常一般,即使 ES 服务运行在本机,一秒钟大概也就能写入…

catalog java,Java Connection getCatalog()方法与示例

通常,目录是一个目录,其中包含有关数据集,文件或数据库的信息。而数据库目录中包含所有数据库,基本表,视图(虚拟表),同义词,值范围,索引,用户和用户组的列表。Connection…

matlab 函数 命名参数,如何处理MATLAB中的函数参数的名称/值对

我喜欢使用结构为我的选择。这给你一个简单的方法来存储选项和一个简单的方法来定义它们。此外,整个事情变得相当紧凑。function example(varargin)%# define defaults at the beginning of the code so that you do not need to%# scroll way down in case you wan…

ssrf 过滤.php,SSRF技巧之如何绕过filter_var( )

0x00 前言前几天我读了两篇非常棒的论文:第一篇是发表在blackhat.com上的“A New Era of SSRF ”,讲述的是不同编程语言的SSRF问题;第二篇是由Positive Technology发表的一篇名为“PHP Wrapper” 的论文,它主要讲述的是如何以多种…

matlab 爬虫 例子,认识爬虫(示例代码)

爬虫分为两种:1.通用爬虫。2.聚焦爬虫。通用爬虫:搜索引擎用的爬虫系统。一.目标:爬取所有网站的网页下载下来,存放到本地服务器里形成备份。二.抓取流程:a.首选选取一部分已有的url,把这些url放到待爬取队列。b.从队列…

如何用notepad写php,notepad新手怎么使用

新手使用notepad的几个小技巧:一、软件始终置于屏幕最前方有时候我们在运行程序时,需要将notepad放置到屏幕最前方,此时只需要在工具栏中点击:view——always on tops;此时notepad就会一直处于屏幕最前方。注&#xff…

rman打开oracle归档日志,Oracle RAC中使用RMAN管理归档日志

RMAN归档配置的两种方案1.在Oracle asm和集群文件系统时的归档方案对于Oracle RAC来说首选是使用Oracle asm作为reocvery区域。可选择的你也可以使用集群文件系统的归档方案。如果你使用了一种集群文件系统,那么当进行日志归档时每个节点会将归档日志写到集群文件系…

oracle10g数据库复制,oracle -10g 中Duplicate 复制数据库

oracle --10g 中Duplicate 复制数据库本次实验通过duplicate命令,在本机环境中创建一个复制数据库。目标数据库为hongye、复制数据库为catdb。环境别名设置:alias sqlrlwrap sqlplus /nologalias rmanrlwrap rmanalias dbscd $ORACLE_HOME/dbsalias rdbc…

oracle resize什么意思,Oracle调整表空间大小resize

SQL> ALTER DATABASE DATAFILE D:\ORACLE\ORADATA\ICAPP\IC_DATA6.ORA RESIZE 300m;ALTER DATABASE DATAFILE D:\ORACLE\ORADATA\ICAPP\IC_DATA6.ORA RESIZE 300m*ERROR 位于第 1 行:ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据但是SQL>select d.filename,d.fi…

双网卡主机配置oracle监听,VirtualBox设置双网卡实现虚机上网及主宿机互访

VirtualBox 虚拟机之间互连、主宿机互连、以及主宿机连接互联网的功能非常实用。下面介绍实现主宿机通过虚拟网卡互连方式。1 全局配置VirtualBox安装完成后,会在系统中装一块虚拟网卡,我们在 管理> 全局设定中可以看到。这块网卡是在 Host-Only 连接…

oracle英文日期转换为中文,excel中文日期与英文日期如何转换

一、一般的转换方法假如A列为英文日期格式,譬如是:A1 19-Jul-12A2 20-Jul-12A3 21-Jul-12A4 22-Jul-12那么,如果你想将其转换为中文的日期,假如放在B列,首先你得将B列设置为中文的日期格式,方法是&…

oracle笔试题目及答案,Oracle 笔试题目带答案.doc

( )程序包用于读写操作系统文本文件。(选一项)A、Dbms_outputB、Dbms_lobC、Dbms_randomD、Utl_file( )触发器允许触发操作的语句访问行的列值。(选一项)A、行级B、语句级C、模式D、数据库级( )是oracle在启动期间用来标识物理文件和数据文件的二进制文件。(选一项)A、控制文件…

php sphinx api调用,php调用Sphinx

1.将文件 coreseek-3.2.14/testpack/api/sphinxapi.php 拷贝到任意可被php程序包含出。2.在要调用的脚本中包含文件 sphinxapi.php 如下示例namespace Admin\Controller;use Admin\Common\Controller\CommonController;require(./Public/api/sphinxapi.php); //包含sphinxclass…

oracle关于时区,关于oracle时区

关于oracle时区[more]商业和数据库很多时候必须跨时区工作,从9i开始,oracle环境开始有了时区意识,通过指定数据库的时区和使用TIMESTAMP WITH TIME ZONE和TIMESTAMP WITH LOCAL TIME ZONE数据类型来实现该功能。TIMESTAMP WITH TIME ZONE不会…

苹果双系统运行oracle失败,oracle 11gR2 RAC for linux x86_64 grid运行root.sh 失败问题处理...

昨天一个朋友问到我,在oracle 11gR2 RAC for linux x86_64安装过程中,grid用户运行root.sh在第一节点可以成功,但在第二节点不成功,报错如下:CRS-2674: Start of ora.cssd on racnode2 failedCRS-2679: Attempting to clean ora.c…