PDA

View Full Version : آدرس دهی مانند facebook (حل شد)



mahmod2000
دوشنبه 18 آذر 1392, 11:34 صبح
سلام
من میخوام موقع آدرس دهی مثال به این صورت انجام بدم
site.com/mahmod
بعد در صفحه هر چیزی که مربوط به mahmod هستش از دیتابیس بکشه بیرون

به چه صورتی باید انجام بدم؟
و اینکه تداخلی هم با بقیه آدرس های موجود ایجاد نشه

ممنون میشم راهنمایی کنید

MMSHFE
دوشنبه 18 آذر 1392, 12:48 عصر
شما میتونید کامپوننت urlManager رو در protected/config/main.php اینطوری تنظیم کنید:


'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'user/<user:.+>' => 'users/showall',
),
),

و توی کنترلر UsersController یک متد به اسم actionShowAll بسازین و داخلش با ['GET['user_$ نام کاربری که وارد شده رو دریافت کنید و کارهای لازم رو برای نمایش اطلاعات انجام بدین. البته دقت کنید که کد فوق، آٖدرسهای بصورت site.com/user/mahmod رو قبول میکنه که من عمداً اینطوری گذاشتم چون اگه مستقیماً هرچی بعد از اسم سایت بیاد رو بخواین تغییر بدین، اونوقت روش کار کنترلرها و اکشنهای دیگه بهم میریزه و هرچی وارد کنید، میخواد بعنوان user با متد Get برای اکشن users/showall بفرسته. البته میتونید یک اکشن اصلی ایجاد کنید (مثل site/index) و بگین هرچی توی آدرس اومد برای اون ارسال بشه و اونجا یک لیست از actionها درست کنید و بگین اگه آدرس واردشده توی اون لیست بود، بره و controller/action موردنظر رو صدا بزنه درغیر اینصورت اطلاعات کاربر رو نشون بده. به این روش White List میگن که به احتمال زیاد FB هم از همین روش استفاده کرده.
توی جلسه 10 پکیج آموزش Yii درمورد اصلاح آدرس توضیحات کاملی گذاشتم.

mahmod2000
دوشنبه 18 آذر 1392, 16:48 عصر
استاد به چه شکلی Action ها رو چک کنم؟
و چجوری ریدایرکت کنم اگه اکشنی رو پیدا کرد

MMSHFE
دوشنبه 18 آذر 1392, 21:45 عصر
ببینید، مثلاً urlManager رو اینطوری تنظیم میکنید:


'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'<action:.+>' => 'site/index',
),
),

و توی htaccess. هم همه درخواستها رو به index.php میفرستین:


RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

که البته توی localhost باید اینطوری بنویسید:


Options +FollowSymlinks
RewriteEngine On
RewriteBase /site
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

و بجای site اسم پوشه ای که سایتتون رو توی اون داخل webroot گذاشتین، بنویسید.
حالا با این تنظیمات، سایت شما آماده است که هرچی توی نوار آدرس بعد از آدرس سایت نوشته بشه رو بعنوان action با روش GET برای متد actionIndex از کنترلر SiteController بفرسته. مثلاً اگه کاربر توی URL بنویسه site.com/mahmod توی متد فوق، ['GET['action_$ برابر با mahmod خواهد بود یا اگه بنویسه site.com/users/login محتوای ['GET['action برابر با users/login میشه. خوب حالا کافیه توی این متد با بررسی مقدار متغیر GET فوق، عملیات موردنظر رو انجام بدین. مثلاً اگه یکی از Actionهای سایت بود (مثل users/login) اون رو صدا بزنید و اگه چیزی غیر از اینها بود (مثل mahmod) فایل View موردنظر رو که قبلاً ساختین، Render کنید و مدل کاربر رو براش بفرستین. مثال:


<?php
class SiteController extends Controller {
...
public function actionIndex() {
if(isset($_GET['action'])) {
switch(strtolower($_GET['action'])) {
case 'users/login':
list($users) = Yii::app()->createController('users');
$users->actionLogin();
/* or
Yii::import('application.controllers.SiteControlle r');
$users = new UsersController();
$users->actionLogin();
*/
break;
default:
$this->render('users', array(
'model' => Users::model()->find(array(
'condition'=>'LOWER(username)=:userName',
'params' => array(':userName' => strtolower($_GET['action'])),
));
break;
}
}
}
...
}

و توی فایل protected/views/site/users.php کدی شبیه این بنویسید:

echo '<pre>' . print_r($model, true) . '</pre>' . PHP_EOL;
که البته این فقط یک مثاله و همونطور که میدونید، میشه به راحتی عناصر شئ ActiveRecord که به نام model$ در اختیار View گذاشته شده رو مورد استفاده قرار داد و یک صفحه خوب و کاربرپسند طراحی کرد.
امیدوارم خوب توضیح داده باشم.

mahmod2000
دوشنبه 18 آذر 1392, 21:52 عصر
خیلی خیلی ممنون استاد
روش کار میکنم
دمه شما گرم

mahmod2000
سه شنبه 19 آذر 1392, 11:08 صبح
استاد الان من تا 70-80% پیش رفتم

حالا میخوام وقتی آی دی هم توی آدرس بار بود بخونه.. ولی جواب نمیده.. ببینید طریقه گرفتن آی دی رو درست انجام دادم؟
گرفتن اکشن به درستی انجام میشه
این کد هستش
main.php :


'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName' => false,
'rules'=>array(
'<controller:.+>/<action:.+>'=>'showByLink/ShowByWebLink',

),
),


اینم صفحه ای که بهش ارسال میکنیم لینک رو


$action = isset($_GET['action']) ? 'action'.$_GET['action'] : 'Index';
$id = isset($_GET['id']) ? $_GET['id'] : '';
if(isset($_GET['controller'])) {
switch(strtolower($_GET['controller'])) {
case 'business':
list($controller) = Yii::app()->createController('business');
if(!$_GET['action'])
$controller->actionIndex();
else{
$controller->$action();
if($id)
$controller->$action($id);
}
/* or
Yii::import('application.controllers.SiteControlle r');
$users = new UsersController();
$users->actionLogin();
*/
break;

default:
$criteria = new CDbCriteria;
$criteria->condition = 'web_name = "'.$_GET['controller'].'"';
$model = Business::model()->find($criteria);
if($model===null)
throw new CHttpException(404,'Not found user');
else
$this->render('view', array('model' => $model));
break;
}
}
}

MMSHFE
سه شنبه 19 آذر 1392, 11:33 صبح
منظورتون از id اطلاعات کاربره (مثل mahmod) ؟ اگه اینطوره، کد زیر رو تست کنید:


'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName' => false,
'rules'=>array(
'<id:[^\/]+>'='showByLink/ShowByWebLink',
'<controller:.+>/<action:.+>'=>'showByLink/ShowByWebLink',
),
),

MMSHFE
سه شنبه 19 آذر 1392, 11:35 صبح
یا اگه میخواین توی همون کدی که نوشتین، کار موردنظر رو انجام بدین و اون کد تغییر نکنه، اینو تست کنید:


'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName' => false,
'rules'=>array(
'<controller:[^\/]+>/<action:[^\/]+>'=>'showByLink/ShowByWebLink',
'<controller:[^\/]+>/<action:[^\/]+/<id:[^\/]+>'=>'showByLink/ShowByWebLink',
),
),

mahmod2000
سه شنبه 19 آذر 1392, 11:44 صبح
برای اینکه این کاری که انجام دادیم باز تداخل ایجاد میکنه به صفحات دیگه
الان تو کد که ببینید اکشن هم اومدم زدم که اگه مثال business/create اومد اررور نده و کارشو بکنه
الان آی دی هم تشخیص میده.. اصلاحش کردم

حالا وقتی میخوام اطلاعات یوزر رو نمایش بدم لینک هایی که موجوده، کنترلر اون اکشنی رو میاره که توی urlManager صدا میزنیم رو میاره..
داستانیه این حرکت

MMSHFE
سه شنبه 19 آذر 1392, 11:51 صبح
خوب یک Rule جدا برای کاربران اضافه کنید:


'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName' => false,
'rules'=>array(
'<id:[^\/]+>'=>'user/view',
'<controller:[^\/]+>/<action:[^\/]+>'=>'showByLink/ShowByWebLink',
'<controller:[^\/]+>/<action:[^\/]+/<id:[^\/]+>'=>'showByLink/ShowByWebLink',
),
),

mahmod2000
سه شنبه 19 آذر 1392, 12:26 عصر
داشتم الکی درجا میزدم جناب شهرکی
به این صورت نوشتم


'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName' => false,
'rules'=>array(
//'<controller:.+>/<action:.+>/id/<id:.+>'=>'showByLink/ShowByWebLink',
'p<webname:[^\/]+>'=>array('business/ViewByWebLink','caseSensitive'=>false),
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

),
),


برای کاربر ها فعلا مجبور شدم کلمه P رو اول بزنم برای مثال که با کنترلر دوباره تداخل ایجاد نکنه.. الان خیلی خوب داره کار میکنه

فقط راهی باشه که این کلمه p رو هم نیاز نباشه خیلی بهتره
ولی فکر میکنم باید باشه چون آپاچی هم گیج میشه که این کنترلر هست یا یوزر

MMSHFE
سه شنبه 19 آذر 1392, 12:33 عصر
ربطی به Apache نداره. Apache فقط با htaccess. داره همه درخواستها رو میفرسته به index.php و این Ruleها توسط Yii دارن تفسیر میشن. الآن کد شما مشکل خاصی نداره بجز اینکه حواستون باید باشه که کنترلرهاتون نباید با p شروع بشن. بنظرم اگه اینطوری بنویسید باید درست کار کنه:


'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName' => false,
'rules'=>array(
'<webname:[^\/]+$>'=>array('business/ViewByWebLink','caseSensitive'=>false),
'<controller:[^\/]+>/<action:[^\/]+>'=>'<controller>/<action>',
'<controller:[^\/]+>/<action:[^\/]+/<id:[^\/]+>'=>'<controller>/<action>',
),
),

mahmod2000
سه شنبه 19 آذر 1392, 12:41 عصر
از این ایراد میگیره


'<webname:[^\/]+$>'=>array('business/ViewByWebLink','caseSensitive'=>false),

و وقتی از توش $ رو برمیدارم درست کار میکنه و وقتی به این خط میرسه :


'<controller:[^\/]+>/<action:[^\/]+/<id:[^\/]+>'=>'<controller>/<action>',

ارور میگیره. میگه :


The URL pattern "<controller:[^\/]+>/<action:[^\/]+/<id:[^\/]+>" for route "<controller>/<action>" is not a valid regular expression.


و اینکه وقتی خط آخر که ارور میگیره رو بر میدارم باز تداخل پیدا میکنه و یوزر که وارد میکنم رو نمیشناسه

ببخشید استاد، دارم اذیتت میکنم:لبخندساده:

MMSHFE
سه شنبه 19 آذر 1392, 12:53 عصر
این چطور؟


'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName' => false,
'rules'=>array(
'<webname:[^\/]+>'=>array('business/ViewByWebLink','caseSensitive'=>false),
'<controller:[^\/]+>/<action:[^\/]+>'=>'<controller>/<action>',
'<controller:[^\/]+>/<action:[^\/]+>/<id:[^\/]+>'=>'<controller>/<action>',
),
),

یک < توی خط آخر بعد از action جا افتاده بود.

mahmod2000
سه شنبه 19 آذر 1392, 13:23 عصر
الان ارروی نمیده
یورز هم درست کار میکنه
وقتی میخوام کنترلر رو به تنهایی صدا بزنم (site.com/business) چیزی رو نمیاره ولی کنترلر رو همراه اکشن(site.com/business/admin) صدا میزنم درست کار میکنه

MMSHFE
سه شنبه 19 آذر 1392, 14:02 عصر
خوب الآن دیگه اینو نمیشه کاری کرد چون با Rule اول داره یکسان میشه. مگه اینکه مثل حالتی که اول گذاشته بودین، یه پیشوند خاص (مثل p) برای کاربران بگذارین یا اینکه توی اکشن ViewByWebLink از کنترلر business چک کنید اگه ['GET['webname_$ برابر با یکی از کنترلرهاتون بود، اونوقت اکشن پیشفرض ﴿معمولاً actionIndex) از اون کنترلر رو به روشی که گفتم، صدا بزنید و درغیر اینصورت، پروفایل اون کاربر رو نشون بدین.

mahmod2000
سه شنبه 19 آذر 1392, 14:17 عصر
تشکر
حل شد مشکل

ببخشید که اذیتتون کردم استاد
واقعا ممنون