SmartyEngine.php 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\View\Engine;
  4. use Hyperf\View\Engine\EngineInterface;
  5. use Smarty;
  6. use RuntimeException;
  7. class SmartyEngine implements EngineInterface
  8. {
  9. protected Smarty $smarty;
  10. public function __construct(array $options = [])
  11. {
  12. $this->smarty = new Smarty();
  13. // 设置模板目录
  14. $this->smarty->setTemplateDir($options['template_dir'] ?? BASE_PATH . '/storage/view/');
  15. $this->smarty->setCompileDir($options['compile_dir'] ?? BASE_PATH . '/runtime/smarty/compile/');
  16. $this->smarty->setCacheDir($options['cache_dir'] ?? BASE_PATH . '/runtime/smarty/cache/');
  17. // 设置定界符
  18. $this->smarty->setLeftDelimiter($options['left_delimiter'] ?? '{{');
  19. $this->smarty->setRightDelimiter($options['right_delimiter'] ?? '}}');
  20. // 确保目录存在
  21. $this->ensureDirectoryExists($this->smarty->getCompileDir());
  22. $this->ensureDirectoryExists($this->smarty->getCacheDir());
  23. }
  24. protected function ensureDirectoryExists(string $path): void
  25. {
  26. if (!is_dir($path)) {
  27. mkdir($path, 0755, true);
  28. }
  29. }
  30. public function render(string $template, array $data, array $config): string
  31. {
  32. // 标准化模板路径
  33. $template = $this->normalizeTemplatePath($template);
  34. // 获取完整模板路径
  35. $templatePath = $this->smarty->getTemplateDir()[0] . $template;
  36. // 检查模板文件是否存在
  37. if (!file_exists($templatePath)) {
  38. throw new RuntimeException("Template file not found: {$templatePath}");
  39. }
  40. // 分配变量
  41. foreach ($data as $key => $value) {
  42. $this->smarty->assign($key, $value);
  43. }
  44. try {
  45. return $this->smarty->fetch($templatePath);
  46. } catch (\SmartyException $e) {
  47. throw new RuntimeException("Smarty render failed: " . $e->getMessage());
  48. }
  49. }
  50. protected function normalizeTemplatePath(string $path): string
  51. {
  52. // 移除可能的绝对路径前缀
  53. $path = str_replace(BASE_PATH, '', $path);
  54. // 移除开头的斜杠
  55. $path = ltrim($path, '/');
  56. // 确保使用正确的扩展名
  57. if (!str_ends_with($path, '.tpl')) {
  58. $path .= '.tpl';
  59. }
  60. return $path;
  61. }
  62. }