Tôi muốn có một hàm để tạo slugs hay còn gọi là alias từ một chuỗi Unicode, chẳng hạn hàm như sau:
create_slug(‘Hàm PHP tạo url – đường dẫn thân thiện cho seo’) sẽ trả về ham-php-tao-url-duong-dan-than-thien-cho-seo.
Làm thế nào để đạt được điều đó?
Chúng ta tạo hàm như sau:
Cách thứ nhất:
public static function create_slug($text) {
//thay thế các ký tự không phải chữ hoặc dấu bằng dấu gạch ngang "-"
$text = preg_replace('~[^\pL\d]+~u', '-', $text);
// chuyển bảng mã
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
// xoá các ký tự không mong muốn
$text = preg_replace('~[^-\w]+~', '', $text);
// trim $text = trim($text, '-');
// bỏ các ký tự trùng lắp -
$text = preg_replace('~-+~', '-', $text);
// chuyển sang in thường
$text = strtolower($text);
if (empty($text)) {
return 'n-a';
}
return $text;
}
Với cách này chúng ta có thể chuyển đường hàm với kết quả sau:
create_slug(‘Hàm PHP tạo url – đường dẫn thân thiện cho seo’)
=> hm-php-to-url-ng-dn-thn-thin-cho-seo
Do tiếng Việt có thêm các ký tự đặc biệt mà chúng ta cần chuyển đổi. Ví dụ như á, à, ả, ạ, ã, đ, ê, ô, ơ,… Vì vậy chúng ta cần có một bước chuyển trước khi thực hiện hàm create_slug();
Tuy nhiên một số hàm chuyển đổi hoặc lý do bảng mã bị lỗi khi gõ, có một số trường hợp vẫn bị lỗi khi chúng ta tạo slug. Ví dụ thay vì chữ “thiện” sẽ ra thien, nhưng vì lý do đặc biệt nào đó mà nó thành “thie-n”. Để giải quyết triệt để vấn đề này tôi có một cách giải quyết như sau:
function slug(): hàm này dùng để tách chuyển ký tự tiếng Việt có dấu về không dấu.
function toSlug(): hàm này dùng để chuyển toàn bộ ký tự trong chuỗi về slug bằng cách tận dụng hàm con slug. Mã giả như sau:
Input: Chuỗi nhập vào
Bước 1: Tách chuỗi nhập vào thành nhiều từ
Bước 2: Duyệt từng từ trong chuỗi được tách Lấy từng ký tự trong từng từ ra chuyển đổi thành tiếng việt không dấu với hàm slug();
Ghép các ký tự được chuyển đổi thành từ mới không dấu
Bước 3 Ghép các từ được chuyển thành một chuỗi hoàn chỉnh. Mỗi từ được kết nối với nhau bằng dấu gạch “-”
Output: Chuỗi không dấu slug.
Mã hoàn chỉnh:
Hàm toSlug:
function toSlug($string){
$exp2 = explode(" ",$string);
$newString = "";
$sizeOf = sizeof($exp2);
foreach ($exp2 as $key => $value) {
$exp = str_split(slug($value));
foreach ($exp as $c) {
if($c=="�"){
}else if($c==" "){
$newString.="-";
}else{
$newString.=slug($c);
}
}
$newString.="-";
}
return substr($newString, 0,strlen($newString)-1);
}
Hàm slug:
function slug($string, $options = array())
{
//Bản đồ chuyển ngữ
$slugTransliterationMap = array(
'á' => 'a',
'à' => 'a',
'ả' => 'a',
'ã' => 'a',
'ạ' => 'a',
'â' => 'a',
'ă' => 'a',
'Á' => 'A',
'À' => 'A',
'Ả' => 'A',
'Ã' => 'A',
'Ạ' => 'A',
'Â' => 'A',
'Ă' => 'A',
'ấ' => 'a',
'ầ' => 'a',
'ẩ' => 'a',
'ẫ' => 'a',
'ậ' => 'a',
'Ấ' => 'A',
'Ầ' => 'A',
'Ẩ' => 'A',
'Ẫ' => 'A',
'Ậ' => 'A',
'ắ' => 'a',
'ằ' => 'a',
'ẳ' => 'a',
'ẵ' => 'a',
'ặ' => 'a',
'Ắ' => 'A',
'Ằ' => 'A',
'Ẳ' => 'A',
'Ẵ' => 'A',
'Ặ' => 'A',
'đ' => 'd',
'Đ' => 'D',
'é' => 'e',
'è' => 'e',
'ẻ' => 'e',
'ẽ' => 'e',
'ẹ' => 'e',
'ê' => 'e',
'É' => 'E',
'È' => 'E',
'Ẻ' => 'E',
'Ẽ' => 'E',
'Ẹ' => 'E',
'Ê' => 'E',
'ế' => 'e',
'ề' => 'e',
'ể' => 'e',
'ễ' => 'e',
'ệ' => 'e',
'Ế' => 'E',
'Ề' => 'E',
'Ể' => 'E',
'Ễ' => 'E',
'Ệ' => 'E',
'í' => 'i',
'ì' => 'i',
'ỉ' => 'i',
'ĩ' => 'i',
'ị' => 'i',
'Í' => 'I',
'Ì' => 'I',
'Ỉ' => 'I',
'Ĩ' => 'I',
'Ị' => 'I',
'ó' => 'o',
'ò' => 'o',
'ỏ' => 'o',
'õ' => 'o',
'ọ' => 'o',
'ô' => 'o',
'ơ' => 'o',
'Ó' => 'O',
'Ò' => 'O',
'Ỏ' => 'O',
'Õ' => 'O',
'Ọ' => 'O',
'Ô' => 'O',
'Ơ' => 'O',
'ố' => 'o',
'ồ' => 'o',
'ổ' => 'o',
'ỗ' => 'o',
'ộ' => 'o',
'Ố' => 'O',
'Ồ' => 'O',
'Ổ' => 'O',
'Ỗ' => 'O',
'Ộ' => 'O',
'ớ' => 'o',
'ờ' => 'o',
'ở' => 'o',
'ỡ' => 'o',
'ợ' => 'o',
'Ớ' => 'O',
'Ờ' => 'O',
'Ở' => 'O',
'Ỡ' => 'O',
'Ợ' => 'O',
'ú' => 'u',
'ù' => 'u',
'ủ' => 'u',
'ũ' => 'u',
'ụ' => 'u',
'ư' => 'u',
'Ú' => 'U',
'Ù' => 'U',
'Ủ' => 'U',
'Ũ' => 'U',
'Ụ' => 'U',
'Ư' => 'U',
'ứ' => 'u',
'ừ' => 'u',
'ử' => 'u',
'ữ' => 'u',
'ự' => 'u',
'Ứ' => 'U',
'Ừ' => 'U',
'Ử' => 'U',
'Ữ' => 'U',
'Ự' => 'U',
'ý' => 'y',
'ỳ' => 'y',
'ỷ' => 'y',
'ỹ' => 'y',
'ỵ' => 'y',
'Ý' => 'Y',
'Ỳ' => 'Y',
'Ỷ' => 'Y',
'Ỹ' => 'Y',
'Ỵ' => 'Y',
'd' => 'd',
'đ' => 'd',
'D' => 'd',
'Đ' => 'd',
'?' => '',
);
//Ghép cài đặt do người dùng yêu cầu với cài đặt mặc định của hàm
$options = array_merge(array(
'delimiter' => '-',
'transliterate' => true,
'replacements' => array(),
'lowercase' => true,
'encoding' => 'UTF-8'
), $options);
//Chuyển ngữ các ký tự theo bản đồ chuyển ngữ
if ($options['transliterate']) {
$string = str_replace(array_keys($slugTransliterationMap), $slugTransliterationMap, $string);
}
//Nếu có bản đồ chuyển ngữ do người dùng cung cấp thì thực hiện chuyển ngữ
if (is_array($options['replacements']) && !empty($options['replacements'])) {
$string = str_replace(array_keys($options['replacements']), $options['replacements'], $string);
}
//Thay thế các ký tự không phải ký tự latin
$string = preg_replace('/[^\p{L}\p{Nd}]+/u', $options['delimiter'], $string);
//Chỉ giữ lại một ký tự phân cách giữa 2 từ
$string = preg_replace('/(' . preg_quote($options['delimiter'], '/') . '){2,}/', '$1', trim($string, $options['delimiter']));
//Chuyển sang chữ thường nếu có yêu cầu
if ($options['lowercase']) {
$string = mb_strtolower($string, $options['encoding']);
}
//Trả kết quả
return $string;
}
Chúc các bạn thành công!
1 comment
Thanks for sharing your thoughts. I truly appreciate your efforts and I
will be waiting for your next write ups thank you once again.