Benim işlevini geliştirmek: SEO dostu başlığı oluşturmak

6 Cevap php

Ben SEO dostu başlıkları oluşturmak için bu işlevi kullanıyorum, ama geliştirilebilir düşünüyorum, herkes denemek ister misin? Bu bir şeyler yapar: Ortak aksanlı harfleri temizler, bir "yasak" dizisine karşı kontrol edin ve kullanımı başlıkların bir veritabanı karşı isteğe bağlı kontrol.

	/**
	* Recursive function that generates a unique "this-is-the-title123" string for use in URL.
	* Checks optionally against $table and $field and the array $forbidden to make sure it's unique.
	* Usage: the resulting string should be saved in the db with the object. 
	*/
	function seo_titleinurl_generate($title, $forbidden = FALSE, $table = FALSE, $field = FALSE)
	{
		## 1. parse $title
		$title = clean($title, "oneline"); // remove tags and such

		$title = ereg_replace(" ", "-", $title); // replace spaces by "-"
		$title = ereg_replace("á", "a", $title); // replace special chars
		$title = ereg_replace("í", "i", $title); // replace special chars
		$title = ereg_replace("ó", "o", $title); // replace special chars
		$title = ereg_replace("ú", "u", $title); // replace special chars
		$title = ereg_replace("ñ", "n", $title); // replace special chars
		$title = ereg_replace("Ñ", "n", $title); // replace special chars

		$title = strtolower(trim($title)); // lowercase
	  	$title = preg_replace("/([^a-zA-Z0-9_-])/",'',$title); // only keep standard latin letters and numbers, hyphens and dashes

		## 2. check against db (optional)
		if ($table AND $field)
		{
			$sql = "SELECT * FROM $table WHERE $field = '" . addslashes($title) . "'";
			$res = mysql_debug_query($sql);
			if (mysql_num_rows($res) > 0)
			{
				// already taken. So recursively adjust $title and try again.
				$title = append_increasing_number($title);
				$title = seo_titleinurl_generate($title, $forbidden, $table, $field);
			}
		}

		## 3. check against $forbidden array
		if ($forbidden)
		{
			while (list ($key, $val) = each($forbidden))
			{
				// $val is the forbidden string
				if ($title == $val)
				{
					$title = append_increasing_number($title);
					$title = seo_titleinurl_generate($title, $forbidden, $table, $field);
				}
			}
		}
		return $title;
	}
	/**
	* Function that appends an increasing number to a string, for example "peter" becomes "peter1" and "peter129" becomes "peter130".
	* (To improve, this function could be made recursive to deal with numbers over 99999.)
	*/
	function append_increasing_number($title)
	{
		##. 1. Find number at end of string.
		$last1 = substr($title, strlen($title)-1, 1);
		$last2 = substr($title, strlen($title)-2, 2);
		$last3 = substr($title, strlen($title)-3, 3);
		$last4 = substr($title, strlen($title)-4, 4);
		$last5 = substr($title, strlen($title)-5, 5); // up to 5 numbers (ie. 99999)

		if (is_numeric($last5))
		{
			$last5++; // +1
			$title = substr($title, 0, strlen($title)-5) . $last5;
		} elseif (is_numeric($last4))
		{
			$last4++; // +1
			$title = substr($title, 0, strlen($title)-4) . $last4;
		} elseif (is_numeric($last3))
		{
			$last3++; // +1
			$title = substr($title, 0, strlen($title)-3) . $last3;
		} elseif (is_numeric($last2))
		{
			$last2++; // +1
			$title = substr($title, 0, strlen($title)-2) . $last2;
		} elseif (is_numeric($last1))
		{
			$last1++; // +1
			$title = substr($title, 0, strlen($title)-1) . $last1;
		} else 
		{
			$title = $title . "1"; // append '1'	
		}

		return $title;
	}

6 Cevap

Eğer (muhtemelen çağrı kodunun ardından DB ekleyecektir) iade değilse o zaman, başlık daha önce kullanılmış olup olmadığını görmek için bir SELECT yapıyoruz çünkü bir yarış durumu var gibi görünüyor. Ne başka bir işlem aynı şeyi yapar, ancak SELECT ve INSERT arasında eklerse? Sizin eklemek başarısız olur. Muhtemelen gerek SEO dostu URL sorunu önlemek için (StackOverflow bunu nasıl benzer SEO dostu isim, daha yüksek bir düzey yolunda belki de bir "dizin") URL bazı garantili benzersiz simge eklemek gerekir tüm benzersiz olması.

Ben de yerine bir devin / else if onu anlamaya, programlı ucunda kaç sayı belirlemek ve uygun bir iş var ... append_increasing_number() function daha okunabilir olması için yeniden olurdu. Kod daha hızlı belki, net basit, ve olacaktır.

Str_replace önerileri üzerinde mükemmel. Ayrıca, tek bir satır ile son işlev değiştirebilirsiniz:

function append_increasing_number($title) {
  return preg_replace('@([0-9]+)$@e', '\1+1', $title);
}

Sen daha iyi yapmak ve tamamen sorgu-in-a-döngü fikri kaldırın, ve benzeri bir şey yapabilir

"SELECT MAX($field) + 1 FROM $table WHERE $field LIKE '" . mysql_escape_string(preg_replace('@[0-9]+$@', '', $title)) . "%'";

Böyle bir döngü içinde seçer Koşu sadece çirkin.

Diğerleri (özellikle sonek artırma ve bir döngü içinde / özyinelemeli SQL sorguları yürütme ile ilgili) önemli noktaları çoğu isabet var gibi görünüyor, ama ben yine de yapılmış olabilir büyük gelişmeler bir çift görüyorum.

Öncelikle, kendi Aksanları-to-ASCII değiştirmeleri ile gelip çalışırken rahatsız etmeyin; Tüm bunları yakalamak asla ve daha iyi araçlar var. Özellikle, iconv 's "DAMGAÇEVİRİSİ" özelliği dikkatinizi yönlendirin. Aşağıdaki gibi düz eski 7-bitlik ASCII UTF-8 (veya ne olursa olsun kodlama kitaplarınızın için kullanılır) gelen dönüştürebilirsiniz:

$title = strtolower(strip(clean($title)));
$title = iconv('UTF-8', 'ASCII//TRANSLIT', $title);
$title = str_replace("'", "", $title);
$title = preg_replace(array("/\W+/", "/^\W+|\W+$/"), array("-", ""), $title);

Bu da uzay-to-dash değiştirme trim() denilen önce orijinal kodunda bir hata düzeltmeleri ve tek tire ile non-letter/-number/-underscores tüm çalışır yerini unutmayın. Örneğin, " Héllo, world's peoples!" olur "hello-worlds-peoples". Bu, tüm bölüm 1. değiştirir.

İkinci olarak, $forbidden döngü daha verimli olması ve özyineleme ortadan kaldırmak için yeniden olabilir:

if ($forbidden)
{
    while (in_array($title, $forbidden))
    {
        $title = append_increasing_number($title);
    }
}

Bu bölüm 3 değiştirir.

Karim79 cevabı takiben, ilk bölümü daha okunabilir ve bu gibi korumak için kolay yapılabilir:

Değiştirmek

$title = ereg_replace(" ", "-", $title); // replace spaces by "-"
$title = ereg_replace("á", "a", $title); // replace special chars
$title = ereg_replace("í", "i", $title); // replace special chars

ile

$replacements = array(
  ' ' => '-',
  'á' => 'a',
  'í' => 'i'
);
$title = str_replace(array_keys($replacements, array_values($replacements), $title);

Append_increasing_number () kullanılan son bölümü kötü görünüyor. Muhtemelen tüm işlevini silmek ve sadece böyle bir şey yapabilir

while ($i < 99999){
//check for existance of $title . $i; if doesn't exist - insert!
}

Sen kaybedebilir:

$title = ereg_replace(" ", "-", $title);

Ve daha hızlı bu satırların yerine str_replace():

$title = str_replace(" ", "-", $title);

Için PHP kılavuzu sayfasından str_replace():

If you don't need fancy replacing rules (like regular expressions), you should always use this function instead of ereg_replace() or preg_replace().

EDIT:

Ben sadece sonunda basamak sayısında herhangi bir sınır ile, tam olarak aynı şeyi yapar (ve :) güzelmiş, sizin append_increasing_number($title) fonksiyonu geliştirilmiş:

function append_increasing_number($title)
{
    $counter = strlen($title);
    while(is_numeric(substr($title, $counter - 1, 1))) {
        $counter--;
    }
    $numberPart = (int) substr($title,$counter,strlen($title) - 1);
    $incrementedNumberPart = $numberPart + 1;
    return str_replace($numberPart, $incrementedNumberPart, $title);
}

Ayrıca yapabilirsin str_replace ile diziler kullanmak () yani olabilir

$replace = array(' ', 'á');
$with = array('-', 'a');

Dizideki konumu uygun olmalıdır.

Bu bir kaç satır dışarı tıraş ve birkaç millisceonds gerekir.

Ayrıca ne sıklıkta, `'" tırnak ve!? Vb ifferent setleri URL'ler içine almak şaşırtıcı, tüm noktalama dikkate vermek isteyeceksiniz. Ben \ W bir preg_replace (değil kelime) yapardım

preg_replace('/\w/', '', $title);

Bu size biraz yardımcı olmalıdır.

Phil