没有不值得去解决的问题,也没有不值得去学习的技术!

Yii2 Supports Generating Alias-Based Links: Aliases Can Only Contain Lowercase Letters, Numbers, Hyphens, @, and Underscores

When the alias is @dd87-_s, the generated link is /industry/%40dd87-_s.html

1. The table structure is designed to allow the alias to be null, defaults to null, and has a unique index added.

SQL
-- `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. When submitting the edit form in the backend, empty strings are automatically converted to null. Set the conversion rule and validation in the model’s rules.

PHP
    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            ['alias', 'filter', 'filter' => function ($value) {
                return $value === '' ? null : $value;
            }],
            ['alias', 'match', 'pattern' => '/^[a-z0-9\-@_]+$/', 'message' => '别名只能包含小写字母、数字、中划线、@ 和下划线。'],
        ];
    }

3. In the frontend view file, the link generation is implemented as follows:

frontend/views/article/index.php

PHP
<a class="item" href="<?= ArticleUrlHelper::detailUrl($article) ?>">


frontend/helpers/ArticleUrlHelper.php

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

PHP
    public static function isValidAlias(string $alias): bool
    {
        return preg_match('/^[a-z0-9\-@_]+$/', $alias) === 1;
    }

4. Configure urlManager in frontend/config/main.php as follows:

PHP

        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => true,
            'normalizer' => [
                'class' => yii\web\UrlNormalizer::class,
                'collapseSlashes' => true,
                'normalizeTrailingSlash' => true,
            ],
            'rules' => [
                '' => 'page/index',
                // 资讯详情
                'industry/detail-.html' => 'article/view',
                'industry/.html' => 'article/view',
            ],
        ],

5. When the alias is @dd87-_s, the generated link is /industry/%40dd87-_s.html. See Figure 1.

When the alias is @dd87-_s, the generated link is /industry/%40dd87-_s.html
Figure 1

6. The reason is that Url::to() automatically URL-encodes the parameters. The alias is @dd87-_s, where @ is a special character and gets encoded as %40. I decided not to apply additional processing for now.

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系