You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP header跳转商品页如何拼接带横杠分隔商品名的SEO URL

问题说明

现有PHP业务文件通过自定义编号字段id_4d查询映射对应商品主键id_product,目前已实现搜索栏输入id_4d提交后,跳转地址可自动填充查询到的id_product值,但还需在URL中拼接横杠分隔的商品名称,才能匹配站点商品页路由,目标URL格式为:/website/www/fr/{id_product}-here-is-the-name-of-the-product.html。
当前待解决问题共2项:

  • 不知道如何将商品名称处理为横杠分隔的格式拼接到URL中
  • 站点数据库体量较大,暂未定位到商品名称存储的对应字段
现有代码

页面查询逻辑

?>
    <form action="p.php" method="GET">
        <input name="4d">
    </form>

            <p class="card-text"><b>ID 4d</b> : <?php echo $_GET['4d']; ?></p>
            <p class="card-text"><b>Id_product</b> :
                <?php
                $id_4d = $_GET['4d'];

                $db = \Db::getInstance();
                $request = 'SELECT `id_product`  FROM `' . _DB_PREFIX_ . 'product` WHERE `id_4d` = '.$id_4d.' ';
                $id = $db->executeS($request);
                $prod = new Product($id);
                
                if(empty($id))
                {
                    echo 'Le produit demandé n\'existe pas';
                } else{
                    echo ($id[0]['id_product']);
                }

                ?></p>
        </div>
<?php
   
    $page = $id[0]['id_product'];

当前跳转逻辑

header("location:/website/www/fr/$page.html");
实现方案

从代码里的_DB_PREFIX_常量、Product类、Db类调用方式判断,站点基于PrestaShop开发,不需要全库遍历查找字段,直接按系统原生结构处理即可。

1. 定位商品名称存储字段

PrestaShop商品多语言名称默认存储在{_DB_PREFIX_}product_lang表,通过id_product和主商品表关联,路由中fr对应法语,可直接关联查询:

  • 商品名字段为name
  • 系统预生成的URL slug(横杠分隔格式)字段为link_rewrite,优先取这个字段值,和系统原生生成的商品URL规则完全匹配,不会出现路由404
  • 关联时需匹配法语语言ID、当前店铺ID,避免多语言、多店铺场景下取错数据

2. 商品名称转横杠分隔格式

不需要自己写正则替换规则,直接调用系统自带的Tools::link_rewrite()方法即可,该方法会自动处理重音符号、特殊字符、空格转横杠、去除无效字符,完全匹配站点路由规则。如果product_lang表中已经有预生成的link_rewrite值,直接使用即可,不需要重复生成。

3. 修正后完整代码

原有代码存在SQL注入风险、参数未校验、空结果下标报错、Product类实例化传参错误、header跳转前有输出导致报错等问题,修正后代码如下:

<?php
$errorMsg = '';
$productInfo = [];
// 校验提交参数
if (isset($_GET['4d']) && trim($_GET['4d']) !== '') {
    $id_4d = trim($_GET['4d']);
    $db = \Db::getInstance();
    $context = \Context::getContext();
    // 连表查询商品ID、法语名称、预生成slug,参数用pSQL转义防注入
    $request = 'SELECT p.id_product, pl.name, pl.link_rewrite 
                FROM `' . _DB_PREFIX_ . 'product` p
                LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl 
                    ON p.id_product = pl.id_product 
                    AND pl.id_lang = (SELECT id_lang FROM `' . _DB_PREFIX_ . 'lang` WHERE iso_code = "fr")
                    AND pl.id_shop = ' . (int)$context->shop->id . '
                WHERE p.id_4d = "' . pSQL($id_4d) . '"';
    $productInfo = $db->getRow($request);
    
    if (empty($productInfo) || empty($productInfo['id_product'])) {
        $errorMsg = 'Le produit demandé n\'existe pas';
    } else {
        // 优先取系统预生成slug,不存在则现场生成
        $slug = !empty($productInfo['link_rewrite']) 
            ? $productInfo['link_rewrite'] 
            : \Tools::link_rewrite($productInfo['name']);
        $targetUrl = '/website/www/fr/' . (int)$productInfo['id_product'] . '-' . $slug . '.html';
        // 清空提前输出的内容,避免header报错
        ob_clean();
        header("Location: " . $targetUrl, true, 302);
        exit;
    }
}
?>
<form action="p.php" method="GET">
    <input name="4d">
    <button type="submit">查询</button>
</form>
<?php if ($errorMsg): ?>
    <p class="text-danger"><?php echo $errorMsg; ?></p>
<?php endif; ?>
<?php if (!empty($productInfo)): ?>
    <p class="card-text"><b>ID 4d</b> : <?php echo htmlspecialchars($_GET['4d']); ?></p>
    <p class="card-text"><b>Id_product</b> : <?php echo (int)$productInfo['id_product']; ?></p>
<?php endif; ?>

注意事项

  • 所有数据库查询参数必须做转义处理,ID类参数强制转整型,避免SQL注入风险
  • 页面输出用户提交的内容时必须做HTML转义,避免XSS漏洞
  • header跳转前必须清空已输出的内容,跳转后加exit终止后续代码执行
  • 不要自己写slug生成规则,优先使用系统原生方法或预生成的slug值,避免和系统路由规则不匹配导致404

内容的提问来源于stack exchange,提问作者Guillaume KS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:18:22