PHP将配置映射文件移动到XML但是如何创建动态XPATH

时间:2010-06-21 17:40:54

标签: php xml configuration dynamic

所以我有一个PHP文件,用于定义我的所有常量,但现在想要使用XML的灵活性。

示例PHP配置文件

define("LOGIN_URL", "secure_login.php");
define("REDIRECT", "redirect.php");

define("MAPPED_VALUE_GREEN", "object_green");
define("MAPPED_VALUE_KEY", "object_key_12345");

我要做的是:

<scriptNameConfig>
  <urls>
     <url alias="LOGIN_URL" scriptname="secure_login.php" location="optional/path/to/file"/>
     <url alias="REDIRECTL" scriptname="redirect.php" location="optional/path/to/file"/>
  </urls>
  <mapping>
     <mapped name="MAPPED_VALUE_GREEN" data="object_green"/>
     <mapped name="MAPPED_VALUE_KEY" data="object_key_12345"/>
  </mapping>
</scriptNameConfig>

现在这没关系,但我想使用XPATH从这种类型的配置文件中提取值,但希望它足够动态,所以我不需要对代码进行硬编码

这是我的基类

class ParseXMLConfig {
    protected $xml;

    public function __construct($xml) {
        if(is_file($xml)) {
            $this->xml = simplexml_load_file($xml);
        } else {
            $this->xml = simplexml_load_string($xml);
        }
    }
}

我像这样扩展它

class ParseURLS extends ParseXMLConfig {

public function getUrlArr($url_alias) {
        $attr = false;
        $el = $this->xml->xpath("//url[@alias='$url_alias']");
        if($el && count($el) === 1) {
            $attr = (array) $el[0]->attributes();
            $attr = $attr['@attributes'];
        } 
        return $attr; // this will return the element array with all attributes
    }
}

但问题是如果我想在confie文件中引入一个新值,我必须为XPATH添加某种函数来解析它。我想知道是否有人知道如何进行这种通用/动态操作,因此在XML配置文件中添加/更改或删除元素/属性会更容易,编码也更少。

感谢您提供任何提示/示例/代码/提示, -Phill

1 个答案:

答案 0 :(得分:1)

我很好奇 - 你认为你从中得到了什么灵活性?您正在经历大量的工作,只需将XML转换为PHP数据即可将其放入XML中。

如果你对弃用XML没问题(也就是说没有其他人使用这种配置),为什么不这样呢?

class Config
{
  private static $urls = array(
      'LOGIN_URL' => array(
          'scriptname' => 'secure_login.php'
        , 'location'   => 'optional/path/to/file'
      )
    , 'REDIRECTL' => array(
          'scriptname' => 'redirect.php'
        , 'location'   => 'optional/path/to/file'
      )
  );

  public static function getUrlArr( $alias )
  {
    if ( isset( self::$urls[$alias] ) )
    {
      return self::$urls[$alias];
    }
    throw new Exception( "URL alias '$alias' not defined" );
  }
}

另外,作为旁注,我对你选择将动词(解析)放在类名中有所保留。如果你要去那条路线,请尝试使用该动词的名词表示。

class XmlConfigParser {}

修改

在这种情况下,你就不能有任何引用XML节点结构的方法名称(除非你想进入元编程的世界)

真的不管你做什么,你只是要在XPath表达式上创建语法糖

以下是您可能制作的方法示例

// Use XPath from the client
$config->fetchAttributesByXpath( "/urls/url[@alias='LOGIN_URL']" );

// Abstract away the XPah
$config->fetchAttributes( 'urls.url', 'alias', 'LOGIN_URL' );

例如,symfony使用其配置文件执行类似的操作,这些文件是YAML。在像这样的配置文件中

// app.yml
urls:
  LOGIN_URL: {scriptname: 'secure_login.php', location='optional/path/to/file'}

你会像这样检索值

$values = sfConfig::get( 'app_urls_LOGIN_URL' );