Lasam urli.

3
Dec
0

Nu jau kāds laiks pagājis, kopš parādijies tāds brīnums kā mod_rewrite priekš Apache. Tas padara mūsu mājaslapas draudzīgākas gūglei un cilvēkiem. Kāpēc? Jo jau saitē mēs redzam ar ko saistīta konkrētā sadaļa vai raksts. Pats personīgī, šķiet, bez šī rīka vairs īsti nemāku strādāt.

Sāksim ar rewrite nosacījumu uzstādīšanu. Iespējas ir dažādas un atkarīgas no vajadzībām, piemēram, mēs varam, caur slešiem atdalītus vārdus, padot kā $_GET mainīgos vai ļaut rakstīt jebko un padoto saiti apstrādāt ar server-side skriptiem. Esmu piekopis otro metodi un lai labāk saprastu, parādīšu savu RewriteRule.

<VirtualHost *>
    DocumentRoot /home/www/domens
    ServerName domens.lv
    ServerAlias www.domens.lv

    RewriteEngine On
    AcceptPathInfo On
    RewriteRule ^/lv/(.*) /lv.php/$1
    RewriteRule ^/ru/(.*) /ru.php/$1
    RewriteRule ^/en/(.*) /en.php/$1
</VirtualHost>

Jā, rewrite nosacījumus rakstu Apache konfigurācijas failā, nevis .htaccess failā. Lūk, manā gadījumā, viss, kas sekos aiz domens.lv/lv/, tiks pārrakstīts.

Iekš lv.php, ru.php, en.php tiek definēti izvēlētās valodas apzīmējoši mainīgiem un inklūdots fails, kas inklūdo pārējos failus, taisa konekcijas ar datubāzi un, protams, apstrādā padoto saiti.

Apskatīsim mūsu mājaslapas sadaļu tabulu, kas dzīvo MySQLā. Manā gadījumā tā izskatās līdzīga šai:

+----+-----------+----------+----------+----------+----------+----------+
| id | parent_id | position | url      | name_lv  | name_ru  | name_en  |
+----+-----------+----------+----------+----------+----------+----------+
| 1  | 0         | 1        | main     | Sākums   | Начало   | Home     |
+----+-----------+----------+----------+----------+----------+----------+
| 2  | 0         | 2        | contacts | Kontakti | Контакты | Contacts |
+----+-----------+----------+----------+----------+----------+----------+
| 3  | 1         | 2        | news     | Jaunumi  | Новости  | News     |
+----+-----------+----------+----------+----------+----------+----------+
| 4  | 1         | 1        | photo    | Foto     | Фото     | Photo    |
+----+-----------+----------+----------+----------+----------+----------+
| 5  | 2         | 1        | map      | Karte    | Карта    | Map      |
+----+-----------+----------+----------+----------+----------+----------+

Tagad Iedomāsimies, ka cilvēks ir ieradies lapā, ar adresi domens.lv/lv/contacts/map. Atvērtās sadaļas ID ir 5. Kā mēs to noskaidrosim ar PHP? Sākumā apstrādāsim saņemto saiti:

1
2
3
4
5
6
7
<?
  $xpieces=explode("/",$_SERVER['PATH_INFO']);
  $cnt=count($xpieces);
  if(empty($xpieces[--$cnt])){
    unset($xpieces[$cnt]);
  }
?>

Kā redzams, izmantoju $_SERVER['PATH_INFO'] mainīgo (to ir iespējams ieslēgt tikai Apaches konfigurācija un noklusējuma uzstādījumos šis mainīgais neparādās), šis mainīgais man atgriež “lv/contacts/map”.

Tiksim pie atvērtās sadaļas ID! Atkal jāsaka, ka esmu redzējis dažādus variantus – tādus, kas skatās tikai pēc pēdējās sadaļas un tādus, kas uz katru direktoriju taisa jaunu pieprasījumu uz datubāzi.
Pirmais variants būs pietiekami ātrs, bet ceļš netiks ņemts vērā, kā arī kolonai “url”, datubāzē, jābūt unikālai vērtībai.
Otrs variants jau būs labāks, katras sadaļas saitei (”url” kolona datubāzē) jābūt unikālai pie katra “parent_id”. Turklāt, meklējot atvērtās sadaļas id, ir iespējams savākt datus par iepriekšējām sadaļām, ja nu kādam tas ir vajadzīgs. Rādīšu kolēģa rakstītu piemēru:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?
  function get_lastid($pid,$i=1){
    global $xpieces;
    $sql="SELECT id FROM `topics` WHERE parent_id=".intval($pid)." AND url='".mysql_real_escape_string($xpieces[$i])."' LIMIT 1";
    $res=mysql_query($sql);
    if(mysql_num_rows($res)<1){
      return $pid;
    }
    $row=mysql_fetch_object($res);
    return get_lastid($row->id,++$i);
  }
  $lastid = get_lastid(0);
?>

Šī funkcija veiks pārāk daudz lieku pieprasījumu uz datubāzi, turklāt, ja kāda sadaļa, datubāzē, būs ar tukšu “url” lauku un parent_id būs vienāds ar atvērtās sadaļas ID, tad funkcija mainīgajam $lastid piešķirs šīs sadaļas ID. Tādēļ ķersimies klāt vienam selektam un masīviem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?
  function get_lastid($arr,$pid=0,$i=1){
    global $xpieces;
    if(!is_array($arr[$pid])){
      return $pid;
    }
    $n=array_search($xpieces[$i],$arr[$pid]);
    if(!$n){
      return $pid;
    }
    return get_lastid($arr,$n,++$i);
  }
 
  $all=array();
  $allsql="SELECT id, parent_id, url FROM `topics` ORDER BY position ASC";
  $allres=mysql_query($allsql);
  while($allrow=mysql_fetch_object($allres)){
    $all[$allrow->parent_id][$allrow->id]=$allrow->url;
  }
  $lastid=get_lastid($all);
?>