在 Yii2 中,支持生成基于别名的链接,别名只能包含小写字母、数字、中划线、@ 和下划线。
1、表结构设计为 允许别名为 null,且默认为 null,添加唯一索引。
-- `official-website-management-system`.articles definition CREATE TABLE `articles` ( `id` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, `alias` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx-alias` (`alias`), KEY `idx-category_id` (`category_id`), KEY `idx-status` (`status`), KEY `idx-updated_at` (`updated_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
2、在后台表单提交编辑时,自动将空字符串转换为 null。在模型的 rules 中设置转换规则与验证
/** * {@inheritdoc} */ public function rules() { return [ ['alias', 'filter', 'filter' => function ($value) { return $value === '' ? null : $value; }], ['alias', 'match', 'pattern' => '/^[a-z0-9\-@_]+$/', 'message' => '别名只能包含小写字母、数字、中划线、@ 和下划线。'], ]; }
3、在前端的视图文件中,生成链接的实现如下
frontend/views/article/index.php
<a class="item" href="<?= ArticleUrlHelper::detailUrl($article) ?>">
frontend/helpers/ArticleUrlHelper.php
public static function detailUrl($article): string { if (!empty($article['alias']) && UrlHelper::isValidAlias($article['alias'])) { return Url::to(['article/view', 'alias' => $article['alias']]); } return Url::to(['article/view', 'id' => $article['id']]); }
frontend/helpers/UrlHelper.php
public static function isValidAlias(string $alias): bool { return preg_match('/^[a-z0-9\-@_]+$/', $alias) === 1; }
4、在 frontend/config/main.php 中配置 urlManager 如下
'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'enableStrictParsing' => true, 'normalizer' => [ 'class' => yii\web\UrlNormalizer::class, 'collapseSlashes' => true, 'normalizeTrailingSlash' => true, ], 'rules' => [ '' => 'page/index', // 资讯详情 'industry/detail-<id:\d+>.html' => 'article/view', 'industry/<alias:[a-z0-9\-@_]+>.html' => 'article/view', ], ],
5、当别名为:@dd87-_s 时,生成的链接为:/industry/%40dd87-_s.html 。如图1
6、原因是,Url::to() 自动对参数进行了 URL 编码, alias 是 @dd87-_s,其中 @ 是特殊字符,会被编码为 %40。决定暂不做处理。
近期评论