ניהול קישורים
==============

ניהול קישורים מלא עבור אפליקציות ווב כרוך בשני היבטים. ראשית, ברגע שבקשת המשתמש מתקבלת בפורמט של קישור, האפליקציה צריכה לעבד את הקישור לפרמטרים שניתן להבין אותם. שנית, האפליקציה צריכה לספק דרך ליצירת קישורים בצורה כזו שהאפליקציה תוכל להבין את הקישורים הנוצרים לאחר מכן. עבור אפליקצית Yii, היבטים אלו ממומשים בעזרת [CUrlManager].

יצירת קישורים
-------------

למרות שניתן לכתוב קישורים מלאים בצורה הרגילה והמלאה בקבצי תצוגה, רצוי ליצור אותם בצורה דינאמית כדי לאפשר מקסימום גמישות:

~~~
[php]
$url=$this-»createUrl($route,$params);
~~~

האובייקט `this$` מתייחס לאובייקט של הקונטרולר הנוכחי; `route$` מציין את [נתב](/doc/guide/basics.controller#route) של הבקשה; ו `params$` הנו מערך של אלמנטים המייצג רשימה של פרמטרים (GET) אשר יצורפו לקישור.

כברירת מחדל, קישורים הנוצרים על ידי [createUrl|CController::createUrl] הם בפורמט הנקרא `get`. לדוגמא, בהנחה שיש ברשותנו את הנתונים



~~~

$route='post/read', $params=array('id' =» 100)
~~~


אנו נקבל את הקישור הבא:

~~~
/index.php?r=post/read&id=100
~~~

כשהפרמטרים מופיעים בקישור כרשימה של `מפתח=ערך` המחוברים אחד לשני בעזרת התו `&`, והפרמטר `r` מציין את בקשת [הנתב](/doc/guide/basics.controller#route). הפורמט הזה אינו ידידותי כל כך למשתמש מאחר והוא מכיל כמה ערכים שהם אינם בהכרח תווים אלפאנומריים (אותיות ומספרים).

אנו יכולים ליצור את אותו הקישור בצורה נקייה וידידותית יותר למשתמש על ידי שימוש בפורמט שנקרא `path` המסיר את השאילתה מהמחרוזת של הקישור ומוסיף את הפרמטרים (GET) כחלק מהנתיב:

~~~
/index.php/post/read/id/100
~~~

בכדי לשנות את פורמט הקישורים, אנו צריכים להגדיר את המאפיין [urlManager|CWebApplication::urlManager] בהגדרות האפליקציה כדי שבעת השימוש ב-[createUrl|CController::createUrl] המתודה תדע להחליף את הקישורים לפורמט החדש והאפליקציה תוכל להבין ולנתח את הקישורים החדשים:

~~~
[php]
array(
    ......
    'components'=»array(
        ......
        'urlManager'=»array(
            'urlFormat'=»'path',
        ),
    ),
);
~~~

זכור שאנו לא צריכים לציין את שם המחלקה של הרכיב [urlManager|CWebApplication::urlManager] מאחר והוא כבר מוגדר מראש כ-[CUrlManager] ב [CWebApplication].

» Tip|טיפ: הקישורים הנוצרים על ידי המתודה [createUrl|CController::createUrl] הם קישורים יחסיים (רלטיביים ללא ה //:http ). כדי לקבל את הקישור המלא (הכולל את //:http) אנו יכולים להשתמש ב `Yii::app()-»hostInfo` לפני שאנו קוראים למתודה [createUrl|CController::createUrl], או לקרוא למתודה [createAbsoluteUrl|CController::createAbsoluteUrl].

קישורים ידידותיים
------------------

בעת השימוש בפורמט `path` כפורמט של הקישורים, אנו יכולים לקבוע כמה כללים עבור הקישורים שלנו כדי לגרום להם להיות ידידותיים אף יותר. לדוגמא, אנו יכולים ליצור קישור קצר כמו `post/100/`, במקום הקישור הארוך `index.php/post/read/id/100/`. כללי הקישורים משומשים על ידי [CUrlManager] עבור יצירת הקישורים וניתוחם.

כדי להגדיר כללים לקישורים, אנו צריכים להגדיר את המאפיין [rules|CUrlManager::rules] של הרכיב [urlManager|CWebApplication::urlManager]:

~~~
[php]
array(
    ......
    'components'=»array(
        ......
        'urlManager'=»array(
            'urlFormat'=»'path',
            'rules'=»array(
                'pattern1'=»'route1',
                'pattern2'=»'route2',
                'pattern3'=»'route3',
            ),
        ),
    ),
);
~~~

הכללים מוגדרים כמערך המכיל זוגות של דפוס-נתב, כל אחד מקביל לכלל אחד. הדפוס של הכלל הוא סטרינג הנועד להתאים את החלק המכיל את המידע אודות הנתיב המגיע מבקשת המשתמש. והנתב של הכלל צריך להתייחס [לנתב](/doc/guide/basics.controller#route) תקין של קונטרולר.

מלבד פורמט הכללים המוצג למעלה, כלל יכול להכיל אפשרויות בתור פרמטרים, כפי שמוצג בדוגמא הבאה:

~~~
[php]
'pattern1'=»array('route1', 'urlSuffix'=»'.xml', 'caseSensitive'=»false)
~~~

בקוד המוצג למעלה, המערך מכיל רשימה של אפשרויות המותאמות אישית. החל מגרסא 1.1.0, ניתן להשתמש באפשרויות הבאות:

- [urlSuffix|CUrlRule::urlSuffix]: סיומת הקישור המוגדרת ספציפית לכלל זה. כברירת מחדל אפשרות זו מוגדרת כ-null, שאומר שימוש בערך המוגדר במאפיין [CUrlManager::urlSuffix].

- [caseSensitive|CUrlRule::caseSensitive]: אפשרות זו מציינת אם הכלל הזה רגיש לאותיות גדולות-קטנות. כברירת מחדל אפשרות זו מוגדרת כ-null, שאומר שימוש בערך המוגדר במאפיין [CUrlManager::caseSensitive].

- [defaultParams|CUrlRule::defaultParams]: הפרמטרים (GET בפורמט של מפתח=»ערך) שיופיעו בקישור. שהכלל הזה ינותח עבור הבקשה הנכנסת, הערכים שהוגדרו במאפיין זה יוזרקו לפרמטרים של GET_$ באפליקציה.

- [matchValue|CUrlRule::matchValue]: אפשרות זו קובעת אם הערכים בפרמטרים (GET) צריכים להיות תואמים לדפוס של כלל הקישור. כברירת מחדל אפשרות זו מוגדר כ-null, שאומר שימוש בערך המוגדר במאפיין [CUrlManager::matchValue]. במידה והאפשרות הזו מוגדרת לערך השווה ל-false, זה אומר שיהיה שימוש בכלל ליצירת הקישור אם הניתוב ושמות הפרמטרים תואמים לאלו שהוגדרו במאפיין זה. במידה והערך הזה מוגדר ל-true, אז הערכים בפרמטרים שהוגדרו צריכים להיות תואמים לערכים המוגדרים בדפוס של הכלל. יש לזכור שהגדרת הערך הזה ל-true משפיע על הביצועים של האפליקציה לרעה.

### שימוש בשמות פרמטרים

כלל יכול להיות מקושר לכמה פרמטרים (GET). פרמטרים אלו מופיעים בדפוס הכלל כסימונים מיוחדים בפורמט הבא:

~~~
&lt;ParamName:ParamPattern&gt;
~~~

כשהערך `ParamName` מציין את שם הפרמטר GET, והפרמטר האופציונלי `ParamPattern` מציין את הביטוי הרגולרי שבעזרתו תתבצע בדיקת התאמה לערך בפרמטר GET. במקרה והערך `ParamPattern` חסר, זה אומר שהפרמטר צריך להיות תואם לכל תו מלבד סלאש (`/`). בעת יצירת הקישור, הסימונים המיוחדים הללו בפרמטרים יוחלפו עם הערכים המקבלים שלהם; בעת ניתוח קישור, הפרמטרים שהתקבלו יאוכלסו אל תוך השתנה GET_$ עם התוצאה שנותחה.

הבא ונשתמש בכמה דוגמאות כדי להסביר כיצד כללי קישורים עובדים. אנו מניחים שהכללים שלנו מכילים שלוש כללים:

~~~
[php]
array(
    'posts'=»'post/list',
    'post/«id:\d+»'=»'post/read',
    'post/«year:\d{4}»/«title»'=»'post/read',
)
~~~

- קריאה ל-

~~~
$this-»createUrl('post/list')
~~~

תיצור `index.php/posts/`. החוק הראשון נמצא תואם.

- קריאה ל-

~~~
$this-»createUrl('post/read',array('id'=»100))
~~~

תיצור `index.php/post/100/`. החוק השני נמצא תואם.

- קריאה ל-

~~~
$this-»createUrl('post/read',array('year'=»2008,'title'=»'a
sample post'))
~~~

תיצור `index.php/post/2008/a%20sample%20post/`. החוק השלישי נמצא תואם.

- קריאה ל-

~~~
$this-»createUrl('post/read')
~~~

תיצור `index.php/post/read/`. אף אחד מהכללים לא נמצא תואם.


בקצרה, בעת השימוש ב-[createUrl|CController::createUrl] כדי ליצור קישור, הנתב והפרמטרים המועברים למתודה שעליהם מתבצעת התאמה כדי להחליט איזה כלל תואם לקישור זה ויש צורך להשתמש בו. אם כל פרמטר המצורף לכלל נמצא בפרמטרים של GET שהועברו למתודה [createUrl|CController::createUrl], ואם הנתב של הכלל תואם לפרמטר של הניתוב שהועבר למתודה, כלל זה יכנס לשימוש בכדי ליצור את הקישור.

אם הפרמטרים GET שהועברו למתודה [createUrl|CController::createUrl] הם יותר מאלו שדרושים על ידי הכלל, הפרמטרים הנוספים יופיעו במחרוזת השאילתה (בקישור). לדוגמא,

אם נקרא ל-

~~~
$this-»createUrl('post/read',array('id'=»100,'year'=»2008))
~~~

אנו נקבל את הקישור `index.php/post/100?year=2008/`. כדי להציג את הפרמטרים הנוספים הללו כחלק ידידותי של הקישור (כדי שיופרדו על ידי סלאש (`/`) כמו השאר ), אנו צריכים להוסיף את `*/` אל סוף הכלל.
לכן, בעזרת הכלל -

~~~
post/«id:\d+»/*
~~~

אנו יכולים לקבל קישור הנראה כך: `index.php/post/100/year/2008/`.

כפי שכבר ציינו, ישנה מטרה נוספת לכללים והיא לנתח את הבקשות הנכנסות. כמובן, שזהו תהליך הפוך מיצירת הקישור. לדוגמא, ברגע שהמשתמש מבקש את `index.php/post/100/`, הכלל השני בדוגמא למעלה יכנס לשימוש מאחר והוא זה שהותאם ראשון, אשר מכוון לנתב `post/read` (קונטרולר `post` והפעולה `read` בתוכו) ניתן לגשת לפרמטר GET

~~~
array('id'=»100)
~~~

בעזרת GET_$.


» Note|הערה: שימוש בכללים עבור הקישורים ישפיע על ביצועי האפליקציה לרעה. הסיבה לכך היא שבעת ניתוח קישור הבקשה, [CUrlManager] ינסה להתאים אותו מול כל הכללים הקיימים עד שאחד יהיה תואם. ככל שישנם יותר כללים, גדלה ההשפעה לרעה על הביצועים. לכן, אפליקציה עם כניסות רבות ותעבורה גדולה צריכה לצמצם את מספר הכללים שנעשה בהם שימוש.

### שימוש בפרמטרים במסלולים

החל מגרסא 1.0.5, אנו יכולים לפנות לפרמטרים בחלק של המסלול בכלל אשר אנו מגדירים. אפשרות זו מתירה לכלל להיות תואם למספר מסלולים בהתבסס על הקריטריון שנמצא תואם. כמו כן זה יכול לעזור להפחית את מספר הכללים הדרושים לאפליקציה, ובכך לשפר את ביצועי המערכת.

אנו משתמשים בכללים הבאים כדי להדגים כיצד להגדיר כללים עם פרמטרים:

~~~
[php]
array(
    '«_c:(post|comment)»/«id:\d+»/«_a:(create|update|delete)»' =» '«_c»/«_a»',
    '«_c:(post|comment)»/«id:\d+»' =» '«_c»/read',
    '«_c:(post|comment)»s' =» '«_c»/list',
)
~~~

בקוד המוצג למעלה, אנו משתמשים בשני פרמטרים בחלק של המסלול בכלל: `c_` ו `a_`. הראשון תואם לקונטרולר שהוא `post` או `comment`, בזמן שהשני תואם לשם פעולה שיכולה להיות `create`, `update` או `delete`. ניתן לשנות את שמות הפרמטרים כל עוד הם לא יתנגשו עם פרמטרים שיכולים להופיע כפרמטרים של GET בקישור.

שימוש בכללים המוצגים למעלה, הקישור `index.php/post/123/create/` ינותח כמסלול אל `post/create` עם הפרמטרים `id=123` מופיעים במערך של GET_$. ונניח שיש ברשותנו את המסלול `comment/list` ופרמטר GET שהוא `page=2`, אנו יכולים ליצור קישור `index.php/comments?page=2`.

### הגדרת פרמטרים כסאב-דומיינים

החל מגרסא 1.0.11, ניתן להוסיף את החלק של הסאב-דומיינים לכללים כדי לנתח וליצור קישורים. ניתן להגדיר פרמטר כסאב-דומיין כדי לחלץ אותו לאחר מכן כפרמטר GET. לדוגמא, את הקישור `http://admin.example.com/en/profile` ניתן לנתח אל תוך פרמטרים של `user=admin`ו `lang=en`. מצד שני, ניתן להשתמש בכללים המכילים סאב-דומיינים ליצירת קישורים.

בכדי להשתמש בכללים המכילים פרמטרים בחלק של הסאב-דומיין, יש להגדיר את הכללים עם פרטי הדומיין, לדוגמא:

~~~
[php]
array(
    'http://«user:\w+».example.com/«lang:\w+»/profile' =» 'user/profile',
)
~~~

הדוגמא למעלה מציינת שהקטע הראשון בסאב-דומיין צריך להיות מיוחס כפרמטר `user` בזמן שהקטע הראשון בחלק לאחר הדומיין צריך להיות מיוחס כפרמטר `lang`. הכלל מתייחס למסלול `user/profile`.

יש לזכור ש-[CUrlManager::showScriptName] לא יקח בחשבון כקישור יווצר בעזרת כלל המשתמש בפרמטרים בסאב-דומיין.

כמו כן יש לזכור שכללים עם פרמטרים כסאב-דומיין לא צריכים להכיל את שם תת-התיקיה אם האפליקציה נמצאת בתת-תיקיה של תיקית הווב הראשית. לדוגמא, אם האפליקציה נמצאת תחת `http://www.example.com/sandbox/blog`, אז אנו עדיין צריכים להשתמש באותה השיטה כמו שהוסבר למעלה ללא ציון שם תת-התיקיה `sandbox/blog` אלה פשוט `blog`.

### הסתרת `index.php`

ישנו דבר נוסף שאנו יכולים לבצע כדי לנקות את הקישורים אף יותר, להסתיר את קובץ הכניסה הראשי `index.php` מהקישורים. זה דורש מאתנו להגדיר את השרת ואת הרכיב [urlManager|CWebApplication::urlManager].

אנו קודם צריכים להגדיר את שרת הווב ככה שקישורים המגיעים ללא ציון סקריפט הכניסה הראשי עדיין יהיה ניתן לנהל אותם בעזרת הסקריפט. עבור שרתי [Apache](http://httpd.apache.org/), ניתן לבצע זאת על ידי הפעלת התוסף `mod_rewrite` המנהל את כל הנושא של ניתוב מסלולים. אנו יכולים ליצור את הקובץ `wwwroot/blog/.htaccess/` עם התוכן הבא.
דע שניתן להשתמש באותו התוכן בקובץ הגדרות שרת Apache בתוך האלמנט `Directory` עבור `wwwroot/blog/`.

~~~
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php
~~~

לאחר מכן אנו מגדירים את המאפיין [showScriptName|CUrlManager::showScriptName] הנמצא ברכיב האפליקציה [urlManager|CWebApplication::urlManager] לערך השווה ל-`false`.

כעת אם אנו נקרא למתודה

~~~
$this-»createUrl('post/read',array('id'=»100))
~~~

אנו נקבל את הקישור `post/100/`. יותר חשוב, שהאפליקציה שלנו תוכל לנתח ולזהות את הקישור.

### זיוף סיומת הקישור

אנו גם יכולים להוסיף סיומת לקישורים. לדוגמא, אנו יכולים לקבל `post/100.html/` במקום `post/100/`. זה נותן תחושה לקישור שהוא עמוד סטטי. בכדי לבצע זאת, עליכם פשוט להגדיר את המאפיין [urlSuffix|CUrlManager::urlSuffix] ברכיב האפליקציה [urlManager|CWebApplication::urlManager] לכל סיומת שתרצו (לדוגמא, `html.` או `xml.` וכדומה...).

«div class="revision"»$Id: topics.url.txt 1809 2010-02-17 22:08:34Z qiang.xue $«/div»