【问题标题】:Merging multiple CSS files into one in PHP在 PHP 中将多个 CSS 文件合并为一个
【发布时间】:2013-02-28 06:02:51
【问题描述】:

我正在编写一个将多个 CSS 合二为一的脚本。这是脚本。

    $full_string = "";

    foreach($allfiles as $curfile => $file) {           
        $file = $PATH[$curfile] . $file;
        $file_open = fopen($file , 'r');
        $concat = "\n" . fread($file_open , filesize($file)) . "\n";
        $full_string .= $concat;
        fclose($file_open);
    }

    return $full_string;

在这里,我将所有 CSS 文件合并为一个。但现在的问题是我必须将当前的 CSS($file) 与另一个 css 进行比较(让我们将其视为overrider.css)。如果 $file 具有类似的样式,

h1 {
    color: white; 
    background: teal; 
    FONT-FAMILY: arial, helvetica, lucida-sans, sans-serif; 
    FONT-SIZE: 18pt; 
    FONT-STYLE: normal; 
    FONT-VARIANT: normal;
}

body 
{
    font-family: arial;
    FONT-SIZE: 14px; 
}

如果 overrider.css 具有类似的样式,

body 
{
    font-family: Calibri;
    color: #3E83F1; 
}

那么最终生成的 CSS(output.css) 应该是,

h1 {
    color: white; 
    background: teal; 
    FONT-FAMILY: arial, helvetica, lucida-sans, sans-serif; 
    FONT-SIZE: 18pt; 
    FONT-STYLE: normal; 
    FONT-VARIANT: normal;
}

body 
{
    font-family: Calibri;
    FONT-SIZE: 14px;
    color: #3E83F1;
}

这里,由于 override.css 中的 body 样式具有 font-family,它替换了原始 CSS 中的 font-family 属性,并且由于颜色是一个新属性,它不存在于原始 CSS 文件 ($file) 中,所以它应该将属性添加到原始 CSS 文件中。那么如何在 PHP 中实现这一点,因为我对解析 CSS 没有任何想法。对此的任何想法将不胜感激。

请注意,我需要通过将输入作为 file1($file) 和 file2(override.css) 来生成一个新的 CSS 文件,并且我们需要生成 output.css 并覆盖样式。

提前致谢。

【问题讨论】:

    标签: php css-parsing


    【解决方案1】:

    有一些可用的 CSS 解析器(google "php css parser"),例如 this one,我没有尝试过,但看起来很有趣。但就我个人而言,我会自己进行解析——遵循那种伪 PHP 算法

    • 将所有文件读入一个字符串Str,将所有“\n”、“\r”和“\t”替换为空格(以使解析(稍微)更容易)

    然后,要处理的函数(选择器 => 规则)

    func deal with selectors and rules:
    
    rules = array()
    do {
      S = string from current pos to next `{` excluded (selectors)
      R = string from '{' to next '}' (rules)
      r = explode(';', R) 
      lr = make array of rules from r trimmed elements
      s = explode (',', S)
      ls = make array of [selector => lr]
    
      // same sel: latest rule overwrite existing, added if not exist
      merge ls into rules 
    } while (not '}' and not '@' and not EOF); // the '}' would be the closing media
    
    return rules
    

    处理媒体的main函数,然后调用上面的函数

    medias = array();
    
    func deal with Str
    do {
      if (first non blank char is @) {
         media = array of listed medias
         eat fist '{'
      }
      else {
         media = array ('GLOBAL')
      }
      selectorsrules = deal with selectors and rules(rest of Str)
    
      foreach (media as m) {
        merge in medias(m) selectorsrules, same procedure as above
      }
    } while (not EOF);
    

    有趣的项目,但我没有时间完全实施它。结果在medias 数组中。

    【讨论】:

      【解决方案2】:

      如果您想申请font-family: arial;,请将其添加为font-family: arial !important;

      您无需担心合并它们,因为浏览器会自动将颜色从第一个 css 中找到的第二个 css 添加到 body 标签,然后它会用第二个 css 覆盖它。

      【讨论】:

      • @Udhay 你的意思是找到差异并使用 php 创建新的 css。?
      【解决方案3】:

      你有两个选择:

      1. 简单的方法是更改​​您的 css 文件并添加 !important 重要的位置。例如,在 css 中有超过 1 次的“body”是正确的。每当您要覆盖的样式时,请离开它。当然,这种方法大多是手动的。你必须知道哪里会被覆盖,哪里不会。

      2. 第二种方法需要字符串解析、正则表达式,我的意思是你应该知道如何解析它们。您应该获取每个文件的内容,将它们保存到一个字符串中,并且您应该使用正则表达式将它们与两者中是否存在标签进行比较,然后合并标签内容。这种方式说起来容易做起来难。

      【讨论】:

        猜你喜欢
        • 2013-04-13
        • 1970-01-01
        • 2013-11-20
        • 2020-12-16
        • 2012-10-15
        • 2011-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多