donglv6747 2015-09-22 15:22
浏览 80

用PHP生成独特的url slug

I'm developing a small CMS system. Currently brain dead while trying to generate a unique url. I generate the url from the title of the page. Got a nice script to make this happen but I can't resolve the issue of duplicates.

Similar question here but getting the exact output.

I manage to make the following;

this-is-the-slug
this-is-the-slug-2

But if I create the same post the third time, it would just duplicate: this-is-the-slug-2

$i = 1;
$baseurl = $url;
//$check database here
if($thereisamatch){
$url = $baseurl . "-" . $i++;  
}

I can't get around it, would be thankful for assistance.

if(isset($_POST['save'])) {
    $title = mysqli_real_escape_string($db, $_POST['title']);
    $url = toAscii($title);
    // check url
    $content = $_POST['content'];
    $author = $_SESSION['thelab_username'];
    $type = $_POST['type'];
    $showtitle = $_POST['showtitle'];
    $saveas = $_POST['status'];

    $insert = $connection->query(" INSERT INTO lab_pages (title, permalink, content, author, status, type, showtitle)
    VALUES ('$title', '$newslug', '$content', '$author', '$saveas', '$type', '$showtitle') ");

    if($insert === TRUE) {
        echo '<div id="success">Page added. <button id="close">Close</button></div>';
    }

    else {
        echo '<div id="error">Failed. Try again. <button id="failed">Close</button></div>';
        printf("Errormessage: %s
", $db->error);
    }
}

function toAscii($str, $replace=array(), $delimiter='-') {
 if( !empty($replace) ) {
  $str = str_replace((array)$replace, ' ', $str);
 }

 $clean = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
 $clean = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $clean);
 $clean = strtolower(trim($clean, '-'));
 $clean = preg_replace("/[\/_|+ -]+/", $delimiter, $clean);

 return $clean;
}
  • 写回答

4条回答 默认 最新

  • duanbi5906 2015-09-22 15:27
    关注

    Use the value of database matches (by SELECT COUNT(*)) and increase it to get a new postfix.

    PHP scripts do not talk to each other, so $i will always be set to 1 at start and then be increased by 1, hence the 2.

    Thanks for the source code. Therefore the beginning of your code should be like:

    if(isset($_POST['save'])) {
        $title = mysqli_real_escape_string($db, $_POST['title']);
        $url = toAscii($title);
        // check url
        $content = $_POST['content'];
        $author = $_SESSION['thelab_username'];
        $type = $_POST['type'];
        $showtitle = $_POST['showtitle'];
        $saveas = $_POST['status']; // no modifications until here
    
        // count entries with permalink like our slug
        $urlmask = $url.'%';
        $sql = 'SELECT COUNT(*) FROM lab_pages WHERE permalink LIKE ?';
        $stst =  $db->stmt_init();
        $stst->bind_param('s', $urlmask);
        $stst->execute();
        $stst->store_result();
        $stst->bind_result($count);
        $stst->fetch();
        $stst->free_result();
        $newslug = sprintf('%s-%d', $url, $count+1);
    
        $insert = $connection->query(" INSERT INTO lab_pages (title, permalink, content, author, status, type, showtitle)
        VALUES ('$title', '$newslug', '$content', '$author', '$saveas', '$type', '$showtitle') ");
        :
    

    The important thing is fetching the number of present slugs with an SQL statement like SELECT COUNT(*) FROM lab_pages WHERE permalink LIKE "$url%". Then you can increase it and create a new unique slug. The column permalink should be indexed due to performance.

    But, I'd rather use uniqid() for stuff like that.

    I used prepared statements for sake of demonstration, but you can of course run the query by the normal query-fetch_array-free_result sequence.

    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大