Yii Framework Forum: نحوه استفاده از مدل و ارتباط با کنترلر - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

نحوه استفاده از مدل و ارتباط با کنترلر

#1 User is offline   Manee 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 87
  • Joined: 23-September 12

Posted 02 March 2013 - 03:59 AM


این تکه کد که داخل فایل سایت کنترلر هستش نحوه استفاده از مدل رو نوشته که یه متغیر را تعریف کرده و اومده ازدستور زیر استفاده کرده. من مدل مربوط به فایل LoginForm رو باز کردم ولی هیچ متغیر و یا تابعی به اسم attributes ندیدم. این جریان ارتباط چطوریه

$model->attributes=$_POST['LoginForm'];

public function actionLogin()
	{
		if (!defined('CRYPT_BLOWFISH')||!CRYPT_BLOWFISH)
			throw new CHttpException(500,"This application requires that PHP was compiled with Blowfish support for crypt().");

 		$model=new LoginForm;

 		// if it is ajax validation request
		if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
		{
			echo CActiveForm::validate($model);
			Yii::app()->end();
		}

 		// collect user input data
		if(isset($_POST['LoginForm']))
		{
			$model->attributes=$_POST['LoginForm'];
			// validate user input and redirect to the previous page if valid
			if($model->validate() && $model->login())
				$this->redirect(Yii::app()->user->returnUrl);
		}
		// display the login form
		$this->render('login',array('model'=>$model));
	}












0

#2 User is offline   Ali Borjian 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 303
  • Joined: 19-January 11

Posted 02 March 2013 - 04:19 AM


نیازی نیست که شما کلمه attributes را ببینید.
کاری که انجام می شود این است که محتوای LoginForm شما توسط مد Post برای کنترلر ارسال می شه.
در کنترلر نمونه ای از مدل که همان فیلدهای LoginForm شما هستند ساخته می شود و با مقادیر پست شده پر می شوند
توسط validate سازگاری ها با rules تعریف شده بررسی می شود و نهایتا از طریق فراخوانی فیلدها مقادیر قابل استفاده می شوند.



You can do anything, but not everything.
0

#3 User is offline   Manee 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 87
  • Joined: 23-September 12

Posted 02 March 2013 - 04:25 AM


اینکه نیازی نیست ببینیم رو من نفهمیدم. الان باید یه همچین چیزی تو مدل - کلاس به صورت متغیر یا تابع نباید باشه؟ من تو مفهوم این تیکه کد موندم.
اگه به رول میره چرا ما مستقیم از اون استفاده نمیکنیم یا بهش معرفی کنیم چک بکنه؟

0

#4 User is offline   Ali Borjian 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 303
  • Joined: 19-January 11

Posted 02 March 2013 - 04:45 AM


در کنترلر ابتدا نمونه ای از مدل ساخته می شود که کلاس مدل که شامل فیلدها و قوانین می باشند در LoginForm تعریف شده است.
بعد از اینکه نمونه ساخته شد باید مقدار دهی شود یعنی با مقادیری که کاربر در فرم خود پست کرده تکمیل شوند. 2 روش برای پر کردن مقادیر وجود دارد روش اول تکمیل موردی یعنی فیلد به فیلد مدل ساخته شده را با فیلد به فیلد فرم پست شده تکمیل کنیم
روش دوم که مورد سوال شما هست massive assignment است که مدل ر ا به طور یکجا با مقادیر فرم پر می کند
این روش که massive assignment نام دارد کلیه مقادیر فرم را یکجا در مدل قرار می دهد.

    $model->attributes=$_POST['LoginForm'];


مراحل انجام کار :
1- ساخت نمونه از روی کلاس مدل
2- پر کردن مقادیر نمونه با مقادیر فرستاده شده در فرم پست شده
3- بررسی صحت. بعد از اینکه مقادیر وارد شد باید بررسی یا Validation انجام شود به این صورت که مقادیر قرار داده شده را با قوانین تعریف شده مطابقت می دهد و اگر همخوانی وجود نداشته باشد false را بر می گرداند

You can do anything, but not everything.
1

#5 User is offline   Reza m 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 131
  • Joined: 07-March 12

Posted 02 March 2013 - 08:10 AM

Manee said:


من مدل مربوط به فایل LoginForm رو باز کردم ولی هیچ متغیر و یا تابعی به اسم attributes ندیدم.


Manee said:


اینکه نیازی نیست ببینیم رو من نفهمیدم. الان باید یه همچین چیزی تو مدل - کلاس به صورت متغیر یا تابع نباید باشه؟ من تو مفهوم این تیکه کد موندم.




این مساله به خاطر اینه که مدل LoginForm شما از کلاس CFormModel و اون هم از کلاس CModel وراثت گرفتند، و شما با استفاده از این دستور، متد setAttributes رو که در CModel تعریف شده فراخوانی میکنید.


1

#6 User is offline   Nabi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 121
  • Joined: 22-February 12
  • Location:Ahwaz

Posted 03 March 2013 - 06:51 AM


سلام،

فکر کنم خیلی دوست داری با دم شیر بازی کنی :D
البته دوستان خیلی خوب و علمی کاربرد متد attributes در سطح بالای فریم ورک رو گفتند ولی من حدس میزنم جواب سوالت رو نگرفتی!
تو سوالت اینه که فلسفه کارکرد متد attributes چگونست؟
اگر حدس من درست بوده باشه بایستی بگم که سوالت خوب و منطقی بود!
اما جوابش رو شاید توی هیچ راهنما و کتاب YII نمیتونی پیدا کنی، مگر اینکه خودت کدهای فریم ورک رو بخونی.
در یک کلام فریم ورک YII اینکارو به صورت جادویی انجام میده!
سعی میکنم به زبون خیلی ساده بهت بگم چطور! ;)

از بالا شروع میکنیم به trace برنامه.
اینطور نوشته شده:
$model=new LoginForm;
$model->attributes=$_POST['LoginForm'];

مدلی از نوع LoginForm ساخته شده و سپس متد attributes اون فراخوانی شده. پس میریم توی مدل LoginForm سراغ متد attributes.
ولی همچین چیزی توش نیست!
اما این مدل از یک کلاس دیگه به نام CFormModel به ارث برده شده (extend شده) پس شاید متد attributes توی اون کلاس باشه. پس میریم سراغ اون کلاس که در framework/web/CFormModel.php قرار داره (اگر از IDE های پیشرفته مثلاً Eclipse استفاده کنی، با نگه داشتن Ctrl و کلیک روی اسم کلاس، مستقیم میری توی فایل اون کلاس)
خب فایل CFormModel.php باز شد ولی اینجا هم خبری از متد attributes نیست! ولی نا امید نمیشیم و ادامه میدیم!
این کلاس هم از CModel ارث بری کرده پس میریم سراغ فایلش یعنی framework/base/CModel.php اما همچنان اینجا هم اثری از متد attributes نیست!
اما یک متد به اسم getAttributes هست! شبیهش هست ولی خودش نیست! پس شاید بهش نزدیک شدیم!
میریم جلوتر...
کلاس CModel هم از کلاس CComponent ارث بری کرده پس به سراغ فایلش framework/base/CComponent.php میریم.
ولی اینجا هم اثری از متد attributes نیست!
پس چی شد؟!
سر کاریم؟!
حالا فهمیدید چرا گفتم فریم ورک YII اینکارو به صورت جادویی انجام میده؟!
برای توضیح این جادو، لازم یکم به جد بزرگ YII یعنی PHP برگردیم! (اینا همه خانوادگی جادوگرن!!! :D )

یه کد ساده داریم بدین صورت:
<?php
class Test {
    public $param;
}

$obj = new Test();
$obj->param = "Hello";
echo $obj->param; //output: Hello
?>

خب مشخه یک attribute به نام param که درون سطح کلاس تعریف شده مقدار دهی میشه و چاپ میشه که عبارت Hello در خروجی ظاهر میشه.
اما وقتی که متغییر param در سطح کلاس تعریف نشده، شاید کد بازهم درست کار کنه، یعنی شاید خود PHP به صورت داخلی متغییر رو بسازه و انتساب رو انجام بده. اما شما کنترلی روی این قضیه ندارید. برای اینکه اون رو مدیریت یا سفارشی کنید اینجا از یک متد سیستمی به اسم ‎__set()‎ استفاده میشه.
مثال:
<?php
class Test {
    function __set($name, $value) {
        $this->$name = $value * 2;
    }
}

$obj = new Test();
$obj->param = 100;
echo $obj->param; //output: 200
$obj->yii = 30;
echo $obj->yii; //output: 60
?>

در این مثال توجه کنید متغییرهای param و yii در سطح کلاس تعریف نشدند ولی نه تنها مقدار میگیرند بلکه حتی در لحظه ای که مقدار میگیرند عملیاتی رو روشون انجام دادیم.

حالا برمیگردیم سر قضیه خودمون!
تا جایی پیش رفتیم که به آخرین کلاس یعنی CComponent رسیدیم، در این کلاس دقت کنید این متد رو میبینید:
public function __set($name,$value)
{
    $setter='set'.$name;
    if(method_exists($this,$setter))
        return $this->$setter($value);
:
:
:

میبینید که به متغییری که در کلاس مقدار دهی میشه یه set چسبونده بعد با method_exists سعی کرده چک کنه آیا همچین متدی درون کلاس جاری تعریف شده یا نه و اگر وجود داشت اون رو صدا بزنه و البته value رو هم بهش پاس بده تا توی اون یه بلایی به سرش بیاد!
مثلاً اگر ما بنویسیم:
$model->yii = 'yes it is';

چون yii جزو متغییرهای سطح کلاس نیست (و دقیقاً هم نباید باشه) بنابراین متد ‎__set()‎ وارد عمل میشه و چک میکنه آیا متدی به نام setYii وجود داره یا نه، اگر وجود داشت مقدار 'yes it is' رو به همون متد ارسال میکنه.

حالا به اول داستان برمیگردیم. اونجایی که نوشته شده بود:
$model->attributes = $_POST['LoginForm'];

متدی به نام attributes درسته که وجود نداره اما با این توضیحاتی که دادم، سعی میشه setAttributes پیدا بشه و مقدار ‎$_POST['LoginForm']‎ به همون متد ارسال بشه.

پس از این به بعد بایستی دنبال setAttributes بگردیم. اگر یه مرحله به عقب برگردیم در کلاس CModel میتونیم اون رو پیدا کنیم که ‎$values که ما به صورت یک آرایه بهش پاس دادیم رو گرفته و یک به یک مقادیر رو درون کلیدشون ریخته.
یعنی اگر ‎$_POST['LoginForm']‎ به صورت زیر باشه:
Array (
    'username' => 'iran', 
    'password' => 'yii',
)

کار setAttributes اینه که این آرایه رو میگیره و iran رو میریزه توی یه متغییر در سطح کلاس به نام username (که در کلاس تعریف نشده) و همینطور yii رو درون password (که در کلاس تعریف نشده) بنابراین پس از اون ما میتونیم به این نحو از اونها استفاده کنیم:
echo $model->username; //output: iran
echo $model->password; //output: yii


اگر متد attributes در فریم ورک تعریف نمیشد ما مجبور بودیم اینطور مقادیر رو انتساب بدیم:
$model->username = $_POST['LoginForm']['username'];
$model->password = $_POST['LoginForm']['password'];

که اگر تعداد فیلدها زیاد باشه کار وقت گیر و تکراریه. بنابراین متد attributes با اون داستان پشت پردش رو ساختند تا تنها بنویسیم:
$model->attributes = $_POST['LoginForm'];

و دیگر هیچ!

ببخشید زیاد حرف زدم.
خواستم موضوع رو زیاد باز کنم تا دوستان مبتدی تر هم بتونن استفاده کنند، چون خیلی از دوستان درمورد نحوه عملکرد پشت پرده فریم ورک پرسیده بودند و به نوعی با این مطلب فکر میکنم روش trace کردن کد رو هم یاد گرفتند تا بقیه چیزها رو خودشون بتونن کشف کنند.

امیدوارم توضیحات مفید واقع شده باشه.
موفق باشید
نبی


وقتی پیغام میذارید، بی زحمت متنتون رو انتخاب کنید و این دو تا کار ناقابل رو هم انجام بدید:
1. از اون بالا RTL رو انتخاب کنید.
2. فونت رو هم Tahoma بگذارید.
که چشمون در نیاد.
دمت گرم!

www.IranPHP.ir
2

#7 User is offline   Manee 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 87
  • Joined: 23-September 12

Posted 03 March 2013 - 11:30 AM

احسنت دقیقا به چیزی که میخواستم اشاره کردی ممنونم دوست عزیز.

0

#8 User is offline   Manee 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 87
  • Joined: 23-September 12

Posted 03 March 2013 - 11:37 PM

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



0

#9 User is offline   Nabi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 121
  • Joined: 22-February 12
  • Location:Ahwaz

Posted 04 March 2013 - 03:47 AM

خواهش.
در خدمتیم



وقتی پیغام میذارید، بی زحمت متنتون رو انتخاب کنید و این دو تا کار ناقابل رو هم انجام بدید:
1. از اون بالا RTL رو انتخاب کنید.
2. فونت رو هم Tahoma بگذارید.
که چشمون در نیاد.
دمت گرم!

www.IranPHP.ir
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users