PHP项目模板引擎标签如何自定义

wen PHP项目 21

本文目录导读:

PHP项目模板引擎标签如何自定义

  1. Smarty 自定义标签
  2. Twig 自定义标签
  3. Blade 自定义标签(Laravel)
  4. 原生 PHP 模板引擎自定义
  5. 通用最佳实践
  6. 注意事项

在PHP模板引擎中自定义标签有多种方式,下面介绍主流模板引擎(Smarty、Twig、Blade)的自定义方法:

Smarty 自定义标签

自定义函数(简单标签)

// 注册自定义函数
$smarty->registerPlugin('function', 'hello', 'smarty_function_hello');
function smarty_function_hello($params, $smarty) {
    $name = $params['name'] ?? 'World';
    return "Hello, $name!";
}

模板中使用:

{hello name="John"}

自定义块标签

// 注册块插件
$smarty->registerPlugin('block', 'upper', 'smarty_block_upper');
function smarty_block_upper($params, $content, $smarty, &$repeat) {
    if (!$repeat) {
        return strtoupper($content);
    }
}

模板中使用:

{upper}hello world{/upper}

Twig 自定义标签

自定义函数

// 创建扩展类
class MyTwigExtension extends \Twig\Extension\AbstractExtension {
    public function getFunctions() {
        return [
            new \Twig\TwigFunction('greeting', [$this, 'greetingFunction']),
        ];
    }
    public function greetingFunction($name) {
        return "Hello, $name!";
    }
}
// 注册扩展
$twig->addExtension(new MyTwigExtension());

模板中使用:

{{ greeting('John') }}

自定义标签(复杂)

class UpperTokenParser extends \Twig\TokenParser\AbstractTokenParser {
    public function parse(\Twig\Token $token) {
        $parser = $this->parser;
        $stream = $parser->getStream();
        $stream->expect(\Twig\Token::BLOCK_END_TYPE);
        $body = $parser->subparse(function($token) {
            return $token->test('endupper');
        }, true);
        $stream->expect(\Twig\Token::BLOCK_END_TYPE);
        return new UpperNode($body, $token->getLine(), $tag);
    }
    public function getTag() {
        return 'upper';
    }
}

Blade 自定义标签(Laravel)

自定义指令

// 在 AppServiceProvider 的 boot 方法中
public function boot() {
    Blade::directive('hello', function ($expression) {
        return "<?php echo 'Hello, ' . {$expression}; ?>";
    });
    Blade::directive('uppercase', function ($expression) {
        return "<?php echo strtoupper({$expression}); ?>";
    });
}

模板中使用:

@hello('John')
@uppercase('hello world')

自定义 if 语句

Blade::if('admin', function () {
    return auth()->check() && auth()->user()->isAdmin();
});

模板中使用:

@admin
    <p>Welcome Admin!</p>
@else
    <p>Welcome User!</p>
@endadmin

原生 PHP 模板引擎自定义

简单模板引擎实现

class SimpleTemplate {
    private $customTags = [];
    public function registerTag($tag, $callback) {
        $this->customTags[$tag] = $callback;
    }
    public function render($content, $data = []) {
        foreach ($this->customTags as $tag => $callback) {
            $pattern = '/\{\{' . $tag . ':(.*?)\}\}/';
            $content = preg_replace_callback($pattern, function($matches) use ($callback, $data) {
                $params = array_merge($data, ['value' => $matches[1]]);
                return call_user_func($callback, $params);
            }, $content);
        }
        return $content;
    }
}
// 使用
$template = new SimpleTemplate();
$template->registerTag('hello', function($params) {
    return "Hello, {$params['value']}!";
});
$content = "{{hello:World}}";
echo $template->render($content); // 输出: Hello, World!

通用最佳实践

安全考虑

// 始终对用户输入进行转义
$smarty->registerPlugin('function', 'safe_output', function($params) {
    return htmlspecialchars($params['value'], ENT_QUOTES, 'UTF-8');
});

性能优化

// 缓存编译结果
class CachedCustomTag {
    private $cache = [];
    public function process($tag, $params) {
        $key = md5($tag . serialize($params));
        if (isset($this->cache[$key])) {
            return $this->cache[$key];
        }
        $result = $this->renderTag($tag, $params);
        $this->cache[$key] = $result;
        return $result;
    }
}

注意事项

  1. 命名规范:使用有意义的前缀避免冲突
  2. 文档化:详细记录标签参数和用途
  3. 测试:为自定义标签编写单元测试
  4. 兼容性:考虑不同PHP版本的语法差异
  5. 性能:避免在标签中进行复杂的数据库操作

选择哪种方式取决于你的项目使用的模板引擎,推荐优先使用官方支持的扩展机制来实现自定义标签。

抱歉,评论功能暂时关闭!