ฟังก์ชั่น PHP เพื่อสร้างกระสุน (สตริง URL)


166

ฉันต้องการจะมีฟังก์ชั่นเพื่อสร้างทากจากสตริง Unicode เช่นควรกลับgen_slug('Andrés Cortez') andres-cortezฉันควรทำอย่างไร


2
ส่งคืน 'andres' สำหรับฉัน คุณแน่ใจเหรอ
typeoneerror

ฉันคัดลอกรหัสของคุณที่นี่: writecodeonline.com/phpและมันออกandresมา คุณแน่ใจหรือว่าอินพุตของคุณเป็น "andrés" อย่างแน่นอน
nico

ใน PHP ธรรมดามันทำงาน ขออภัยฉันลืมที่จะพูดถึงว่าฟังก์ชั่นจะถูกดำเนินการจากฝั่งเซิร์ฟเวอร์ฟังก์ชั่น ajax อาจเป็นปัญหาที่เกิดขึ้นเนื่องจากคุณสมบัติตัวอักษร?
Andres SK

นี่เป็นวิธีแก้ปัญหาการทำงานที่ดีสำหรับไซริลลิก: stackoverflow.com/questions/7461406/…
d.raev

1
แทนที่จะสร้างโซลูชันของคุณเองคุณสามารถใช้ห้องสมุดที่มีอยู่เช่นgithub.com/cocur/slugifyหรือgithub.com/ausi/slug-generator
ausi

คำตอบ:


444

แทนที่จะลองเปลี่ยนมาลองดู:

public static function slugify($text)
{
  // replace non letter or digits by -
  $text = preg_replace('~[^\pL\d]+~u', '-', $text);

  // transliterate
  $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);

  // remove unwanted characters
  $text = preg_replace('~[^-\w]+~', '', $text);

  // trim
  $text = trim($text, '-');

  // remove duplicate -
  $text = preg_replace('~-+~', '-', $text);

  // lowercase
  $text = strtolower($text);

  if (empty($text)) {
    return 'n-a';
  }

  return $text;
}

สิ่งนี้อิงจากบททดสอบ Jobeet ของ Symfony


4
ไม่ preg_replace ตัวแรกจะเช็ดทุกอย่างที่ไม่ใช่ตัวอักษรหรือตัวเลข สังเกต^หลังวงเล็บเปิด - มันตรงกันข้ามการแข่งขัน
Maerlyn

11
iconvจะไม่แปลงอย่างถูกต้องหาก$textมีอักขระที่ไม่ได้มี ASCII ที่เทียบเท่ากัน ตัวอย่างเช่นiconv('utf-8', 'us-ascii//TRANSLIT', "EFI收购Cretaprint")จะกลับมา"EFI"และรั่วไหลคำเตือน
Kendall Hopkins

2
@ Maerlyn และ andufo ฉันคิดว่ามี "\" พิเศษแม้ว่าใน regex แรกถูกต้องหรือไม่ ควรเป็น '~ [^ \ pL \ d] + ~ u' หรือไม่
groovenectar

2
$text = trim($text, '-');ควรจะเป็นที่สิ้นสุดมิฉะนั้นจะกลายเป็นFoo 收 foo-นอกจากนี้Foo 收 Barจะกลายเป็นfoo--bar(ซ้ำ-ดูเหมือนซ้ำซ้อน)
rybo111

2
ไม่ไม่ไม่ไม่ไม่ทำงาน การแสดงออกครั้งแรกไม่แทนที่ตัวอักษรที่ไม่ใช่ทั้งหมด ไม่ควรยอมรับ
Romain Bruckert

44

ปรับปรุง

เนื่องจากคำตอบนี้ได้รับความสนใจฉันจึงเพิ่มคำอธิบาย

โซลูชันที่ให้มาจะแทนที่ทุกอย่างยกเว้น AZ, az, 0-9, & - (ยัติภังค์) ด้วย - (เครื่องหมายขีดกลาง) ดังนั้นจึงไม่สามารถทำงานได้อย่างถูกต้องกับอักขระ Unicode อื่น ๆ (ซึ่งเป็นอักขระที่ถูกต้องสำหรับทาก URL / สตริง) สถานการณ์ทั่วไปคือเมื่อสตริงอินพุตมีอักขระที่ไม่ใช่ภาษาอังกฤษ

ใช้โซลูชันนี้เฉพาะเมื่อคุณมั่นใจว่าสตริงอินพุตจะไม่มีอักขระ Unicode ซึ่งคุณอาจต้องการเป็นส่วนหนึ่งของเอาต์พุต / กระสุน

เช่น. "नारीशक्ति" จะกลายเป็น "----------" (ยัติภังค์ทั้งหมด) แทน "नारी-शक्ति" (ทาก URL ที่ถูกต้อง)

คำตอบเดิม

เกี่ยวกับ...

$slug = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $string)));

?


5
จริง ๆ แล้วมันทำ หัวข้อนี้แปลกมาก ... คำตอบที่ยอมรับไม่ได้ผลชนิดอื่น ๆ ของทั้งหมด ...
Romain Bruckert

มันให้คำตอบสำหรับคำถามที่ถามในชื่อซึ่งเป็นสิ่งที่ทำให้ฉันที่นี่และคำตอบนี้ซึ่งเหมาะสำหรับความต้องการของฉัน
AGB

1
เพิ่งเพิ่มไปนี้ไม่ทดสอบ 100% ฉันพบว่าคุณแทนที่ช่องว่างทั้งหมดด้วยเส้นประจากนั้นใช้ฟังก์ชันนี้เพื่อลบอักขระอื่น ๆ เพื่อแทนที่ด้วยค่าว่างเช่น ''
จาค็อบเดวิดซีคัน

strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', "Étienne")))ส่งคืน"-tienne"แทน"etienne"ดังนั้นจึงไม่สามารถใช้งานได้กับอักขระที่เน้นเสียง
Julien

1
ทากที่สร้างขึ้นด้วยวิธีนี้ไม่เคยเป็นมิตรกับ SEO หรือใช้งานง่าย นอกจากนี้พวกเขายังสร้างการชนกันจำนวนมากในหลายภาษามากกว่าการทับศัพท์ที่เหมาะสมจะทำให้เกิด

43

หากคุณติดตั้งส่วนขยายintlไว้คุณสามารถใช้ฟังก์ชันTransliterator :: transliterateเพื่อสร้างกระสุนได้อย่างง่ายดาย

<?php
$string = 'Namnet på bildtävlingen';
$slug = \Transliterator::createFromRules(
    ':: Any-Latin;'
    . ':: NFD;'
    . ':: [:Nonspacing Mark:] Remove;'
    . ':: NFC;'
    . ':: [:Punctuation:] Remove;'
    . ':: Lower();'
    . '[:Separator:] > \'-\''
)
    ->transliterate( $string );
echo $slug; // namnet-pa-bildtavlingen
?>

17
สำหรับผู้ที่เดินทางมาถึงโพสต์นี้ในปีต่อมาส่วนขยาย intl จะรวมอยู่ใน PHP ตั้งแต่ 5.3.0 php.net/manual/th/intl.requirements.php
Jessedc

25

หมายเหตุ: ฉันนำสิ่งนี้มาจาก wordpress และใช้งานได้ !!

ใช้มันแบบนี้:

echo sanitize('testing this link');

รหัส

//taken from wordpress
function utf8_uri_encode( $utf8_string, $length = 0 ) {
    $unicode = '';
    $values = array();
    $num_octets = 1;
    $unicode_length = 0;

    $string_length = strlen( $utf8_string );
    for ($i = 0; $i < $string_length; $i++ ) {

        $value = ord( $utf8_string[ $i ] );

        if ( $value < 128 ) {
            if ( $length && ( $unicode_length >= $length ) )
                break;
            $unicode .= chr($value);
            $unicode_length++;
        } else {
            if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3;

            $values[] = $value;

            if ( $length && ( $unicode_length + ($num_octets * 3) ) > $length )
                break;
            if ( count( $values ) == $num_octets ) {
                if ($num_octets == 3) {
                    $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
                    $unicode_length += 9;
                } else {
                    $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
                    $unicode_length += 6;
                }

                $values = array();
                $num_octets = 1;
            }
        }
    }

    return $unicode;
}

//taken from wordpress
function seems_utf8($str) {
    $length = strlen($str);
    for ($i=0; $i < $length; $i++) {
        $c = ord($str[$i]);
        if ($c < 0x80) $n = 0; # 0bbbbbbb
        elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
        elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
        elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
        elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
        elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b
        else return false; # Does not match any model
        for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
            if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
                return false;
        }
    }
    return true;
}

//function sanitize_title_with_dashes taken from wordpress
function sanitize($title) {
    $title = strip_tags($title);
    // Preserve escaped octets.
    $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
    // Remove percent signs that are not part of an octet.
    $title = str_replace('%', '', $title);
    // Restore octets.
    $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);

    if (seems_utf8($title)) {
        if (function_exists('mb_strtolower')) {
            $title = mb_strtolower($title, 'UTF-8');
        }
        $title = utf8_uri_encode($title, 200);
    }

    $title = strtolower($title);
    $title = preg_replace('/&.+?;/', '', $title); // kill entities
    $title = str_replace('.', '-', $title);
    $title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
    $title = preg_replace('/\s+/', '-', $title);
    $title = preg_replace('|-+|', '-', $title);
    $title = trim($title, '-');

    return $title;
}

ใน WordPress 3.9.1 (ซึ่งผมใช้) ผมต้องโทรsanitize_title_with_dashes($string, null, 'save')(หมายเหตุพารามิเตอร์เพิ่มเติม) telstra%e2%80%99s-%e2%80%98all-roles-flex%e2%80%99มิฉะนั้นคุณจะได้รับรหัสอักขระบางยุ่งเหมือน ไม่สวยมาก :-(
Simon East

1
ดูคำตอบที่เกี่ยวข้องในหน้านี้จาก @czerasz ลิงก์ไปยังล่าสุด: formatting.phpยังfunctions.php
iDev247

2
sanitizeเป็นชื่อฟังก์ชั่นที่แปลกและน่าจดจำในการสร้างกระสุน
rybo111

9

เป็นความคิดที่ดีเสมอที่จะใช้โซลูชันที่มีอยู่ซึ่งได้รับการสนับสนุนโดยนักพัฒนาระดับสูงจำนวนมาก ได้รับความนิยมมากที่สุดคือhttps://github.com/cocur/slugify ประการแรกสนับสนุนภาษามากกว่าหนึ่งภาษาและกำลังได้รับการอัปเดต

หากคุณไม่ต้องการใช้ทั้งแพ็คเกจคุณสามารถคัดลอกส่วนที่คุณต้องการ


overkill ของมัน ... เราแค่ต้องการฟังก์ชั่นที่เรียบง่ายตัวพิมพ์เล็กไม่มีช่องว่าง / ตัวละครแปลก ๆ
Sagive SEO

8

นี่คืออีกหนึ่งตัวอย่างเช่น "ชื่อเรื่องที่มีตัวอักษรแปลก ๆ ééé AX Z" กลายเป็น "ชื่อเรื่องที่มีความแปลก - ตัวอักษร - eee-axz"

/**
 * Function used to create a slug associated to an "ugly" string.
 *
 * @param string $string the string to transform.
 *
 * @return string the resulting slug.
 */
public static function createSlug($string) {

    $table = array(
            'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c',
            'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
            'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
            'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
            'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
            'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
            'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
            'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r', '/' => '-', ' ' => '-'
    );

    // -- Remove duplicated spaces
    $stripped = preg_replace(array('/\s{2,}/', '/[\t\n]/'), ' ', $string);

    // -- Returns the slug
    return strtolower(strtr($string, $table));


}

7

รุ่นที่ปรับปรุงของรหัส @Imran Omar Bukhsh (จากสาขา Wordpress (4.0) ล่าสุด):

<?php

// Add methods to slugify taken from Wordpress:
// - https://github.com/WordPress/WordPress/blob/master/wp-includes/formatting.php 
// - https://github.com/WordPress/WordPress/blob/master/wp-includes/functions.php

/**
 * Set the mbstring internal encoding to a binary safe encoding when func_overload
 * is enabled.
 *
 * When mbstring.func_overload is in use for multi-byte encodings, the results from
 * strlen() and similar functions respect the utf8 characters, causing binary data
 * to return incorrect lengths.
 *
 * This function overrides the mbstring encoding to a binary-safe encoding, and
 * resets it to the users expected encoding afterwards through the
 * `reset_mbstring_encoding` function.
 *
 * It is safe to recursively call this function, however each
 * `mbstring_binary_safe_encoding()` call must be followed up with an equal number
 * of `reset_mbstring_encoding()` calls.
 *
 * @since 3.7.0
 *
 * @see reset_mbstring_encoding()
 *
 * @param bool $reset Optional. Whether to reset the encoding back to a previously-set encoding.
 *                    Default false.
 */
function mbstring_binary_safe_encoding( $reset = false ) {
  static $encodings = array();
  static $overloaded = null;

  if ( is_null( $overloaded ) )
    $overloaded = function_exists( 'mb_internal_encoding' ) && ( ini_get( 'mbstring.func_overload' ) & 2 );

  if ( false === $overloaded )
    return;

  if ( ! $reset ) {
    $encoding = mb_internal_encoding();
    array_push( $encodings, $encoding );
    mb_internal_encoding( 'ISO-8859-1' );
  }

  if ( $reset && $encodings ) {
    $encoding = array_pop( $encodings );
    mb_internal_encoding( $encoding );
  }
}

/**
 * Reset the mbstring internal encoding to a users previously set encoding.
 *
 * @see mbstring_binary_safe_encoding()
 *
 * @since 3.7.0
 */
function reset_mbstring_encoding() {
  mbstring_binary_safe_encoding( true );
}


/**
 * Checks to see if a string is utf8 encoded.
 *
 * NOTE: This function checks for 5-Byte sequences, UTF8
 *       has Bytes Sequences with a maximum length of 4.
 *
 * @author bmorel at ssi dot fr (modified)
 * @since 1.2.1
 *
 * @param string $str The string to be checked
 * @return bool True if $str fits a UTF-8 model, false otherwise.
 */
function seems_utf8($str) {
  mbstring_binary_safe_encoding();
  $length = strlen($str);
  reset_mbstring_encoding();
  for ($i=0; $i < $length; $i++) {
    $c = ord($str[$i]);
    if ($c < 0x80) $n = 0; # 0bbbbbbb
    elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
    elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
    elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
    elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
    elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b
    else return false; # Does not match any model
    for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
      if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
        return false;
    }
  }
  return true;
}


/**
 * Encode the Unicode values to be used in the URI.
 *
 * @since 1.5.0
 *
 * @param string $utf8_string
 * @param int $length Max length of the string
 * @return string String with Unicode encoded for URI.
 */
function utf8_uri_encode( $utf8_string, $length = 0 ) {
  $unicode = '';
  $values = array();
  $num_octets = 1;
  $unicode_length = 0;

  mbstring_binary_safe_encoding();
  $string_length = strlen( $utf8_string );
  reset_mbstring_encoding();

  for ($i = 0; $i < $string_length; $i++ ) {

    $value = ord( $utf8_string[ $i ] );

    if ( $value < 128 ) {
      if ( $length && ( $unicode_length >= $length ) )
        break;
      $unicode .= chr($value);
      $unicode_length++;
    } else {
      if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3;

      $values[] = $value;

      if ( $length && ( $unicode_length + ($num_octets * 3) ) > $length )
        break;
      if ( count( $values ) == $num_octets ) {
        if ($num_octets == 3) {
          $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
          $unicode_length += 9;
        } else {
          $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
          $unicode_length += 6;
        }

        $values = array();
        $num_octets = 1;
      }
    }
  }

  return $unicode;
}


/**
 * Sanitizes a title, replacing whitespace and a few other characters with dashes.
 *
 * Limits the output to alphanumeric characters, underscore (_) and dash (-).
 * Whitespace becomes a dash.
 *
 * @since 1.2.0
 *
 * @param string $title The title to be sanitized.
 * @param string $raw_title Optional. Not used.
 * @param string $context Optional. The operation for which the string is sanitized.
 * @return string The sanitized title.
 */
function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) {
  $title = strip_tags($title);
  // Preserve escaped octets.
  $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
  // Remove percent signs that are not part of an octet.
  $title = str_replace('%', '', $title);
  // Restore octets.
  $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);

  if (seems_utf8($title)) {
    if (function_exists('mb_strtolower')) {
      $title = mb_strtolower($title, 'UTF-8');
    }
    $title = utf8_uri_encode($title, 200);
  }

  $title = strtolower($title);
  $title = preg_replace('/&.+?;/', '', $title); // kill entities
  $title = str_replace('.', '-', $title);

  if ( 'save' == $context ) {
    // Convert nbsp, ndash and mdash to hyphens
    $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title );

    // Strip these characters entirely
    $title = str_replace( array(
      // iexcl and iquest
      '%c2%a1', '%c2%bf',
      // angle quotes
      '%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba',
      // curly quotes
      '%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d',
      '%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f',
      // copy, reg, deg, hellip and trade
      '%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2',
      // acute accents
      '%c2%b4', '%cb%8a', '%cc%81', '%cd%81',
      // grave accent, macron, caron
      '%cc%80', '%cc%84', '%cc%8c',
    ), '', $title );

    // Convert times to x
    $title = str_replace( '%c3%97', 'x', $title );
  }

  $title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
  $title = preg_replace('/\s+/', '-', $title);
  $title = preg_replace('|-+|', '-', $title);
  $title = trim($title, '-');

  return $title;
}

$title = '#PFW Alexander McQueen Spring/Summer 2015';
echo "title -> slug: \n". $title ." -> ". sanitize_title_with_dashes($title);
echo "\n\n";
$title = '«GQ»: Elyas M\'Barek gehört zu Männern des Jahres';
echo "title -> slug: \n". $title ." -> ". sanitize_title_with_dashes($title);

ดูออนไลน์ตัวอย่างเช่น


ลิงก์ไปยังล่าสุด: formatting.phpยังfunctions.php
iDev247

ตัวอย่างที่สองล้มเหลวสำหรับฉันผลตอบแทน%c2%abgq%c2%bb-elyas-mbarek-geh%c3%b6rt-zu-m%c3%a4nnern-des-jahres
สแลม

6
public static function slugify ($text) {

    $replace = [
        '&lt;' => '', '&gt;' => '', '&#039;' => '', '&amp;' => '',
        '&quot;' => '', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä'=> 'Ae',
        '&Auml;' => 'A', 'Å' => 'A', 'Ā' => 'A', 'Ą' => 'A', 'Ă' => 'A', 'Æ' => 'Ae',
        'Ç' => 'C', 'Ć' => 'C', 'Č' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Ď' => 'D', 'Đ' => 'D',
        'Ð' => 'D', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ē' => 'E',
        'Ę' => 'E', 'Ě' => 'E', 'Ĕ' => 'E', 'Ė' => 'E', 'Ĝ' => 'G', 'Ğ' => 'G',
        'Ġ' => 'G', 'Ģ' => 'G', 'Ĥ' => 'H', 'Ħ' => 'H', 'Ì' => 'I', 'Í' => 'I',
        'Î' => 'I', 'Ï' => 'I', 'Ī' => 'I', 'Ĩ' => 'I', 'Ĭ' => 'I', 'Į' => 'I',
        'İ' => 'I', 'IJ' => 'IJ', 'Ĵ' => 'J', 'Ķ' => 'K', 'Ł' => 'K', 'Ľ' => 'K',
        'Ĺ' => 'K', 'Ļ' => 'K', 'Ŀ' => 'K', 'Ñ' => 'N', 'Ń' => 'N', 'Ň' => 'N',
        'Ņ' => 'N', 'Ŋ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O',
        'Ö' => 'Oe', '&Ouml;' => 'Oe', 'Ø' => 'O', 'Ō' => 'O', 'Ő' => 'O', 'Ŏ' => 'O',
        'Œ' => 'OE', 'Ŕ' => 'R', 'Ř' => 'R', 'Ŗ' => 'R', 'Ś' => 'S', 'Š' => 'S',
        'Ş' => 'S', 'Ŝ' => 'S', 'Ș' => 'S', 'Ť' => 'T', 'Ţ' => 'T', 'Ŧ' => 'T',
        'Ț' => 'T', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'Ue', 'Ū' => 'U',
        '&Uuml;' => 'Ue', 'Ů' => 'U', 'Ű' => 'U', 'Ŭ' => 'U', 'Ũ' => 'U', 'Ų' => 'U',
        'Ŵ' => 'W', 'Ý' => 'Y', 'Ŷ' => 'Y', 'Ÿ' => 'Y', 'Ź' => 'Z', 'Ž' => 'Z',
        'Ż' => 'Z', 'Þ' => 'T', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a',
        'ä' => 'ae', '&auml;' => 'ae', 'å' => 'a', 'ā' => 'a', 'ą' => 'a', 'ă' => 'a',
        'æ' => 'ae', 'ç' => 'c', 'ć' => 'c', 'č' => 'c', 'ĉ' => 'c', 'ċ' => 'c',
        'ď' => 'd', 'đ' => 'd', 'ð' => 'd', 'è' => 'e', 'é' => 'e', 'ê' => 'e',
        'ë' => 'e', 'ē' => 'e', 'ę' => 'e', 'ě' => 'e', 'ĕ' => 'e', 'ė' => 'e',
        'ƒ' => 'f', 'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'ĥ' => 'h',
        'ħ' => 'h', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ī' => 'i',
        'ĩ' => 'i', 'ĭ' => 'i', 'į' => 'i', 'ı' => 'i', 'ij' => 'ij', 'ĵ' => 'j',
        'ķ' => 'k', 'ĸ' => 'k', 'ł' => 'l', 'ľ' => 'l', 'ĺ' => 'l', 'ļ' => 'l',
        'ŀ' => 'l', 'ñ' => 'n', 'ń' => 'n', 'ň' => 'n', 'ņ' => 'n', 'ʼn' => 'n',
        'ŋ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'oe',
        '&ouml;' => 'oe', 'ø' => 'o', 'ō' => 'o', 'ő' => 'o', 'ŏ' => 'o', 'œ' => 'oe',
        'ŕ' => 'r', 'ř' => 'r', 'ŗ' => 'r', 'š' => 's', 'ù' => 'u', 'ú' => 'u',
        'û' => 'u', 'ü' => 'ue', 'ū' => 'u', '&uuml;' => 'ue', 'ů' => 'u', 'ű' => 'u',
        'ŭ' => 'u', 'ũ' => 'u', 'ų' => 'u', 'ŵ' => 'w', 'ý' => 'y', 'ÿ' => 'y',
        'ŷ' => 'y', 'ž' => 'z', 'ż' => 'z', 'ź' => 'z', 'þ' => 't', 'ß' => 'ss',
        'ſ' => 'ss', 'ый' => 'iy', 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G',
        'Д' => 'D', 'Е' => 'E', 'Ё' => 'YO', 'Ж' => 'ZH', 'З' => 'Z', 'И' => 'I',
        'Й' => 'Y', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O',
        'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F',
        'Х' => 'H', 'Ц' => 'C', 'Ч' => 'CH', 'Ш' => 'SH', 'Щ' => 'SCH', 'Ъ' => '',
        'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'YU', 'Я' => 'YA', 'а' => 'a',
        'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo',
        'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l',
        'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's',
        'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch',
        'ш' => 'sh', 'щ' => 'sch', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e',
        'ю' => 'yu', 'я' => 'ya'
    ];

    // make a human readable string
    $text = strtr($text, $replace);

    // replace non letter or digits by -
    $text = preg_replace('~[^\\pL\d.]+~u', '-', $text);

    // trim
    $text = trim($text, '-');

    // remove unwanted characters
    $text = preg_replace('~[^-\w.]+~', '', $text);

    $text = strtolower($text);

    return $text;
}

4
สวัสดี Nady ยินดีต้อนรับสู่ SO คำตอบที่ไม่ใช้รหัสเท่านั้นที่ทำให้หมดกำลังใจเพราะพวกเขาไม่ได้สอนวิธีการใช้รหัสให้ผู้อื่น คุณสามารถแก้ไขโพสต์ของคุณเพื่ออธิบายว่าโค้ดตัวอย่างของคุณทำอะไรและตอบคำถามได้อย่างไร ขอบคุณ
ทิมมาโลน

4

อย่าใช้ preg_replace สำหรับสิ่งนี้ มีฟังก์ชั่น php ที่สร้างขึ้นสำหรับงานเท่านั้น: strtr () http://php.net/manual/en/function.strtr.php

นำมาจากความคิดเห็นในลิงค์ด้านบน (และฉันทดสอบด้วยตัวเองมันใช้งานได้:

function normalize ($string) {
    $table = array(
        'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c',
        'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
        'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
        'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
        'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
        'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
        'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
        'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r',
    );

    return strtr($string, $table);
}

การแปลก็โอเคปัญหาคือว่าฉันใช้ฟังก์ชั่นผ่านการโทร ajax และมันไม่ทำงานที่นั่น = (
Andres SK

@andufo คุณต้องตั้งชุดอักขระในคำขอ ajax
Silvio Delgado

4

ฉันใช้:

function slugify($text)
{ 
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
    return strtolower(preg_replace('/[^A-Za-z0-9-]+/', '-', $text));
}

ทางเลือกเดียวคือตัวอักษรซีริลลิกจะไม่ถูกแปลงและฉันกำลังค้นหาวิธีแก้ปัญหาที่ไม่นาน str_replace สำหรับอักขระซิริลลิกทุกตัว


iconv ไม่ได้ติดตั้งบนเซิร์ฟเวอร์จำนวนมาก ทางออกสำหรับการแปลงอักขระใด ๆ คือการใช้set_locale('cyrillic.UTF-8')ก่อน ค่าที่แน่นอนขึ้นอยู่กับตำแหน่งที่ตั้งของคุณ
Daniel W.

3

ฉันไม่รู้ว่าจะใช้อันไหนดังนั้นฉันจึงสร้างบัลลังก์ด่วนบน phptester.net

<?php

// First test
// https://stackoverflow.com/a/42740874/10232729
function slugify(STRING $string, STRING $separator = '-'){
    
    $accents_regex = '~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i';
    $special_cases = [ '&' => 'and', "'" => ''];
    $string = mb_strtolower( trim( $string ), 'UTF-8' );
    $string = str_replace( array_keys($special_cases), array_values( $special_cases), $string );
    $string = preg_replace( $accents_regex, '$1', htmlentities( $string, ENT_QUOTES, 'UTF-8' ) );
    $string = preg_replace('/[^a-z0-9]/u', $separator, $string);
    
    return preg_replace('/['.$separator.']+/u', $separator, $string);
}

// Second test
// https://stackoverflow.com/a/13331948/10232729
function slug(STRING $string, STRING $separator = '-'){
    
    $string = transliterator_transliterate('Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();', $string);
        
    return str_replace(' ', $separator, $string);;
}

// Third test - My choice
// https://stackoverflow.com/a/38066136/10232729
function slugbis($text){

    $replace = [
        '<' => '', '>' => '', '-' => ' ', '&' => '',
        '"' => '', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä'=> 'Ae',
        'Ä' => 'A', 'Å' => 'A', 'Ā' => 'A', 'Ą' => 'A', 'Ă' => 'A', 'Æ' => 'Ae',
        'Ç' => 'C', 'Ć' => 'C', 'Č' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Ď' => 'D', 'Đ' => 'D',
        'Ð' => 'D', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ē' => 'E',
        'Ę' => 'E', 'Ě' => 'E', 'Ĕ' => 'E', 'Ė' => 'E', 'Ĝ' => 'G', 'Ğ' => 'G',
        'Ġ' => 'G', 'Ģ' => 'G', 'Ĥ' => 'H', 'Ħ' => 'H', 'Ì' => 'I', 'Í' => 'I',
        'Î' => 'I', 'Ï' => 'I', 'Ī' => 'I', 'Ĩ' => 'I', 'Ĭ' => 'I', 'Į' => 'I',
        'İ' => 'I', 'IJ' => 'IJ', 'Ĵ' => 'J', 'Ķ' => 'K', 'Ł' => 'K', 'Ľ' => 'K',
        'Ĺ' => 'K', 'Ļ' => 'K', 'Ŀ' => 'K', 'Ñ' => 'N', 'Ń' => 'N', 'Ň' => 'N',
        'Ņ' => 'N', 'Ŋ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O',
        'Ö' => 'Oe', 'Ö' => 'Oe', 'Ø' => 'O', 'Ō' => 'O', 'Ő' => 'O', 'Ŏ' => 'O',
        'Œ' => 'OE', 'Ŕ' => 'R', 'Ř' => 'R', 'Ŗ' => 'R', 'Ś' => 'S', 'Š' => 'S',
        'Ş' => 'S', 'Ŝ' => 'S', 'Ș' => 'S', 'Ť' => 'T', 'Ţ' => 'T', 'Ŧ' => 'T',
        'Ț' => 'T', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'Ue', 'Ū' => 'U',
        'Ü' => 'Ue', 'Ů' => 'U', 'Ű' => 'U', 'Ŭ' => 'U', 'Ũ' => 'U', 'Ų' => 'U',
        'Ŵ' => 'W', 'Ý' => 'Y', 'Ŷ' => 'Y', 'Ÿ' => 'Y', 'Ź' => 'Z', 'Ž' => 'Z',
        'Ż' => 'Z', 'Þ' => 'T', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a',
        'ä' => 'ae', 'ä' => 'ae', 'å' => 'a', 'ā' => 'a', 'ą' => 'a', 'ă' => 'a',
        'æ' => 'ae', 'ç' => 'c', 'ć' => 'c', 'č' => 'c', 'ĉ' => 'c', 'ċ' => 'c',
        'ď' => 'd', 'đ' => 'd', 'ð' => 'd', 'è' => 'e', 'é' => 'e', 'ê' => 'e',
        'ë' => 'e', 'ē' => 'e', 'ę' => 'e', 'ě' => 'e', 'ĕ' => 'e', 'ė' => 'e',
        'ƒ' => 'f', 'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'ĥ' => 'h',
        'ħ' => 'h', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ī' => 'i',
        'ĩ' => 'i', 'ĭ' => 'i', 'į' => 'i', 'ı' => 'i', 'ij' => 'ij', 'ĵ' => 'j',
        'ķ' => 'k', 'ĸ' => 'k', 'ł' => 'l', 'ľ' => 'l', 'ĺ' => 'l', 'ļ' => 'l',
        'ŀ' => 'l', 'ñ' => 'n', 'ń' => 'n', 'ň' => 'n', 'ņ' => 'n', 'ʼn' => 'n',
        'ŋ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'oe',
        'ö' => 'oe', 'ø' => 'o', 'ō' => 'o', 'ő' => 'o', 'ŏ' => 'o', 'œ' => 'oe',
        'ŕ' => 'r', 'ř' => 'r', 'ŗ' => 'r', 'š' => 's', 'ù' => 'u', 'ú' => 'u',
        'û' => 'u', 'ü' => 'ue', 'ū' => 'u', 'ü' => 'ue', 'ů' => 'u', 'ű' => 'u',
        'ŭ' => 'u', 'ũ' => 'u', 'ų' => 'u', 'ŵ' => 'w', 'ý' => 'y', 'ÿ' => 'y',
        'ŷ' => 'y', 'ž' => 'z', 'ż' => 'z', 'ź' => 'z', 'þ' => 't', 'ß' => 'ss',
        'ſ' => 'ss', 'ый' => 'iy', 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G',
        'Д' => 'D', 'Е' => 'E', 'Ё' => 'YO', 'Ж' => 'ZH', 'З' => 'Z', 'И' => 'I',
        'Й' => 'Y', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O',
        'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F',
        'Х' => 'H', 'Ц' => 'C', 'Ч' => 'CH', 'Ш' => 'SH', 'Щ' => 'SCH', 'Ъ' => '',
        'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'YU', 'Я' => 'YA', 'а' => 'a',
        'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo',
        'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l',
        'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's',
        'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch',
        'ш' => 'sh', 'щ' => 'sch', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e',
        'ю' => 'yu', 'я' => 'ya'
    ];

    // make a human readable string
    $text = strtr($text, $replace);

    // replace non letter or digits by -
    $text = preg_replace('~[^\pL\d.]+~u', '-', $text);

    // trim
    $text = trim($text, '-');

    // remove unwanted characters
    $text = preg_replace('~[^-\w.]+~', '', $text);

    return strtolower($text);
}

// Fourth test
// https://stackoverflow.com/a/2955521/10232729
function slugagain($string){
    
    $table = [
        'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c',
        'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
        'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
        'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
        'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
        'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
        'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
        'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r', ' '=>'-'
    ];

    return strtr($string, $table);
}

// Fifth test
// https://stackoverflow.com/a/27396804/10232729
function slugifybis($url){
    $url = trim($url);

    $url = str_replace(' ', '-', $url);
    $url = str_replace('/', '-slash-', $url);
    
    return rawurlencode($url);
}

// Sixth and last test
// https://stackoverflow.com/a/39442034/10232729
setlocale( LC_ALL, "en_US.UTF8" );  
function slugifyagain($string){
    
    $string = iconv('utf-8', 'us-ascii//translit//ignore', $string); // transliterate
    $string = str_replace("'", '', $string);
    $string = preg_replace('~[^\pL\d]+~u', '-', $string); // replace non letter or non digits by "-"
    $string = preg_replace('~[^-\w]+~', '', $string); // remove unwanted characters
    $string = preg_replace('~-+~', '-', $string); // remove duplicate "-"
    $string = trim($string, '-'); // trim "-"
    $string = trim($string); // trim
    $string = mb_strtolower($string, 'utf-8'); // lowercase
    
    return urlencode($string); // safe;
};

$string = $newString = "¿ Àñdréß l'affreux ğarçon & nøël en forêt !";

$max = 10000;

echo '<pre>';
echo 'Beginning :';
echo '<br />';
echo '<br />';    
echo '> Slugging '.$max.' iterations of following :';
echo '<br />';
echo '>> ' . $string;
echo '<br />';  
echo '<br />';
echo 'Output results :';
echo '<br />';
echo '<br />';  

$start = microtime(true);

for($i = 0 ; $i < $max ; $i++){
    
    $newString = slugify($string);
}

$time = (microtime(true) - $start) * 1000;

echo '> First test passed in **' . round($time, 2) . 'ms**';
echo '<br />';  
echo '>> Result : ' . $newString;
echo '<br />';
echo '<br />';

$start = microtime(true);

for($i = 0 ; $i < $max ; $i++){
    
    $newString = slug($string);
}

$time = (microtime(true) - $start) * 1000;

echo '> Second test passed in **' . round($time, 2) . 'ms**';
echo '<br />';
echo '>> Result : ' . $newString;
echo '<br />';
echo '<br />';

$start = microtime(true);

for($i = 0 ; $i < $max ; $i++){
    
    $newString = slugbis($string);
}

$time = (microtime(true) - $start) * 1000;

echo '> Third test passed in **' . round($time, 2) . 'ms**';
echo '<br />';
echo '>> Result : ' . $newString;
echo '<br />';
echo '<br />';

$start = microtime(true);

for($i = 0 ; $i < $max ; $i++){
    
    $newString = slugagain($string);
}

$time = (microtime(true) - $start) * 1000;

echo '> Fourth test passed in **' . round($time, 2) . 'ms**';
echo '<br />';
echo '>> Result : ' . $newString;
echo '<br />';
echo '<br />';

$start = microtime(true);

for($i = 0 ; $i < $max ; $i++){
    
    $newString = slugifybis($string);
}

$time = (microtime(true) - $start) * 1000;

echo '> Fifth test passed in **' . round($time, 2) . 'ms**';
echo '<br />';
echo '>> Result : ' . $newString;
echo '<br />';
echo '<br />';

$start = microtime(true);

for($i = 0 ; $i < $max ; $i++){
    
    $newString = slugifyagain($string);
}

$time = (microtime(true) - $start) * 1000;

echo '> Sixth test passed in **' . round($time, 2) . 'ms**';
echo '<br />';
echo '>> Result : ' . $newString;
echo '</pre>';

เริ่มต้น:

Slugging 10,000 การวนซ้ำของต่อไปนี้:

l Àñdréß l'affreux ğarçon & nøël en forêt!

ผลลัพธ์ที่ได้:

การทดสอบครั้งแรกผ่านไปใน120.78ms

ผลลัพธ์: -iquest-andresz-laffreux-arcon-and-noel-en-foret-

การทดสอบครั้งที่สองผ่านไปแล้วใน3883.82ms

ผลลัพธ์: - andreß-laffreux-garcon - nøel-en-foret-

การทดสอบครั้งที่สามผ่านใน56.83ms

ผลลัพธ์: andress-l-affreux-garcon-noel-en-foret

การทดสอบครั้งที่สี่ผ่านไป18.93ms

ผลลัพธ์: nd -AndreSs-l'affreux-ğarcon - & - noel-en-foret-!

การทดสอบครั้งที่ห้าผ่านไปในเวลา 6.45ms

ผลลัพธ์:% C2% BF-% C3% 80% C3% B1dr% C3% A9% C3% 9F-l% 27affreux-% C4% 9Far% C3% A7on-% 26-n% C3% B8% C3% ABl- en-สำหรับ% C3% AAt-% 21

การทดสอบครั้งที่หกผ่านไปใน112.42ms

ผลลัพธ์: andress-laffreux-garcon-n-el-en-foret

การทดสอบเพิ่มเติมที่จำเป็น

แก้ไข: ทดสอบซ้ำน้อยลง

เริ่มต้น:

Slugging 100 การวนซ้ำของต่อไปนี้:

l Àñdréß l'affreux ğarçon & nøël en forêt!

ผลลัพธ์ที่ได้:

การทดสอบครั้งแรกผ่านไปใน1.72ms

ผลลัพธ์: -iquest-andresz-laffreux-arcon-and-noel-en-foret-

การทดสอบครั้งที่สองผ่านไปใน48.59ms

ผลลัพธ์: - andreß-laffreux-garcon - nøel-en-foret-

การทดสอบครั้งที่สามผ่านไป0.91ms

ผลลัพธ์: andress-l-affreux-garcon-noel-en-foret

การทดสอบที่สี่ผ่านไปใน0.3ms

ผลลัพธ์: nd -AndreSs-l'affreux-ğarcon - & - noel-en-foret-!

การทดสอบครั้งที่ห้าผ่านไป0.14ms

ผลลัพธ์:% C2% BF-% C3% 80% C3% B1dr% C3% A9% C3% 9F-l% 27affreux-% C4% 9Far% C3% A7on-% 26-n% C3% B8% C3% ABl- en-สำหรับ% C3% AAt-% 21

การทดสอบที่หกผ่านไปใน1.4ms

ผลลัพธ์: andress-laffreux-garcon-n-el-en-foret


คุณคือ MVP
bbosternak

2

คุณอาจจะมีลักษณะที่Normalizer::normalize(), ดูที่นี่ เพียงแค่ต้องโหลดโมดูล intl สำหรับ PHP


2

สิ่งที่เกี่ยวกับการใช้สิ่งที่มีอยู่แล้วในแกน

//Clean non UTF-8 characters    
Mage::getHelper('core/string')->cleanString($str)

หรือหนึ่งในวิธีการเขียน url / url หลัก ..


1
ขอบคุณสำหรับโซลูชัน
คุณภาพเยี่ยม

1

เนื่องจากgTLDsและIDNsมีการใช้งานมากขึ้นเรื่อย ๆ ฉันจึงไม่สามารถดูได้ว่าทำไม URL ไม่ควรมีAndrés

เพียง rawurlencode $ URL ที่คุณต้องการแทน เบราว์เซอร์ส่วนใหญ่แสดงตัวอักษร UTF-8 ใน URL (ไม่ใช่ IE6 แบบโบราณ) และ bit.ly / goo.gl สามารถใช้ในการทำให้สั้นในกรณีเช่นรัสเซียและอารบิกหากต้องการเพื่อการโฆษณาหรือเพียงแค่เขียนลงโฆษณา เหมือนที่ผู้ใช้จะเขียนไว้ใน URL ของเบราว์เซอร์

ความแตกต่างเพียงอย่างเดียวคือช่องว่าง "" คุณควรแทนที่ด้วย "-" และ "/" ถ้าคุณไม่ต้องการอนุญาต

<?php
function slugify($url)
{
    $url = trim($url);

    $url = str_replace(" ","-",$url);
    $url = str_replace("/","-slash-",$url);
    $url = rawurlencode($url);
}
?>

url เป็นเข้ารหัส http://www.hurtta.com/RU/%D0%9F%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B/

URL ตามที่เขียนไว้http://www.hurtta.com/RU/Продукты/


1

ฉันเขียนสิ่งนี้ตามการตอบสนองของ Maerlyn ฟังก์ชั่นนี้จะทำงานโดยไม่คำนึงถึงการเข้ารหัสตัวอักษรในหน้า มันจะไม่เปลี่ยนเครื่องหมายคำพูดเดี่ยว ๆ เป็นเครื่องหมายขีดกลาง :)

function slugify ($string) {
    $string = utf8_encode($string);
    $string = iconv('UTF-8', 'ASCII//TRANSLIT', $string);   
    $string = preg_replace('/[^a-z0-9- ]/i', '', $string);
    $string = str_replace(' ', '-', $string);
    $string = trim($string, '-');
    $string = strtolower($string);

    if (empty($string)) {
        return 'n-a';
    }

    return $string;
}

ใช่แล้วอันนี้ใช้งานได้จริงนั่นคือการหลอกฉันให้เปลี่ยนเครื่องหมายอัญประกาศเดี่ยว / คำพูดเดี่ยวเป็นเครื่องหมายยัติภังค์ ขอบคุณ.
GibsonFX

1

บน localhost ของฉันทุกอย่างก็โอเค แต่บนเซิร์ฟเวอร์มันช่วยฉัน "set_locale" และ "utf-8" ที่ "mb_strtolower"

<?
setlocale( LC_ALL, "en_US.UTF8" );
function slug( $string )
{
    $string = iconv( "utf-8", "us-ascii//translit//ignore", $string ); // transliterate
    $string = str_replace( "'", "", $string );
    $string = preg_replace( "~[^\pL\d]+~u", "-", $string ); // replace non letter or non digits by "-"
    $string = preg_replace( "~[^-\w]+~", "", $string ); // remove unwanted characters
    $string = preg_replace( "~-+~", "-", $string ); // remove duplicate "-"
    $string = trim( $string, "-" ); // trim "-"
    $string = trim( $string ); // trim
    $string = mb_strtolower( $string, "utf-8" ); // lowercase
    $string = urlencode( $string ); // safe
    return $string;
};
?>

สำหรับละตินěščřžýáíéúůóขยาย
จิริดวอรัก

1

วิธีที่หรูหราที่สุดที่ฉันคิดคือใช้ Behat \ Transliterator \ Transliterator

ฉันต้องขยายคลาสนี้ด้วยคลาสของคุณเพราะมันเป็นบทคัดย่อบางอย่างเช่นนี้:

<?php
use Behat\Transliterator\Transliterator;

class Urlizer extends Transliterator
{
}

จากนั้นใช้เพียง:

$text = "Master Ápiu";
$urlizer = new Urlizer();
$slug = $urlizer->transliterate($slug, "-");
echo $slug; // master-apiu

แน่นอนคุณควรใส่สิ่งนี้ไว้ในผู้แต่งเพลงด้วย

composer require behat/transliterator

ข้อมูลเพิ่มเติมที่นี่https://github.com/Behat/Transliterator


1

มีทางออกที่ดีที่นี่ที่เกี่ยวข้องกับตัวละครพิเศษเช่นกัน

Texto Fantástico => texto-fantastico

function slugify( $string, $separator = '-' ) {
    $accents_regex = '~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i';
    $special_cases = array( '&' => 'and', "'" => '');
    $string = mb_strtolower( trim( $string ), 'UTF-8' );
    $string = str_replace( array_keys($special_cases), array_values( $special_cases), $string );
    $string = preg_replace( $accents_regex, '$1', htmlentities( $string, ENT_QUOTES, 'UTF-8' ) );
    $string = preg_replace("/[^a-z0-9]/u", "$separator", $string);
    $string = preg_replace("/[$separator]+/u", "$separator", $string);
    return $string;
}

ผู้แต่ง: Natxet


1

นี่อาจเป็นวิธีที่จะทำเช่นกัน แรงบันดาลใจจากลิงค์เหล่านี้ผู้เชี่ยวชาญแลกเปลี่ยนและalinalexander

function slugifier($txt){

   /* Get rid of accented characters */
   $search = explode(",","ç,æ,œ,á,é,í,ó,ú,à,è,ì,ò,ù,ä,ë,ï,ö,ü,ÿ,â,ê,î,ô,û,å,e,i,ø,u");
   $replace = explode(",","c,ae,oe,a,e,i,o,u,a,e,i,o,u,a,e,i,o,u,y,a,e,i,o,u,a,e,i,o,u");
   $txt = str_replace($search, $replace, $txt);

   /* Lowercase all the characters */
   $txt = strtolower($txt);

   /* Avoid whitespace at the beginning and the ending */
   $txt = trim($txt);

   /* Replace all the characters that are not in a-z or 0-9 by a hyphen */
   $txt = preg_replace("/[^a-z0-9]/", "-", $txt);
   /* Remove hyphen anywhere it's more than one */
   $txt = preg_replace("/[\-]+/", '-', $txt);
   return $txt;   
}

0

เนื่องจากฉันเคยเห็นวิธีการมากมายที่นี่ แต่ฉันพบวิธีที่ง่ายที่สุดสำหรับตัวเองบางทีมันจะช่วยใครซักคน

$slug = strtolower(preg_replace('/[^a-zA-Z0-9\-]/', '',preg_replace('/\s+/', '-', $string) ));

0

สำหรับผมตัวแปรนี้เป็นที่สมบูรณ์แบบยังจะเปลี่ยนไป& andนี่คือรหัส:

function dSlug($string) {
    return strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1',htmlentities(preg_replace('/[&]/', ' and ', $title), ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8')), '-'));
}`
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.