在PHP中将多个CSS文件合并为一个

时间:2013-02-28 06:02:52

标签: php css-parsing

我正在编写一个生成多个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中的正文样式有font-family,它会替换原始CSS中的font-family属性,因为颜色是($ file)中不存在的新属性,是原始CSS文件,因此它应该将属性添加到原始CSS文件。那么如何在PHP中实现这一点,因为我对解析CSS没有任何想法。对此有任何想法将不胜感激。

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

提前致谢。

3 个答案:

答案 0 :(得分:1)

有一些CSS解析器可用(谷歌“php css解析器”),就像this one我没试过,但看起来很有趣。但我个人自己做了解析 - 遵循那种伪PHP算法

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

然后,功能处理(selector =>规则)

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

处理媒体的主要功能,然后调用上面的函数

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数组。

答案 1 :(得分:0)

如果您希望应用font-family: arial;,请将其添加为font-family: arial !important;

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

答案 2 :(得分:0)

您有两个选择:

  1. 简单的方法是更改​​您的css文件,并在重要的地方添加!important。在css中使用例如“body”超过1次是正确的。每当你被覆盖的风格离开它。当然,这种方法大多是手工的。你必须知道它将被覆盖的位置以及不在何处。

  2. 第二种方法需要字符串解析,正则表达式,我的意思是你应该知道如何解析字符串广告。您应该获取每个文件内容,将它们保存为字符串,并且如果两者中都存在标记,则应使用正则表达式对它们进行比较,然后合并标记内容。这种方式很容易说,但很难实现。