【问题标题】:PHP parse YAML, store in DB for easy value modification, and return to original structure afterwardsPHP解析YAML,存入DB方便修改值,之后返回原结构
【发布时间】:2012-11-17 17:00:14
【问题描述】:

我需要能够在 MySQL 数据库中存储、修改和检索 YAML 数据内容

我的项目(和问题)目标:

  • 将 .yml 文件解析为 PHP 多维数组
  • 将这些存储到 MySQL 数据库中
  • 允许修改数据库中的单个值主要目标
  • 从数据库中检索值、解析并放回 .yml 文件中

第 1 步 - YAML 文件示例

string 'name:
  singular: null
  plural: null
fields:
  price:
    label: Preis
  company_id:
     label: null
     placeholder: null'

这里需要注意的重要一点是,嵌套键的数量可能不受限制,而且键和值可能具有相同的名称/数据。 p>

第 2 步 - 将其放入 PHP 数组中

我正在使用a library called Spyc 来解析 YAML。这很好用!它给了我以下信息:

array
  'name' => 
    array
      'singular' => null
      'plural' => null
  'fields' => 
    array
      'price' => 
        array
          'label' => string 'Preis' (length=5)
      'company_id' => 
        array
          'label' => null
          'placeholder' => null

我接下来的目标是将这些中的每一个都存储在 MySQL 数据库中。所以...

第 3 步 - CSV 文件

这里我写了自己的函数,基本上就是一长串foreach()s 把这些细节分隔成下面的数组:

array
   0 => string 'name||singular||' (length=16)
   1 => string 'name||plural||' (length=14)
   2 => string 'fields||price||label||Preis' (length=27)
   3 => string 'fields||company_id||label||' (length=27)
   4 => string 'fields||company_id||placeholder||' (length=33)

第 4 步 - MySQL 数据库

从逻辑上讲,我正在尝试将这些字符串存储在数据库中。我不确定架构。我猜值将是 value 列中的end($array[$key],而 key 列将包含数组中的其余元素。

这将有效地允许我在将它们拉出、解析并返回到 .yml 文件之前更改数据库中的值。

第 5 步 - 我迷路了!

所以我不知道现在该做什么。目前我正在尝试使用以下逻辑解析这些字符串:

  • 最后一个值end($array[$key]是值,数组中所有前面的元素都是父键
  • 一旦我的代码工作正常,将这些字符串有效地转回数组将是下一个优先事项

必须有更好的方法来做到这一点。我的主要目标是能够更新数据库中的各个值。我的主要问题是数组维度计数不是恒定的。

如何帮助我

请给我:

  • 如果有更合适的方法来实现我的项目目标(见顶部)
  • 将此数据存储在数据库中的最佳方式是允许轻松修改值(例如,您在第 1 步中看到的 nulls)
  • 从数据库返回这些数据后,一个 PHP 函数将这些键和值返回到原始数组的确切结构(第 2 步),以便我可以使用 Spyc 将其转换回YAML 并输出到 .yml 文件。

【问题讨论】:

    标签: php mysql parsing multidimensional-array yaml


    【解决方案1】:

    如果你想创建一个可以序列化为 YAML 的键值存储,你应该只创建它:

    CREATE TABLE key_values(
      id INT PRIMARY KEY AUTO_INCREMENT,
      parent_id INT,
      type VARCHAR(255),
      key VARCHAR(255),
      value VARCHAR(255)
    )
    

    在这种情况下,id 是指根记录的方式,parent_id 是用于链接子记录的机制,type 用于区分数组映射和索引数组。 keyvalue 用于存储各自的值。

    有了这个,您应该能够创建适当的记录。

    您的数据中的一个示例可能是创建根节点:

    INSERT INTO key_values VALUES (parent_id, type, key, value)
      VALUES (NULL, 'map', NULL NULL)
    

    然后添加 name 键的值,假设 id 之前的 INSERT 为 1:

    INSERT INTO key_values VALUES (parent_id, type, key, value)
      VALUES (1, 'map', 'name' NULL)
    

    该过程对每个值递归地重复:

    INSERT INTO key_values VALUES (parent_id, type, key, value)
      VALUES (2, 'string', 'singular' NULL),
             (2, 'string', 'plural' NULL)
    

    无论如何,您都需要为所有这些编写一个包装类,否则使用起来会太复杂。

    在实践中,我不确定解决所有这些麻烦是否会比简单地将 YAML 按原样存储在 LONGTEXT 字段中并称其为一天要容易得多。操纵和重新储蓄通常不会那么昂贵。迭代多层树结构是。

    不过,对于纯 YAML 方法,您必须小心避免在竞争条件下踩踏写入,但这不是使用跟踪您保存的版本的 revision 列无法解决的问题。构造您的 UPDATE 使其不匹配:

    UPDATE yamls SET value='...', revision=93 WHERE id=20 AND revision=92
    

    如果其他进程已经对其进行了更新,您会看到查询无法运行并可以相应地进行处理。

    【讨论】:

    • 这很有趣!我稍后会尝试你的代码。我最初正在查看修改的预购树遍历:stackoverflow.com/questions/192220/…,但这似乎是一个不错的(而且更容易、更有效)的方法。
    • 使用您答案中的代码,我应该能够更新子元素并为其提供所有父键。那么这是访问该值的正确方法吗? sqlfiddle.com/#!2/83c3c/5 我可以编写一个 PHP 函数来创建这个字符串,具体取决于所寻求的值和传入的键。func($value,array($key1,$key2)); 例如...
    • 这真的取决于你是想访问一个键还是多个键。在您的 WHERE 子句中指定 type 不是必需的,因为它仅用于提供信息。
    • 你说得对,我为此得到的包装器非常棒,但这正是我所需要的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 2019-01-17
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 2021-06-06
    • 2023-03-11
    相关资源
    最近更新 更多