【问题标题】:PHP Moving config mapping file to XML but how to I create a dynamic XPATHPHP 将配置映射文件移动到 XML 但如何创建动态 XPATH
【发布时间】:2010-06-21 17:40:53
【问题描述】:

所以我有一个 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 配置文件中添加/更改或删除元素/属性会更容易且编码更少。

感谢您提供任何提示/示例/代码/想法, -菲尔

【问题讨论】:

    标签: php xml configuration dynamic


    【解决方案1】:

    我很好奇 - 您认为您从中获得了什么样的灵活性?您需要做大量工作才能将内容放入 XML 中,只是为了将其转换为 PHP 数据。

    如果您可以放弃 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' );
    

    【讨论】:

    • 我希望在我的组织(我工作的地方)中,除了 XML 更改之外的任何内容都需要通过发布,这意味着停机和维护窗口以及所有这些爵士乐。但是,如果使用 XML,我可以配置所有我想要的东西,而不会让人头疼,所以我不介意做一些工作来得到我想要的东西 :)
    • 另外,在您的示例中,您仍在专门为 URL 编码,我想让这个通用。所以我可以传递任何 XML 结构,能够随意搜索和提取具有属性的元素
    • 这确实更有意义:class XmlConfigParser {} 谢谢
    • 添加内容以响应您的 cmets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 2021-09-05
    • 2012-12-29
    • 1970-01-01
    相关资源
    最近更新 更多