یه باگ کوچیک تو Activerecord

[rtl]

[right]

فرض کنید کلاس book رو از activerecord مشتق کردین حالا اگه مثلا کد زیر رو وارد کنید

[left]




$obj = new book();

echo $obj->birthday;



[/left]

با یک استثنا روبرو خواید شد که میگه:

Property "Book.birthday" is not defined.

که با توجه به نحوه تعریف تابع جادویی __get در activerecord و component طبیعیه.

حالا اگه کد زیر را وارد کنیم

[left]




$obj = new book();

echo $obj->attribute();



[/left]

دیگه با استثنا

Property "Book.birthday" is not defined.

مواجه نمیشیم و بجاش یک هشدار php داریم که میگه

Missing argument 1 for CActiveRecord::getAttribute(), called in /path/to/yii/base/CComponent.php on line xxx and defined

حالا اگه تابع __get رو در activerecord و component یه مروری بکنیم:

activerecord :

[left]




	public function __get($name)

	{

		if(isset($this->_attributes[$name]))

			return $this->_attributes[$name];

		elseif(isset($this->getMetaData()->columns[$name]))

			return null;

		elseif(isset($this->_related[$name]))

			return $this->_related[$name];

		elseif(isset($this->getMetaData()->relations[$name]))

			return $this->getRelated($name);

		else

			return parent::__get($name);

	}




[/left]

component :

[left]




	public function __get($name)

	{

		$getter='get'.$name;

		if(method_exists($this,$getter))

			return $this->$getter();

		elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))

		{

			// duplicating getEventHandlers() here for performance

			$name=strtolower($name);

			if(!isset($this->_e[$name]))

				$this->_e[$name]=new CList;

			return $this->_e[$name];

		}

		elseif(isset($this->_m[$name]))

			return $this->_m[$name];

		elseif(is_array($this->_m))

		{

			foreach($this->_m as $object)

			{

				if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))

					return $object->$name;

			}

		}

		throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',

			array('{class}'=>get_class($this), '{property}'=>$name)));

	}




[/left]

وقتی ما


$obj->attribute

رو صدا میزنیم تابع __get از activerecord فراخوانی میشه و چون نمی‌تونه چیزی برگردونه میآد __get والدش یعنی model رو صدا میزنه و چون model تابع جادویی __get رو پیاده‌سازی نکرده لذا __get از کلاس component فراخوانی میشه که اونم با توجه به تعریفش میاد getattribute() رو فراخوانی میکنه که تعداد پارامتراش با اون چیزی که تو activerecord پیاده‌سازی شده فرق می‌کنه و همین باعث میشه php هشدار بده.

خلاصه مطلب اینکه توابع setattribute و getattribute در activerecord با توجه به تعریف توابع جادویی __get و __set در component باعث میشه که php فکر کنه کلاسهایی که از activerecord مشتق میشن داری خاصیتی به نام attribute هستند که در واقع درست نیست.

[/right]

[/rtl]

[rtl]

[font="Tahoma"] الان راه حل این مشکل چیه؟ [/font]

[/rtl]

[rtl]

[right]

کلا مشکلی نیست

فقط باید حواسمون باشه با توجه به توابع به تعریف توابع جادویی get و set تو کلاس component اگه کلاسی از این کلاس مشتق بشه هر تابعی که با set یا get شروع میشه به عنوان تابعی برای گرفتن یا ست کردن یک مقداری در نظر گرفته میشه.

مثلا اگه یه تابعی به نام setsomething تو کلاسمون داشته باش داشته باشیم وقتی می‌نویسیم

[left]




$obj = new subcomponent();

$obj-> something = 10;



[/left]

باعث میشه تابع

[left]




setsomething(10)



[/left]

صدا زده بشه.

حالا فرض کنید تابعی به نام setting داشته باشیم که خیلی هم چیز بعیدی نیست که با عث میشه با نوشتن

[left]




$obj->ting = 10;



[/left]

تابع setting(10) صدا زده بشه

[/right]

[/rtl]

[rtl][font="Tahoma"]دوست عزیز این باگ نیست و یکی از خواص کلاسهایی هست که از CComponent یا مشتقاتش مشتق شدند

مثل CActiveRecord و CController و برای اینه که بشه با استفاده از توابعی که با get یا set شروع میشن property های مجازی ایجاد کرد.

Component Property

[/font][/rtl]

[rtl]

ساختار ccomponent رو می‌دونم و طبق همین ساختار باید کلاسهایی که از این کلاس مشتق می‌شد تنها در صورتی نام تابعی رو با get یا set شروع کنند که با تعریفی که تو توابع جادویی set و get هست مشکلی پیش نیاد.

در حالیکه cactiverecord این ساختار رو رعایت نکرده

چیزی که میگید دقیقا درسته و این در حالیه که setattribute و getattribute برای این نوشته نشدن که خاصیت مجازی attribute ایجاد بشه

[/rtl]

[rtl]

[font="Tahoma"]کاملا درسته، اما به سختی میتونم بهش بگم باگ، به این خاطر که مشکلی ایجاد نمیکنه[/font]

[/rtl]

[rtl]

[right]

منم تو تایپیک های قبلی هم گفتم که مشکلی نیست

فقط من یه خورده زیادی حساسم

[/right]

[/rtl]