0

我正在重新编写一个支持多种皮肤的网站。目前,我只是计划允许修改图像和 CSS,但底层 HTML 不会改变。如果皮肤不修改图像或 CSS 文件,它会从基础皮肤继承该文件。

考虑到这一点,到目前为止,我考虑过以下 3 种方式来提供与皮肤相关的文件:

  1. 使用查找函数将所有特定于皮肤的请求请求包装在视图中,即:
    <img src="<?php get_skin_file('/images/header.png', 'skin1'); ?>" />

    函数 get_skin_file($file, $skin) {
        $skin_file = '/' 。$皮肤。'/' 。$文件;
        if(is_readable($skin_file)) 返回 $skin_file;
        返回 '​​/default/' 。$文件;
    }
  1. 让 php 提供图像

    <img src="/header.png.php?skin=skin1" />

  2. 总是尝试加载皮肤文件,如果它不存在,使用 ModRewrite 将结果发送到 php 处理程序脚本:

    <img src="/skin1/header.png" />

第 2 项是我想做的,但我只关心让 PHP 提供基本上每个图像文件的性能影响。

我的用户群足够小(大约 30k 用户),我认为这不是一个问题,但我也想了解其他人在这种情况下会做什么。

谢谢。

编辑:我不知道为什么我的代码格式不正确。我点击了代码按钮并检查了它是 4 个空格,但它仍然很难看。对于那个很抱歉。

4

4 回答 4

1

我会尝试构建它,以便它是模块化的并且易于适应未来的变化。我会避免在您的代码中尽可能多地放置硬位置,或者至少将其最小化到 1 个位置。

可能值得研究的一件事是拥有某种 ini 文件或 xml 文件,其中包含有关特定皮肤图片的信息。这样,硬位置不在您的 php 或 html 中,它们只是在易于更改的资源文件中。

我喜欢使用 xml,所以这里有一个你可以做的例子。

这是html。

<?php $skin = "notDefault"; ?>
<img src="<?php get_skin_image("header",$skin) ?>" />
<img src="<?php get_skin_image("footer",$skin) ?>" />

那么这就是你的功能,如果没有找到皮肤图像,它将从默认的 xml 文件中提取它。

function get_skin_image($type,$skin){
    $skin_xml_data = xml2array("skinFolderLocation/ " . $type . ".xml"); 
    $default_xml_data = xml2array("defaultFolderLocation/default.xml");
    // here is a link to the xml2array function for you to download 
    // http://www.php.net/manual/en/function.xml-parse.php#87920
    if(isset($skin_xml_data[$skin][$type])){
        return $skin_xml_dat[$skin][$type];
    } else {
        return $default_xml_data["default"][$type];
    }
}

最后将xml页面保存为notDefault.xml

<notDefault>
    <header>locationToHeader/header.png</header>
    <footer>locationToFooter/footer.png</footer>
</notDefault>
于 2010-08-02T19:00:48.800 回答
1

所有这三个都是完全有效的选项。我个人更喜欢第一个,尽管使用图像名称而不是图像路径。如果您的主题控制位足够强大,这可以允许主题定义自己的额外用户可控图像。

考虑第四个选项:实际上不要使用 img 标签插入图像。相反,使用带有背景图像的 div。这适用于大多数情况,并且完全由样式表定义图像。不幸的是,这也是一个更复杂的选择。

于 2010-08-02T18:35:15.140 回答
0

我最终选择了选项 2 的变体。我让 apache 查找 url 模式,如果存在皮肤可替换的 url,则请求将路由到我的皮肤图像选择脚本。

这是相关的apache配置:

<Directory /var/www/website>
  RewriteEngine on
  RewriteBase /

  RewriteCond %{REQUEST_URI} \.select.(png|jpg|gif|txt|css)$ [NC]
  RewriteRule ^(.*)$ index.php?mode=select&q=$1 [L,QSA]
</Directory>

这是呈现图像的文件中的 PHP 代码:

<?php
preg_match("%^(?P<path>.+)\.select\.(?P<ext>(jpg|gif|png|txt|css))$%", $_REQUEST['q'], $matches);

$base = '/' . $matches['path'] . '.' . $matches['ext'];

$file = '/skins/' . App::get('skin') . '/' . $base;

if(is_readable($file)) {
  header('Content-type: image/' . $matches['ext']);
  header('Content-Transfer-Encoding: binary');
  header('Content-Length: ' . filesize($file)+1);
  readfile($file);
  exit();
}
//custom file isn't available, so load the default
$file = '/skins/default/' . $base;
header('Content-type: image/' . $matches['ext']);
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file)+1);
readfile($file);
exit();
?>

因此,对于我认为需要具有皮肤感知能力的任何资产,我将其加载为:

<img src="/images/header.select.png" />

和 apache 捕获它并将其发送到我的处理程序脚本。

感谢您对此的帮助。其他两个建议都提供了 stmpy,Charles 也可以,但这对我来说是理想的解决方案。作为这样做的好处,我还可以替换 css 中的图像,以及在没有自定义 css 文件的情况下不能动态替换的图像。我的应用程序主要包括替换主背景,所以我的主题所需要的一切,大部分只是创建一个新的皮肤文件夹并上传一个背景图像。

于 2010-08-03T15:38:10.770 回答
0

你不能命名你的皮肤资产吗?例如,我构建的大多数应用程序都有一个inc目录(包含编程逻辑)和一个tpl目录,然后将其分解为单独的目录以用于单独的皮肤。如果站点只有一个皮肤,那么它们将只是一个目录。

例如:

inc/
    ...
tpl/
    default/
        assets/
            css/
            images/
            js/
    alternative/
        assets/
            css/
            images/
            js/

在我的控制器脚本中index.php,我可以侦听tpl要通过$_GET数组传递的变量。例如:

if (!isset($_SESSION['tpl'])) {
    $tpl = "default";
}
if (isset($_GET['tpl']) && is_dir('tpl/'.$_GET['tpl'])) {
    $_SESSION['tpl'] = $_GET['tpl'];
}
$tpl = $_SESSION['tpl'];

现在,当前tpl值在我的$_SESSION数组中可用(如果我希望该值在会话之间持续存在,我可以轻松地将其更改为使用 cookie)和$tpl变量。然后我可以像这样获取图像和 CSS 路径:

<img src="tpl/<?php echo $tpl; ?>/assets/images/heading.jpg" alt="Heading image" />

<link rel="stylesheet" href="tpl/<?php echo $tpl; ?>/assets/css/screen.css" type="text/css" />

然后可以将资产(CSS、图像、JavaScript)请求包装在自定义函数中。这也可以处理所有 JavaScript 文件都包含在default皮肤中的情况,并且您不想在alternative皮肤中复制它们。

function get_template_file($filename, $tpl)
{
    // if we're requesting a JavaScript file, serve from 'default' regardless
    if (substr($filename, -3) == ".js") {
        return "tpl/default/".$filename;
    }
    else {
        $file = "tpl/{$tpl}/{$filename}";
        if (is_file($file) && is_readable($file)) {
            return $file;
        }
        else {
            $tpl = "default";
            return $file; // try return 'default' filepath
        }
    }
}
于 2010-08-03T15:48:14.483 回答