简体   繁体   English

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

[英]Merging multiple CSS files into one in PHP

i'm working on a script that generates multiple CSS into one. 我正在研究一种将多个CSS生成一个的脚本。 And Here is the script. 这是脚本。

    $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;

Here i'm combining all the CSS files into one. 在这里,我将所有CSS文件合并为一个。 But the problem now is i have to compare the current CSS($file) with another css(let's consider it as overrider.css ). 但是现在的问题是我必须将当前的CSS($ file)与另一个CSS进行比较(让我们将其视为overrider.css )。 And if $file is having a style like, 如果$ 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; 
}

and if overrider.css is having a style like, 如果overrider.css具有类似的样式,

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

Then final CSS(output.css) generated should be, 然后生成的最终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;
}

Here, since style for body in override.css have font-family , it replaces the font-family property in original CSS and since the color is a new property which is not present in ($file) which is original CSS file, so it should add the property to original CSS file. 在这里,由于override.css body的样式具有font-family ,它替换了原始CSS中的font-family属性,并且由于color是一个新属性,而该属性在原始CSS文件的($ file)中不存在,因此应该将该属性添加到原始CSS文件中。 So how to achieve this in PHP, since i don't have any idea on parsing CSS. 那么如何在PHP中实现此目标,因为我对解析CSS没有任何想法。 Any idea on this would be greatly appreciated. 任何想法,将不胜感激。

Please note that i need to generate a new CSS file by giving the input as file1($file) and file2(override.css) and we need to genrate output.css with the styles overridden. 请注意,我需要通过将输入指定为file1($ file)和file2(override.css)来生成一个新的CSS文件,并且我们需要使用覆盖的样式生成output.css。

Thanks in advance. 提前致谢。

There are a few CSS parsers available (google "php css parser"), like this one that I didn't try, but seems interesting. 有几个CSS解析器可用(谷歌“的PHP解析器的CSS”),像这一次 ,我没有尝试,但似乎有趣。 But personally I'd do the parsing myself - following that kind of pseudo-PHP algorithm 但是我个人会自己解析-遵循这种伪PHP算法

  • read all the files into one string Str , with all "\\n", "\\r" and "\\t" replaced by a space (to make parsing (a bit) easier) 将所有文件读入一个字符串Str ,用空格替换所有“ \\ n”,“ \\ r”和“ \\ t”(使解析(稍微容易一点))

then, function to process (selector => rules) 然后,函数进行处理(选择器=>规则)

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 function to deal with medias, and then call the above function 主要功能是处理媒体,然后调用上面的功能

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);

Interesting project but I don't have the time to implement it fully. 有趣的项目,但我没有时间充分实施它。 Result is in medias array. 结果在medias数组中。

if you want font-family: arial; 如果您想要font-family: arial; to be apply then add it as font-family: arial !important; 要应用,然后将其添加为font-family: arial !important;

you do not need to worry about merging them because browser will automatically add color to body tag from second css of color found in first css then it will overwrite it with second css. 您无需担心合并它们,因为浏览器会自动将颜色从第二个CSS中的第二个CSS添加到body标签中,然后用第二个CSS覆盖它。

You have 2 choices: 您有2个选择:

  1. The simple way is to change your css files and add !important where it is important to be there. 简单的方法是更改​​您的css文件,并在重要的位置添加!important。 It is correct to have for example "body" in css more than 1 time. 例如,在CSS中多次包含“ body”是正确的。 And whenever you a style to be overridden leave it. 每当您要覆盖的样式都保留时。 Ofcourse this kind of approach is mostly manual. 当然,这种方法大部分是手动的。 You have to know where it will be overwritten and where not. 您必须知道它将在何处被覆盖以及在何处不会被覆盖。

  2. The second approach requires string parsing, regular expressions, and i mean you should know your way around the string ad how to parse them. 第二种方法需要字符串解析,正则表达式,我的意思是您应该了解字符串广告的解析方式。 You should get each of the files content, save them to a string, and you should compare them using regex to if a tag is exists in both, then merge the tags content. 您应该获取每个文件的内容,将它们保存到字符串中,并且应该使用正则表达式比较它们是否存在标签,然后合并标签内容。 This way is easy to say but hard to implement. 这种方法很容易说,但很难实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM