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

نسخه‌ی کامل: آموزش کدایگنایتر CodeIgniter
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
صفحات: 1 2 3
ارزیابی کارآیی برنامه
کلاس Profiler نتایج محک‌زدن برنامه (Benchmark)، کوئری‌های اجراشده و مقادیر $_POST رو در انتهای صفحاتتون نشون میده. این اطلاعات میتونه درحین توسعه‌ی پروژه برای کمک به اشکال‌زدایی و بهینه‌سازی برنامه، مفید باشه.

آماده‌سازی کلاس
نقل قول:مهم: این کلاس نیاز به آماده‌سازی خاصی نداره و بطور خودکار توسط کتابخانه‌ی خروجی بارگذاری میشه اگه قابلیت نمایش اطلاعات مربوطه رو به‌شکلی که در ادامه میگیم، فعال کرده باشین.

فعال‌کردن گزارش
برای فعال‌کردن Profiler کافیه این‌خط رو هرجایی توی متدهای کنترلرتون بگذارین:
$this->output->enable_profiler(TRUE);

وقتی این قابلیت رو فعال کنید، یه گزارش تولید و در انتهای صفحاتتون درج میشه. برای غیرفعال‌کردنش هم کافیه از این دستور استفاده کنید:
$this->output->enable_profiler(FALSE);

مشخص‌کردن نقاط سنجش
برای اینکه Profiler رو وادار با کامپایل و نمایش داده‌های Benchmark کنین، باید نقاط موردنظرتون رو باکمک دستور زبان مشخصی اسم ببرین. اطلاعات موردنیاز درخصوص نقاط Benchmark رو از مستندات کتابخانه‌ی Benchmark بخونین.

فعال و غیرفعال‌کردن قسمت‌های مختلف Profiler
هر قسمتی از داده‌های پروفایلر رو میشه فعال یا غیرفعال کرد. برای این‌کار باید متغیر تنظیمات مربوطه رو TRUE یا FALSE کنید. این‌کار به دو روش قابل انجامه. روش اول اینکه تنظیمات کلی برنامه رو توی فایل application/config/profiler.php مشخص کنین. برای مثال:
$config['config']  = FALSE;
$config['queries'] = FALSE;

در روش دوم، توی کنترلرهاتون میتونین تنظیمات پیشفرض رو تغییر بدین و مقادیر رو با صدازدن متد set_profiler_sections() از کتابخانه‌ی خروجی ویرایش کنین:
$section = [
    'config'  => TRUE,
    'queries' => TRUE,
];

$this->output->set_profiler_sections($sections);

مقادیر مجاز برای کلیدهای آرایه‌ای که برای این متد ارسال می‌کنید، شامل فهرست زیر هست:
  • benchmarks زمان سپری‌شده برای هر نقطه‌ی Benchmark و زمان کلی اجرای اسکریپت (پیشفرض: TRUE)
  • config متغیرهای تنظیمات CodeIgniter (پیشفرض: TRUE)
  • controller_info کلاس کنترلر و متد درخواست‌شده (پیشفرض: TRUE)
  • get هرگونه داده‌ای که با روش Get برای صفحه ارسال شده باشه (پیشفرض: TRUE)
  • http_headers هدرهای HTTP درخواست جاری (پیشفرض: TRUE)
  • memory_usage مقدار حافظه‌ی مصرفی درخواست جاری برحسب بایت (پیشفرض: TRUE)
  • post مقادیر ارسال‌شده برای صفحه با روش Post (پیشفرض: TRUE)
  • queries فهرست تمام کوئری‌های اجراشده در دیتابیس، شامل زمان اجرای هرکدوم (پیشفرض: TRUE)
  • uri_string نشانی URI درخواست جاری (پیشفرض: TRUE)
  • session_data اطلاعات ذخیره‌شده در Session جاری (پیشفرض: TRUE)
  • query_toggle_count تعداد مشخصی که اگه کوئری‌های صفحه از اون تعداد بیشتر شد، مقدار پیشفرض بلاک کوئری (queries) بشه FALSE و این بلاک بطور پیشفرض مخفی بشه (پیشفرض 25)

نقل قول:نکته: غیرفعال‌کردن گزینه‌ی save_queries توی تنظیمات دیتایبس باعث غیرفعال‌شدن تولید گزارش برای کوئری‌های دیتابیس و نمایش بلاک queries هم میشه و تنظیمات بالا رو در این بخش خاص، عملاً بلااستفاده میکنه. البته میتونین درصورت تمایل، این تنظیم رو با اجرای کد زیر تغییر بدین:
$this->db->save_queries = TRUE;

بدون این تنظیمات، شما نمیتونین کوئری‌های مختلف یا حتی نتیجه‌ی تابع last_query رو از فایل کمکی database/helpers مشاهده کنین.
اجرای برنامه با کمک رابط خط فرمان CLI
همونطور که کنترلرها رو میشه توسط URL توی مرورگر فراخوانی کرد، میشه اونها رو با کمک رابط خط فرمان (CLI) هم فراخوانی کنیم.

رابط خط فرمان CLI چیه؟
ابزار Command Line Interface یک روش متنی برای تعامل با کامپیوترها محسوب میشه. برای اطلاعات بیشتر، این مقاله‌ی ویکی‌پدیا رو مطالعه کنید.

چرا برنامه رو با خط فرمان اجرا کنیم؟
دلایل زیادی وجود داره که بخوایم کدایگنایتر رو ازطریق خط فرمان اجرا کنیم ولی این دلایل همیشه ممکنه واضح نباشن:
  • اجرای کارهای زمانبندی‌شده ازطریق Cron Jobs یا Scheduled Tasks بدون نیاز به wget یا curl
  • جلوگیری از اجرای کنترلرها و اکشن‌های مخصوص خط‌فرمان توسط URL در مرورگر با کمک مقدار بازگشتی is_cli()
  • ایجاد «وظایف» تعاملی که میتونن کارهایی مثل تعیین مجوزها، خالی‌کردن پوشه‌های کَش (Cache)، پشتیبان‌گیری و... رو انجام بدن
  • ادغام با سایر برنامه‌ها در زبان‌های دیگه. برای مثال یک اسکریپت فرضی C++ ممکنه یک دستور رو فراخوانی کنه و کدی رو داخل مدل‌های شما اجرا کنه!

بذارین امتحان کنیم: سلام دنیا!
اجازه بدین یه کنترلر ساده بسازیم که بتونیم در عمل اجرای CodeIgniter رو ازطریق CLI ببینیم. با کمک ویرایشگر متنی خودتون، فایلی به‌اسم Tools.php بسازین و این کد رو داخلش بنویسین:
<?php
class Tools extends CI_Controller
{
    public function message ($to = 'World')
    {
        echo "Hello {$to}!" . PHP_EOL;
    }
}

حالا این فایل رو در مسیر application/controllers/ ذخیره کنید. قاعدتاً اگه آدرسی شبیه این رو اجرا کنین، میتونین خروجی رو مشاهده کنید:
localhost/ci_example/index.php/tools/message/to

اما الان بجای این روش، میخوایم پنجره‌ی خط‌فرمان (Command Prompt در ویندوز یا Terminal در مک و لینوکس) رو باز کنیم و وارد مسیر پروژه‌ی کدایگنایترمون بشیم:
cd /var/www/html/ci_example
php index.php tools message

اگه کارها رو درست انجام داده باشین، خروجی Hello World! چاپ میشه. حالا این رو تست کنید:
php index.php tools message "CodeIgniter Developer"

و ببینید خروجی تولیدشده چیه. در ایجا ما داریم یه آرگومان رو به‌شکل مشابه با زمانی که از URL استفاده میکردیم، ارسال میکنیم. CodeIgniter Developer آرگومانی هست که ارسال میکنیم و خروجی هم بصورت زیر خواهد بود:
Hello CodeIgniter Developer!

همش همین بود
این توضیحات، خیلی خلاصه شامل تمام مواردی بود که لازمه درمورد اجرا کنترلرها در خط فرمان بدونین. دقت کنید که این کنترلر، همچنان یک کنترلر عادیه و درنتیجه مسیریابی و _remap() به‌خوبی کار میکنه.
مدیریت برنامه
در اصل اینطور فرض شده که شما میخواین از کدایگنایتر برای مدیریت یک برنامه استفاده کنین که توی پوشه‌ی application میسازینش. هرچند ممکنه که مجموعه‌ای از چند برنامه داشته باشین که از یک نصب واحد CodeIgniter استفاده میکنن، یا حتی میتونین پوشه‌ی برنامه‌ی خودتون رو جابجا کنین و اسمش رو تغییر بدین.

تغییر نام پوشه‌ی برنامه
اگه میخواین اسم پوشه‌ی برنامه‌ی خودتون رو عوض کنین، مشکلی وجود نداره. کافیه فایل index.php رو باز کنین و اسم پوشه‌ی جدید رو توی متغیر $application_folder قرار بدین:
$application_folder = 'application';

جابجایی پوشه‌ی برنامه
این امکان وجود داره که پوشه‌ی برنامه رو در مکان متفاوتی توی سرورتون قرار بدین. برای این‌کار باید فایل index.php رو باز کنین و «مسیر کامل» رو توی متغیر $application_folder ذخیره کنین:
$application_folder = '/path/to/your/application';

اجرای چند برنامه با یک نصب CodeIgniter
اگه میخواین با یکبار نصب کدایگنایتر، چند برنامه رو مدیریت کنین، کافیه تمام برنامه‌ها رو توی یک پوشه‌ی مشترک (مثلاً application) قرار بدین. برای مثال فرض کنین نیاز به دو برنامه‌ی foo و bar دارین. میتونین ساختار پوشه‌ها رو اینطوری تنظیم کنین:
applications/foo/
applications/foo/config/
applications/foo/controllers/
applications/foo/libraries/
applications/foo/models/
applications/foo/views/
applications/bar/
applications/bar/config/
applications/bar/controllers/
applications/bar/libraries/
applications/bar/models/
applications/bar/views/

حالا برای انتخاب یک برنامه‌ی دلخواه برای استفاده، کافیه که فایل index.php رو باز کنین و متغیر $application_folder رو تنظیم کنین. برای مثال، اگه بخواین برنامه‌ی foo انتخاب بشه، اینطوری باید بنویسین:
$application_folder = 'application/foo';

نقل قول:نکته: هرکدوم از برنامه‌های شما میتونن به فایل index.php خاص خودشون نیاز داشته باشن که تنظیمات خاص اون برنامه داخلشه. لازم نیست حتماً اسم فایل index.php باشه. میتونین با .htaccess درخواست‌ها رو به فایل دلخواه خودتون هدایت کنین.
کنترل محیط‌های چندگانه
توسعه‌دهندگان اغلب ترجیح میدن رفتارهای متفاوتی رو از سیستم بسته‌به اینکه برنامه داره توی محیط توسعه یا محیط محصول نهایی اجرا میشه، مشاهده کنن. برای مثال، خروجی خطای با جزئیات کامل، چیزیه که میتونه درحین توسعه کارآمد باشه ولی یه مشکل امنیتی جدی در زمان اجرای «زنده»ی برنامه ایجاد کنه.

ثابت ENVIRONMENT
بطور پیشفرض کدایگنایتر از ثابت محیطی استفاده میکنه که مقدارش رو از متغیر سرور $_SERVER['CI_ENV'] میگیره و اگه این متغیر مقداردهی نشده باشه، مقدار پیشفرض development براش درنظر گرفته میشه. در ابتدای فایل index.php چنین کدی رو مشاهده می‌کنید:
define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');

این متغیر سرور میتونه توی فایل .htaccess یا تنظیمات سرور آپاچی SetEnv مقداردهی بشه. روش‌های جایگزین دیگه توی nginx و سایر سرورها هم وجود دارن، یا میتونین کلاً این منطق رو حذف کنین و ثابت مربوطه رو براساس آدرس IP سرور تنظیم کنین.

علاوه‌بر تأثیری که روی برخی رفتارهای پایه‌ی فریمورک گذاشته میشه (که در ادامه، درموردش توضیح میدیم)، این ثابت توی توسعه‌ی شخصی خودتون هم برای تفاوت‌گذاشتن بین محیطی که درحال اجراست میتونه به‌کار گرفته بشه.

تأثیرها روی رفتار پیشفرض فریمورک
مکان‌های خاصی در سیستم CodeIgniter وجود دارن که ثابت ENVIRONMENT بکار گرفته شده. این مکان‌ها چگونگی رفتار پیشفرض فریمورک رو مشخص میکنن.

گزارش خطا
تنظیم‌کردن ثابت ENVIRONMENT با مقدار development باعث میشه تمام خطاهای PHP توی مرورگر درصورت بروز خطا نمایش داده بشن. درمقابل، قراردادن این ثابت با مقدار production باعث میشه تمام خطاهای خروجی غیرفعال بشن. غیرفعال‌کردن خطاها در محیط اجرای محصول نهایی، یک الگوی خوب امنیتی محسوب میشه.

فایل‌های تنظیمات
درصورت تمایل، میتونین از کدایگنایتر بخواین که فایل‌های تنظیمات وابسته به محیط رو بارگذاری کنه. این‌کار میتونه برای مدیریت مواردی مثل کلیدهای API مختلف در محیط‌های متفاوت و... مفید باشه. این موضوع رو بعداً با جزئیات بیشتر در بخش کلاس Config توضیح میدیم.
دستورزبان جایگزین PHP برای فایل‌های ویو
اگه از موتور قالب کدایگنایتر استفاده نمیکنین، اونوقت باید از PHP خام توی فایل‌های View خودتون بهره ببرین. برای کاهش کدهای PHP شما توی این فایلها و خواناترشدن تشخیص بلاک‌های کد، پیشنهاد میکنیم که از دستورزبان جایگزین PHP برای ساختارهای کنترلی و دستور کوتاه echo استفاده کنین. اگه با این دستورزبان آشنا نیستین، باید بگم که این ساختار به شما کمک میکنه تا آکولادها و دستور echo رو از کدتون حذف کنین.

پشتیبانی خودکار از تگ کوتاه
نقل قول:نکته: اگه متوجه شدین ساختاری که اینجا توضیح میدیم، توی سرور شما کار نمیکنه، ممکنه بخاطر این باشه که short tags توی تنظیمات php.ini سرور شما غیرفعال شده. کدایگنایتر میتونه بطور خودکار تگ‌های کوتاه رو بازنویسی کنه تا از این دستورزبان حتی در مواقعی که سرور شما ازش پشتیبانی نمیکنه هم استفاده کنین. میتونین این قابلیت رو توی فایل config/config.php تنظیم کنین:
$config['rewrite_short_tags'] = TRUE;

دقت کنید که اگه از این قابلیت استفاده کنید، درصورتی‌که خطاهای PHP توی «فایل‌های ویو» اتفاق بیفته، پیغام خطا و شماره‌ی خط مربوطه بطور دقیق نشون داده نمیشه. درعوض تمام خطاها بصورت خطاهای دستور eval() ظاهر میشن.

جایگزین echo
معمولاً برای نمایش مقدار یک متغیر، از دستوری به این شکل استفاده میشه:
<?php echo $variable; ?>

اما با ساختار جایگزین میتونین این‌شکلی بنویسین:
<?=$variable?>

ساختارهای کنترلی جایگزین
ساختارهای کنترلی نظیر if و for و foreach و while میتونن با روشی ساده‌تر هم نوشته بشن. در اینجا مثالی از foreach رو مشاهده میکنین:
<ul>
<?php foreach ($todo as $item): ?>
    <li><?=$item?></li>
<?php endforeach; ?>
</ul>

دقت‌کنید که هیچ آکولادی وجود نداره. درعوض بجای آکولاد باز از کالن (:) و بجای آکولاد بسته از endforeach استفاده شده. هرکدوم از ساختارهای کنترلی که در بالا اشاره کردیم، الگوی بستن متناظر با خودشون یعنی endif و endfor و endforeach و endwhile رو دارن.

یه مثال دیگه از ساختار if/elseif/else رو ببینید:
<?php if ($username === 'sally'): ?>
    <h3>Hi Sally</h3>
<?php elseif ($username === 'joe'): ?>
    <h3>Hi Joe</h3>
<?php else: ?>
    <h3>Hi unknown user</h3>
<?php endif; ?>
امنیت
توی این پست میخوایم درمورد برخی از «بهترین الگوهای» مرتبط با امنیت و جزئیات مربوط‌به ویژگی‌های امنیتی کدایگنایتر صحبت کنیم.

نقل قول:نکته: اگه دنبال اطلاعات تماس با تیم امنیتی هستین، راهنمای مشارکت در پروژه‌ی کدایگنایتر رو بخونین.

امنیت URI
CodeIgniter درخصوص کارکترهای مجاز در رشته‌های URI سخت‌گیری‌های مناسبی داره تا کمک‌کنه امکان درج داده‌های خطرناک و مخرب در برنامه به حداقل برسه. URIها فقط میتونن شامل موارد زیر باشن:
  • متن‌های تشکیل‌شده از حروف لاتین و اعداد
  • کارکتر Tilde یا مد ~
  • کارکتر درصد %
  • نقطه .
  • دونقطه :
  • خط‌زیر _
  • خط‌تیره -
  • فاصله

register_globals
درحین آماده‌سازی سیستم، تمام متغیرهای سراسری که توی متغیرهای $_GET و $_POST و $_REQUEST و $_COOKIE قرار دارن، حذف میشن و توی کلاس‌های متناظر با خودشون قرار میگیرن. حذف این مقادیر ازنظر عملکرد، معادل خاموش‌کردن register_globals در PHP هست که ازنظر امنیتی، کاملاً توصیه میشه.

display_errors
در محیط محصول نهایی (Production)، معمولاً گزارش خطاهای PHP غیرفعال میشن و این‌کار با مقداردهی display_errors با عدد 0 انجام میشه. این‌کار جلوی نمایش خطاهای داخلی و بومی PHP رو در داخل مرورگر میگیره که میتونن حاوی اطلاعات حساسی باشن.

تنظیم ثابت ENVIRONMENT کدایگنایتر در فایل index.php با مقدار production باعث میشه این خطاها خاموش بشن. توی محیط توسعه پیشنهاد میشه که از مقدار development برای این ثابت استفاده کنین. اطلاعات بیشتر رو قبلاً در پست مربوط به کنترل محیط‌های چندگانه توضیح دادیم.

magic_quotes_runtime
هدایت‌گر magic_quotes_runtime درحین آماده‌سازی سیستم غیرفعال میشه تا نیاز به حذف اسلش‌ها / در زمان دریافت اطلاعات از پایگاه داده‌ها نداشته باشین.

بهترین تمرین‌ها
قبل‌از قبول‌کردن هرگونه داده‌ای در برنامه، چه یکسری اطلاعات باشه که با روش POST ازطریق ارسال فرم اومده باشه، چه داده‌ای در COOKIE باشه، چه یکسری اطلاعات از URI باشه، چه داده‌هایی باشه که ازطریق XML-RPC ارسال شده یا حتی داده‌ای از آرایه‌ی SERVER، بهتره این کارهای سه‌گانه رو روش انجام بدین:
  1. داده‌ها رو اعتبارسنجی کنین تا مطمئن بشین که از نوع، طول، اندازه و... صحیح برخوردار هستن.
  2. اگه داده‌ها خراب شدن، اونها رو فیلتر کنین.
  3. داده‌ها رو قبل‌از ارسال به پایگاه داده‌ها یا نمایش در مرورگر، خنثی‌سازی (Escape) کنین.

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

فیلترکردن XSS
CodeIgniter داخل خودش فیلتر Cross Site Scripting داره. این فیلتر توی کد شما به‌دنبال تکنیک‌های رایجی میگرده که برای درج کدهای JavaScript یا سایر انواع کد بکار میره که تلاش میکنن کوکی‌ها رو به‌سرقت ببرن یا هرگونه عملیات مخرب دیگه انجام بدن. فیلتر XSS رو توی جلسه‌ی مربوط به کتابخانه‌ی Security توضیح میدیم.

نقل قول:نکته: فیلتر XSS باید فقط روی خروجی انجام بشه. فیلترکردن داده‌های ورودی ممکنه اونها رو به‌شکل نامناسبی تغییر بده. مثلاً ممکنه کارکترهای خاصی رو از داخل Password کاربر حذف کنه که باعث کاهش امنیت بجای افزایشش میشه.

امنیت درمقابل CSRF
CSRF مخفف Cross-Site Request Forgery و به‌معنای کارهایی هست که نفوذگر با کمک اونها باعث میشه قربانی، بدون اطلاع خودش درخواستی رو ارسال کنه (مثلاً یه محصول بدون اطلاعش به سبد خریدش اضافه بشه و وقتی پرداخت کنه و پول از حسابش کم بشه و ببینه محصول دیگری هم توی سفارشش ثبت شده که انتخاب نکرده بوده، به سایت شما بدبین بشه و دیگه به سراغ شما نیاد یا حتی از شما شکایت کنه).

کدایگنایتر همراه خودش ابزارهای جلوگیری از CSRF رو هم داره که بطور خودکار روی هر درخواست HTTP که با روشی بجز GET ارسال شده باشه، فعال میشه، اما این موضوع نیازمند اینه که فرم‌های خودتون رو با روش خاصی ارسال کنین. این موضوع هم با جزئیات کامل در پست مربوط به کتابخانه‌ی Security توضیح داده میشه.

مدیریت رمزهای عبور
مدیریت Passwordها در برنامه به‌شکل صحیح، یک موضوع حیاتیه. متأسفانه اغلب توسعه‌دهندگان نمیدونن چطور اینکار رو انجام بدن و اینترنت هم پر از پیشنهادات قدیمی و منسوخ‌شده و یا حتی اشتباهه که کمکی بهشون نمیکنه. در اینجا قصد داریم فهرستی از بایدها و نبایدها رو خدمتتون ارائه بدیم که به شما در این مورد کمک میکنن. پس با دقت اونها رو بخونین:
  • هرگز رمزها رو بصورت متن خام ذخیره نکنید. همیشه اونها رو بصورت Hash (رمزگذاری غیرقابل برگشت) نگهداری کنین.
  • از الگوریتم Base64 یا سیستم‌های رمزگذاری مشابه اون که قابل برگشت هستن، برای ذخیره‌ی پسورد استفاده نکنید. این‌موضوع درست مثل نگهداری اونها بصورت متن خام خواهد بود. باز هم تأکید میکنیم که از Hash استفاده کنید نه از Encoding. عملیات Encoding هم رمزگذاریه ولی از نوع قابل برگشت. رمزها اطلاعات محرمانه‌ای هستن که باید فقط صاحبشون از اونها اطلاع داشته باشه و درنتیجه باید فقط بصورت یکطرفه کار کنن. Hash چنین‌کاری رو انجام میده چون برگشتی درکار نیست و نمیشه از متن Hashشده به محتوای اصلی برسیم؛ درحالی‌که توی Encoding یا Encryption، عملیات برگشت هم وجود داره که بهش میگن Decoding یا Decryption.
  • از الگوریتم‌های ضعیف یا شکسته‌شده نظیر MD5 یا SHA1 استفاده نکنید. این الگوریتم‌ها قدیمی هستن و ثابت‌شده که میشه در برخی موارد خاص بهشون نفوذ پیدا کرد و در اصل هم برای رمزنگاری پسورد طراحی نشدن. همچنین الگوریتم‌های خاص هم از خودتون «اختراع» نکنید. فقط از الگوریتم‌های قوی هش‌کردن پسورد مثل BCrypt که توی توابع Password Hashing خود PHP بکار رفته، استفاده کنین. لطفاً از اینها استفاده کنید. حتی اگه از PHP نسخه‌ی 5.5 به‌بعد استفاده نمیکنین، باز هم کدایگنایتر این قابلیت‌ها رو برای شما فراهم میکنه.
  • هرگز رمز کاربر رو در صفحه نمایش ندین یا براش ایمیل نکنین. حتی برای مالک رمز عبور هم اگه نیاز به قابلیت «فراموشی رمز عبور» دارین، فقط یک رمز تصادفی جدید و یکبارمصرف (خیلی مهمه) تولید کنین و اون‌رو براش بفرستین و در اولین ورود هم کاربر رو مجبور کنین رمز جدیدش رو عوض کنه.
  • محدودیت‌های غیرضروری روی رمزعبور کاربران ایجاد نکنید. اگه از الگوریتم رمزنگاری خاصی بجز BCrypt استفاده کنین (که محدودیت 72 کارکتری داره)، ممکنه بخواین محدودیت بالایی روی طول پسورد درنظر بگیرین تا جلوی حملات DoS رو بگیرین (مثلاً 1024 کارکتر). بجز این مورد، دلیل وجود نداره که قانون خاصی بگذارین که مثلاً یه رمز عبور میتونه فقط تا تعداد مشخصی کارکتر طول داشته باشه یا داخلش کارکترهای ویژه و خاص و علائم و... نداشته باشه. این‌کار نه‌تنها باعث کاهش امنیت بجای افزایشش میشه، بلکه دلیل منطقی هم برای این‌کار وجود نداره. هیچ محدودیت فنی و قیدوبندی ازنظر نگهداری در حافظه و پایگاه داده‌ها بعد از Hashکردن رمز عبور کاربر وجود نداره، هیچ!

اعتبارسنجی داده‌های ورودی
کدایگنایتر دارای کتابخانه‌ی اعتبارسنجی فرم هست که به شما توی اعتبارسنجی، فیلترکردن و آماده‌سازی داده‌ها کمک میکنه. حتی اگه این کتابخانه هم برای نیاز شما کارآیی لازم رو نداشته باشه، مطمئن‌بشین که همیشه داده‌های ورودی رو اعتبارسنجی و ورودی‌های مخرب رو از داخلش حذف میکنین. برای مثال اگه انتظار یه رشته‌ی عددی رو در یک متغیر ورودی دارین، میتونین این‌کار رو با توابع is_numeric() یا ctype_digit() انجام بدین. همیشه سعی‌کنین بررسی‌های خودتون رو به یک الگوی خاص محدود کنین.

فراموش نکنین که این‌موضوع نه‌تنها شامل متغیرهای $_POST و $_GET میشه، بلکه کوکی‌ها، رشته‌های UserAgent و اساساً «تمام» داده‌هایی که مستقیماً توسط کد خودتون تولید نشدن، میشه.

تمام داده‌ها رو قبل‌از درج در پایگاه داده‌ها خنثی‌سازی کنین
هرگز اطلاعات رو در دیتابیس بدون Escapeکردن ثبت نکنید. در این مورد توی بحث Queryهای پایگاه داده‌ها بیشتر توضیح میدیم.

فایل‌های خودتون رو مخفی کنین
یه الگوی خوب امنیتی دیگه اینه که فقط فایل index.php و «منابع» خودتون (مثلاً فایلهای js و css و تصاویر و...) رو توی پوشه‌ی webroot سرور (که در اغلب موارد htdocs یا public_html هست)، قرار بدین. این فایل‌ها تنها مواردی هستن که نیاز به دسترسی مستقیم ازطریق وب دارن.

اگه به کاربرانتون اجازه بدین هرچیزی بجز این موارد رو ببینن، ممکنه باعث بشه به اطلاعات محرمانه دسترسی پیدا کنن یا اسکریپت‌های خاص خودشون رو آپلود و اجرا کنن یا هر کار دیگه. اگه توی سرور خودتون اجازه‌ی دسترسی به پوشه‌های بالاتر از webroot رو ندارین، میتونین از فایل .htaccess برای جلوگیری از دسترسی به سایر منابع استفاده کنید. کافیه توی پوشه‌های محرمانه‌ی خودتون فایل .htaccess رو با چنین محتوایی بسازین:
<IfModule authz_core_module>
   Require all denied
</IfModule>
<IfModule !authz_core_module>
   Deny from all
</IfModule>

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

کدایگنایتر یه فایل index.html هم داخل پوشه‌های محرمانه‌ی خودش داره که جلوی نمایش محتوا رو درصورتی‌که فایل .htaccess کار نکنه (مثل مواقعی که از وب‌سرویس غیر از Apache استفاده میکنین)، میگیره. محتوای این فایل اینه:
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>

<p>Directory access is forbidden.</p>

</body>
</html>

وجود این فایل باعث میشه که دسترسی مستقیم به این پوشه‌ها، بجای نمایش فایلهای داخلشون، یک صفحه‌ی HTML با محتوای فوق رو به نفوذگر نشون بده. البته فراموش نکنین که این‌کار برای جلوگیری از یه هکر جدی، کافی نیست و باید حتماً سایر مواردی که در بالا اشاره کردیم رو رعایت کنید.
دستورزبان توصیه‌شده‌ی PHP
توی این پست میخوایم درمورد روش‌های استاندارد کدنویسی که بهتره توی کدنویسی رعایت کنید صحبت کنیم. البته این روش‌ها فقط درصورتی‌که بخواین توی توسعه‌ی کدایگنایتر مشارکت داشته باشین، الزامی هستن.

قالب فایل
فایل‌ها باید با کدگذاری یونیکد (UTF-8) ذخیره بشن. BOM «نباید» استفاده بشه. برخلاف UTF-16 و UTF-32، هیچ کارکتر Byte Order خاصی برای مشخص‌کردن فایل UTF-8 نیاز نیست و BOM میتونه یه تأثیر منفی روی ارسال خروجی PHP داشته باشه که باعث میشه برنامه نتونه هدرهای خودش رو تنظیم کنه. همچنین باید از کارکتر پایان خطوط Unix استفاده کنید (LF). در اینجا نحوه‌ی انجام این‌کار رو در دو مورد از ادیتورهای معروف بیان میکنیم. روش انجام کار توی ادیتور شما ممکنه متفاوت باشه و باید به مستنداتش مراجعه کنید.

TextMate
  1. تنظیمات برنامه رو باز کنین
  2. روی گزینه‌ی Advanced کلیک و سربرگ Saving رو باز کنین
  3. توی قسمت File Encoding گزینه‌ی UTF-8 (recommended) رو انتخاب کنین
  4. توی قسمت Line Endings گزینه‌ی LF (recommended) رو انتخاب کنین
  5. اختیاری: گزینه‌ی Use for existing files as well رو هم انتخاب کنین اگه میخواین کارکترهای انتهای خطوط توی فایلهایی که باز کردین هم با تنظیمات جدید اصلاح بشه

BBEdit
  1. تنظیمات برنامه رو باز کنین
  2. از قسمت سمت چپ Text Encoding رو انتخاب کنین
  3. در قسمت Default text encoding for new documents گزینه‌ی Unicode (UTF-8, no BOM) رو انتخاب کنین
  4. اختیاری: در قسمت If file's encoding can't be guessed, use گزینه‌ی Unicode (UTF-8, no BOM) رو انتخاب کنین
  5. از قسمت سمت چپ Text Files رو انتخاب کنین
  6. در قسمت Default line breaks گزینه‌ی Mac OS X and Unix (LF) رو انتخاب کنین

بستن تگ PHP
بستن تگ PHP ازنظر مفسر PHP اختیاریه. هرچند اگه استفاده بشه، هر کارکتر فضای سفید (مثل Space یا Tab یا Enter و...) که بعدش توسط توسعه‌دهنده، کاربر، برنامه‌ی ویرایشگر یا FTP تولید شده باشه، ممکنه خروجی نامناسبی ایجاد کنه که موردنظر شما نباشه یا حتی باعث بروز خطای PHP در تغییر هدرها، یا ایجاد صفحات خالی و... بشه. برای جلوگیری از این مشکل، تمام فایل‌های PHP باید بدون تگ بستن PHP در انتهای خودشون باشن و انتهای این فایل‌ها باید یک تگ باز PHP وجود داشته باشه که آخرین خطش، یک خط خالیه.

نامگذاری فایل‌ها
اسامی کلاس‌ها باید با ساختار Ucfirst باشن (یعنی حرف اول با حروف بزرگ نوشته بشه) درحالی‌که هر فایل دیگری (تنظیمات، ویوها، اسکریپت‌های عمومی و...) باید تماماً با حروف کوچک نوشته بشن.

این مثال‌ها اشتباه هستن:
somelibrary.php
someLibrary.php
SOMELIBRARY.php
Some_Library.php

Application_config.php
Application_Config.php
applicationConfig.php

اما این اسامی درست هستن:
Somelibrary.php
Some_library.php

applicationconfig.php
application_config.php

بعلاوه، فایل‌های حاوی کلاس‌ها باید با اسم خود کلاس مطابقت داشته باشن. برای مثال اگه کلاسی به‌اسم Myclass دارین، فایلش هم باید Myclass.php باشه.

نامگذاری کلاس‌ها و متدها
اسم کلاس‌ها همیشه باید با یک حرف بزرگ شروع بشه و اسامی چندکلمه‌ای باید با خط‌زیر جدا بشن نه اینکه بصورت CamelCased نوشته بشه. مثال:
class superclass // wrong
class SuperClass // wrong
class Super_class // correct

class Super_class
{
   public function __construct()
   {

   }
}

اسامی متدها باید تماماً با حروف کوچک نوشته بشه و اسمشون باید به‌وضوع کارکردشون رو نشون بده و ترجیحاً بصورت فعل باشه. سعی کنید از اسامی خیلی طولانی خودداری کنید. اسامی چندکلمه‌ای باید با خط‌زیر از هم جدا بشن:
function fileproperties() // Wrong, not descriptive and needs underscore separator
function fileProperties() // Wrong, not descriptive and uses CamelCase
function getfileproperties() // Wrong, It's better! But still missing underscore separator
function getFileProperties() // Uses CamelCase
function get_the_file_properties_from_the_file() // Wrong, it's too long

function get_file_properties() // Correct, it's descriptive, uses underscore separator, and all letters are lowercase

اسامی متغیرها
قواعد نامگذاری متغیرها خیلی شبیه اسامی نامگذاری متدهای کلاسه. متغیرها باید فقط از حروف کوچک استفاده کرده باشن و کلماتشون با خط‌زیر از هم جدا بشه و اسمشون هم مفهوم و کاربردشون و محتواشون رو منتقل کنه. اسامی خیلی کوتاه و غیر کلمه‌ای فقط باید بعنوان متغیرهای حلقه بکار برن. مثال:
$j = 'foo'; // Wrong, single letter variables should only be used in for() loops
$Str // Wrong, contains uppercase letters
$bufferedText // Wrong, uses CamelCasing, and could be shortened without losing semantic meaning
$groupid // Wrong, multiple words, needs underscore separator
$name_of_last_city_used // Wrong, too long

for ($j = 0; $j < 10; $j++) // Correct
$str // Correct
$buffer // Correct
$group_id // Correct
$last_city // Correct

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

توضیحات به‌سبک DocBlock قبل‌از کلاس‌ها، متدها و متغیرها میتونه توسط IDEها شناسایی بشه و توی پنجره‌ی AutoComplete اونها به نمایش در بیاد:
/**
* Super Class
*
* @package     Package Name
* @subpackage  Subpackage
* @category    Category
* @author      Author Name
* @link        http://example.com
*/
class Super_class {

/**
* Encodes string for use in XML
*
* @param       string  $str    Input string
* @return      string
*/
function xml_encode($str)

/**
* Data for class manipulation
*
* @var array
*/
public $data = array();

از توضیحات تک‌خطی در داخل کد استفاده کنین و یک خط خالی بین توضیحات طولانی و کدتون قرار بدین:
// break up the string by newlines
$parts = explode("n", $str);

// A longer comment that needs to give greater detail on what is
// occurring and why can use multiple single-line comments.  Try to
// keep the width reasonable, around 70 characters is the easiest to
// read.  Don't hesitate to link to permanent external resources
// that may provide greater detail:
//
// http://example.com/information_about_som...articular/

$parts = $this->foo($parts);

ثابت‌ها
ثابت‌ها از ساختاری مشابه متغیرها پیروی میکنن، بجز اینکه ثابت‌ها باید همیشه تماماً با حروف بزرگ نوشته بشن. همیشه از ثابت‌های داخلی کدایگنایتر (مثل SLASH و LD و RD و PATH_CACHE و...) در زمان‌های موردنیاز استفاده کنید. مثال:
myConstant // Wrong, missing underscore separator and not fully uppercase
N // Wrong, no single-letter constants
S_C_VER // Wrong, not descriptive
$str = str_replace('{$foo}', 'bar', $str); // Wrong, should use LD and RD constants

MY_CONSTANT // Correct
NEWLINE // Correct
SUPER_CLASS_VERSION // Correct
$str = str_replace(LD.'foo'.RD, 'bar', $str); // Correct

TRUE و FALSE و NULL
این مقادیر باید همیشه با حروف بزرگ نوشته بشن. مثال:
// Wrong
if ($foo == true)
$bar = false;
function foo($bar = null)

// Correct
if ($foo == TRUE)
$bar = FALSE;
function foo($bar = NULL)

عملگرهای منطقی
استفاده از علمگر یا بصورت || مناسب نیست چون وضوحش در برخی دستگاه‌های خروجی پایینه (برای مثال شبیه 11 بنظر میرسه). استفاده از && نسبت‌به AND ترجیح داده میشه ولی هردو قابل‌قبول هستن و ضمناً قبل و بعد از ! باید فاصله گذاشته بشه. مثال:
// Wrong
if ($foo || $bar)
if ($foo AND $bar)  // okay but not recommended for common syntax highlighting applications
if (!$foo)
if (! is_array($foo))

// Correct
if ($foo OR $bar)
if ($foo && $bar) // recommended
if ( ! $foo)
if ( ! is_array($foo))

مقایسه‌ی مقادیر بازگشتی و تبدیل نوع
برخی از توابع PHP درصورت عدم موفقیت، خروجی FALSE تولید میکنن ولی ممکنه که خروجی معتبری هم با مقدار 0 یا رشته‌ی خالی داشته باشن که میتونه بعنوان FALSE هم در مقایسه‌های معمولی که نوع رو بررسی نمیکنن، ارزیابی بشه. در چنین مقایسه‌هایی، صراحتاً مشخص‌کنین که دنبال چی هستین. موقع بررسی مقادیر بازگشتی و چک‌کردن متغیرهای معمولی خودتون، سخت‌گیری کنین و از === یا ==! استفاده کنین. مثال:
// Wrong, If 'foo' is at the beginning of the string, strpos will return a 0,
// resulting in this conditional evaluating as TRUE
if (strpos($str, 'foo') == FALSE)

// Correct
if (strpos($str, 'foo') === FALSE)

// Wrong
function build_string($str = "")
{
       if ($str == "") // uh-oh!  What if FALSE or the integer 0 is passed as an argument?
       {

       }
}

// Correct
function build_string($str = "")
{
       if ($str === "")
       {

       }
}

همچنین اطلاعات تبدیل نوع رو هم مطالعه کنین که میتونن مفید باشن. تبدیل نوع، میتونه تأثیر نسبتاً متفاوتی با اونچه که قابل انتظاره داشته باشه. وقتی یه متغیر رو بصورت رشته تبدیل میکنین، برای مثال NULL و FALSE تبدیل به رشته‌ی خالی میشن و 0 (یا سایر اعداد) بصورت رشته‌ای از ارقام در میان و TRUE هم به رشته‌ی "1" تبدیل میشه:
$str = (string) $str; // cast $str as a string

کدهای اشکال‌زدایی
هیچوقت کدهای اشکال‌زدایی رو توی ارسال نهایی روی سرور رها نکنید، حتی اگه بصورت کامنت (توضیحات) قرار گرفته باشن. مواردی مثل var_dump() یا print_r() یا دستورات die() و exit() نباید توی کد شما قرار گرفته باشن، مگه اینکه هدفی بجز اشکال‌زدایی داشته باشن.

فاصله‌های خالی در فایل‌ها
هیچ فاصله‌ی خالی نباید قبل‌از بازشدن تگ PHP یا بعد از بستن تگ PHP قرار گرفته باشه. خروجی در بافر قرار میگیره، بنابراین فواصل خالی توی فایل شما ممکنه باعث بشن خروجی قبل‌از اینکه کدایگنایتر ارسال خروجی خودش رو شروع کنه، برای مرورگر کاربر ارسال بشه و درنتیجه باعث بروز خطا بشه و کدایگنایتر نتونه هدرهای خودش رو تنظیم کنه.

سازگاری
کدایگنایتر پیشنهاد میکنه از PHP5.6 یا بالاتر استفاده کنین ولی میتونه با PHP5.3.7 هم سازگار باشه. کدتون باید با این نیازمندی‌ها سازگاری داشته باشه و اگه از نسخه‌های قدیمی استفاده بشه، جایگزین مناسب براش نوشته باشین یا اینکه قابلیت خاصی باشه که به آرامی درصورت عدم سازگاری، غیرفعال بشه بدون اینکه به برنامه‌ی نهایی آسیبی بزنه.

بعلاوه، از توابع داخلی PHP که نیاز به نصب کتابخانه‌های غیر پیشفرض دارن استفاده نکنین، مگه اینکه کدتون شامل روش جایگزین برای مواقعی که اون کتابخانه‌ها موجود نیست، باشه.

یک فایل به‌ازای هر کلاس
از فایل‌های جداگانه برای هر کلاس استفاده کنین، مگه اینکه کلاس‌ها به‌شدت به‌هم وابسته باشن. یکی از مثال‌هایی که یک فایل CodeIgniter شامل چند کلاس هست، فایل کتابخانه‌ی Xmlrpc هست.

فضاهای خالی
از Tab برای فاصله‌های خالی توی کد استفاده کنید نه Space. این‌کار ممکنه بنظر کوچک بیاد ولی استفاده از Tab بجای فاصله‌های خالی باعث میشه که توسعه‌دهندگانی که به کد شما نگاه میکنن، بتونن هرجور دوست دارن توی ویرایشگرشون نمایش محتوا رو سفارشی‌سازی کنن. ازطرف دیگه، حجم فایل هم (کمی) کاهش پیدا میکنه. ذخیره‌سازی یک کارکتر Tab بجای چهار کارکتر Space، فضای کمتری اشغال میکنه.

شکستن خطوط
فایل‌های باید با کارکترهای انتهای خطوط Unix ذخیره بشن. این‌کار بیشتر برای کسانی که با Windows کار میکنن ممکنه مشکل باشه، ولی درهرحال مطمئن بشین که ویرایشگر متنی شما برای ذخیره‌ی فایل‌ها با کارکترهای انتهای خط Unix تنظیم شده.

تورفتگی کد
از روش تورفتگی Allman استفاده کنید. در این روش، بجز تعریف کلاس‌ها، در بقیه‌ی موارد آکولادها همیشه در یک خط جداگانه قرار میگیرن و ازنظر تورفتگی، هم‌سطح با دستور والد خودشون خواهند بود. مثال:
// Wrong
function foo($bar) {
       // ...
}

foreach ($arr as $key => $val) {
       // ...
}

if ($foo == $bar) {
       // ...
} else {
       // ...
}

for ($i = 0; $i < 10; $i++)
       {
       for ($j = 0; $j < 10; $j++)
               {
               // ...
               }
       }

try {
       // ...
}
catch() {
       // ...
}

// Correct
function foo($bar)
{
       // ...
}

foreach ($arr as $key => $val)
{
       // ...
}

if ($foo == $bar)
{
       // ...
}
else
{
       // ...
}

for ($i = 0; $i < 10; $i++)
{
       for ($j = 0; $j < 10; $j++)
       {
               // ...
       }
}

try
{
       // ...
}
catch()
{
       // ...
}

فاصله‌های کروشه‌ها و پرانتزها
بطور کلی، پرانتزها و کروشه‌ها نباید حاوی هیچ فاصله‌ی اضافه‌ای باشن. تنها استثنا، وجود یک فاصله در جاهایی هست که یک ساختار کنترلی PHP آرگومان‌های خودش رو توی پرانتز دریافت میکنه (declare و do-while و elseif و for و foreach و if و switch و while) تا کمک کنه با توابع و متدها اشتباه گرفته نشن و خوانایی افزایش پیدا کنه:
// Wrong
$arr[ $foo ] = 'foo';

// Correct
$arr[$foo] = 'foo'; // no spaces around array keys

// Wrong
function foo ( $bar )
{

}

// Correct
function foo($bar) // no spaces around parenthesis in function declarations
{

}

// Wrong
foreach( $query->result() as $row )

// Correct
foreach ($query->result() as $row) // single space following PHP control structures, but not in interior parenthesis

متن بومی‌سازی‌شده
کتابخانه‌های کدایگنایتر میتونن از مزایای فایل‌های زبان مناسب در زمان امکان استفاده کنن. برای مثال:
// Wrong
return "Invalid Selection";

// Correct
return $this->lang->line('invalid_selection');

متدها و متغیرهای خصوصی
متدها و متغیرهایی که فقط بصورت داخلی مورد استفاده قرار میگیرن (مثل توابع کمکی و سودمندی که متدهای عمومی شما برای خلاصه‌سازی کد ازشون کمک میگیرن)، باید با کارکتر خط‌زیر شروع بشن. مثال:
public function convert_text()
private function _convert_text()

خطاهای PHP
کد شما باید بدون خطا اجرا بشه و وابسته به پنهان‌کردن هشدارها و یادآوری‌ها نباشه. برای مثال، هیچوقت متغیری رو که خودتون تعریف نکردین، مستقیماً مورد دسترسی قرار ندین (مثل کلیدهای آرایه‌ی $_POST) مگه اینکه قبلش وجود اونها رو با isset() بررسی کرده باشین.

مطمئن بشین که محیط توسعه‌ی شما گزارش خطا رو برای تمام کاربران فعال کرده و نمایش خطاها هم توی محیط PHP فعاله. میتونین این موضوع رو با چنین کدی بررسی کنین:
if (ini_get('display_errors') == 1)
{
       exit "Enabled";
}

دربرخی از سرورها display_errors غیرفعاله و شما هم دسترسی به php.ini ندارین. در اغلب مواقع مشابه این وضعیت، میتونین با دستور زیر نمایش خطاها رو فعال کنین:
ini_set('display_errors', 1);

نقل قول:نکته: تنظیم‌کردن display_errors با دستور ini_set در زمان اجرا، مشابه فعال‌کردنش ازطریق تنظیمات PHP نیست. برای مثال، هیچ تأثیری روی اسکریپتی که خطاهای مرگبار (Fatal Errors) داشته باشه، نداره.

تگ‌های کوتاه بازکردن
همیشه در مواقعی که یک سرور خاص، short_open_tags رو فعال نکرده باشه، از تگ کامل PHP برای بازکردن استفاده کنین. برای مثال:
// Wrong
<? echo $foo; ?>
<?=$foo?>

// Correct
<?php echo $foo; ?>

نقل قول:نکته: از نسخه‌ی PHP5.4 به‌بعد، همیشه شکل خلاصه‌شده‌ی echo قابل استفاده است.

یک دستور در هر خط
هیچوقت چند دستور رو در یک خط ادغام نکنید:
// Wrong
$foo = 'this'; $bar = 'that'; $bat = str_replace($foo, $bar, $bag);

// Correct
$foo = 'this';
$bar = 'that';
$bat = str_replace($foo, $bar, $bag);

رشته‌ها
همیشه رشته‌ها رو داخل کوتیشن تک بگذارین، مگه اینکه نیاز به پردازش متغیرها داشته باشین و در چنین شرایطی، متغیرها رو داخل آکولاد قرار بدین تا جلوی تفسیر حریصانه‌ی متغیرها گرفته بشه. همچنین درصورتی‌که توی رشته از کارکتر کوتیشن تک استفاده شده باشه، ممکنه که بخواین از کوتیشن جفت برای محصورکردن کل رشته استفاده کنین تا نخواین کوتیشن تک رو مدام خنثی‌سازی کنین. مثال:
// Wrong
"My String"                                     // no variable parsing, so no use for double quotes
"My string $foo"                                // needs braces
'SELECT foo FROM bar WHERE baz = 'bag''       // ugly

// Correct
'My String'
"My string {$foo}"
"SELECT foo FROM bar WHERE baz = 'bag'"

پرس‌وجوهای SQL
کلمات کلیدی SQL رو همیشه با حروف بزرگ بنویسین: SELECT و INSERT و UPDATE و WHERE و AS و JOIN و ON و IN و...

کوئری‌های طولانی رو به چند خط بشکنین تا خواناتر بشه. ترجیحاً این شکستگی رو در بین بخش‌های کوئری انجام بدین. مثال:
// Wrong, keywords are lowercase and query is too long for
// a single line (... indicates continuation of line)
$query = $this->db->query("select foo, bar, baz, foofoo, foobar as raboof, foobaz from exp_pre_email_addresses
...where foo != 'oof' and baz != 'zab' order by foobaz limit 5, 100");

// Correct
$query = $this->db->query("
   SELECT foo, bar, baz, foofoo, foobar AS raboof, foobaz
   FROM exp_pre_email_addresses
   WHERE
   (
       foo != 'oof'
       AND baz != 'zab'
   )
   ORDER BY foobaz
   LIMIT 5, 100
");

آرگومان‌های پیشفرض توابع
هر زمان که امکان داشت، برای توابع خودتون مقادیر پیشفرض تعریف کنین. این‌کار جلوی بسیاری از خطاهای PHP رو که بخاطر فراخوانی‌های اشتباه و بدون مقدارهای مناسب توسط کاربر اتفاق میفته میگیره و باعث میشه کدتون هم برای کارکردن با مقادیر پیشفرض، کوتاه‌تر بشه. برای مثال:
function foo($bar = '', $baz = FALSE)
کتابخانه‌ها
در این بخش از آموزش، قصد داریم شما رو با کتابخانه‌های مختلف CodeIgniter آشنا کنیم. این کتابخانه‌ها که همراه‌با کدایگنایتر ارائه میشن، قابلیت‌های بسیار زیادی به هسته‌ی مرکزی فریمورک اضافه میکنن و تسلط به اونها میتونه به شما کمک کنه که کارها رو سریع‌تر و اصولی‌تر انجام بدین و از اختراع مجدد چرخ جلوگیری کنید. توی پست‌های بعدی، هر کتابخانه رو جداگانه بررسی خواهیم کرد.
کلاس سنجش کارآیی
کدایگنایتر یک کلاس سنجش کارآیی (Benchmark) داره که همیشه فعاله و به شما اجازه میده اختلاف زمانی بین هر دو نقطه‌ی دلخواه از اسکریپت رو محاسبه کنین.

نقل قول:نکته: این کلاس بطور خودکار توسط سیستم آماده‌سازی میشه و نیازی به انجام دستی این‌کار نیست.

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

استفاده از کلاس Benchmark
کلاس سنجش کارآیی رو میشه توی کنترلرها، ویوها یا مدل‌ها بکار ببرین. روش استفاده اینطوریه:
  1. نقطه‌ی شروع رو علامت بزنید
  2. یک نقطه‌ی پایان رو مشخص کنید
  3. تابع elapsed_time رو صدا بزنین تا نتایج خروجی رو مشاهده کنین

در اینجا یک مثال رو مشاهده میکنید:
$this->benchmark->mark('code_start');
// Some code happens here
$this->benchmark->mark('code_end');
echo $this->benchmark->elapsed_time('code_start', 'code_end');

نقل قول:نکته: کلمات code_start و code_end کاملاً اختیاری هستن. این کلمات صرفاً یک‌سری عبارات ساده برای مشخص‌کردن دو نقطه در اسکریپت هستن و میتونن با هر کلمه‌ی دیگه جایگزین بشن. میتونین چندین مجموعه‌ی Marker (علامت) مشخص کنین. این مثال رو ببینین:
$this->benchmark->mark('dog');
// Some code happens here
$this->benchmark->mark('cat');
// More code happens here
$this->benchmark->mark('bird');
echo $this->benchmark->elapsed_time('dog', 'cat');
echo $this->benchmark->elapsed_time('cat', 'bird');
echo $this->benchmark->elapsed_time('dog', 'bird');

بررسی دقیق‌تر نقاط سنجش کارآیی
اگه بخواین داده‌های سنجش کارآیی در دسترس کلاس Profiler قرار بگیرن، تمام نقاط علامت‌گذاری‌شده باید بصورت جفت و زوج تعریف بشه و اسم هر نقطه با پسوندهای _start و _end خاتمه پیدا کنه. هر زوج از نقاط باید اسم منحصربفردی داشته باشه. برای مثال:
$this->benchmark->mark('my_mark_start');
// Some code happens here...
$this->benchmark->mark('my_mark_end');
$this->benchmark->mark('another_mark_start');
// Some more code happens here...
$this->benchmark->mark('another_mark_end');

توضیحات مربوط به ارزیابی کارآیی برنامه رو برای اطلاعات بیشتر مطالعه کنید.

نمایش زمان کلی اجرا
اگه بخواین کل زمان اجرای اسکریپت از لحظه‌ی شروع به کار کدایگنایتر تا لحظه‌ای که خروجی نهایی برای مرورگر ارسال میشه رو نمایش بدین، کافیه این کد رو توی یکی‌از ویوهای خودتون بگذارین:
<?php echo $this->benchmark->elapsed_time(); ?>

ممکنه متوجه شده باشین که این تابع، همونیه که توی مثال‌های بالا برای محاسبه‌ی اختلاف زمانی بین دو نقطه‌ی اسکریپت بکار رفته بود، با این تفاوت که از هیچ پارامتری استفاده نکردیم. وقتی که پارامترها اعلام نشن، کدایگنایتر اجرای کلاس Benchmark رو تا زمانی که خروجی نهایی برای مرورگر ارسال میشه، متوقف نمیکنه. اینکه کجا این تابع رو صدا زده باشین اهمیتی نداره، زمان‌سنج تا انتها ادامه پیدا میکنه.

یک راه دیگه برای نمایش زمان سپری‌شده توی ویوها، با استفاده از شبه‌متغیری هست که توی موتور قالب CodeIgniter در اختیار شما گذاشته میشه:
{elapsed_time}

نقل قول:نکته: اگه میخواین هرچیزی توی توابع کنترلرتون (نه کل اجرای اسکریپت) بررسی بشه، باید نقاط اختصاصی شروع/پایان خودتون رو تعریف کنین.

نمایش مصرف حافظه
اگه PHP رو با تنظیمات -enable-memory-limit نصب کرده باشین، میتونین میزان مصرف حافظه‌ی کل سیستم رو با کمک دستور زیر توی ویوها نمایش بدین:
<?php echo $this->benchmark->memory_usage(); ?>

نقل قول:نکته: این تابع فقط توی فایل‌های ویو قابل استفاده است و حافظه‌ی مصرف‌شده توسط کل سیستم رو نشون میده.

یک راه دیگه برای نمایش مصرف حافظه، استفاده از شبه‌متغیری هست که توی موتور قالب کدایگنایتر در اختیار شما گذاشته میشه:
{memory_usage}

مرجع کلاس
نام کلاس: CI_Benchmark

فهرست متدها:

mark($name)

پارامترها:
  • $name (رشته) - عنوان موردنظر شما برای اختصاص به Marker

خروجی: هیچ

این تابع برای تعریف یک نقطه‌ی سنجش در اسکریپت بکار میره.


elapsed_time([$point1 = '' [, $point2 = '' [, $decimals = 4]]])

پارامترها:
  • $point1 (رشته) - یک نقطه‌ی مشخص برای شروع سنجش (اختیاری)
  • $point2 (رشته) - یک نقطه‌ی مشخص برای پایان سنجش (اختیاری - درصورت تعریف پارامتر اول)
  • $decimals (عدد صحیح) - تعداد ارقام اعشار در نتیجه (اختیاری - درصورت تعریف پارامترهای اول و دوم)

خروجی: (رشته) زمان سپری‌شده

این تابع زمان سپری‌شده بین دو نقطه‌ی مشخص‌شده رو محاسبه میکنه و برمیگردونه. اگه اولین‌پارامتر خالی باشه، شبه‌متغیر {elapsed_time} برگردونده میشه. این‌موضوع اجازه‌ی محاسبه‌ی کل زمان اجرا رو توی قالب میده. کلاس خروجی مقدار واقعی رو با این متغیر جایگزین میکنه.


memory_usage()

خروجی: (رشته) اطلاعات مصرف حافظه

این تابع به‌سادگی شبه‌کد {memory_usage} رو برمیگردونه. این شبه‌متغیر میتونه هر جایی توی قالب قرار بگیره، بدون اینکه محاسبه تا پایان اسکریپت قطع بشه. کلاس خروجی مقدار واقعی رو با این شبه‌متغیر جایگزین میکنه.
کلاس مدیریت کش
کدایگنایتر کلاس‌های خوبی برای دربرگرفتن انواع رایج و محبوب کش پویا و سریع ارائه می‌کنه. همه‌ی این کلاس‌ها بجز کش مبتنی‌بر فایل، نیازمند یکسری ملزومات سرور هستن و یه Fatal Exception تولید میشه اگه این ملزومات روی سرور وجود نداشته باشن.

مثالی از استفاده
مثال زیر، درایور کش رو بارگذاری میکنه و APC رو بعنوان آداپتر مورداستفاده مشخص میکنه و اگه APC روی فضای هاست قابل استفاده نباشه، به کش مبتنی‌بر فایل برمیگرده.
$this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));

if ( ! $foo = $this->cache->get('foo'))
{
        echo 'Saving to the cache!<br />';
        $foo = 'foobarbaz!';

        // Save into the cache for 5 minutes
        $this->cache->save('foo', $foo, 300);
}

echo $foo;

همچنین میتونین عناصر کش رو با پیشوند مشخصی که توسط تنظیمات key_prefix مشخص میکنین، ذخیره کنین که جلوی تداخل در زمان استفاده از چند برنامه روی یک فضای مشترک رو میگیره.
$this->load->driver('cache',
        array('adapter' => 'apc', 'backup' => 'file', 'key_prefix' => 'my_')
);

$this->cache->get('foo'); // Will get the cache entry named 'my_foo'

مرجع کلاس
نام کلاس: CI_Cache

فهرست متدها:
is_supported($driver)

پارامترها:
  1. $driver (رشته) - اسم راه‌انداز کش موردنظر

خروجی: درصورت پشتیبانی‌شدن روی سرور TRUE و درغیر اینصورت FALSE

این متد بطور خودکار در زمانی که به آداپترهای مختلف با کمک $this->cache->get() دسترسی پیدا میکنید، فراخوانی میشه. هرچند اگه آداپترهای مختلفی مورداستفاده قرار میگیرن، مطمئن بشین که این متد رو برای تضمین پشتیبانی از آداپتر موردنظر روی هاستی که برنامه قراره روش اجرا بشه، صدا میزنین.
if ($this->cache->apc->is_supported())
{
        if ($data = $this->cache->apc->get('my_cache'))
        {
                // do things.
        }
}


get($id)

پارامترها:
  1. $id (رشته) - اسم آیتم کش‌شده

خروجی: مقدار آیتم موردنظر یا FALSE اگه پیدا نشه.

این متد سعی میکنه یه آیتم رو از منبع کش استخراج کنه. اگه آیتم وجود نداشته باشه، این متد FALSE برمیگردونه.
$foo = $this->cache->get('my_cached_item');


save($id, $data [, $ttl = 60 [, $raw = FALSE]])

پارامترها:
  1. $id (رشته) اسم آیتم کش
  2. $data (ترکیبی) - داده‌ی موردنظر برای ذخیره‌سازی
  3. $ttl (عدد صحیح) - زمان بقای عنصر موردنظر کش برحسب ثانیه (اختیاری - مقدار پیشفرض 60)
  4. ltr$raw[/ltr] (منطقی) - آیا مقدار بصورت خام باید ذخیره بشه یا نه (اختیاری - مقدار پیشفرض FALSE)

خروجی: درصورت موفقیت TRUE و درغیر اینصورت FALSE

این متد یک عنصر رو در داخل منبع کش ذخیره می‌کنه. اگه این عملیات شکست بخوره، خروجی متد FALSE خواهد بود.

نقل قول:نکته: پارامتر $raw فقط توسط APC و Memcache مورد استفاده قرار میگیره تا اجازه‌ی استفاده از increment() و decrement() رو بده.


delete($id)

پارامترها:
  1. $id (رشته) - اسم آیتم کش‌شده

خروجی: درصورت موفقیت TRUE و درغیر اینصورت FALSE

این متد یک عنصر رو از منبع کش حذف میکنه. اگه عملیات حذف شکست بخوره، مقدار FALSE برگردونده میشه.
$this->cache->delete('cache_item_id');


increment($id [, $offset = 1])

پارامترها:
  1. $id (رشته) - نام عنصر کش‌شده
  2. $offset (عدد صحیح) - گام (مقدار) موردنظر برای اضافه‌کردن (اختیاری - مقدار پیشفرض 1)

مقدار عنصر خام ذخیره‌شده در منبع کش رو به‌سرعت با مقدار مشخص‌شده جمع میزنه و دوباره داخل خودش ذخیره میکنه.
// 'iterator' has a value of 2

$this->cache->increment('iterator'); // 'iterator' is now 3

$this->cache->increment('iterator', 3); // 'iterator' is now 6


decrement($id [, $offset = 1])

پارامترها:
  1. $id (رشته) نام عنصر کش‌شده
  2. $offset (عدد صحیح) - گام (مقدار) موردنظر برای کم‌کردن (اختیاری - مقدار پیشفرض 1)

خروجی: درصورت موفقیت TRUE و درغیر اینصورت FALSE

مقدار مشخص‌شده رو به‌سرعت از مقدار عنصر خام ذخیره‌شده در منبع کش کم میکنه و دوباره داخل خودش ذخیره میکنه.
// 'iterator' has a value of 6

$this->cache->decrement('iterator'); // 'iterator' is now 5

$this->cache->decrement('iterator', 2); // 'iterator' is now 3


clean()

خروجی: درصورت موفقیت TRUE و درغیر اینصورت FALSE
این متد کل حافظه‌ی کش رو خالی میکنه. اگه عملیات حذف فایل‌های کش‌شده با شکست مواجه بشه، این متد نتیجه‌ی FALSE برمیگردونه.


cache_info()

خروجی: اطلاعات کل حافظه‌ی کش

این متد اطلاعات کلی درباره‌ی کل محتوای حافظه‌ی کش برمیگردونه.
var_dump($this->cache->cache_info());

نقل قول:نکته: اطلاعاتی که برگردونده میشه و ساختار داده‌ها بستگی به نوع آداپتر کش مورداستفاده داره.


get_metadata($id)

پارامترها:
  1. $id (رشته) - نام عنصر کش موردنظر

خروجی: (ترکیبی) - اطلاعات جانبی مرتبط با عنصر ذخیره‌شده در کش

این متد اطلاعات و جزئیات مربوط به یک عنصر خاص رو در کش برمیگردونه.
var_dump($this->cache->get_metadata('my_cached_item'));

نقل قول:نکته: اطلاعات برگردونده‌شده و ساختار داده‌ها بستگی به آداپتر کش مورداستفاده داره.


آداپترهای کش
سیستم کش کدایگنایتر میتونه با آداپترهای زیر کار کنه:

کش Alternative PHP Cache یا به‌اختصار APC
برای استفاده از این آداپتر، یا باید موقع بارگذاری کش، خاصیت adapter رو به‌روشی که در ابتدای این پست مشخص شده، با مقدار apc تنظیم کنین. البته میشه بدون تنظیم این خاصیت هم بصورت زیر از تمام متدهای بالا استفاده کنید:
$this->load->driver('cache');
$this->cache->apc->save('foo', 'bar', 10);

برای اطلاعات بیشتر درمورد APC به نشانی http://php.net/apc مراجعه کنید.

کش مبتنی‌بر فایل
برخلاف کش‌کردن ازطریق کلاس خروجی، کش مبتنی‌بر فایل به شما اجازه‌ی ذخیره‌ی تکه‌های مختلف از فایل‌های ویو رو میده. از این قابلیت به‌دقت استفاده کنید و مطمئن بشین که با کمک کلاس Benchmark کارآیی برنامه رو بررسی میکنین، چون ممکنه بسته به شرایط مختلف سرور مثل سرعت دیسک و حجم عملیات و تعداد درخواست‌های کاربران و غیره، عملیات ورودی/خروجی دیسک باعث کاهش کارآیی بشه و معایبش از مزایاش بیشتر باشه.

این آداپتر هم مثل بقیه‌ی آداپترها، هم میتونه با تنظیم خاصیت adapter و هم به‌روش زیر مورد استفاده قرار بگیره:
$this->load->driver('cache');
$this->cache->file->save('foo', 'bar', 10);

کش Memcached
چندین سرور Memcached مختلف میتونن توی فایل تنظیمات memcached.php که در مسیر application/config قرار داره معرفی بشن. این آداپتر هم مثل بقیه‌ی آداپترها، هم میتونه با تنظیم خاصیت adapter و هم به‌روش زیر مورد استفاده قرار بگیره:
$this->load->driver('cache');
$this->cache->memcached->save('foo', 'bar', 10);

برای اطلاعات بیشتر درمورد Memcached میتونین به نشانی http://php.net/memcached مراجعه کنین.

کش WinCache
توی سرورهای ویندوز میتونین از آداپتر WinCache استفاده کنین. این آداپتر هم مثل بقیه‌ی آداپترها، هم میتونه با تنظیم خاصیت adapter و هم به‌روش زیر مورد استفاده قرار بگیره:
$this->load->driver('cache');
$this->cache->wincache->save('foo', 'bar', 10);

برای اطلاعات بیشتر درمورد WinCache به نشانی http://php.net/wincache مراجعه کنین.

کش Redis
Redis یه منبع ذخیره‌سازی key/value در حافظه است که میتونه در حالت کش LRU (کمترین مصرف منابع) کار کنه. برای استفاده از اون نیاز به سرور Redis و افزونه‌ی phpredis برای PHP دارین.

تنظیمات موردنیاز برای اتصال به سرور Redis باید در فایل application/config/redis.php ذخیره بشن. انتخاب‌های موجود اینها هستن:
$config['socket_type'] = 'tcp'; //`tcp` or `unix`
$config['socket'] = '/var/run/redis.sock'; // in case of `unix` socket type
$config['host'] = '127.0.0.1';
$config['password'] = NULL;
$config['port'] = 6379;
$config['timeout'] = 0;

این آداپتر هم مثل بقیه‌ی آداپترها، هم میتونه با تنظیم خاصیت adapter و هم به‌روش زیر مورد استفاده قرار بگیره:
$this->load->driver('cache');
$this->cache->redis->save('foo', 'bar', 10);

برای کسب اطلاعات بیشتر درمورد Redis به لینک http://redis.io مراجعه کنید.

کش Dummy
این کش درحقیقت هیچ کاری نمیکنه و چیزی رو ذخیره نمیکنه و همیشه اطلاعات داخلش از بین میره. تنها کاربردش در زمانی هست که شما میخواین کدتون رو در مواقعی که کش روی سرور پشتیبانی نمیشه، بدون تغییر نگه‌دارین. برای این‌کار کافیه که adapter کش رو با مقدار dummy تنظیم کنید. اینطوری، هروقت که مشکل کش سرور برطرف شد، میتونین آداپتر کش رو ویرایش کنین و بقیه‌ی کدتون دیگه دست نمیخوره.
کلاس تقویم
کلاس Calendar به شما اجازه میده که تقویم‌های پویا بسازین. تقویم‌های شما میتونن با استفداه از یک قالب تقویم، قالب‌بندی بشن و این‌موضوع به شما اجازه‌ی کنترل 100درصد روی هر جنبه‌ای از طراحی ظاهری اون رو میده. بعلاوه میتونین داده‌هایی رو برای خانه‌های تقویم ارسال کنین.

آماده‌سازی کلاس
مثل اغلب کلاس‌های دیگه در کدایگنایتر، کلاس تقویم در داخل کنترلر با استفاده از تابع $this->load->library بارگذاری میشه:
$this->load->library('calendar');

وقتی که تقویم بارگذاری شد، شئ تقویم رو میتونین باکمک $this->calendar مورد استفاده قرار بدین.

نمایش تقویم
یه مثال خیلی ساده از نمایش تقویم رو ببینید:
$this->load->library('calendar');
echo $this->calendar->generate();

این کد یه تقویم برای ماه/سال جاری براساس زمان سرور شما تولید میکنه. برای نمایش تقویم براساس یک ماه و سال دیگه، باید این اطلاعات رو برای تابع تولید تقویم بفرستین:
$this->load->library('calendar');
echo $this->calendar->generate(2006, 6);

این کد تقویمی رو نشون میده که ماه روئن 2006 رو به نمایش میگذاره. پارامتر اول مشخص‌کننده‌ی سال و پارامتر دوم مشخص‌کننده‌ی ماه هست.

ارسال اطلاعات به خانه‌های تقویم
برای اضافه‌کردن داده‌ها به خانه‌های تقویم، باید یک آرایه‌ی انجمنی بسازین که کلیدهاش روزهای ماه و مقادیرش داده‌های مرتبط با روزها هستن. این آرایه رو باید بعنوان پارامتر سوم برای تابع تولید تقویم بفرستین:
$this->load->library('calendar');
$data = array(
   3  => 'http://example.com/news/article/2006/06/03/',
   7  => 'http://example.com/news/article/2006/06/07/',
   13 => 'http://example.com/news/article/2006/06/13/',
   26 => 'http://example.com/news/article/2006/06/26/'
);
echo $this->calendar->generate(2006, 6, $data);

مثال بالا باعث میشه روزهای 3 و 7 و 13 و 26 تبدیل به لینک‌هایی بشن که به URLهای مشخص‌شده اشاره میکنن.

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

تنظیم خصوصیات تقویم
هفت خصوصیت وجود داره که میتونین باکمک اونها، جنبه‌های مختلف تقویم رو کنترل کنین. تنظیمات با ارسال یک آرایه بعنوان پارامتر دوم برای تابع بارگذاری مشخص میشن. برای مثال:
$prefs = array(
   'start_day'    => 'saturday',
   'month_type'   => 'long',
   'day_type'     => 'short'
);
$this->load->library('calendar', $prefs);
echo $this->calendar->generate();

کد بالا باعث میشه تقویم از شنبه شروع بشه و اسم طولانی ماه و اسامی کوتاه روزها توی تقویم بکار برن. اطلاعات بیشتر درمورد تنظیمات رو در اینجا براتون فهرست کردیم:
  • template (پیشفرض: هیچ) - یک رشته یا آرایه که حاوی قالب تقویم شماست. اطلاعات بیشتر رو در بخش قالب تقویم خواهید دید
  • local_time (پیشفرض: time() یا زمان فعلی سرور) - مُهر زمانی (Timestamp) جاری برای مشخص‌کردن زمان فعلی در تقویم
  • start_day (پیشفرض: sunday) - اسم یکی‌از روزهای هفته که مشخص‌کننده‌ی شروع هفته است
  • month_type (پیشفرض: long) - یکی‌از مقادیر long و short که به‌ترتیب اسم ماه رو بصورت January یا Jan نشون میده
  • day_type (پیشفرض: abr) - یکی‌از مقادیر long و short و abr که به‌ترتیب اسم روز رو بصورت Sunday یا Sun یا Su نشون میده
  • show_next_prev (پیشفرض: FALSE) - مشخص‌کننده‌ی اینه که لینک‌های ماه بعد/قبل باید ظاهر بشه یا نه
  • next_prev_url (پیشفرض: controller/method جاری) - مشخص‌کننده‌ی URL پایه برای تولید لینک‌های ماه بعد/قبل هست
  • show_other_days (پیشفرض: FALSE) - مشخص میکنه که روزهای مربوط به ماه قبل/بعد که با روز اول و آخر ماه جاری توی یک هفته‌ی مشترک قرار دارن، نمایش داده بشن یا بجاشون خانه‌ی خالی توی تقویم ظاهر بشه.

نمایش لینک‌های ماه بعد/قبل
برای اینکه تقویم شما بطور پویا بتونه ازطریق لینک‌های بعد/قبل افزایش یا کاهش پیدا کنه، باید تقویم رو مشابه مثال زیر تنظیم کنین:
$prefs = array(
   'show_next_prev'  => TRUE,
   'next_prev_url'   => 'http://example.com/index.php/calendar/show/'
);
$this->load->library('calendar', $prefs);
echo $this->calendar->generate($this->uri->segment(3), $this->uri->segment(4));

چند نکته درمورد تنظیمات بالا وجود داره:
  • شما باید show_next_prev رو با مقدار TRUE تنظیم کنید
  • شما لاید URL کنترلری که شامل تقویم شماست رو توی خصوصیت next_prev_url مشخص کنین. اگه اینکار رو انجام ندین، از controller/method جاری استفاده میشه
  • شما باید year و month رو توی تابع تولید تقویم مشخص کنین (کلاس تقویم بطور خودکار سال/ماه رو به URL پایه‌ای که مشخص کردین اضافه میکنه

ایجاد یک قالب تقویم
با تولید یک قالب تقویم، شما کنترل 100درصد طراحی تقویم رو بدست میارین. با استفاده از روش رشته‌ای، هر عنصر در تقویم شما داخل یک جفت شِبه‌متغیر شبیه مثال زیر قرار میگیره:
$prefs['template'] = '
   {table_open}<table border="0" cellpadding="0" cellspacing="0">{/table_open}

   {heading_row_start}<tr>{/heading_row_start}

   {heading_previous_cell}<th><a href="{previous_url}">&lt;&lt;</a></th>{/heading_previous_cell}
   {heading_title_cell}<th colspan="{colspan}">{heading}</th>{/heading_title_cell}
   {heading_next_cell}<th><a href="{next_url}">&gt;&gt;</a></th>{/heading_next_cell}

   {heading_row_end}</tr>{/heading_row_end}

   {week_row_start}<tr>{/week_row_start}
   {week_day_cell}<td>{week_day}</td>{/week_day_cell}
   {week_row_end}</tr>{/week_row_end}

   {cal_row_start}<tr>{/cal_row_start}
   {cal_cell_start}<td>{/cal_cell_start}
   {cal_cell_start_today}<td>{/cal_cell_start_today}
   {cal_cell_start_other}<td class="other-month">{/cal_cell_start_other}

   {cal_cell_content}<a href="{content}">{day}</a>{/cal_cell_content}
   {cal_cell_content_today}<div class="highlight"><a href="{content}">{day}</a></div>{/cal_cell_content_today}

   {cal_cell_no_content}{day}{/cal_cell_no_content}
   {cal_cell_no_content_today}<div class="highlight">{day}</div>{/cal_cell_no_content_today}

   {cal_cell_blank}&nbsp;{/cal_cell_blank}

   {cal_cell_other}{day}{/cal_cel_other}

   {cal_cell_end}</td>{/cal_cell_end}
   {cal_cell_end_today}</td>{/cal_cell_end_today}
   {cal_cell_end_other}</td>{/cal_cell_end_other}
   {cal_row_end}</tr>{/cal_row_end}

   {table_close}</table>{/table_close}
';
$this->load->library('calendar', $prefs);
echo $this->calendar->generate();

در روش آرایه‌ای، شما باید بصورت key => value کار کنین. میتونین هر تعداد مقداری که دوست دارین رو بفرستین. کلیدهایی که ارسال نشدن، از مقادیر پیشفرضشون توی کلاس Calendar استفاده میکنن. مثال:
$prefs['template'] = array(
   'table_open'           => '<table class="calendar">',
   'cal_cell_start'       => '<td class="day">',
   'cal_cell_start_today' => '<td class="today">'
);
$this->load->library('calendar', $prefs);
echo $this->calendar->generate();

مرجع کلاس CI_Calendar

initialize([$config = array()])

پارامترها:
  • $config (آرایه) پارامترهای پیکربندی

مقدار بازگشتی: شئ نمونه‌ی CI_Calendar (زنجیره‌ی متدها)

این تابع تنظیمات تقویم رو آماده‌سازی میکنه. یک آرایه‌ی انجمنی بعنوان ورودی دریافت میکنه که حاوی پارامترهای تنظیمات نمایش تقویم هست.


generate([$year = '' [, $month = '' [, $data = array()]]])

پارامترها:
  • $year (عدد صحیح) سال
  • $month (عدد صحیح) ماه
  • $data (آرایه) - داده‌هایی که باید داخل خانه‌های تقویم نمایش داده بشه

مقدار بازگشتی: (رشته) تقویم با قالب HTML

این تابع تقویم رو تولید میکنه.


get_month_name($month)

پارامترها:
  • $month (عدد صحیح) - ماه

مقدار بازگشتی: (رشته) اسم ماه

این تابع یک اسم متنی براساس شماره‌ی ماه اعلام‌شده برمیگردونه.


get_day_names($day_type = '')

پارامترها:
  • $day_type (رشته) یکی‌از مقادیر long یا short یا abr

مقدار بازگشتی: آرایه‌ی حاوی اسامی روزهای هفته

این تابع آرایه‌ی از اسامی روزهای هفته رو برحساس نوع روز درخواستی برمیگردونه. اگه پارامتری مشخص نشده باشه (یا مقدار غیرمجاز داشته باشه)، حالت خلاصه (Abbreviated) برگردونده میشه.


adjust_date($month, $year)

پارامترها:
  • $month (عدد صحیح) ماه
  • $year (عدد صحیح) سال

مقدار بازگشتی: آرایه‌ی انجمنی حاوی مقدار صحیح ماه و سال

این تابع مطمئن میشه که شما یک ترکیب صحیح از ماه/سال در اختیار دارین. برای مثال اگه عدد 13 رو بعنوان ماه ارسال کنین، سال یک‌واحد اضافه میشه و ماه January خواهد شد:
print_r($this->calendar->adjust_date(13, 2014));

خروجی:
Array
(
    [month] => '01'
    [year] => '2015'
)


get_total_days($month, $year)

پارامترها:
  • $month (عدد صحیح) ماه
  • $year (عدد صحیح) سال

مقدار بازگشتی: (عدد صحیح) تعداد روزهای موجود در ماه مشخص‌شده

echo $this->calendar->get_total_days(2, 2012);
// 29

نقل قول:نکته: این تابع یک اسم مستعار برای تابعdays_in_month() موجود در فایل کمکی Date محسوب میشه.


default_template()

مقدار بازگشتی: آرایه‌ی انجمنی از مقادیر پیشفرض قالب

این دستور قالب پیشفرض رو مشخص میکنه و در مواقعی که قالب اختصاصی خودتون رو نساختین کاربرد داره.


parse_template()

مقدار بازگشتی: شئ CI_Calendar (زنجیره‌ی متدها)

این متد داده‌های موجود در شبه‌متغیرها {pseudo-variables} که برای نمایش تقویم بکار رفتن رو پردازش میکنه.
صفحات: 1 2 3