Объединение нескольких файлов 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 варианта:
Простой способ - изменить ваши CSS-файлы и добавить! Важное, где важно быть там. Правильно иметь, например, "тело" в CSS более 1 раза. И всякий раз, когда вам нужно изменить стиль, оставьте его. Конечно, такой подход в основном ручной. Вы должны знать, где это будет перезаписано, а где нет.
Второй подход требует парсинга строк, регулярных выражений, и я имею в виду, что вы должны знать, как разбирать строки и как их анализировать. Вы должны получить содержимое каждого из файлов, сохранить их в строку и сравнить их с помощью регулярных выражений, чтобы, если тег существует в обоих, затем объединить содержимое тегов. Этот способ легко сказать, но трудно реализовать.