需要在include()ed css文件之间添加换行符

时间:2011-04-03 04:50:15

标签: php css string concatenation string-concatenation

我有一堆CSS文件可以在每个页面上加载(标题,全局,主页,页脚等)。

我编写了一个简单的PHP脚本,将它们编译成单个字符串,然后输出该字符串。

<?php
    set_include_path('../');
    header('Content-Type: text/css');

    $q = $_GET['q'];

    $patterns = array(
                        '/.*[\.]{2,}.*/',
                        '/,\//',
                        '/^\//'
                    );

    $replacements = array(
                        '',
                        ',',
                        ''
                    );

    $q = preg_replace($patterns, $replacements, $q);

    $css = explode(",", $q);

    $output = '';

    foreach( $css as $link )
    {
        $output .= include($link);
    }

    print $output;
?>

它可以被调用(以及我调用它的方式),如下所示:

<?php
$cssLinks = array(
                    "/global/global.css",
                    "/styles/local.css",
                    $tmpl->headerContent['css']['link'],
                    $tmpl->appContent['css']['link'],
                    "/styles/css3buttons.css"
             );
$css = implode(",", $cssLinks);
?>
<link rel="stylesheet" href="/components/CSS.php?q=<?= $css; ?>" type="text/css" />

结果是这样的字符串:

<link rel="stylesheet" href="/components/CSS.php?q=/global/global.css,/styles/local.css,/styles/header.css,/styles/index.css,/styles/css3buttons.css" type="text/css" />

这很好,而且 - 更重要的是 - 可行

那么,我问你的问题是什么?

这是两个部分:

  1. 我在脚本中忽略了哪些安全漏洞?
    • 我删除了任何目录遍历的可能性,但还有什么?
    • 我确实需要能够更改链接的内容,因此我无法将它们硬编码到此脚本中。例如,$tmpl->appContent['css']['link']是每个页面的动态样式表,其中会有很多。
  2. 如何在包含的文件之间添加换行符?
    • 我在$output .= '\n\n';循环中添加了foreach(),但它不起作用。
    • 我仍然坚持输出:
  3. #footer, #push {
    height: 3em;
    padding-top: 1em;
    }#header{

    列出的CSS 有效,但我希望将#header阻止两行,例如:

    #footer, #push {
    height: 3em;
    padding-top: 1em;
    }

    #header{

    (我为这个奇怪的代码块道歉,Markdown在那些哈希上肆无忌惮地破坏了,我无法弄清楚如何修复它。)

    请注意,缺少换行符只发生在两个不同文件之间的连接处。每个CSS文件中的代码都应该按照原样编写。

2 个答案:

答案 0 :(得分:0)

关于安全漏洞:

  • 任何包含都有点危险。它将执行指定为PHP脚本的任何文件。如果它包含纯粹的非PHP代码,例如CSS,那么简单地使用readfile()会更安全。
  • 很难保证没有目录遍历。您仍有可能在系统上显示Web服务器具有读取权限的任何文件。
  • 在包含路径中使用\的Windows服务器怎么样?

关于第二个问题,请发布不起作用的确切代码。你说你试过。='\ n \ n',它应该引入文字\ n \ n字符(而不是“\ n \ n”)。如果你确实使用双引号,那应该有效。除非您在编辑器中查看过想要\ r \ n的文件。无论哪种方式,如果没有看到特定的破碎代码,很难说清楚。

就个人而言,最好只生成大量链接标记,而不是试图将这些脚本连接在一起。我想你有理由。

答案 1 :(得分:0)

您应该只将基本名称传递给CSS.php合并脚本:

<link rel="stylesheet" href="CSS.php?q=global,local,header,index,css3buttons" type="text/css" >

然后用CSS:

在CSS.php中实现更安全
preg_match_all('#\w+#', $_GET["q"], $files);

foreach ($files[0] as $fn) {

     foreach (array("global/$fn.css", "local/$fn.css") as $fn)
         if (file_exists($fn)) 
            $content .= file_get_contents($fn);

     $content .= "\n\n";

}

唯一的区别是这个脚本现在有一点智能,知道在哪里寻找样式表。因此,您不会失去将变量样式表部件粘合在一起的灵活性。