
توی دوره رایگان PHP، هر چیزی که برای حرفهای شدن نیاز داری رو یاد میگیری! از مفاهیم پایه تا پیشرفته، همراه با یه پروژه واقعی برای ساخت یه سایت مثل آپارات.
مشاهده بیشتر
توی این دوره با هم یه وبسایت خبری واقعی رو از صفر میسازیم! از طراحی دیتابیس و احراز هویت تا ساخت API و یه پنل مدیریت حرفهای، همه رو یاد میگیریم و آماده پروژههای واقعی میشی!
مشاهده بیشترمشخصات مقاله
آموزش زمان بندی Task ها در لاراول
زمان بندی Task ها
- مقدمه
-
تعریف برنامه ی زمانی اجرای کار ها (تعریف تسک های زمان بندی شده)
- تنظیمات زمان بندی و تکرار اجرای تسک ها
- جلوگیری از تداخل و همپوشانی تسک ها
- خروجی تسک ها
- کدهایی برای اجرا قبل و پس از انجام تسک (task hook)
مقدمه
در گذشته، توسعه دهندگان به ازای هر تسک یا عملیاتی که قصد زمان بندی آن را داشتند، یک ورودی یا آیتم Cron تعریف می کردند. پیدا است که این کار بسیار ملال آور و طاقت فرساست. در Laravel دیگر،task schedule ها (برنامه ی زمانی اجرای کارها) در source control (سیستم کنترل نسخه) نیستند و برای افزودن آیتم Cron جدید بایستی از طریق پروتکل ssh از راه دور به server متصل شوید. ابزار Command scheduler (زمان بند اجرای دستورات) لاراول به شما این امکان را می دهد تا به روشی بهینه و آسان command schedule (برنامه ی زمانی اجرای دستورات) خود را داخل خود Laravel تعریف نمایید. همچنین لزومی به ایجاد یک آیتم cron برای زمان بندی هر تسک وجود ندارد و افزودن تنها یک Cron در server نیاز شما را برطرف خواهد کرد.
Cron = امکانی است در سیستم عاملهای مبتنی بر Unix که وظیفه ی آن اجرای برنامه در زمان بندیهای مشخص است. Cron این زمینه را برای کاربران فراهم می کند تا بتوانند کارها (دستورها و shell script) را به صورت زمان بندی شده و در دورههای زمانی مشخص اجرا کنند.
Task schedule ها داخل متد schedule از فایل app/Console/Kernel.php تعریف می شوند. جهت آشنایی و آموزش کار با آن یک نمونه ی آماده برای برنامه نویس در نظر گرفته شده است. می توان بی نهایت کار زمان بندی شده در شی Schedule ذخیره نمود.
راه اندازی scheduler
کافی است آیتم Cron زیر را به server اضافه نمایید:
1 2 | * * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1 <button></button> |
Cron ابزار command scheduler (زمان بند اجرای دستورات) لاراول را هر دقیقه یکبار صدا می زند. سپس Laravel تمامی تسک های زمان بندی شده ی شما را مورد بررسی قرار داده و آن تسک هایی که زمان اجرای آن ها بر اساس برنامه ی زمانی تعریف شده فرا رسیده را اجرا می کند.
تعریف برنامه ی زمانی اجرای کار ها (تعریف تسک های زمان بندی شده)
می توانید تمامی تسک های زمان بندی شده خود را در متد schedule از کلاس App\Console\Kernel تعریف نمایید. برای شروع به مثال ساده ای از زمان بندی یک تسک می پردازیم. در این مثال، یک تابع Closure را طوری زمان بندی می کنیم که درست نیمه شب هر روز فراخوانده شود. داخل تابع Closure یک کوئری جهت اجرای عملیات حذف جدول تعریف می کنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php namespace App\Console; use DB; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ \App\Console\Commands\Inspire:: class , ]; /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule ) { $schedule ->call( function () { DB::table( 'recent_users' )-> delete (); })->daily(); } } <button></button> |
علاوه بر زمان بندی فراخوانی توابع Closure، می توانید دستورات Artisan و سیستم عامل را برای اجرا زمان بندی نمایید. برای مثال، می توان متدcommand را برای زمان بندی اجرای یک دستور ساده ی Artisan به صورت زیر بکار برد:
1 2 | $schedule ->command( 'emails:send --force' )->daily(); <button></button> |
همچنین می توان دستور exec را برای دادن دستور اجرای عملیات خاصی به سیستم عامل فراخوانی کرد:
1 2 | $schedule -> exec ( 'node /home/forge/script.js' )->daily(); <button></button> |
تنظیمات زمان بندی و تکرار اجرای تسک ها
برنامه های زمانی متعددی برای تخصیص به تسک مورد نظر وجود دارد:
این متدها را می توان همراه با constraint ها و قیودی ترکیب نموده و برنامه های زمانی دقیق تری تنظیم کرد، به طوری که یک تسک تنها در روزهای خاصی از هفته اجرا شود. برای مثال جهت تنظیم یک برنامه ی زمانی که هر هفته تنها در روز دوشنبه اجرا شود:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Run once per week on Monday at 1 PM... $schedule ->call( function () { // })->weekly()->mondays()->at( '13:00' ); // Run hourly from 8 AM to 5 PM on weekdays... $schedule ->command( 'foo' ) ->weekdays() ->hourly() ->timezone( 'America/Chicago' ) ->when( function () { return date ( 'H' ) >= 8 && date ( 'H' ) <= 17; }); <button></button> |
در زیر لیستی از constraint هایی که می توان به برنامه های زمانی فوق اعمال کرد را مشاهده می کنید:
محدود نمودن اجرای تسک بر اساس نتیجه ی شرط یک تابع Closure
متد when را می توان جهت محدود سازی اجرای یک تسک بر اساس نتیجه ی شرط تعریف شده در یک تابع Closure مورد استفاده قرار داد. به عبارت دیگر، چنانچه خروجی Closure مقدار بولی true باشد، تسک مادامی که هیچ شرط دیگری مانع اجرای آن نشود، اجرا خواهد شد.
1 2 3 4 | $schedule ->command( 'emails:send' )->daily()->when( function () { return true; }); <button></button> |
متد skip را می توان نقطه ی مقابل و معکوس متد when قلمداد کرد. اگر متد skip مقدار true را برگرداند، تسک اجرا نخواهد شد:
1 2 3 4 | $schedule ->command( 'emails:send' )->daily()->skip( function () { return true; }); <button></button> |
در صورت استفاده از متدهای when زنجیره ای (که پشت سرهم فراخوانی می شوند)، دستور زمان بندی شده تنها زمانی اجرا می شود که شرطهای تعریف شده در when همگی مقدار بولی true را برگردانند.
جلوگیری از تداخل و همپوشانی تسک ها
به طور پیش فرض تسک زمان بندی شده حتی اگر هم نمونه ی قبلی از تسک مورد نظر هنوز در حال اجرا باشد، اجرا می شود و این امر تداخل آن ها را به دنبال دارد. برای جلوگیری از این رخداد، می توان متد withoutOverlapping را بکار برد:
1 2 | $schedule ->command( 'emails:send' )->withoutOverlapping(); <button></button> |
در این مثال دستور آرتیزان emails:send، چنانچه از قبل در حال اجرا نباشد، هر دقیقه یکبار اجرا خواهد شد. متد withoutOverlapping در شرایطی بسیار مفید محسوب می شود که تسک های زمان بندی شده از نظر مدت زمان اجرا با یکدیگر تفاوت قابل توجهی دارند و از این رو نمی توان پیشبینی کرد اجرای هر تسک دقیقا چه مدت به طول می انجامد.
خروجی تسک ها
ابزار scheduler (زمان بند اجرای تسک های) لاراول توابع متعددی برای کار با خروجی حاصل از اجرای تسک ها ارائه می دهد. ابتدا با استفاده از متدsendOutputTo، خروجی تسک را به یک فایل ارسال می کنیم (تا در آینده امکان بررسی آن وجود داشته باشد):
1 2 3 4 | $schedule ->command( 'emails:send' ) ->daily() ->sendOutputTo( $filePath ); <button></button> |
اگر می خواهید خروجی را به یک فایل مشخص پیوست کنید، کافی است متد appendOutputTo را مانند زیر بکار ببرید:
1 2 3 4 | $schedule ->command( 'emails:send' ) ->daily() ->appendOutputTo( $filePath ); <button></button> |
می توانید خروجی تسک را به آدرس ایمیل دلخواه خود ارسال کنید. برای این منظور کافی است متد emailOutputTo را فراخوانی نمایید. اما قبل از این کار باید خروجی را با فراخوانی متد sendOutputTo به یک فایل ارسال نمایید و همچنین سرویس های e-mail لاراول را تنظیم کنید:
1 2 3 4 5 | $schedule ->command( 'foo' ) ->daily() ->sendOutputTo( $filePath ) ->emailOutputTo( 'foo@example.com' ); <button></button> |
متدهای emailOutputTo و sendOutputTo تنها ویژه ی کار با متد command طراحی شده و برای تابع call قابل استفاده نمی باشند (پشتیبانی نمی شوند).
کدهایی برای اجرا قبل و پس از انجام تسک (task hook)
با بهره گیری از متدهای before و after می توانید کدی تعریف کنید که قبل و بعد از اتمام اجرای تسک زمان بندی شده مورد نظر اجرا شود:
1 2 3 4 5 6 7 8 9 | $schedule ->command( 'emails:send' ) ->daily() ->before( function () { // Task is about to start... }) ->after( function () { // Task is complete... }); <button></button> |
پینگ گرفتن از URL ها
با بهره گیری از دو متد pingBefore و thenPing، ابزار scheduler می تواند از یک URL قبل و بعد از اتمام اجرای تسک پینگ بگیرید. با بکارگیری این متد می توانید به راحتی به سرویس های خارجی لاراول نظیر Envoyer، اطلاع رسانی کنید که تسک معینی در حال آغاز به کار یا اتمام اجرا می باشد:
1 2 3 4 5 | $schedule ->command( 'emails:send' ) ->daily() ->pingBefore( $url ) ->thenPing( $url ); <button></button> |
استفاده از امکان pingBefore($url) یا thenPing($url) لازمه ی نصب کتابخانه ی Guzzle HTTP است. می توان به راحتی کتابخانه یGuzzle را با افزودن کد زیر به فایل composer.json به پروژه ی خود اضافه کرد:
1 2 | "guzzlehttp/guzzle" : "~5.3|~6.0" <button></button> |