下面我将从基础到高级,全面介绍 ECSHOP 模板中 PHP 代码的使用方法。

ecshop 模板 php代码
(图片来源网络,侵删)

核心原则:逻辑与表现分离

在开始之前,必须理解这个最重要的原则:

  • PHP 文件 (.php):负责处理数据、业务逻辑,比如从数据库查询商品信息、计算价格、判断用户权限等,这是“后台”。
  • 模板文件 (.html):负责展示数据,它接收 PHP 文件传递过来的数据,并按照预定的样式(HTML + CSS)将其渲染成最终的网页,这是“前台”。

错误的做法:在 .html 文件里写 foreach 循环去查询数据库。 正确的做法:在 .php 文件里查询数据库,然后把查询结果(一个商品数组)传递给模板,然后在 .html 文件里用 {foreach} 循环来显示这个数组。


在模板中直接使用 PHP 代码(不推荐,但有时必要)

虽然不推荐,但在某些极端情况下,你可能需要在模板中直接执行一小段 PHP 代码。 Smarty 提供了两种方式来实现:

{php}

这是最直接的方式,可以执行任意 PHP 代码。

ecshop 模板 php代码
(图片来源网络,侵删)

语法:

{php}
    // 在这里写你的 PHP 代码
    $myVar = "Hello from PHP in template!";
    echo $myVar;
{/php}

重要警告

  • 安全风险:如果模板变量可以被用户控制(比如从 URL 参数传入),使用 {php} 可能导致 代码注入攻击
  • 违反 MVC 原则:它让业务逻辑混入表现层,使代码难以维护。
  • 性能影响:Smarty 编译模板时,{php} 里的代码不会被编译,而是原样执行,效率较低。

使用场景:仅用于调试,或者执行一些非常简单、安全、且与业务逻辑无关的辅助性代码。

{literal}

它的作用不是执行 PHP,而是 原样输出 标签内的内容,防止 Smarty 将其解释为自己的标签,这在需要输出包含 的 JavaScript 或 CSS 代码时非常有用。

ecshop 模板 php代码
(图片来源网络,侵删)

示例

{literal}
<script type="text/javascript">
    function test() {
        var myVar = "{if $smarty.get.debug == 1}Debug Mode{/if}";
        alert(myVar);
    }
</script>
{/literal}

如果没有 {literal},Smarty 会尝试解析 {if} 标签并导致错误。


推荐的做法:使用 Smarty 的标准函数和自定义变量

这才是 ECSHOP 模板开发的正确方式。

输出 PHP 变量

这是最基本、最常用的操作,PHP 文件将变量传递给 Smarty 后,在模板中直接用 $变量名 输出。

PHP 文件 (index.php):

<?php
$smarty->assign('page_title', '欢迎来到我的商城');
$smarty->assign('user_name', '张三');
$smarty->assign('products', [
    ['id' => 1, 'name' => '商品A', 'price' => 100],
    ['id' => 2, 'name' => '商品B', 'price' => 200]
]);
$smarty->display('index.dwt');
?>

模板文件 (index.dwt):

<!DOCTYPE html>
<html>
<head>{$page_title}</title>
</head>
<body>
    <h1>你好, {$user_name}!</h1>
    <ul>
    {foreach from=$products item=product}
        <li>
            ID: {$product.id} - 名称: {$product.name} - 价格: {$product.price}
        </li>
    {/foreach}
    </ul>
</body>
</html>

使用 Smarty 内置函数

Smarty 提供了一系列强大的函数来控制流程和格式化数据。

a) 条件判断: {if}...{elseif}...{else}...{/if}

{if $user_name}
    欢迎回来, {$user_name}!
{else}
    您好,请登录。
{/if}
{if $product.price > 150}
    <span style="color: red;">高价商品</span>
{elseif $product.price > 100}
    <span style="color: orange;">中等价位</span>
{else}
    <span style="color: green;">优惠商品</span>
{/if}

b) 循环: {foreach}...{/foreach}{section}...{/section} {foreach} 是最常用的循环方式,用于遍历数组。

{foreach from=$products item=product key=key}
    {if $product@first}
        <p>这是第一个商品</p>
    {/if}
    <div class="product">
        <h3>{$product.name}</h3>
        <p>价格: {$product.price}</p>
    </div>
    {if $product@last}
        <p>这是最后一个商品</p>
    {/if}
    {if $product@iteration == 2}
        <p>这是循环的第2次</p>
    {/if}
{/foreach}
  • {$product@first}: 是否是第一个元素。
  • {$product@last}: 是否是最后一个元素。
  • {$product@iteration}: 当前循环的索引(从1开始)。

c) 包含其他模板: {include} 用于将一个小的、可复用的模板片段嵌入到当前模板中。

<!-- 在头部模板中 -->
{include file='header.dwt'}
<!-- 在主体内容中 -->
{include file='user_menu.dwt'}
<!-- 在底部模板中 -->
{include file='footer.dwt'}

d) 调用 PHP 函数: {function name=...} 可以调用一些简单的 PHP 函数来修改变量。

<!-- 将时间戳格式化为日期 -->
<p>发布时间: {function name="date" format="Y-m-d H:i:s" var=$article.add_time}</p>
<!-- 截取字符串 -->
<p>简介: {function name="substr" string=$article.intro length=100}...</p>
<!-- 转义HTML,防止XSS攻击 -->
<p>{$article.content|escape}</p>

|escape 是一个“修饰器”,用于对变量进行过滤处理。


ECSHOP 自定义的模板函数和变量

ECSHOP 在 Smarty 的基础上封装了大量自己的函数和变量,这些是开发 ECSHOP 模板的核心。

常用 ECSHOP 模板函数

a) 获取指定分类的商品: get_children

<!-- 获取 ID 为 3 的分类下的所有子分类的商品 -->
{get_children category_id=3 type=goods assign=sub_category_goods}
{foreach from=$sub_category_goods item=goods}
    <a href="{$goods.url}">{$goods.goods_name}</a>
{/foreach}

b) 获取推荐/热销商品: get_recommend_goods

<!-- 获取 'best' (精品) 推荐的商品 -->
{get_recommend_goods type='best' assign=best_goods limit=5}
{foreach from=$best_goods item=goods}
    <li><a href="{$goods.url}"><img src="{$goods.goods_thumb}" />{$goods.goods_name}</a></li>
{/foreach}

type 可以是 best (精品), new (新品), hot (热销) 等。

c) 获取分类列表: get_cat_list

<!-- 获取顶级分类列表 -->
{get_cat_list type=parent assign=parent_cats}
{foreach from=$parent_cats item=cat}
    <h2><a href="{$cat.url}">{$cat.name}</a></h2>
    {get_cat_list parent_id=$cat.cat_id assign=child_cats}
    <ul>
    {foreach from=$child_cats item=child_cat}
        <li><a href="{$child_cat.url}">{$child_cat.name}</a></li>
    {/foreach}
    </ul>
{/foreach}

d) 获取页面标题/关键字: page_titlepage_keyword 这些函数会根据当前页面(如首页、分类页、商品详情页)自动生成对应的标题和关键字,有利于 SEO。

<head>{if $page_title}{$page_title}_{/if}{if $page_keywords}{$page.keywords}{/if}{if !$page_title && !$page_keywords}{$shop_name}{/if}</title>
    <meta name="keywords" content="{$page_keywords}" />
</head>

常用 ECSHOP 模板变量

a) 全局变量

  • {$shop_name}: 商城名称。
  • {$lang.*}: 语言变量,{$lang.home} 对应语言包中的 home强烈推荐使用,便于多语言。
  • {$smarty.get.*}: 获取 URL 的 GET 参数,URL 是 goods.php?id=123{$smarty.get.id} 的值就是 123
  • {$smarty.post.*}: 获取表单 POST 提交的数据。
  • {$site_url}: 网站根目录 URL。

b) 循环中的变量 在使用 ECSHOP 的循环函数(如 get_recommend_goods)后,每个商品项都会包含一组预定义的变量:

  • {$goods.goods_id}: 商品 ID。
  • {$goods.goods_name}: 商品名称。
  • {$goods.goods_thumb}: 商品缩略图 URL。
  • {$goods.goods_img}: 商品主图 URL。
  • {$goods.shop_price}: 商品店铺价格。
  • {$goods.market_price}: 商品市场价。
  • {$goods.url}: 商品详情页 URL。
  • {$goods.short_style_name}: 短样式的商品名。

实战案例:修改首页模板

假设我们要在首页添加一个“新品上市”的模块。

步骤 1:找到并修改 PHP 文件

首页的 PHP 文件是 index.php,我们需要在这个文件中调用获取新品的函数,并将结果传递给模板。

打开 index.php,找到类似 $smarty->assign('new_goods', get_new_goods()); 的代码(如果没有,就添加它)。get_new_goods() 是 ECSHOP 的一个内置函数,用于获取新品。

步骤 2:在模板文件中循环输出

打开首页模板文件 index.dwt,在合适的位置(比如轮播图下面)添加以下代码:

<!-- 新品上市模块 Start -->
<div class="new-goods-box">
    <h2 class="box-title"><span>{$lang.new_goods}</span></h2>
    <div class="box-content">
        <ul class="clearfix">
            {get_recommend_goods type='new' assign=new_goods limit=6}
            {foreach from=$new_goods item=goods}
                <li>
                    <a href="{$goods.url}" title="{$goods.goods_name|escape:html}">
                        <img src="{$goods.goods_thumb}" alt="{$goods.goods_name|escape:html}" />
                        <p class="name">{$goods.short_style_name}</p>
                        <p class="price">¥ {$goods.shop_price}</p>
                    </a>
                </li>
            {/foreach}
        </ul>
    </div>
</div>
<!-- 新品上市模块 End -->

步骤 3:添加 CSS 样式

在模板的 CSS 文件(通常是 style.css)中,为新模块添加样式,使其看起来美观。

.new-goods-box { width: 100%; margin-bottom: 20px; border: 1px solid #eee; }{ height: 35px; line-height: 35px; background: #f4f4f4; padding-left: 10px; font-size: 14px; font-weight: bold; }
.box-content ul { padding: 10px; list-style: none; }
.box-content li { float: left; width: 150px; margin-right: 10px; text-align: center; }
.box-content img { width: 150px; height: 150px; display: block; margin-bottom: 5px; }
.box-content .name { font-size: 12px; height: 20px; overflow: hidden; }
.box-content .price { color: #ff3300; font-weight: bold; }

通过以上三步,你就成功地修改了首页,添加了一个新的模块,整个过程完全遵循了“逻辑与表现分离”的原则。

场景 推荐方法 不推荐方法
控制页面流程 {if}, {foreach}, {section} 在模板里写 if/else/for/foreach 语句
显示数据 {$variable}, {$variable\|modifier} 在模板里写 echo 语句
包含复用代码 {include file='...'} 复制粘贴 HTML 代码
获取特定数据 ECSHOP 自定义函数 (get_recommend_goods, get_cat_list) 在模板里写 SQL 查询
执行简单逻辑 Smarty 的 {function} 或 ECSHOP 自定义变量 使用 {php}
输出脚本/样式 {literal} 直接写,不处理 冲突

掌握这些方法和原则,你就能高效、安全地开发出高质量的 ECSHOP 模板。