تالار گفتمان nCIS.ir

نسخه‌ی کامل: توضیح کد layout/main
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
<?php foreach(Categories::model()->findAll('parent_id IS NULL AND confirmed=1') as $category) : ?>
                            <?php if(!($subCategories = Categories::model()->findAll('parent_id=:parentId AND confirmed=1',array(':parentId'=>$category->id)))): ?>
                            <li><a href="<?php echo Yii::app()->createUrl('categories/view',array('id'=>$category->id)); ?>"><?php echo CHtml::encode($category->name); ?></a></li>
                            <?php else : ?>
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><?php echo CHtml::encode($category->name); ?> <span class="caret"></span></a>
                                <ul class="dropdown-menu" role="menu">
                                    <?php foreach($subCategories as $subCategory) : ?>
                                    <li><a reef="<?php echo Yii::app()->createUrl('categories/view',array('id'=>$subCategory->id)); ?>"><?php echo CHtml::encode($subCategory->name); ?></a></li>
                                    <?php endforeach; ?>
                                </ul>
                            </li>
                            <?php endif; ?>
                            <?php endforeach; ?>
سلام
استاد من خطوط php کد بالا( از صفحه main در پوشه layout جلسه 5 پیشرفته تا حرفه ای ،پروژه shop )رو متوجه نمیشم .میشه یه توضیح کامل از این دستورات بدید.
ابتدا اومدیم گفتیم به ازای تمام رکوردهایی از جدول categories که parent_id اونها خالی هست (دسته بندیهای اصلی) یه حلقه بساز. بعد داخل حلقه، میگیم اگه نتونستی رکوردی استخراج کنی از جدول categories که parent_id اون با id دسته بندی اصلی یکی بود و بگذاری داخل subCategories$ (یعنی این متغیر null بود)، اونوقت فقط لینک دسته بندی رو بصورت عادی بگذار ولی اگه null نبود (قسمت else) اونوقت باید لینک رو بصورت DropDrown بسازیم و داخلش دسته بندیهای فرعی (subCategories$) رو پیمایش کنیم و برای هرکدوم یک لینک فرعی بسازیم. ضمناً توی کدتون اشتباهاً بجای href نوشتین reef
در این دستور
findAll('parent_id=:parentId AND confirmed=1',array(':parentId'=>$category->id))

منظور از :parentId چیه؟ Huh
با Parameterized Queries و Prepared Statements کار کردین؟ توی PDO این شکلی میشه پارامتر تعریف کرد و بعد، پارامترها رو مقداردهی میکنیم و خودش Escape میکنه. الان گفتیم بعد از =parent_id یک متغیر داریم به اسم parentId: که مقدارش هم فیلد id از شئ category$ هست. خودش این مقدار رو Escape میکنه و خطر SQL Injection از بین میره.
من تا به حال با Parameterized Queries و Prepared Statements کار نکردم،اما از توضیحتون تقریبا متوجه این خط کد شدم.
توی PDO این شکلیه که همیشه اگر بخوایم پارامتر تعریف کنیم و بعد، پارامترها رو مقداردهی کنیم باید همین طوری بنویسیم منظورم اینه که سینتکس دستور همین جوریه؟
بله به همین شکله. البته اینطوری هم میشه کار کرد:
findAll('parent_id=? AND confirmed=1', array($category->id));
توی این روش، پارامترها اسم ندارن و باید به همون ترتیبی که ? گذاشتیم، توی آرایه مقدارها رو بنویسیم که روش خلاصه تریه ولی انعطاف روش نامگذاری شده رو نداره. مثلاً یکی از امکانات روش نامگذاری شده، امکان استفاده از یک متغیر در چند جا توی کوئری هست. همچنین میشه متغیرها رو به ترتیب تعریف کردن، توی آرایه تعریف نکنیم که برای مواقعی که متغیرها رو از جای دیگری (مثل دیتابیس) بارگذاری میکنیم، کاربرد داره.
میشه دستورات createUrl و chtml::encode رو هم توضیح بدید.
createUrl میاد با ساختاری که توی تنظیمات urlManager مشخص کردین، براتون لینک میسازه به کنترلر/اکشن موردنظر شما. CHtml::encode هم متن ورودی شما رو با تابع htmlspecialchars تبدیل به متن بی خطر میکنه (Escape) تا خطر Javascript Injection و XSS و... منتفی بشه. نقطه مقابل این تابع هم CHtml::decode هست.
میشه دستور createUrl رو با جزئیات بیشتری با توجه به کد زیر توضیح بدید؟
createUrl('categories/view',array('id'=>$category->id))
خوب این دستور میاد در حالت عادی، چنین لینکی میسازه (با فرض اینکه $category->id مقدارش 5 هست) :
کد:
/?r=categories/view&id=5

اما اگه urlManager رو فعال کرده باشین، همین دستور در حالت پیشفرض میاد چنین لینکی میسازه:
کد:
/categories/view/id/5

حالا اگه توی تنظیمات urlManager توی protected/config/main.php چنین چیزی نوشته باشین (در قسمت rules) :
'category-<id:d+>' => 'categories/view',

این دستور لینکی که میسازه این شکلی میشه:
کد:
'/category-5'

اگه توی تنظیمات urlManager این رو هم نوشته باشین:
'urlSuffix' => '.html',

اونوقت لینکی که میسازه اینطوری میشه:
کد:
'/category-5.html'

درواقع شما وقتی لینکها رو با این دستور میسازین، برحسب تنظیماتی که برای urlManager مشخص میکنید، خودش تمام لینکهای سایت شما رو اصلاح میکنه. اینطوری، فرضاً اگه خواستین پسوند html. رو از تمام لینکها حذف کنین، کافیه که توی urlManager قسمت urlSuffix رو حذف کنید. اونوقت تمام لینکهایی که با این دستور ساختین، بطور خودکار اصلاح خواهند شد.

یه دستور دیگه هم داریم که شبیه همینه به اسم createAbsoluteUrl که تنها تفاوتشون در اینه که دومی، آدرس مطلق میسازه (آدرس سایتتون رو هم به اولش اضافه میکنه) که برای مواقعی کاربر داره که میخواین از لینکی که ساخته میشه، توی سایر سایتها استفاده بشه. مثلاً لینکی که به مطالبتون توی RSS میدین.

توصیه میکنم برای درک بهتر نحوه کار فریمورک، پکیج Yii رو تهیه کنید. اگه نمیخواین هزینه کنید هم مطالعه کتاب Web Application Development with Yii and PHP رو توصیه میکنم.
ضمناً لطف کنید برای هر سؤال، یک تاپیک جدا ایجاد کنید. منظورم اینه که توی هر تاپیک، فقط به یک سؤال بپردازین. اینطوری هم تاپیکها سنگین و طولانی و کسل کننده نمیشن و هم قابلیت جستجوی اونها افزایش پیدا میکنه.