PHP ile SEO uyumlu daha anlaşılır web adresleri hazırlama

Uzun zamandır, geliştirdiğim web sitelerinde, hem daha anlaşılır olması, hem de SEO açısından daha faydalı olduğu genel kanaat olduğu için, adresleri ilgili sayfanın başlığından oluşturuyorum. İlk başlarda başlığı adrese çeviren bir metot yazmıştım, fakat zaman geçtikçe bu metodun çeşitli durumlarda düzgün çalışmadığını gözledim. Bunun üzerine örnekler ve en iyi pratiklere göz atmaya başladım.

Bu konuda en başarılı bulduğum uygulama WordPress oldu. WordPress açık kaynak kodlu bir uygulama olduğundan hemen kaynak kodlarını inceleyerek bu problemin üstesinden nasıl geldiklerini inceledim ve gerekli kısımları bir araya getirdim. WordPress’i seçme sebeplerimden birisi de, uygulamanın bir çok dilde kullanılması ve ilgili metotların bu dilleri destekleyecek şekilde geliştirilmeleriydi.

Neyse lafı fazla uzatmadan kodları paylaşayım, önce bir örnek ile nasıl kullanacağınızı göstereyim:

1$baslik = "Öğümce yolları çakıl taşları ile dolmuş - Test başlığı";
2echo sanitize_title_with_dashes($baslik);
3// "ogumce-yollari-cakil-taslari-ile-dolmus-test-basligi" çıktısını üretecektir.

Son olarak da gerekli metotlar:

001/**
002 * Sanitizes title, replacing whitespace with dashes.
003 *
004 * Limits the output to alphanumeric characters, underscore (_) and dash (-).
005 * Whitespace becomes a dash.
006 *
007 * @since 1.2.0
008 *
009 * @param string $title The title to be sanitized.
010 * @return string The sanitized title.
011 */
012function sanitize_title_with_dashes($title) {
013    $title = strip_tags($title);
014    // Preserve escaped octets.
015    $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
016    // Remove percent signs that are not part of an octet.
017    $title = str_replace('%', '', $title);
018    // Restore octets.
019    $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
020 
021    $title = remove_accents($title);
022    if (seems_utf8($title)) {
023        if (function_exists('mb_strtolower')) {
024            $title = mb_strtolower($title, 'UTF-8');
025        }
026        $title = utf8_uri_encode($title, 200);
027    }
028 
029    $title = strtolower($title);
030    $title = preg_replace('/&.+?;/', '', $title); // kill entities
031    $title = str_replace('.', '-', $title);
032    $title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
033    $title = preg_replace('/\s+/', '-', $title);
034    $title = preg_replace('|-+|', '-', $title);
035    $title = trim($title, '-');
036 
037    return $title;
038}
039 
040/**
041 * Converts all accent characters to ASCII characters.
042 *
043 * If there are no accent characters, then the string given is just returned.
044 *
045 * @since 1.2.1
046 *
047 * @param string $string Text that might have accent characters
048 * @return string Filtered string with replaced "nice" characters.
049 */
050function remove_accents($string) {
051    if ( !preg_match('/[\x80-\xff]/', $string) )
052        return $string;
053 
054    if (seems_utf8($string)) {
055        $chars = array(
056        // Decompositions for Latin-1 Supplement
057        chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
058        chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
059        chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
060        chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
061        chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
062        chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
063        chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
064        chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
065        chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
066        chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
067        chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
068        chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
069        chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
070        chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
071        chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
072        chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
073        chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
074        chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
075        chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
076        chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
077        chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
078        chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
079        chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
080        chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
081        chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
082        chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
083        chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
084        chr(195).chr(191) => 'y',
085        // Decompositions for Latin Extended-A
086        chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
087        chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
088        chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
089        chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
090        chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
091        chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
092        chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
093        chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
094        chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
095        chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
096        chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
097        chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
098        chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
099        chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
100        chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
101        chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
102        chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
103        chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
104        chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
105        chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
106        chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
107        chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
108        chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
109        chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
110        chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
111        chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
112        chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
113        chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
114        chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
115        chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
116        chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
117        chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
118        chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
119        chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
120        chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
121        chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
122        chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
123        chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
124        chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
125        chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
126        chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
127        chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
128        chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
129        chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
130        chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
131        chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
132        chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
133        chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
134        chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
135        chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
136        chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
137        chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
138        chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
139        chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
140        chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
141        chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
142        chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
143        chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
144        chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
145        chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
146        chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
147        chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
148        chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
149        chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
150        // Euro Sign
151        chr(226).chr(130).chr(172) => 'E',
152        // GBP (Pound) Sign
153        chr(194).chr(163) => '');
154 
155        $string = strtr($string, $chars);
156    } else {
157        // Assume ISO-8859-1 if not UTF-8
158        $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
159            .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
160            .chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
161            .chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
162            .chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
163            .chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
164            .chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
165            .chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
166            .chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
167            .chr(252).chr(253).chr(255);
168 
169        $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
170 
171        $string = strtr($string, $chars['in'], $chars['out']);
172        $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
173        $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
174        $string = str_replace($double_chars['in'], $double_chars['out'], $string);
175    }
176 
177    return $string;
178}
179 
180/**
181 * Checks to see if a string is utf8 encoded.
182 *
183 * NOTE: This function checks for 5-Byte sequences, UTF8
184 *       has Bytes Sequences with a maximum length of 4.
185 *
186 * @author bmorel at ssi dot fr (modified)
187 * @since 1.2.1
188 *
189 * @param string $str The string to be checked
190 * @return bool True if $str fits a UTF-8 model, false otherwise.
191 */
192function seems_utf8($str) {
193    $length = strlen($str);
194    for ($i=0; $i < $length; $i++) {
195        $c = ord($str[$i]);
196        if ($c < 0x80) $n = 0; # 0bbbbbbb
197        elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
198        elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
199        elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
200        elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
201        elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b
202        else return false; # Does not match any model
203        for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
204            if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
205                return false;
206        }
207    }
208    return true;
209}
210 
211/**
212 * Encode the Unicode values to be used in the URI.
213 *
214 * @since 1.5.0
215 *
216 * @param string $utf8_string
217 * @param int $length Max length of the string
218 * @return string String with Unicode encoded for URI.
219 */
220function utf8_uri_encode( $utf8_string, $length = 0 ) {
221    $unicode = '';
222    $values = array();
223    $num_octets = 1;
224    $unicode_length = 0;
225 
226    $string_length = strlen( $utf8_string );
227    for ($i = 0; $i < $string_length; $i++ ) {
228 
229        $value = ord( $utf8_string[ $i ] );
230 
231        if ( $value < 128 ) {
232            if ( $length && ( $unicode_length >= $length ) )
233                break;
234            $unicode .= chr($value);
235            $unicode_length++;
236        } else {
237            if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3;
238 
239            $values[] = $value;
240 
241            if ( $length && ( $unicode_length + ($num_octets * 3) ) > $length )
242                break;
243            if ( count( $values ) == $num_octets ) {
244                if ($num_octets == 3) {
245                    $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
246                    $unicode_length += 9;
247                } else {
248                    $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
249                    $unicode_length += 6;
250                }
251 
252                $values = array();
253                $num_octets = 1;
254            }
255        }
256    }
257 
258    return $unicode;
259}

“PHP ile SEO uyumlu daha anlaşılır web adresleri hazırlama” için bir yorum

Yorumlar kapalı.

Buy Me A Coffee