千家信息网

构建可配置PHP应用程序的方式有哪些

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容主要讲解"构建可配置PHP应用程序的方式有哪些",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"构建可配置PHP应用程序的方式有哪些"吧!使用INI文
千家信息网最后更新 2026年11月02日构建可配置PHP应用程序的方式有哪些

本篇内容主要讲解"构建可配置PHP应用程序的方式有哪些",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"构建可配置PHP应用程序的方式有哪些"吧!

  使用INI文件进行配置

  PHP内建了对配置文件的支持。这是通过php.ini文件这样的初始化文件(INI)机制实现的,在php.ini文件中定义了数据库连接超时或会话如何存储等常量。如果愿意的话,可以在这个php.ini文件中为应用程序定制配置。为了说明,我将下列代码行添加到php.ini文件中。

  myapptempdir=foo

  然后,我编写了一个小PHP脚本来读取这个配置项,如清单1所示。

  清单1.ini1.php

  functionget_template_directory()

  {

  $v=get_cfg_var("myapptempdir");

  return($v==null)?"tempdir":$v;

  }

  echo(get_template_directory()."\n");

  ?>

  当在命令行中运行这段代码时,得到如下结果:

  %phpini1.php

  foo

  %

  太棒了。但为什么不能用标准的INI函数来获取myapptempdir配置项的值呢?我研究了一下,发现在大多数情况下,定制配置项不能使用这些方法来获取。然而,使用get_cfg_var函数却是可以访问的。

  为使这个方法更加简单,将对变量的访问封装在第二个函数中,该函数使用配置键名及一个缺省值作为参数,如下所示。

  清单2.ini2.php

  functionget_ini_value($n,$dv)

  {

  $c=get_cfg_var($n);

  return($c==null)?$dv:$c;

  }

  functionget_template_directory()

  {

  returnget_ini_value("myapptempdir","tempdir");

  }

  这是对如何访问INI文件的一个很好的概括,所以,如果要使用一个不同的机制或将这个INI文件存储到其他位置,就不需要为更改大量的函数而大费周折。

  我不推荐使用INI文件作为应用程序的配置,这有两个理由。首先,虽然这样做较容易读取INI文件,但却几乎不可能安全地写INI文件。所以这样做只适合于只读配置项。第二,php.ini文件在服务器的所有应用程序上共享,所以我认为特定于应用程序的配置项不应该写在该文件中。

  需要对INI文件了解什么呢?最重要的是如何重置include路径来添加配置项,如下所示。

  清单3.ini3.php

  echo(ini_get("include_path")."\n");

  ini_set("include_path",

  ini_get("include_path").":./mylib");

  echo(ini_get("include_path")."\n");

  ?>

  在本例中,我将我的本地mylib目录添加到了include路径中,所以能够从该目录中requirePHP文件,而不需要将该路径添加到require语句中。

  PHP中的配置

  通常对于在INI文件中存储配置条目的一个替代办法是使用一个简单的PHP脚本来保持数据。如下是一个样例。

  清单4.config.php

  #Specifythelocationofthetemporarydirectory

  #

  $TEMPLATE_DIRECTORY="tempdir";

  ?>

  使用该常量的代码如下所示。

  清单5.php.php

  require_once'config.php';

  functionget_template_directory()

  {

  global$TEMPLATE_DIRECTORY;

  return$TEMPLATE_DIRECTORY;

  }

  echo(get_template_directory()."\n");

  ?>

  该代码首先包含配置文件(config.php),接着就可以直接使用这些常量了。

  使用这项技术有很多优势。首先,如果某些人仅仅浏览config.php文件,该页面是空白的。所以可以将config.php放到相同的文件中,并作为Web应用程序的根。第二,在任何编辑器中都可编辑,并且在一些编辑器中甚至具备语法着色及语法检查功能。

  这项技术的缺点是,这是一个像INI文件一样的只读技术。将数据从此文件中提取出来是轻而易举的,但在该PHP文件中调整数据却很困难,在一些情况下甚至是不可能的。

  下面的替代方法显示了如何编写在本质上既可读又可写的配置系统。

  文本文件

  前面的两个例子对于只读配置条目都是合适的,但对于既读又写的配置参数来说又如何呢?首先,看看清单6中的文本配置文件。

  清单6.config.txt

  #Myapplication'sconfigurationfile

  Title=MyApp

  TemplateDirectory=tempdir

  这是同INI文件相同的文件格式,但我自己编写了辅助工具。为此,我创建了自己的Configuration类,如下所示。

  清单7.text1.php

  classConfiguration

  {

  private$configFile='config.txt';

  private$items=array();

  function__construct(){$this->parse();}

  function__get($id){return$this->items[$id];}

  functionparse()

  {

  $fh=fopen($this->configFile,'r');

  while($l=fgets($fh))

  {

  if(preg_match('/^#/',$l)==false)

  {

  preg_match('/^(.*?)=(.*?)$/',$l,$found);

  $this->items[$found[1]]=$found[2];

  }

  }

  fclose($fh);

  }

  }

  $c=newConfiguration();

  echo($c->TemplateDirectory."\n");

  ?>

  该代码首先创建了一个Configuration对象。该构造函数接下来读取config.txt并用解析过的文件内容来设置局部变量$items。

  该脚本随后寻找TemplateDirectory,这并没有在对象中直接定义。因此,使用设置成'TemplateDirectory'的$id来调用神奇的__get方法,__get方法针对该键返回$items数组中的值。

  这个__get方法特定于PHPV5环境,所以此脚本必须在PHPV5下运行。实际上,本文中所有的脚本都需要在PHPV5下运行。

  当在命令行运行此脚本时,能看到下列结果:

  %phptext1.php

  tempdir

  %

  一切都在预料之中,该对象读取config.txt文件,然后为TemplateDirectory配置项获得正确的值。

  但对于设置一个配置值,应该怎么做呢?在此类中建立一个新方法及一些新的测试代码,就能够得到这个功能,如下所示。

  清单8.text2.php

  classConfiguration

  {

  ...

  function__get($id){return$this->items[$id];}

  function__set($id,$v){$this->items[$id]=$v;}

  functionparse(){...}

  }

  $c=newConfiguration();

  echo($c->TemplateDirectory."\n");

  $c->TemplateDirectory='foobar';

  echo($c->TemplateDirectory."\n");

  ?>

  现在,有了一个__set函数,它是__get函数的"堂兄弟"。该函数并不为一个成员变量获取值,当要设置一个成员变量时,才调用这个函数。底部的测试代码设置值并打印出新值。

  下面是在命令行中运行此代码时出现的结果:

  %phptext2.php

  tempdir

  foobar

  %

  太好了!但如何能将它存储到文件中,从而将使这个改动固定下来呢?为此,需要写文件并读取它。用于写文件的新函数,如下所示。

  清单9.text3.php

  classConfiguration

  {

  ...

  functionsave()

  {

  $nf='';

  $fh=fopen($this->configFile,'r');

  while($l=fgets($fh))

  {

  if(preg_match('/^#/',$l)==false)

  {

  preg_match('/^(.*?)=(.*?)$/',$l,$found);

  $nf.=$found[1]."=".$this->items[$found[1]]."\n";

  }

  else

  {

  $nf.=$l;

  }

  }

  fclose($fh);

  copy($this->configFile,$this->configFile.'.bak');

  $fh=fopen($this->configFile,'w');

  fwrite($fh,$nf);

  fclose($fh);

  }

  }

  $c=newConfiguration();

  echo($c->TemplateDirectory."\n");

  $c->TemplateDirectory='foobar';

  echo($c->TemplateDirectory."\n");

  $c->save();

  ?>

  新的save函数巧妙地操作config.txt。我并没有仅用更新过的配置项重写文件(这样会移除掉注释),而是读取了这个文件并灵活地重写了$items数组中的内容。这样的话,就保留了文件中的注释。

  在命令行运行该脚本并输出文本配置文件中的内容,能够看到下列输出。

  清单10.保存函数输出

  %phptext3.php

  tempdir

  foobar

  %catconfig.txt

  #Myapplication'sconfigurationfile

  Title=MyApp

  TemplateDirectory=foobar

  %

  构建可配置PHP应用程序有哪些方式

  原始的config.txt文件现在被新值更新了。

  XML配置文件

  尽管文本文件易于阅读及编辑,但却不如XML文件流行。另外,XML有众多适用的编辑器,这些编辑器能够理解标记、特殊符号转义等等。所以配置文件的XML版本会是什么样的呢?清单11显示了XML格式的配置文件。

  清单11.config.xml

  tempdir

  清单12显示了使用XML来装载配置设置的Configuration类的更新版。

  清单12.xml1.php

  classConfiguration

  {

  private$configFile='config.xml';

  private$items=array();

  function__construct(){$this->parse();}

  function__get($id){return$this->items[$id];}

  functionparse()

  {

  $doc=newDOMDocument();

  $doc->load($this->configFile);

  $cn=$doc->getElementsByTagName("config");

  $nodes=$cn->item(0)->getElementsByTagName("*");

  foreach($nodesas$node)

  $this->items[$node->nodeName]=$node->nodeValue;

  }

  }

  $c=newConfiguration();

  echo($c->TemplateDirectory."\n");

  ?>

  看起来XML还有另一个好处:代码比文本版的代码更为简洁、容易。为保存这个XML,需要另一个版本的save函数,将结果保存为XML格式,而不是文本格式。

  清单13.xml2.php

  ...

  functionsave()

  {

  $doc=newDOMDocument();

  $doc->formatOutput=true;

  $r=$doc->createElement("config");

  $doc->appendChild($r);

  foreach($this->itemsas$k=>$v)

  {

  $kn=$doc->createElement($k);

  $kn->appendChild($doc->createTextNode($v));

  $r->appendChild($kn);

  }

  copy($this->configFile,$this->configFile.'.bak');

  $doc->save($this->configFile);

  }

  ...

  这段代码创建了一个新的XML文档对象模型(DocumentObjectModel,DOM),然后将$items数组中的所有数据都保存到这个模型中。完成这些以后,使用save方法将XML保存为一个文件。

  使用数据库

  最后的替代方式是使用一个数据库保存配置元素的值。那首先要用一个简单的模式来存储配置数据。下面是一个简单的模式。

  清单14.schema.sql

  DROPTABLEIFEXISTSsettings;

  CREATETABLEsettings(

  idMEDIUMINTNOTNULLAUTO_INCREMENT,

  nameTEXT,

  valueTEXT,

  PRIMARYKEY(id)

  );

  这要求进行一些基于应用程序需求的调整。例如,如果想让配置元素按照每个用户进行存储,就需要添加用户ID作为额外的一列。

  为了读取及写入数据,我编写了如图15所示的更新过的Configuration类。

  清单15.db1.php

  require_once('DB.php');

  $dsn='mysql://root:password@localhost/config';

  $db=&DB::Connect($dsn,array());

  if(PEAR::isError($db)){die($db->getMessage());}

  classConfiguration

  {

  private$configFile='config.xml';

  private$items=array();

  function__construct(){$this->parse();}

  function__get($id){return$this->items[$id];}

  function__set($id,$v)

  {

  global$db;

  $this->items[$id]=$v;

  $sth2=$db->prepare('DELETEFROMsettingsWHEREname=?');

  $db->execute($sth2,$id);

  if(PEAR::isError($db)){die($db->getMessage());}

  $sth3=$db->prepare('INSERTINTOsettings(id,name,value)VALUES(0,?,?)');

  $db->execute($sth3,array($id,$v));

  if(PEAR::isError($db)){die($db->getMessage());}

  }

  functionparse()

  {

  global$db;

  $doc=newDOMDocument();

  $doc->load($this->configFile);

  $cn=$doc->getElementsByTagName("config");

  $nodes=$cn->item(0)->getElementsByTagName("*");

  foreach($nodesas$node)

  $this->items[$node->nodeName]=$node->nodeValue;

  $res=$db->query('SELECTname,valueFROMsettings');

  if(PEAR::isError($db)){die($db->getMessage());}

  while($res->fetchInto($row)){

  $this->items[$row[0]]=$row[1];

  }

  }

  }

  $c=newConfiguration();

  echo($c->TemplateDirectory."\n");

  $c->TemplateDirectory='newfoo';

  echo($c->TemplateDirectory."\n");

  ?>

  这实际上是一个混合的文本/数据库解决方案。请仔细观察parse方法。该类首先读取文本文件来获取初始值,然后读取数据库,进而将键更新为最新的值。在设置一个值后,键就从数据库中移除掉,并添加一条具有更新过的值的新记录。

  观察Configuration类如何通过本文的多个版本来发挥作用是一件有趣的事,该类能从文本文件、XML及数据库中读取数据,并一直保持相同的接口。我鼓励您在开发中也使用具有相同稳定性的接口。对于对象的客户机来说,这项工作具体是如何运行的是不明确的。关键的是对象与客户机之间的契约。

到此,相信大家对"构建可配置PHP应用程序的方式有哪些"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

文件 配置 清单 函数 数据 代码 应用程序 程序 应用 方法 文本 数据库 脚本 运行 对象 存储 方式 内容 更新 相同 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 天津市摩尔互联网科技 重生之互联网科技帝国 互联网科技卖菜 互联网科技开发公司 上海互联网科技有限公司 火传媒上海互联网科技 北京大学互联网科技怎么样 厦门比较好的科技互联网公司 工业互联网等科技实现智能化赋能 卓翼科技产业互联网合作 科技赋能视角下互联网保险发展 滨湖区互联网智能科技产品有哪些 互联网科技包装股 普陀区互联网教育科技管理办法 江苏互联网智能科技产品出厂价 互联网科技手机排行榜 容联科技互联网电商 互联网科技职业技能培训学校 上海互联网科技园景观 如何强化互联网金融科技 亿人帮互联网科技有限公司 中国互联网科技工作委员会毛军 互联网 科技创新 奇酷互联网科技 顺玮阁互联网科技 大白互联网科技 互联网科技公司介绍 栖莱科技互联网股份有限公司 唯美互联网科技 互联网金融运营模式中的金融科技
0