ارتقا از نسخه 1.1
تفاوتهای خیلی زیادی بین نسخه های 1.1 و 2.0 فریمورک Yii وجود داره چون فریمورک کاملاً توی 2.0 بازنویسی شده. درنتیجه، ارتقاء از نسخه 1.1 به راحتی ارتقاء توی نسخه های فرعی نیست. توی این قسمت تفاوتهای اصلی بین دو نسخه رو پیدا میکنید.
اگه از نسخه 1.1 قبلاً استفاده نکردین، میتونید با خیال راحت از این بخش بگذرین و مستقیماً «
شروع به کار» رو بخونید.
لطفاً دقت کنید که Yii 2.0 قابلیتهای جدید بیشتری نسبت به چیزهایی که توی این فهرست خلاصه پوشش داده شده، معرفی کرده. شدیداً پیشنهاد میکنیم که کل این آموزش رو برای یادگیری همه اونها بخونید. مواردی وجود دارن که یکسری قابلیتها که قبلاً مجبور بودین خودتون پیاده سازی کنید، حالا جزو کد هسته فریمورک شده باشن.
نصب
Yii 2.0 از مدیر بسته PHP یعنی
کامپوزر استفاده میکنه. نصب هسته فریمورک و افزونه ها الآن ازطریق Composer انجام میشه. لطفاً به بخش
نصب Yii برای فهمیدن روش نصب Yii 2.0 مراجعه کنید. اگه میخواین افزونه جدیدی بسازین یا افزونه قبلی خودتون رو برای 1.1 به افزونه سازگار با 2.0 تبدیل کنید، به بخش «
ساخت افزونه» توی آموزش مراجعه کنید.
نیازمندیهای PHP
Yii 2.0 نیاز به PHP 5.4 یا بالاتر داره که نسبت به نسخه 5.2 که موردنیاز Yii 1.1 بود، یه رشد خیلی بزرگ محسوب میشه. درنتیجه، تفاوتهای زیادی توی سطح زبان برنامه نویسی وجود داره که باید بهش دقت کنید. خلاصه ای از تغییرات اصلی با توجه به نسخه جدید PHP رو مشاهده میکنید:
فضاهای نام
آشکارترین تغییر توی Yii 2.0 استفاده از namespace هاست. تقریباً تمامی کلاسهای پایه دارای فضای نام شدن. برای مثال yiiwebRequest. پیشوند C دیگه توی اسامی کلاسها استفاده نمیشه. الگوی نامگذاری الان از ساختار پوشه ها پیروی میکنه. برای مثال، yiiwebRequest نشون میده که فایل کلاس موردنظر، web/Request.php توی پوشه فریمورک Yii هست.
(شما میتونین از هر کلاس هسته فریمورک بدون ضمیمه کردن فایل کلاس مربوطه، به لطف بارگذاری خودکار کلاسها در Yii استفاده کنید).
جزء و شئ
Yii 2.0 کلاس CComponent نسخه 1.1 رو به دو کلاس شکسته:
yiibaseObject و
yiibaseComponent. کلاس Object یه کلاس پایه سبک هست که اجازه تعریف
خصوصیات اشیاء رو با کمک دستیابهای getter و setter میده. کلاس Component از کلاس Object مشتق شده و از
رویدادها و
رفتارها پشتیبانی میکنه.
اگه کلاس شما نیاز به ویژگی رویدادها یا رفتار نداره، باید از کلاس Object بعنوان کلاس پایه اون استفاده کنید. این مورد بیشتر برای کلاسهایی که نماینده ساختمانهای داده ساده هستن بکار میره.
تنظیم کردن شئ
کلاس Object یه راه یکدست برای تنظیم کردن اشیاء معرفی میکنه. هر کلاس فرعی از کلاس Object باید سازنده خودش رو (درصورت وجود) به شکل زیر تنظیم کنه تا بتونه به شکل صحیح تنظیم بشه:
class MyClass extends yiibaseObject
{
public function __construct($param1, $param2, $config = [])
{
// ... initialization before configuration is applied
parent::__construct($config);
}
public function init()
{
parent::init();
// ... initialization after configuration is applied
}
}
توی کد بالا، آخرین پارامتر سازنده باید یه آرایه از تنظیمات رو بگیره که شامل زوجهای key => value برای مقداردهی اولیه عناصر در انتهای سازنده هست. میتونید متد ()init رو بازنویسی کنید تا آماده سازیهایی رو انجام بده که باید بعد از تنظیم کردن شئ، انجام بشن.
با پیروی از این مفهوم، میتونید اشیاء رو با کمک یه آرایه تنظیمات، بسازین و تنظیم کنید:
$object = Yii::createObject([
'class' => 'MyClass',
'property1' => 'abc',
'property2' => 'cde',
], [$param1, $param2]);
جزئیات بیشتر درمورد تظنیم کردن شئ رو توی بخش
تنظیمات میتونید پیدا کنید.
رویدادها
توی Yii 1.1 رویدادها با تعریف یه متد با پیشوند on (مثل onBeforeSave) تعریف میشدن. توی Yii 2.0 میتونین از هر اسمی برای رویداد استفاده کنید. برای تولید یه رویداد میتونید از متد
()trigger استفاده کنید:
$event = new yiibaseEvent;
$component->trigger($eventName, $event);
برای نسبت دادن یه کنترل کننده به یه رویداد، از متد
()on استفاده کنید:
$component->on($eventName, $handler);
// To detach the handler, use:
// $component->off($eventName, $handler);
پیشرفتهای خیلی زیادی توی قابلیتهای رویدادها ایجاد شده. برای جزئیات بیشتر، بخش
رویدادها رو توی آموزش بخونید.
اسامی مستعار مسیر
Yii 2.0 استفاده از اسامی مستعار مسیر (Path Aliases) رو به مسیر هر دو مورد فایلها/پوشه ها و URL ها گسترش داده. همچنین Yii 2.0 الان نیاز داره که یه اسم مستعار با کارکتر @ شروع بشه تا اون رو از مسیرهای فایلها/پوشه ها یا URL های معمولی متمایز کنه. برای مثال، اسم مستعار yii@ به مسیر نصب Yii اشاره میکنه. اسامی مستعار توی اغلب جاها توی کد هسته Yii پشتیبانی شدن. برای مثال،
YiicachingFileCache::$cachePath میتونه هم اسم مستعار مسیر و هم مسیر معمولی یه پوشه رو قبول کنه.
یه اسم مستعار مسیر به شدت وابسته به فضای نام کلاس هست. پیشنهاد میشه که یه اسم مستعار مسیر برای هر فضای نام ریشه درست بشه. اینطوری به شما اجازه میده که از بارگذاری خودکار کلاس Yii بدون هرگونه تنظیم اضافه استفاده کنید. برای مثال، از اونجا که yii@ به مسیر نصب Yii اشاره میکنه، کلاسی مثل yiiwebRequest رو میشه بطور خودکار بارگذاری کرد. اگه از یه کتابخانه جانبی مثل Zend Framework استفاده میکنید، ممکنه یه اسم مستعار مسیر به اسم Zend@ تعریف کنید که به محل نصب اون فریمورک اشاره میکنه. وقتی اینکار رو انجام دادین، میتونید هر کلاسی رو توی اون کتابخانه فریمورک Zend هم بطور خودکار بارگذاری کنید.
جزئیات بیشتر درمورد اسامی مستعار مسیر رو توی بخش «
اسامی مستعار» بخونید.
ویوها (View)
بزرگترین تغییر توی Yii 2 اینه که متغیر خاص this$ توی ویو دیگه به کنترلر یا ویجت جاری اشاره نمیکنه. this$ الان به یه شئ از کلاس View اشاره میکنه که مفهوم جدیدی هست که توی نسخه 2.0 معرفی شده. شئ ویو از نوع
yiiwebView هست که نماینده بخش View از الگوی MVC محسوب میشه. اگه میخواین به کنترلر یا ویجت توی یه ویو دسترسی داشته باشین، میتونید از this->context$ استفاده کنید.
برای نمایش یه ویو داخل یه ویوی دیگه باید از ()this->render$ استفاده کنید نه ()this->renderPartial$. فراخوانی متد render هم باید مستقیماً و صراحتاً با کمک echo برای نمایش خروجی همراه بشه چون متد ()render خروجی رو بعنوان نتیجه برمیگردونه، بجای اینکه مستقیماً نمایش بده. برای مثال:
echo $this->render('_item', ['item' => $item]);
درکنار استفاده از PHP بعنوان زبان اصلی قالب، Yii 2.0 از پشتیبانی رسمی دو موتور قالب محبوب هم بهره میبره: Smarty و Twig. موتور قالب Prado دیگه پشتیبانی نمیشه. برای استفاده از این موتورهای قالب، باید کامپوننت برنامه به اسم view رو با خاصیت تنظیم کردن
View::$renderers پیکربندی کنید. برای اطلاعات بیشتر به بخش
موتورهای قالب مراجعه کنید.
مدل ها (Model)
Yii 2.0 از کلاس yiibaseModel بعنوان مدل پایه استفاده میکنه، شبیه CModel توی 1.1. کلاس CFormModel کاملاً حذف شده. بجاش توی Yii 2 شما باید از کلاس yiibaseModel یه کلاس مشتق کنید تا یه کلاس مدل فرم بسازین.
Yii 2.0 یه متد جدید به اسم
()scenarios معرفی کرده تا سناریوهای پشتیبانی شده رو مشخص کنید، و بگین که توی هر سناریو کدوم فیلدها نیاز به اعتبارسنجی دارن، میتونن امن درنظر گرفته بشن یا نه. برای مثال:
public function scenarios()
{
return [
'backend' => ['email', 'role'],
'frontend' => ['email', '!role'],
];
}
توی کد بالا، دو سناریو به اسامی backend و frontend معرفی شدن. برای backend هر دو فیلد email و role امن هستن و میتونن بصورت انبوه مقداردهی بشن. برای frontend فیلد email میتونه بصورت انبوه مقداردهی بشه درحالی که برای role اینطور نیست. ضمناً هر دو فیلد email و roleباید با کمک قوانین اعتبارسنجی، تأیید اعتبار بشن.
متد
()rules همچنان برای مشخص کردن قوانین اعتبارسنجی بکار میره. دقت کنید که بخاطر معرفی متد ()scenarios دیگه ولیدیتور unsafe وجود نداره.
در اغلب موارد، نیاز به بازنویسی ()scenarios ندارین، اگه متد ()rules بطور کامل سناریوهایی که وجود دارن رو پوشش بده و نیازی به مشخص کردن فیلدهای unsafe وجود نداشته باشه.
برای کسب اطلاعات بیشتر درباره مدل به بخش
مدل ها مراجعه کنید.
کنترلرها (Controller)
Yii 2.0 از کلاس
yiiwebController بعنوان کلاس پایه کنترلر استفاده میکنه که شبیه CController توی Yii 1.1 هست. کلاس
yiibaseAction هم کلاس پایه برای کلاسهای عملیاتی (action) هست.
بیشنریم تأثیر این تغییرات توی کد شما اینه که یه اکشن توی کنترلر باید خروجی که میخواین نمایش بده رو بعنوان نتیجه برگردونه نه اینکه مستقیماً echo کنه:
public function actionView($id)
{
$model = appmodelsPost::findOne($id);
if ($model) {
return $this->render('view', ['model' => $model]);
} else {
throw new yiiwebNotFoundHttpException;
}
}
برای جزئیات بیشتر درباره کنترلر، به بخش مربوط به
کنترلرها مراجعه کنید.
ویجت ها (Widget)
Yii 2.0 از
yiibaseWidget بعنوان کلاس پایه ویجت استفاده میکنه که شبیه CWidget توی Yii 1.1 هست.
برای پشتیبانی بهتر از فریمورک توی IDEها، Yii 2.0 یه دستور زبان جدید برای استفاده از ویجتها معرفی کرده. متدهای ایستای
()begin و
()end و
()widget معرفی شدن تا به شکل زیر از اونها استفاده کنید:
use yiiwidgetsMenu;
use yiiwidgetsActiveForm;
// Note that you have to echo the result to display it
echo Menu::widget(['items' => $items]);
// Passing an array to initialize the object properties
$form = ActiveForm::begin([
'options' => ['class' => 'form-horizontal'],
'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
]);
// form input fields here
ActiveForm::end();
برای جزئیات بیشتر به بخش
ویجت ها مراجعه کنید.
زمینه ها (Theme)
تم توی 2.0 کاملاً متفاوت کار میکنه. تم ها الآن برمبنای یه مکانیزم نگاشت مسیر کار میکنن که یه مسیر فایل ویوی منبع رو به یه مسیر فایل ویوی تم تبدیل میکنه. برای مثال، اگه نگاشت مسیر یه تم این باشه:
['/web/views' => '/web/themes/basic']
اونوقت نسخه داخل تم برای فایل ویوی web/views/site/index.php/ میشه web/themes/basic/site/index.php/ و به همین دلیل، تم ها الان میتونن به هر فایل ویو نسبت داده بشن، حتی اگه ویو خارج از چهارچوب کنترلر یا ویجت رندر بشه (فراموش نکنید که کلاس View هم متد ()render رو داره).
همچنین دیگه کامپوننتی به اسم CThemeManager وجود نداره و بجاش، theme یه فیلد قابل تنظیم از کامپوننت view توی برنامه شده.
برای اطلاعات بیشتر به بخش
ساخت تم مراجعه کنید.
برنامه های کنسول (خط فرمان)
برنامه های کنسول الآن بعنوان کنترلر سازماندهی میشن، شبیه برنامه های وب. کنترلرهای کنسول باید از کلاس
yiiconsoleController مشتق بشن که شبیه CConsoleCommand توی نسخه 1.1 هست.
برای اجرای یه دستور کنسول باید از الگوی
yii <route> استفاده کنید که <route> نماینده یه مسیر کنترلر هست (مثل sitemap/index). پارامترهای بدون نام اضافه بعنوان پارامترهایی که باید به اکشن مربوطه توی کنترلر ارسال بشن درنظر گرفته میشن درحالی که پارامترهای دارای نام برمبنای تعریفی که توی متد
()options اعلام میشه تفسیر خواهند شد.
Yii 2.0 از تولید خودکار اطلاعات راهنمای دستورات براساس بلاکهای کامنت اکشنها پشتیبانی میکنه.
لطفاً برای اطلاعات بیشتر به بخش
دستورات کنسول مراجعه کنید.
بین المللی سازی (I18N)
Yii 2.0 قالب بندی کننده داخلی تاریخ و اعداد رو بخاطر استفاده از ماژول
intl توی PHP حذفذ کرده.
ترجمه پیامها با کمک کامپوننت i18n انجام میشه. این کامپوننت مدیریت مجموعه ای از منابع پیام رو بعهده داره که به شما اجازه میده از چند منبع پیام مختلف براساس دسته بندی پیامها استفاده کنید.
برای جزئیات بیشتر به بخش
بین المللی سازی مراجعه کنید.
فیلترهای اکشن
فیلدهای اکشن الآن ازطریق رفتارها پیاده سازی میشن. برای تعریف یه فیلتر سفارشی جدید، باید کلاس
yiibaseActionFilter رو گسترش بدین. برای استفاده از یه فیلتر، کلاس فیلتر رو به کنترلر بعنوان یه رفتار نسبت بدین. برای مثال، اگه میخواین از فیلتر
yiifiltersAccessControl استفاده کنین، باید چنین کدی توی کنترلر بنویسید:
public function behaviors()
{
return [
'access' => [
'class' => 'yiifiltersAccessControll',
'rules' => [
['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
],
],
];
}}
به بخش
فیلترکردن برای جزئیات بیشتر مراجعه کنید.
دارایی ها (Assets)
Yii 2.0 یه مفهوم جدید به اسم Asset Bundle رو معرفی کرده که جایگزین مفهوم بسته اسکریپت که توی Yii 1.1 وجود داشت شده.
یه بسته دارایی مجموعه ای از فایلها (مثل Javascript و CSS و تصویر و...) است که توی یه پوشه قرار دارن. هر بسته دارایی نماینده با یه کلاس که از
yiiwebAssetBundle مشتق شده نشون داده میشه. با ثبت یه بسته دارایی ازطریق متد
()register کلاس AssetBundle اون دارایی رو بعنوان یه بسته در اختیار وب میگذارین. برخلاف Yii 1.1، صفحه ای که بسته رو ثبت کرده بطور خودکار شامل ارجاع به فایلهای Javascript و CSS که توی اون بسته معرفی شده خواهد بود.
برای جزئیات بیشتر بخش
مدیریت دارایی ها رو مطالعه کنید.
کمک کننده ها
Yii 2.0 کلاسهای کمک کننده ایستای پرکاربردی زیادی رو معرفی کرده. شامل:
برای جزئیات بیشتر به بخش
نگاه کلی به کمک کننده ها مراجعه کنید.
فرم ها
Yii 2.0 مفهوم field رو برای ساخت یه فرم با کمک
yiiwidgetsActiveForm معرفی کرده. یه فیلد، یه نگه دارنده شامل یه برچسب، یه عنصر ورود اطلاعات، یه پیغام خطا و/یا یه متن راهنما هست. یه فیلد بعنوان یه شئ از کلاس
ActiveField تعریف میشه. با استفاده از فیلدها میتونید یه فرم رو به شکل تمیزتری نسبت به قبل بسازین:
<?php $form = yiiwidgetsActiveForm::begin(); ?>
<?= $form->field($model, 'username'); ?>
<?= $form->field($model, 'password')->paswordInput(); ?>
<div class="form-group">
<?= Html::submitButton('Login'); ?>
</div>
<?php yiiwidgetsActiveForm::end(); ?>
برای اطلاعات بیشتر به بخش
ساخت فرمها مراجعه کنید.
ساخت کوئری (Query Builder)
توی نسخه 1.1، ساخت کوئری توی کلاسهای مختلفی مثل CDbCommand و CDbCriteria و CDbCommandBuilder پراکنده شده بود. Yii 2.0 یه کوئری دیتابیس رو بعنوان یه شئ از کلاس
Query نشون میده که میتونه با کمک کلاس
QueryBuilder در پشت پرده تبدیل به یه دستور SQL بشه. برای مثال:
$query = new yiidbQuery();
$query->select('id, name')
->from('user')
->limit(10);
$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();
از همه بهتر اینکه از این روشهای ساخت کوئری میتونید وقتی با
ActiveRecord کار میکنید، هم استفاده کنید.
برای جزئیات بیشتر به بخش
ساخت کوئری نگاه کنید.
اکتیو رکورد (Active Record)
Yii 2.0 تغییرات خیلی زیادی توی
ActiveRecord معرفی کرده. دوتا از آشکارترین تغییراتش شامل ساخت کوئری و مدیریت کوئریهای رابطه ای هست.
کلاس CDbCriteria که توی نسخه 1.1 وجود داشت با
yiidbActiveQuery توی Yii 2 جایگزین شده. این کلاس از
yiidbQuery مشتق شده و بخاطر همین تمام متدهای ساخت کوئری رو به ارث برده. میتونید از متد
()find توی اکتیورکورد برای شروع ساخت یه کوئری استفاده کنید:
// to retrieve all *active* customers and order them by their ID:
$customers = Customer::find()
->where(['status' => $active])
->orderBy('id')
->all();
برای تعریف یه رابطه، کافیه یه متد getter بنویسین که یه شئ ActiveQuery برمیگردونه. اسم فیلد مربوط به رابطه توسط متد getter تعریف میشه. برای مثال، کد زیر یه رابطه به اسم orders تعریف میکنه (توی 1.1 باید رابطه ها رو توی یه مکان مرکزی ()relations تعریف میکردین) :
class Customer extends yiidbActiveRecord
{
public function getOrders()
{
return $this->hasMany('Order', ['customer_id' => 'id']);
}
}
حالا میتونید از customer->orders$ یا ()customer->getOrders$ برای دسترسی به سفارشهای یه مشتری استفاده کنید. حتی میتونید کد زیر برای دنبال کردن کوئری رابطه ای با شرط جدید هم استفاده کنید:
$orders = $customer->orders->andWhere('status=1')->all();
وقتی از بارگذاری حریصانه استفاده میکنید، Yii 2.0 کاملاً متفاوت با 1.1 عمل میکنه. توی 1.1 از کوئری JOIN برای انتخاب رکوردهای اصلی و وابسته استفاده میشد. توی Yii 2.0 دو کوئری جداگانه بدون استفاده از JOIN استفاده میشه: اولی برای استخراج رکوردهای اصلی و دومی برای انتخاب رکوردهای وابسته با فیلترکردن براساس کلیدهای اصلی رکوردهای اصلی.
بجای برگردوندن اشیاء ActiveRecord، میتونید از متد
()asArray استفاده کنید تا تعداد زیادی از رکوردها رو برگردونید. این کار باعث میشه نتایج کوئری بصورت آرایه های معمولی برگردونده بشن که به میزان زیادی زمان CPU و حافظه موردنیاز رو در زمانی که تعداد رکوردهای بازگشتی خیلی زیاده، کاهش میده. مثال:
$customers = Customer::find()->asArray()->all();
یه تغییر دیگه اینه که شما نمیتونید مقادیر پیشفرض فیلدها رو ازطریق فیلدهای public تعریف کنید. اگه میخواین چنین کاری انجام بدین،باید اونها رو توی متد init کلاس مدل موردنظرتون انجام بدین:
public function init()
{
parent::init();
$this->status = self::STATUS_NEW;
}
یه سری مشکلات وقتی که سازنده کلاس ActiveRecord رو توی 1.1 بازنویسی میکردین وجود داشت. این مشکلات دیگه توی نسخه 2.0 وجود ندارن. دقت کنید که وقتی پارامتری رو به سازنده اضافه میکنید، احتمالاً لازمه متد
()instantiate کلاس ActiveRecord رو هم توی مدل خودتون بازنویسی کنید.
تغییرات خیلی زیاد و پیشرفتهای دیگه توی اکتیورکورد وجود داشته. به بخش
ActiveRecord برای جزئیات بیشتر مراجعه کنید.
رفتارهای ActiveRecord
توی نسخه 2.0 کلاس پایه CActiveRecordBehavior رو حذف کردیم. اگه میخواین یه رفتار توی اکتیورکورد بسازین، باید اون رو مستقیماً از yiiBaseBehavior مشتق کنید. اگه کلاس رفتار نیاز به پاسخ به یکسری رویداد از مالک خودش داشته باشه، باید متد ()events رو به شکل زیر بازنویسی کنید:
namespace appcomponents;
use yiidbActiveRecord;
use yiibaseBehavior;
class MyBehavior extends Behavior
{
// ...
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValide',
];
}
public function beforeValidate($event)
{
// ...
}
}
کاربر و رابط احراز هویت (User و IdentityInterface)
کلاس CWebUser توی نسخه 1.1 الآن با
yiiwebUser جایگزین شده و دیگه کلاس CUserIdentity وجود نداره. بجاش، شما باید رابط
yiiwebIdentityInterface رو پیاده سازی کنید که خیلی برای استفاده، سرراست تره. قالب پروژه Advanced یه مثال ازش داره.
برای اطلاعات بیشتر به بخشهای
Authentication و
Authorization و
قالب پروژه Advanced مراجعه کنید.
مدیریت URL
مدیریت آدرسهای وب توی Yii 2 شبیه نسخه 1.1 هست. یه پیشرفت بزرگ این بوده که مدیریت URL الان از پارامترهای اختیاری هم پشتیبانی میکنه. برای مثال اگه یه رول بصورت زیر تعریف کنید، اونوقت هم از post/popular و هم از post/1/popular پشتیبانی میکنه. توی Yii 1.1 باید دوتا رول برای اینکار مینوشتین:
[
'pattern' => 'post/<page:d+>/<tag>',
'route' => 'post/index',
'defaults' => ['page' => 1],
]
به بخش
مستندات مدیر URL برای جزئیات بیشتر مراجعه کنید.
یه تغییر مهم توی مفهوم نامگذاری مسیرها این بوده که اسامی camelCase و PascalCase برای کنترلرها و اکشنها تبدیل به ID هایی با حروف کوچک و خط تیره بعنوان جداکننده میشن. برای مثال، اگه اسم کنترلر شما CategoryManagementController باشه، ID کنترلر بصورت category-management خواهد بود. قسمت مربوط به
ID های کنترلر و
ID های اکشن رو برای جزئیات بیشتر مطالعه کنید.
استفاده از Yii 1.1 و 2.x با هم
اگه یه کد قدیمی Yii 1.1 دارین و میخواین از اون درکنار Yii 2.0 استفاده کنید، به بخش
استفاده از Yii 1.1 و 2.0 با هم مراجعه کنید.