Объединение нескольких файлов CSS в один в PHP

Я работаю над сценарием, который генерирует несколько 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, он заменяет свойство font-family в исходном CSS и, поскольку цвет является новым свойством, которого нет в ($ file), который является исходным файлом CSS, поэтому он должен добавить свойство в исходный файл CSS. Итак, как добиться этого в PHP, так как я не имею представления о разборе CSS. Любая идея по этому поводу будет принята с благодарностью.

Обратите внимание, что мне нужно сгенерировать новый файл CSS, указав входные данные в виде file1($file) и file2(override.css), и нам нужно сгенерировать output.css с переопределенными стилями.

Заранее спасибо.

3 ответа

Решение

Есть несколько доступных парсеров CSS (google "php css parser"), таких как этот, который я не пробовал, но кажется интересным. Но лично я бы сделал синтаксический анализ сам - следуя такому алгоритму псевдо-PHP

  • прочитать все файлы в одну строку Str, со всеми "\n", "\r" и "\t", замененными пробелом (чтобы облегчить анализ (немного))

затем, функция для обработки (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

Основная функция для работы со средствами массовой информации, а затем вызвать вышеуказанную функцию

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 массив.

Если ты хочешь font-family: arial; чтобы подать заявку, затем добавить его как font-family: arial !important;

вам не нужно беспокоиться об их объединении, потому что браузер автоматически добавит цвет к тегу body из второго css цвета, найденного в первом css, затем перезапишет его вторым css.

У вас есть 2 варианта:

  1. Простой способ - изменить ваши CSS-файлы и добавить! Важное, где важно быть там. Правильно иметь, например, "тело" в CSS более 1 раза. И всякий раз, когда вам нужно изменить стиль, оставьте его. Конечно, такой подход в основном ручной. Вы должны знать, где это будет перезаписано, а где нет.

  2. Второй подход требует парсинга строк, регулярных выражений, и я имею в виду, что вы должны знать, как разбирать строки и как их анализировать. Вы должны получить содержимое каждого из файлов, сохранить их в строку и сравнить их с помощью регулярных выражений, чтобы, если тег существует в обоих, затем объединить содержимое тегов. Этот способ легко сказать, но трудно реализовать.

Другие вопросы по тегам