<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های رضا پارسیان | سازنده PromoSMS.ir</title>
        <link>https://virgool.io/feed/@Rp76</link>
        <description>Full-Stack Developer (Laravel/Vue) | 
در حال ساخت PromoSMS.ir | 
نوشتن درباره کدنویسی، رشد استارتاپ و بازاریابی فنی 💻📈</description>
        <language>fa</language>
        <pubDate>2026-04-14 18:35:11</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/40926/avatar/d9VWD9.png?height=120&amp;width=120</url>
            <title>رضا پارسیان | سازنده PromoSMS.ir</title>
            <link>https://virgool.io/@Rp76</link>
        </image>

                    <item>
                <title>چگونه در ۵ دقیقه احراز هویت دو مرحله‌ای (OTP) را به Laravel اضافه کنیم؟</title>
                <link>https://virgool.io/@Rp76/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%AF%D8%B1-%DB%B5-%D8%AF%D9%82%DB%8C%D9%82%D9%87-%D8%A7%D8%AD%D8%B1%D8%A7%D8%B2-%D9%87%D9%88%DB%8C%D8%AA-%D8%AF%D9%88-%D9%85%D8%B1%D8%AD%D9%84%D9%87-%D8%A7%DB%8C-otp-%D8%B1%D8%A7-%D8%A8%D9%87-laravel-%D8%A7%D8%B6%D8%A7%D9%81%D9%87-%DA%A9%D9%86%DB%8C%D9%85-amc1a49d18eh</link>
                <description>چرا OTP دیگه یک انتخاب نیست، یک ضرورته؟ 🔐چرا OTP دیگه یک انتخاب نیست، یک ضرورته؟ 🔐اگر شما هم یک سایت فروشگاهی، سرویس آنلاین یا اپلیکیشن دارید، حتماً با این چالش روبرو شدید:چطور مطمئن بشم شماره موبایل کاربر واقعاً متعلق به خودشه؟چطور بدون پیچیدگی زیاد، امنیت ثبت‌نام رو بالا ببرم؟در سال ۱۴۰۴، احراز هویت دو مرحله‌ای (OTP) دیگه یک آپشن لوکس نیست. کاربران ایرانی به‌شدت نسبت به امنیت حساس شدن و اگر سایت شما نتونه کد تایید بفرسته، احتمالاً رقیبتون رو انتخاب می‌کنن.اما مشکل اینجاست: خیلی از پنل‌های پیامک یا مستندات ضعیفی دارن، یا پیاده‌سازی‌شون زمان‌بره، یا هزینه‌های پنهان دارن.در این مقاله، قراره در کمتر از ۵ دقیقه و با حدود ۳۰ خط کد، یک سیستم OTP کامل و امن به پروژه Laravel شما اضافه کنیم. بدون نیاز به پکیج اضافی، بدون پیچیدگی.چیزی که در پایان این مقاله دارید:✅ یک کنترلر کامل برای ارسال و بررسی کد تایید✅ کد آماده برای کپی‌پیست در پروژه✅ لینک دانلود پروژه کامل از گیت‌هاب✅ پیامک رایگان برای تستبریم شروع کنیم! 👇چه چیزهایی نیاز داریم؟ 📋قبل از شروع، مطمئن شو این موارد رو داری:Laravel 8 یا بالاتراکانت PromoSMSAPI Token - از پنل کاربری قابل دریافت‌ه (رایگان)آشنایی مقدماتی با لاراول💡 نکته: اگر هنوز اکانت نداری، همین الان ثبت‌نام کن. پیامک رایگان برای تست بهت هدیه میدیم.ساخت کنترلر OTP 🎮اولین قدم، ساخت یک کنترلر برای مدیریت ارسال و بررسی کد تاییده.در ترمینال پروژه‌ت این دستور رو اجرا کن:php artisan make:controller OtpControllerحالا فایل app/Http/Controllers/OtpController.php رو باز کن و این کدها رو اضافه کن:&lt;?php

namespace App\Http\Controllers;

use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class OtpController extends Controller
{
    /**
     * ارسال کد تایید به شماره موبایل
     * @throws ConnectionException
     */
    public function send(Request $request)
    {
        // اعتبارسنجی شماره موبایل
        $request-&gt;validate([
            &#039;phone&#039; =&gt; [&#039;required&#039;, &#039;size:11&#039;, &#039;regex:/^09[0-9]{9}$/&#039;]
        ]);

        $phone = $request-&gt;phone;

        // تولید کد ۵ رقمی تصادفی
        $code = str_pad(rand(1, 99999), 5, 0, STR_PAD_LEFT);

        // ذخیره کد در کش به مدت ۲ دقیقه
        Cache::put(&#039;otp_&#039; . $phone, $code, 120);

        // ارسال پیامک با PromoSMS
        $response = Http::withToken(config(&#039;services.promosms.token&#039;))
            -&gt;withHeaders([
                &#039;Accept&#039; =&gt; &#039;application/json&#039;,
            ])
            -&gt;post(&#039;https://promosms.ir/api/send/pattern&#039;, [
                &#039;number&#039; =&gt; $phone,
                &#039;data&#039; =&gt; [
                    &#039;data1&#039; =&gt; $code,
                ],
                &#039;pattern_code&#039; =&gt; config(&#039;services.promosms.patterns.login&#039;)
            ]);

        // لاگ‌گیری برای دیباگ
        Log::info(&quot;OTP sent to {$phone}&quot;, [
            &#039;status&#039; =&gt; $response-&gt;successful(),
            &#039;code&#039; =&gt; $response-&gt;status(),
            &#039;report_id&#039; =&gt; $response-&gt;json()[&#039;info&#039;][&#039;report_id&#039;],
        ]);

        return response()-&gt;json([
            &#039;success&#039; =&gt; $response-&gt;successful(),
            &#039;message&#039; =&gt; $response-&gt;successful()
                ? &#039;کد تایید ارسال شد&#039;
                : &#039;خطا در ارسال پیامک&#039;
        ]);
    }

    /**
     * بررسی کد تایید واردشده توسط کاربر
     */
    public function verify(Request $request)
    {
        $request-&gt;validate([
            &#039;phone&#039; =&gt; &#039;required|size:11&#039;,
            &#039;code&#039; =&gt; &#039;required|size:5&#039;
        ]);

        $phone = $request-&gt;phone;
        $code = $request-&gt;code;

        // دریافت کد ذخیره‌شده از کش
        $storedCode = Cache::get(&#039;otp_&#039; . $phone);

        if (!$storedCode) {
            return response()-&gt;json([
                &#039;success&#039; =&gt; false,
                &#039;message&#039; =&gt; &#039;کد تایید منقضی شده یا وجود ندارد&#039;
            ], 400);
        }

        // بررسی صحت کد
        if ($storedCode != $code) {
            return response()-&gt;json([
                &#039;success&#039; =&gt; false,
                &#039;message&#039; =&gt; &#039;کد تایید اشتباه است&#039;
            ], 400);
        }

        // حذف کد از کش پس از موفقیت
        Cache::forget(&#039;otp_&#039; . $phone);

        return response()-&gt;json([
            &#039;success&#039; =&gt; true,
            &#039;message&#039; =&gt; &#039;تایید هویت با موفقیت انجام شد&#039;
        ]);
    }
}تعریف روت‌ها 🛣️حالا باید روت‌های API رو تعریف کنیم. فایل routes/api.php رو باز کن:// ارسال کد تایید (با محدودیت 1 درخواست در 2دقیقه)
Route::post(&#039;/otp/send&#039;, [OtpController::class, &#039;send&#039;])
    -&gt;middleware(&#039;throttle:1,2&#039;);

// بررسی کد تایید
Route::post(&#039;/otp/verify&#039;, [OtpController::class, &#039;verify&#039;]);⚠️ نکته امنیتی حیاتی:میدلور throttle:1,2 یعنی هر کاربر حداکثر می‌تونه ۱ درخواست در ۲دقیقه بفرسته. این برای جلوگیری از اسپم و سوءاستفاده ضروریه.تنظیمات API Key ⚙️برای اینکه کد کار کنه، باید API Token و Sender رو به پروژه اضافه کنی.فایل config/services.php رو باز کن و این بخش رو اضافه کن&#039;promosms&#039; =&gt; [
    &#039;token&#039; =&gt; env(&#039;PROMOSMS_API_TOKEN&#039;),
    &#039;patterns&#039; =&gt; [
        &#039;login&#039; =&gt; env(&#039;PROMOSMS_PATTERN_CODE_LOGIN&#039;)
    ],
],حالا در فایل .env این مقادیر رو اضافه کن:#-------Custom Env------
PROMOSMS_API_TOKEN=your_api_token_here
PROMOSMS_PATTERN_CODE_LOGIN=your_pattern_codeتست با Postman 🧪حالا وقتشه که ببینیم کد واقعاً کار می‌کنه!درخواست ارسال OTP: (فقط کافیه کد زیر رو توی postman وارد کنید تا تنظیمات به صورت خودکار انجام بشه)curl --location &#039;http://127.0.0.1:8000/api/otp/send&#039; \
--header &#039;Content-Type: application/json&#039; \
--data &#039;{
    &quot;phone&quot;: &quot;09111111111&quot;
}&#039;خروجی کد بالا باید بشه{
    &quot;success&quot;: true,
    &quot;message&quot;: &quot;کد تایید ارسال شد&quot;
}درخواست بررسی OTP:curl --location &#039;http://127.0.0.1:8000/api/otp/verify&#039; \
--header &#039;Accept: application/json&#039; \
--header &#039;Content-Type: application/json&#039; \
--data &#039;{
    &quot;phone&quot;:&quot;09111111111&quot;,
    &quot;code&quot;:&quot;80910&quot;
}&#039;خروجی کد بالا باید بشه{
    &quot;success&quot;: true,
    &quot;message&quot;: &quot;تایید هویت با موفقیت انجام شد&quot;
}⚠️ نکات امنیتی که باید رعایت کنیمحدودیت تعداد درخواست (Rate Limiting)همون‌طور که دیدید، از میدلور throttle استفاده کردیم. این جلوگیری می‌کنه از:اسپم شدن شماره کاربرانهزینه اضافی برای توحملات Brute Forceاعتبار زمانی کد (Expiration)کد ما فقط ۲ دقیقه اعتبار داره. بعد از این زمان، کش منقضی میشه و کاربر باید دوباره درخواست بده.عدم نمایش خطای دقیقدر پاسخ خطا، هیچ‌وقت نگو «این شماره ثبت‌نام نشده» یا «کد اشتباهه، ۲ بار دیگه شانس داری». این اطلاعات به هکرها کمک می‌کنه.لاگ‌گیری تلاش‌های ناموفقبرای تشخیص حملات، حتماً تلاش‌های ناموفق رو لاگ کنif ($storedCode != $code) {
    Log::warning(&quot;Failed OTP attempt for {$phone}&quot;);
    // ...
}🎁 هدیه ویژه: پروژه آماده گیت‌هابمی‌دونم که بعضی وقت‌ها کپی‌پیست کردن کد از روی مقاله سخته. برای همین، کل این پروژه رو به‌صورت آماده در گیت‌هاب گذاشتم.# 1. کلون کردن پروژه
git clone https://github.com/PromoSmsIR/promosms-laravel-otp-example.git

# 2. نصب وابستگی‌ها
cd promosms-laravel-otp-example
composer install

# 3. کپی فایل محیطی
cp .env.example .env
php artisan key:generate

# 4. تنظیم API Key در فایل .env
#-------Custom Env------
PROMOSMS_API_TOKEN=your_api_token_here
PROMOSMS_PATTERN_CODE_LOGIN=your_pattern_code

# 5. اجرای سرور
php artisan serveدر این ریپو پیدا می‌کنی:✅ کد کامل کنترلر و روت‌ها✅ فایل .env.example آماده✅ کلکشن Postman برای تست سریع✅ راهنمای فارسی در README🎯 حالا با این چیکار می‌تونم بکنم؟ثبت‌نام کاربران (تایید شماره موبایل هنگام ثبت‌نام)ورود دو مرحله‌ای (افزایش امنیت حساب‌های کاربری)تایید تراکنش (ارسال کد برای پرداخت‌های حساس)بازیابی رمز (ارسال کد برای ریست پسورد)❓ سوالی داری؟اگر در حین پیاده‌سازی به مشکلی خوردی، یا ایده‌ای برای بهبود کد داری، حتماً در کامنت‌ها بنویس. شخصاً جواب میدم و اگر باگی پیدا کردی، خوشحال می‌شم گزارش بدی تا ریپو رو آپدیت کنم.اگر این مقاله برات مفید بود:👍 بوک‌مارک کن که گمش نکنی🔄 برای هم‌تیمی‌هات بفرست💬 تجربه‌ت رو درباره OTP در کامنت‌ها بنویسموفق باشید! 💙لینک های مفیدثبت‌نام و تست رایگانآدرس مخزن گیت‌هابچگونه یک سرویس پیامک انبوه را با Laravel ساختیم؟ (از ایده تا اجرا)#لاراول #OTP #احراز_هویت #برنامه_نویسی #PromoSMS #امنیت_وب #استارتاپ #پیامک</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Wed, 25 Feb 2026 09:31:02 +0330</pubDate>
            </item>
                    <item>
                <title>چگونه یک سرویس پیامک انبوه را با Laravel ساختیم؟ (از ایده تا اجرا)</title>
                <link>https://virgool.io/@Rp76/%DA%86%DA%AF%D9%88%D9%86%D9%87-%DB%8C%DA%A9-%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D9%BE%DB%8C%D8%A7%D9%85%DA%A9-%D8%A7%D9%86%D8%A8%D9%88%D9%87-%D8%B1%D8%A7-%D8%A8%D8%A7-laravel-%D8%B3%D8%A7%D8%AE%D8%AA%DB%8C%D9%85-%D8%A7%D8%B2-%D8%A7%DB%8C%D8%AF%D9%87-%D8%AA%D8%A7-%D8%A7%D8%AC%D8%B1%D8%A7-qtr2fbwjxkgu</link>
                <description>سلام دوباره، با یک داستان جدید 👋پرومو اس‌ام‌اسسلام به همه دوستان قدیمی ویرگول! رضا هستم، همون توسعه‌دهنده‌ای که چند سال پیش درباره Laravel و API می‌نوشت.توی این چند سال، از کدنویسی صرف فاصله گرفتم و وارد دنیای چالش‌برانگیز «ساخت محصول» شدم. امروز می‌خوام داستان ساخت PromoSMS رو براتون تعریف کنم؛ سرویسی که از یک نیاز شخصی شروع شد و حالا داره به کسب‌وکارهای ایرانی کمک می‌کنه بهتر با مشتریانشون ارتباط بگیرن.اگر شما هم:- توسعه‌دهنده‌اید و می‌خواید بدونید پشت صحنه یک سرویس SaaS ایرانی چه می‌گذره،- یا صاحب کسب‌وکارید و می‌خواید بدونید چطور می‌تونید با پیامک فروش‌تون رو افزایش بدید،این مقاله برای شماست. بریم شروع کنیم! 👇چرا اصلاً سراغ ساخت پنل پیامک رفتم؟ 🤔همه چیز از یک مشکل شخصی شروع شد.وقتی داشتم روی یک پروژه فروشگاهی کار می‌کردم، نیاز داشتم که به مشتریانم پیامک تأیید سفارش بفرستم. رفتم سراغ پنل‌های موجود، اما با چند چالش روبرو شدم:1. مستندات فنی ضعیف: وب‌سرویس‌ها یا داکیومنت نداشتن، یا مثال‌هاشون قدیمی بود.2. پیچیدگی برای توسعه‌دهنده: برای یک کار ساده مثل ارسال OTP، باید از ده تا منو رد می‌شدم!3. عدم شفافیت قیمت: بعضی پنل‌ها هزینه‌های پنهان داشتن که تازه بعد از شارژ معلوم می‌شد.با خودم گفتم: «من که Full-Stack کار می‌کنم، چرا یک سرویس ساده‌تر، شفاف‌تر و دولوپر-فرندلی نسازم؟»و این‌طور شد که PromoSMS متولد شد.چالش‌های فنی ساخت یک سرویس پیامک با Laravel 💻اینجا می‌خوام کمی فنی‌تر بشم (بخش مورد علاقه دولوپرها!). ساختن یک پنل پیامک فقط «ارسال درخواست HTTP به اپراتور» نیست. چند تا چالش جدی وجود داشت:🔹 مدیریت صف‌ها (Queue) برای ارسال انبوهوقتی یک کاربر می‌خواد ۱۰,۰۰۰ پیامک تبلیغاتی بفرسته، نمی‌تونی همون لحظه همه رو ارسال کنی. سرور کرش می‌کنه!راه‌حل من: استفاده از Laravel Queue + Redis// مثال ساده: ارسال پیامک در پس‌زمینه

SendSmsJob::dispatch($phoneNumber, $message)

-&gt;onQueue(&#039;sms&#039;)

-&gt;delay(now()-&gt;addSeconds(5));این‌طوری کاربر سریع فیدبک می‌گیره و ارسال واقعی در پس‌زمینه انجام میشه.🔹 یکپارچه‌سازی با چندین اپراتورهر اپراتور پیامک در ایران API متفاوتی داره (REST، SOAP، حتی XML!).راه‌حل: طراحی یک Interface واحد و پیاده‌سازی Adapter برای هر اپراتور:interface SmsProviderInterface {

public function send(string $to, string $message): bool;

}



class MedianaAdapter implements SmsProviderInterface { ... }

class KavenegarAdapter implements SmsProviderInterface { ... }این معماری به من اجازه میده بدون تغییر کد اصلی، اپراتور جدید اضافه کنم یا اگر یکی دان‌شد، خودکار سوئیچ کنم به بعدی.🔹 مقیاس‌پذیری و مانیتورینگوقتی تعداد کاربران زیاد شد، دیگه نمی‌تونستم با dd() دیباگ کنم! 😅ابزارهایی که نجاتم دادن:Laravel Telescope برای دیباگ درخواست‌هاSentry برای ردیابی خطاهاLaravel Horizon برای مانیتور کردن Queueها💡درس فنی: همیشه از روز اول لاگ‌گیری و مانیتورینگ رو جدی بگیر. وقتی مشکل پیش بیاد، وقت دیباگ ندارید!درس‌های بیزینسی که کدنویسی به من یاد نداد 📈اینجا می‌خوام از دنیای کد بیام بیرون و درباره چیزی بگم که برای صاحبان کسب‌وکار جالب‌تره.وقتی PromoSMS رو ساختم، فکر می‌کردم «اگر محصول فنی‌ام خوب باشه، مشتریان خودشون میان». اما اشتباه می‌کردم!🔸 درس ۱: مشتری «فیچر» نمی‌خره، «راه‌حل مشکل» می‌خرهیک صاحب فروشگاه اینستاگرامی نمی‌خواد بدونه من از Redis استفاده کردم یا نه. اون می‌خواد بدونه:«آیا می‌تونم وقتی سفارش جدید اومد، خودکار به مشتری پیامک بزنم تا اعتمادش جلب بشه؟»پس توی پنل، فیچرها رو با زبان «سود کسب‌وکار» توضیح دادم، نه زبان فنی.🔸 درس ۲: پشتیبانی سریع = وفاداری مشتریتوی ایران، خیلی از پنل‌های بزرگ پشتیبانی‌شون ساعت‌ها طول می‌کشه. من تصمیم گرفتم:پاسخ به تیکت‌ها در کمتر از ۲ ساعت کاریپاسخ مستقیم من (به‌عنوان سازنده) به سوالات فنی در لینکدین و توییترنتیجه؟ کاربران قدیمی دارن دوستانشون رو معرفی می‌کنن. این یعنی بازاریابی رایگان!🔸 درس ۳: شفافیت، اعتماد می‌سازهتوی صفحه تعرفه‌ها، دقیقاً نوشتم هر پیامک چقدر هزینه داره. بدون «هزینه پنهان»، بدون «کارمزد نامرئی».شاید فکر کنید اینطوری سودم کمتر میشه، اما برعکس: وقتی کاربر اعتماد کنه، بیشتر شارژ می‌کنه و طولانی‌تر می‌مونه.حالا نوبت شماست 👇اگر شما هم توسعه‌دهنده‌اید و می‌خواید این سرویس رو تست کنید:📚 مستندات فنی🎁 پیامک رایگان برای شروعاگر صاحب کسب‌وکارید و می‌خواید بدونید چطور با پیامک فروش‌تون رو افزایش بدید من رو دنبال کنیدو در پایان... ✨ساختن یک محصول، فقط کدنویسی نیست. ترکیبی‌ه از:تخصص فنی ✅درک نیاز مشتری ✅صبر و یادگیری مستمر ✅اگر شما هم ایده‌ای دارید که می‌خواید تبدیلش کنید به محصول، یا سوالی درباره پیاده‌سازی فنی PromoSMS دارید، توی کامنت‌ها بنویسید. قول میدم شخصاً جواب بدم. 👇ممنون که تا اینجا خوندید. اگر این مقاله براتون مفید بود، با به‌اشتراک‌گذاری‌اش به من کمک کنید تا داستان‌های بیشتری از پشت صحنه استارتاپ‌های ایرانی براتون بنویسم. 💙#لاراول #استارتاپ #پیامک_مارکتینگ #توسعه_فردی #PromoSMS #برنامه_نویسی #کسب_و_کار_اینترنتی</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Sun, 22 Feb 2026 08:39:18 +0330</pubDate>
            </item>
                    <item>
                <title>درخواست کمتر، سرعت بیشتر!</title>
                <link>https://virgool.io/@Rp76/%D8%AF%D8%B1%D8%AE%D9%88%D8%A7%D8%B3%D8%AA-%DA%A9%D9%85%D8%AA%D8%B1-%D8%B3%D8%B1%D8%B9%D8%AA-%D8%A8%DB%8C%D8%B4%D8%AA%D8%B1-o0l6jcwnuxlm</link>
                <description>درخواست کمتر، سرعت بیشتر!وقتی صحبت از پروژه ها میشه به صورت اتوماتیک بعد از تکنولوژی  که برای نوشتن اون پروژه استفاده می‌شه می‌ریم سراغ دیتابیس و میشه گفت مهم  ترین بخش هر پروژه دیتابیسی هست که داره.به احتمال خیلی زیاد شما هم با رابطه ها توی پروژه های لاراولی  کار کردید و می‌دونید چطوری باید بین دو جدول رابطه برقرار کنید، بعد از  نوشتن متد فقط کافیه از with یا load استفاده کنید که وقتی داره از دیتابیس اطلاعات رو فراخوانی می‌کنه به همراه رابطه‌هاشون باشه// model Post
public function user(){
    return $this-&gt;belongsTo(User::class);
}

// Controller

$posts=Post::with(&#039;user&#039;)-&gt;get();

// Sql
// حالا دقیقا نمی‌دونم از چه نوع join استفاده می‌کنه ولی کد یچزی میشه مثل این

select * from posts
inner join users on users.id=posts.user_id;نباید چیزی فراتر از این باشه ?خب تا اینجا همه چی داره خوب پیش میره! ولی مشکل از کجا شروع میشه؟فرض کنید که با چند برنامه‌نویس دیگه دارید پرژه رو جلو  می‌برید و بعضی از افراد به اندازه کافی تجربه ندارند یا زمانی که خسته  هستید دارید کدی رو می‌زنید و یادتون میره از with استفاده کنید.load زیاد قابل استفاده نیست وقتی دارید از  دیتابیس اطلاعات می‌گیرید بیشتر برای زمانی هست که دیتا لود شده ولی شما به  چندتا رابطه هم نیاز دارید مثل زمانی که route binding انجام میدید.خب بریم ببینیم دقیقا چی میشه!// model Post
public function user(){
    return $this-&gt;belongsTo(User::class);
}

// Controller

$posts=Post::all();

// فرق نداره توی blade یا resource ها باشه ولی روی blade مثال میزنم راحت تره!

// Blade

@foreach($posts as $post)
    &lt;tr&gt;
        &lt;td&gt;{{$post-&gt;id}}&lt;/td&gt;
        &lt;td&gt;{{$post-&gt;title}}&lt;/td&gt;
        &lt;td&gt;{{$post-&gt;user-&gt;name}}&lt;/td&gt;
    &lt;/tr&gt;
@endforeachخب مشکل کد بالا چی هست؟درخواستی که به دیتابیس زده میشه میشهselect * from postsو زمانی که توی حلقه هستید باز هم به دیتابیس درخواست هایی ارسال میشه به این صورتselect * from user where id = $post-&gt;user_idو اگر ۱۰ تا ردیف واکشی شده باشه برای post شما برای گرفتن دیتا ۱۰+۱ درخواست به دیتابیس میزنید// 1x
select * from posts;

// 10x
select * from user where id = $post-&gt;user_idخب چطوری میشه کاری کرد که جلوی این اتفاق رو بگیریم؟به این حالت می‌گن lazy load کردن دیتا، مدل  های لاراول این قابلیت رو دارند که متوجه بشند شما دیتا رو لود کردید یا  دارید lazy load انجام میدید! خب چطوری میشه جلوش رو گرفت؟فقط کافیه یجایی از پروژه‌اتون از کد زیر استفاده کنید.Model::preventLazyLoading();بهتره که بالاترین جای پروژه باشه مثلا AppServiceProvider.phpبه همین سادگی میشه ازش جلوگیری کرد و سرعت سایت رو بالا برد.امیدوارم از این آموزش خوشتون امده باشه.چون می‌نویسم هستم. https://rp76.ir/blog/post/%D8%AF%D8%B1%D8%AE%D9%88%D8%A7%D8%B3%D8%AA-%DA%A9%D9%85%D8%AA%D8%B1-%D8%B3%D8%B1%D8%B9%D8%AA-%D8%A8%DB%8C%D8%B4%D8%AA%D8%B1 </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Wed, 26 Jul 2023 08:30:30 +0330</pubDate>
            </item>
                    <item>
                <title>جمع‌آوری اطلاعات اساتید از سایت استاد سلام با Cheerio</title>
                <link>https://virgool.io/@Rp76/%D8%AC%D9%85%D8%B9-%D8%A2%D9%88%D8%B1%DB%8C-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA-%D8%A7%D8%B3%D8%A7%D8%AA%DB%8C%D8%AF-%D8%A7%D8%B2-%D8%B3%D8%A7%DB%8C%D8%AA-%D8%A7%D8%B3%D8%AA%D8%A7%D8%AF-%D8%B3%D9%84%D8%A7%D9%85-%D8%A8%D8%A7-cheerio-sndqzjgfnkmp</link>
                <description>جمع‌آوری اطلاعات اساتید از سایت استاد سلام با Cheerioداشتن اطلاعات یکی از مهم ترین بخش هر کسب و کاری هست و برای داشتن اون ها کار زیاد ساده ای نیست توی این ویدیو با هم به سایت استاد سلام یه سری میزنیم و اطلاعات مربوط به اساتید رو جمع‌آوری میکنیم.توی این ویدیور ازAxiosTypescriptNode.jsCheerioاستفاده کردم.که به گفته سایت CheerioThe fast, flexible &amp; elegant library for parsing and manipulating HTML and XML.که به شما توی scrap کردن سایت ها خیلی کمک شایانی میتونه بکنهریپازیتوری پروژهregex101Phpstormآموزش یویتوبچون می‌نویسم هستم.</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Thu, 29 Jun 2023 11:15:27 +0330</pubDate>
            </item>
                    <item>
                <title>حل کپچا با جاوااسکریپت | solve captcha with Js, Ts</title>
                <link>https://virgool.io/@Rp76/%D8%AD%D9%84-%DA%A9%D9%BE%DA%86%D8%A7-%D8%A8%D8%A7-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-solve-captcha-with-js-ts-aimxbeen2h5f</link>
                <description>حل کپچا با جاوااسکریپت | solve captcha with Js, Tsدیروز یه قبض از مخابرات برام آمد، متوجه شدم با nodejs و  react نوشته شده. یه کد کپچا داشت رفتم پکیجش رو پیدا کردم و یطورایی مهندسی معکوسش کردم و  توی این فیلم توضیح میدم که چطوری میشه این کد رو حل کرد و به دیتای قبض  رسید.یکی میگفت که اینطوری پوشه بندی کردی پروژه رو با package ها به مشکل می‌خوری. باید بگم که به پکیج ها زیاد اکتفا نکنید.خودم هم باnodejsjavascripttypescriptaxiosپروژه رو کد زدم.یکم طولانی شده ولی جالبه.آموزش یویتوبچون می‌نویسم هستم.</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Mon, 12 Jun 2023 14:59:29 +0330</pubDate>
            </item>
                    <item>
                <title>Github Copilot</title>
                <link>https://virgool.io/@Rp76/github-copilot-uc0i23ldofzh</link>
                <description>Github Copilotمن تقریباً ۲ سال هست به صورت حرفه‌ای لاراول کار می‌کنم و ماجرا تقریباً از شهریور سال ۱۴۰۰ شروع شد.یک روز بعد از کار مثل همیشه خودم رو کشوندم پشت سیستمم و سایت هایی که هر روز میرفتم رو بررسی کردم، ایمیلم رو چک کردم و یک ایمیل از گیت هاب داشتم که داشت یچیزی رو معرفی می‌کرد که به خودم گفتم الان حالش رو نداری بذار برای بعد.رفتم یوتیوب یه موزیک گوش بدم، توی صفحه اصلی یه ویدیو نظرم رو جلب کرد که دقیقاً با مضمون ایمیلی که داشتم هماهنگ بود.وارد صفحه شدم، فیلم به صورت خودکار پخش شد و خیلی خوب بود تقریباً ۱۵ دقیقه فیلم بود ولی به زبان فارسی نبود، آمد و ابزار رو برای زبان پایتون توی vs code پرزنتیشن کرد و تمام.بدو بدو رفتم توی ایمیلی که بهم رسیده بود و وارد لینک دعوت نامه شدم.وقتی وارد صفحه شدم با یک صفحه فرود (Landing) خیلی جذاب رو به رو شدم، اینطوری تیتر زده بود Your AI pair programmer, هیچ نشونه‌ای توی سایت نبود که بگه از زبان PHP هم پشتیبانی می‌کنه و بدترین چیزی که وجود داشت این بود که باید ثبت نام کنی تا بعداً بهت امتیاز استفاده کردن رو بهت بدن به اصطلاح باید میرفتم توی لیست انتظار.صبح زودتر از همیشه بیدار شدم، سریع خودم رو رسوندم شرکت تا برای دوستام توضیح بدم که چه چیز خفنی آمده و قراره چی بشه، تا دیدمشون بدون اینکه سلام کنم گفتم وااای بچه ها گیت هاب یه برنامه‌ای درست کرده که بهش میگی می‌خوام فایل csv بخونم و اون خودش بقیه کار رو انجام میده، هیجان توی چشماشون موج می‌زد، بردمشون توی یوتیوب و فیلم رو برای اونا هم پخش کردم.بعد از اینکه فیلم تموم شد بهشون گفتم می‌دونید نکته جالبش کجاست؟گفتند مگر جالب تر از این که هوش مصنوعی کد بزنه هم هست؟گفتم آره، فعلاً رایگان هست ولی باید برید توی لیست انتظار، بدو بدو ثبت نام کردند و ما تقریباً ۲ ماه توی لیست انتظار بودیم تا اینکه صبح آمدم شرکت دیدم ایمیل دارم و حدس بزنید چی بود؟درسته، کوپایلت برای من باز شده بود نصبش کردم روی Php strom و پروژه رو باز کردم یه روت درست کردم و توی اون یه متغیر تعریف کردم به این شکل$name=و منتظر شدم.تقریباً زیر ۳ثانیه شروع کرد به پیشنهاد دادن و این خط رو به این شکل کامل کرد.$name=&amp;quotjohn&quot;تا آمدم دست به کیبورد بشم ۲ خط دیگه هم پیشنهاد داد$fname=&amp;quotbrown&quot;
$age=34;خیلی ذوق کرده بودم، اینتر زدم و شروع کردم به نوشتن کد زیرFunction readCsv(){

}درباره شروع کرد و پیشنهاد دادFunction readCsv(){
    Return file&#40;&amp;quotpath/to/file&amp;quotFILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES&#41;;
}من که تا حالا این تابع فایل رو استفاده نکرده بودم و منتظر بودم که file get contents این عمل رو انجام بده با نا‌امیدی کد رو اجرا کردم و دیدم که داره آرایه بر می‌گردونه، خیلی خوشحال شدم.تقریباً از اولین تجربه من ۱ سال میگذره، تقریباً ۵ ماه پیش بود که متوجه شدیم برنامه سربلند از آزمایش ها آمده بیرون و الان قراره برای فروش گذاشته بشه ولی ما هایی که توی این پروسه حضور داشتیم می‌تونیم یه مدتی به صورت رایگان ازش استفاده کنیم.دقیقا هفته پیش بود که اشتراک هامون تموم شد و به من و دوستام غم عظیمی رو تحمیل کردند.خب فکر‌ می‌کنم با این خاطره خوب متوجه شده باشید که این کوپایلت چی هست و چیکار می‌کنه.بخوام توی یک خط بگم دقیقا این ابزار چی هست فقط می‌تونم بگم، دستیار هوش‌مصنوعی برنامه‌نویسی.شاید برای شما سوال پیش آمده باشه که چطوری این ابزار که می‌کنه که اولش هم برای من هم سوال بود که الان بهتون توضیح می‌دم که چطوری کار می‌کنه.گیت‌هاب یک سرور برای ذخیره کدهاست که تقریبا همه نوع برنامه‌نویسی توش پیدا میشه از تازه کار تا حرفه‌ای از برنامه‌نویس تفریحی تا افراد حرفه‌ای که برای شرکت های بزرگی کار می‌کنند.خب این به ما چه؟ اصلا چه سودی داره ما این رو بدونیم؟ بهمون بگو کوپایلت چطوری کار میکنه!!!همه ما میدونیم که سیستم های یادگیری ماشین برای آموزش از میلیون ها داده استفاده می‌کنند که متوجه بشن که چی به چی هست، حالا سایت گیت‌هاب که از مجموعه بی‌پایانی از کد‌هاست آمده و موتور کوپایلت رو با منبع بی‌پایان خودش تغذیه کرده و نتیجه شده چیزی که دارید می‌بینید!اه این که خیلی بده شاید من یک چیزی توی گیت‌هابم داشته باشم که دوست ندارم کسی اون رو بدونه، الان قضیه چیه؟هیچ جای نگرانی نداره این ابزار فقط مخزن های عمومی رو مورد بررسی قراره میده.چقدر میشه به این ابزار اعتماد کرد؟آمار ها نشون داده میانگین ۲۶ درصد افراد از پیشنهاد های کوپایلت استفاده کردند، توی هر فایل هم بیشتر از ۲۷ درصد از کوپایلت استفاده شده که این آمار توی زبانی مثل Python تا ۴۰ درصد هم رسیده.با این حال گیت‌هاب کوپایلت قرار نیست کد های بی‌نقصی برای شما بنویسه و فقط نزدیکترین کد رو به شما پیشنهاد میده.کوپایلت میتونه کمک کنه که توی یه زبان یا فریم‌ورک جدید شروع کنیم به توسعه؟از اونجایی که کوپایلت از مخازن عمومی تغذیه می‌کنه باید بگم که کوپایلت هم مثل شما دانش زیادی نداره و باید منتظر بمونید که مخازن بیشتری منتشر بشن ولی اینطوری هم نیست که نتونه هیچ پیشنهادی بده، فقط باید بیشتر بهش توجه کنید که خراب‌کاری نکنه.چطوری میشه از کوپایلت به بهترین شکل استفاده کرد؟توی کدنویسی مهم ترین قانونی که وجود داره اینکه تمیز کد بزنید و کد هاتون رو به اجزای کوچکتر تقسیم کنید.اگر این اصول رو رعایت کنید و کد هاتون رو به اجزای کوچکتر تجزیه کنید بدون شک پیشنهاد های شگفت‌انگیز تری کوپایلت می‌گیرید!کوپایلت چیزی از ما میدونه؟باید بگم که آره.وقتی شما شروع می‌کنید به کد زدن از یک سبک خاصی پیروی می‌کنید به اصطلاح دست‌خط خودتون رو دارید و بعد از گذشت مدت زمان نه چندان طولانی کوپایلت این هارو متوجه میشه و رعایت می‌کنه مثلا اگر شما همیشه از تک کوتیشن به جای کوتیشن استفاده می‌کنید اون هم همین کارو میکنه.کوپایلت کد های خصوصی من رو هم به اشتراک میذاره؟نه، همونطور که کمی بالاتر گفتم فقط از مخازن عمومی استفاده میکنه و دیتایی که برای سرور های خودش ارسال می‌کنه فقط این هست که شما کد رو قبول کردید یا نه.و در آخر باید بگم نگران مالکیت کد هایی که کوپایلت برای شما پیشنهاد داده هم نباشد، این که ابزار هست که آمده به شما کمک کنه. https://rp76.ir چون می‌نویسم هستم.</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Thu, 01 Sep 2022 20:42:43 +0430</pubDate>
            </item>
                    <item>
                <title>لاراول در لوله‌کشی Decorator</title>
                <link>https://virgool.io/@Rp76/%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%AF%D8%B1-%D9%84%D9%88%D9%84%D9%87-%DA%A9%D8%B4%DB%8C-decorator-cx83drbw7b9j</link>
                <description>لاراول در لوله‌کشی Decoratorتاحالا شده یکسری دستورات تکراری رو هرجایی از پروژتون استفاده کنید و دیگه خسته شده باشید ازش؟ من مثل شما، فقط از این که کد ها تکراری باشه خسته نشده بودم، به هم ریختگی بیشتر اذیتم می‌کرد.داشتم اینترنت رو زیر و رو می‌کردم نه برای پیدا کردن راهی، برای یادگرفتن چیز های جدید.تصمیم گرفتم برم چندتا دیزاین پترن دیگه یادبگیرمدیزاین پترن‌ها به من بیشتر از برنامه‌نویسی سبک فکر کردن رو یاد می‌دند!از دیزاین پترن‌های ساده شروع کردم، یک پترن جالب پیدا کردم به اسم Decorator کارش این‌ بود که یک‌سری تغییرات رو به صورت سلسله مراتب روی ورودی انجام بده و خروجی نهایی رو برگردونه. کارش خیلی باحاله، مثلا شما یه متن دارید قراره کار های زیر رو به ترتیب روش اعمال کنید.۱. حذف کلمات رکیک۲. حذف نماد های اضافه۳. حذف فاصله های اضافه۴. اضافه کردن نیم‌فاصلهمیشه همه این قانین رو یکجا نوشت و توسعه‌اش روز به روز سخت تر و سخت‌تر میشه یا بیایم از این دیزاین پترن استفاده کنیم.?دیاگرام بالا فقط برای درک بهتر هست، ما با همون متن پیش می‌ریم که ساده تر باشهبرای این دیزاین پترن به یک Interface نیاز داریم به این صورت&lt;?php
namespace Rp۷۶\Decorator;
interface Stringify
{
public function operation(): string;
}حالا یک Class باید داشته باشیم به عنوان کلاس اصلی که از این Interface ارث بری کنه.&lt;?php
namespace Rp۷۶\Decorator;
class MainData implements Stringify
{
public function operation(): string
{
return file_get_contents&#40;&amp;quotfile.txt&amp;quot&#41;;
}
}? اسم گذاری یکم سخته !!خب class بالا اصل داستان هست و دیتا از اونجا وارد میشه حالا هر شیوه‌ای که دوست دارید.تا اینجا همون داستان قبلی هست، فرض کنید که MainData جمله رو گرفته و کلمات رکیک رو حذف کرده.فردا دوباره می‌رید پای کار و می‌بینید که باید علامت‌های اضافه هم پاک کنید.یک class دیگه اضافه می‌کنم، از این جا داستان داره یکم عوض میشه!&lt;?php
namespace Rp۷۶\Decorator;
class Decorator implements Stringify
{
protected $component;
public function __construct(Stringify $component)
{
$this-&gt;component = $component;
}
public function operation(): string
{
return $this-&gt;component-&gt;operation();
}
}class ما باید دوباره از interface ارث بری کنه و یک متد سازنده یا Constructor داشته باشه که ورودیش یک کلاسی باشه که از همون interface ارث بری می‌کنه.حالا وقت اون رسیده که قوانین رو بسازیم، هر قانون یک Class.قوانین باید از کلاس بالا ارث‌بری کنند.&lt;?php
namespace Rp۷۶\Decorator;
class BadWords extends Decorator
{
public function operation(): string
{
return str_replace(&amp;quotsome_bad_words&amp;quot,&amp;quot****&amp;quot,parent::operation());
}
}&lt;?php
namespace Rp۷۶\Decorator;
class Emojis extends Decorator
{
public function operation(): string
{
return str_replace(&amp;quotsome_emoji&amp;quot,&amp;quot&amp;quot,parent::operation());
}
}خب حالا چطوری استفاده کنیم؟ خیلی ساده هست!&lt;?php
namespace Rp۷۶\Decorator;
$decorator=new MainData;
echo $decorator-&gt;operation();خب کد بالا متن خام رو برمیگردونه مثل روز اول، اگر می‌خواید که قوانین اعمال بشه باید کد زیر رو استفاده کنید.&lt;?php
namespace Rp۷۶\Decorator;
$decorator=new MainData;
$decorator۱=new BadWords($decorator);
$decorator۲=new Emojis($decorator۱);
echo $decorator۲-&gt;operation();به همین صورت میشه میلیون ها قانون دیگه اضافه کرد بدون این که هر کدوم به هم وابستگی خاصی داشته باشند.توی لاراول از این پترن هم استفاده شده، اگر بخواید توی لاراول همچین چیزی داشته باشد میتونید از کلاس \Illuminate\Pipeline\Pipeline::class استفاده کنید که کار رو خیلی ساده کرده.متد‌های این کلاس شاملSend ورودی ما به Pipe هست برای پرداشزthrough ورودی ما از طریق این متد که یک آرایه ‌ای از کلاس هارو به عنوان ورودی می‌گیره پردازش میشه.via این متد هم یک اسم از ما می‌گیره به عنوان اسم متدی که توی کلاس های بالا باید صدا زده بشه که به صورت پیشفرض روی handle تنظیم شده.then بعد از این که پردازش ها تموم شد این متد صدا زده میشه که یک فانکشن به عنوان ورودی می‌خواد و نتیجه رو به اون فانکشن پاس میده.thenReturn اگر توی کلاس اصلی بهش نگاه متوجه می‌شید که دقیقا متد بالا رو صدا زده و نتیجه رو توی ورودیش برگردونده.به ۲ حالت میشه ازش استفاده کرد.app(\Illuminate\Pipeline\Pipeline::class)
-&gt;send(&amp;quotsalam&amp;quot)
-&gt;through([
Class۱::class,
Class۲::class,
.
.
.
])-&gt;thenReturn();یا$pipe=null \Illuminate\Pipeline\Pipeline();
$pipe-&gt;send(&amp;quotsalam&amp;quot)
-&gt;through([
Class۱::class,
Class۲::class,
.
.
.
])-&gt;thenReturn();توی  نگاه اول می‌گید خب اولی بهتره و قطعا دلیل اصلیتون اینه که به پایپ  لاراول نمیشه دیتایی ارسال کرد، باید بگم که اشتباه می‌کنید برای ارسال  پارامتر اضافه می‌شه توی متد سازنده کلاس ها ورودی رو بگیرید و بدید به  پایپ به این صورت$pipe=null \Illuminate\Pipeline\Pipeline();
$pipe-&gt;send(&amp;quotsalam&amp;quot)
-&gt;through([
new Class۱($param),
new Class۲($param,$arg)
])-&gt;thenReturn();این پایپ خیلی دستمون رو باز گذاشته حتی می‌تونید بهش فانکشن هم پاس بدید و نیاز به کلاس نداشته باشید.$pipe=null \Illuminate\Pipeline\Pipeline();
$pipe-&gt;send(&amp;quotsalam&amp;quot)
-&gt;through([
function($content,\Closure $next){
return $neext($content);
},
function($content,\Closure $next){
return $neext($content);
}
])-&gt;thenReturn();داشت یادم می‌رفت اگر خواستید کلاسی به این پایپ ارسال کنید حتما متد handle رو ایجاد کنید یا با متد via متد خودتون رو معرفی کنید.این متد ۲تا ورودی داره یکی رو از شما میگیره که همون مقداری هست که به send دادید و ورودی دوم هم یک فانکشن هست که وظیفه انتقال اطلاعات رو برعده داره. https://rp76.ir/blog/post/%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%AF%D8%B1-%D9%84%D9%88%D9%84%D9%87-%DA%A9%D8%B4%DB%8C-decorator چون می‌نویسم هستم.</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Wed, 31 Aug 2022 08:29:10 +0430</pubDate>
            </item>
                    <item>
                <title>دیوار و مهندسی معکوس!</title>
                <link>https://virgool.io/Rocket/%D8%AF%DB%8C%D9%88%D8%A7%D8%B1-%D9%88-%D9%85%D9%87%D9%86%D8%AF%D8%B3%DB%8C-%D9%85%D8%B9%DA%A9%D9%88%D8%B3-gvjyfbltfdky</link>
                <description>دیوار و مهندسی معکوس!داره ۲سال میشه که داریم روی این  پروژه کار می کنم. اول از یه کنجکاوی خیلی ساده شروع شد + سی شارپ، داشتم توی اینترنت پرسه  میزدم که گفتم بیهوده نباشه بیام و با برنامه هایی که می شناسم این سایت  دیوار رو بررسی کنم #Burp_suite.خب طبق معمول  از صفحه لاگین شروع کردم و فقط برای اطلاع از نحوه کارکرد سایت بود، رفتم  جلوتر و ارسال آگهی رو بررسی کردم و بعد از اون هم لیست آگهی کاربر و  درنهایت هم آگهی هایی که کاربران دیگه ارسال کردند.دقیقا زمانی بود که سایت Virgool | ویرگول رو پیدا کرده بودم و فعالیت خوبی داشتم، تصمیم گرفتم روی #ویرگول هم منتشر  کنم چیزی رو که پیدا کردم که تصمیم اشتباهی هم نبوده تا به الان.دیوار و مهندسی معکوس! از روی همین مقاله کوچیک تونستم کلی پروژه کوچیک بگیرم که توی زمان هایی که  واقعا بیپول بودم بهم کمک کردند، مهم تر از اون ها آدمهایی بودند که از  این طریق پیدا کرده بودم و الان به من با یه دید دیگهای نگاه میکردند. از روی همین مقاله تونستم یه پروژه بزرگ هم بگیرم که الان ۲هزار کاربر داره  و هر روز دارن باهاش کار میکنند و ما هم داریم تلاش میکنیم که روز به روز  مدیریت حساب هاشون براشون ساده تر بشه، الان خیلی از امکانات دیوار روی  سیستم خودمون داریم و روز به روز داره راحت تر میشه مدیریت آگهی های  کاربرا.سیستم رو من با #php و فریمورک #laravel طراحی کردم، قرار بود قسمت های پر  تعاملش رو با #rust بزنیم که نشد متاسفانه و فرانت کار رو هم Negin D. با #vuejs زده که واقعا داره خوب میشه البته اگر دخالت های بیجای مدیریت روی فرانتکار نباشه بهتر هم میشه. شاید براتون سوال پیش آمده باشه این سیستمی که داری میگی خیلی خوبه چیکار میکنه اصلا؟ اگر بخوام براتون تیتر وار بگم کار های سایت شاملاضافه کردن شماره کاربرارسال آگهیارتقا آگهیدستیار چت ( هنوز هوشمند نشده)نردبان هوشمند + فروشگاهیاسال  هوشمند آگهی کار های دیگه ای هم میکنه ولی خب مهم هاش همین ها بوده. توی این این ۲سال خیلی چیزهای برای من فرق کرد از سیستم عامل گرفته تا زبان  برنامه نویسی خب اول از #ویندوز استفاده میکردم و #سیشارپ ولی الان #لینوکس و #php.حتی #ide هم عوض کردم، البته مجبور بودم ?.اولین پروژه #لاراولی بود که داشتم میزدم، خوب کار میکرد ولی تمیز نبود به  تازگی ریفکتور رو شروع کردیم و تقریبا داره تموم میشه این بین من با کلی  مفاهیم جدید آشنا شدم از سیستم عامل گرفته تا فریمورکی که توش کار میکنم،  حتی #websocket هم یادگرفتم.سوکت نویسی کرده بودم از قبل ولی #websocket  یکم فرق داشت و سختی های خودش هم داشت.با دیزاین پترن های #strategy #observer #singleton #factory #decorator و  #method_factory آشنا شدم.توی لاراول با #request و #response آشنا شدم، حس میکنم چون پروژه API Base  بود این اتفاق افتاد که خیلی تجربه خوبی بود.خلاصه خیلی خوب بود برای من. https://rp76.ir/blog/post/%D8%AF%DB%8C%D9%88%D8%A7%D8%B1-%D9%88-%D9%85%D9%87%D9%86%D8%AF%D8%B3%DB%8C-%D9%85%D8%B9%DA%A9%D9%88%D8%B3  چون می نویسم پس هستم.</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Thu, 18 Aug 2022 18:50:57 +0430</pubDate>
            </item>
                    <item>
                <title>احراز هویت API در لاراول (ساده)</title>
                <link>https://virgool.io/@Rp76/%D8%A7%D8%AD%D8%B1%D8%A7%D8%B2-%D9%87%D9%88%DB%8C%D8%AA-api-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%B3%D8%A7%D8%AF%D9%87-ztk7au9ht7xc</link>
                <description>احراز هویت API در لاراول (ساده)برای همه ما پیش آمده که توی پروژه های تحت وبی که داریم نیاز شده یکسری api هم ارئه بدیم. توی این مقاله می‌خوام ساده ترین راه authenticate کاربران توی لاراول رو بهتون نشون بدم، با من همراه باشید.شروعقبل از هر کاری باید یه پروژه لاراول داشته باشیم یا یکی جدید شروع کنیم! من با دستور زیر یه پروژه جدید می‌سازم.composer create-project laravel/laravel apiتنها پیشنیازی که وجود داره Auth لاراول هست که با دستور زیر اون رو هم نصب می‌کنم!!composer require laravel/uiتنظیمات پروژهبعد از نصب لاراول و احراز هویت اون وقت تنظیم کردن دیتابیس، مایگریشن ها و بقیه چیز هاست... توی فایل .env تنظیمات مربوط به دیتا بیس رو تنظیم می‌کنیم.DB_DATABASE=laravel #اسم دیتابیس
DB_USERNAME=root # نام کاربری
DB_PASSWORD= # پسوردبعد از اون باید یک تغییر کوچولو توی مایگریش مربوط به user باید داشته باشیم$table-&gt;string(&amp;quotapi_token&amp;quot)-&gt;nullable()-&gt;unique();و این فیلد جدید رو توی مدل user باید fillable کنیم که بتونیم بعدا بهش چیزی اضافه کنیم!protected $fillable = [
    &#039;name&#039;,
    &#039;email&#039;,
    &#039;password&#039;,
    &amp;quotapi_token&amp;quot,
];حالا توی فایل config/auth.php باید یک guard جدید تعریف کنیم!&#039;guards&#039; =&gt; [
    .
    .
    .,
    &amp;quotapi&amp;quot=&gt;[
    &amp;quotdriver&amp;quot=&gt;&amp;quottoken&amp;quot,
    &amp;quotprovider&amp;quot=&gt;&amp;quotusers&amp;quot,
    ]
],اگر می‌خواید از فیلد خاصی برای احرازهویت استفاده کنید باید در آرایه بالا storage_key رو برابر با فیلد موردنظر خودتون قرار بدید.ساخت route جدیدبرای استفاده از توکن توی route هایی که نیاز دارید باید از middleware auth:api استفاده کنید.Route::get(&amp;quotuser/all&amp;quot,function (){
    return \App\User::all();
})-&gt;middleware(&amp;quotauth:api&amp;quot);ساخت توکنبرای ایجاد توکن به یک route و controller نیاز داریم توی ترمینال دستور زیر رو وارد می‌کنیم php artisan make:controller Api/AuthenticateControllerبرای ساخت route هم توی فایل routes/api.php به صورت زیر اقدام با ساخت route های احراز هویت می‌کنیم!Route::post(&amp;quotlogin&amp;quot,[\App\Http\Controllers\Api\AuthenticateController::class,&amp;quotlogin&amp;quot]);
Route::post(&amp;quotregister&amp;quot,[\App\Http\Controllers\Api\AuthenticateController::class,&amp;quotregister&amp;quot]);حالا باید کد های کنترلر رو بنویسیمpublic function login(Request $request): \Illuminate\Http\JsonResponse
{
    $valid = $request-&gt;validate([
        &amp;quotemail&amp;quot =&gt; [&amp;quotrequired&amp;quot, &amp;quotemail&amp;quot],
        &amp;quotpassword&amp;quot =&gt; [&amp;quotrequired&amp;quot]
    ]);

    if (!auth()-&gt;attempt($valid))
        return response()-&gt;json([
            &amp;quotmessage&amp;quot =&gt; &amp;quotInvalid credentials&amp;quot
        ], ۴۰۱);

    $user =auth()-&gt;user();
    $user-&gt;update([
        &amp;quotapi_token&amp;quot =&gt; \Illuminate\Support\Str::random(۶۰)
    ]);

    return response()-&gt;json([
        &amp;quotmessage&amp;quot =&gt; &amp;quotSuccessfully logged in&amp;quot,
        &amp;quotuser&amp;quot =&gt; $user
    ]);
}
public function register(Request $request): \Illuminate\Http\JsonResponse
{
    $valid= $request-&gt;validate([
        &amp;quotname&amp;quot =&gt; [&amp;quotrequired&amp;quot],
        &amp;quotemail&amp;quot =&gt; [&amp;quotrequired&amp;quot, &amp;quotemail&amp;quot,&amp;quotunique:users&amp;quot],
        &amp;quotpassword&amp;quot =&gt; [&amp;quotrequired&amp;quot]
    ]);

    $valid[&#039;api_token&#039;] = \Illuminate\Support\Str::random(۶۰);
    $valid[&#039;password&#039;] = bcrypt($valid[&#039;password&#039;]);

    $user = \App\Models\User::create($valid);

    return response()-&gt;json([
        &amp;quotmessage&amp;quot =&gt; &amp;quotSuccessfully registered&amp;quot,
        &amp;quotuser&amp;quot =&gt; $user
    ]);
}چون فیلدی که توی دیتابیس ذخیره کردیم محدودیت ۲۵۵ کارکتری داره مجاز هستم هرجوری که دوست داریم توکن رو بسازیم! خب دیگه تموم هست فقط میمونه ارسال توکن به پروژه و احرازهویت توکن و کاربر، برای این کار همیادتون نره که پسور رو hash کنیدارسال توکنخب بعد از این همه دردسر وقت اون می‌رسه که توکن رو ارسال کنیم، برای اینکار چندتا راه وجود دارهQuery Stringمی‌تونید token ساخته شده رو به صورت زیر به سایت خودتون ارسال کنید.$response = $client-&gt;request(&#039;GET&#039;, &#039;/api/user?api_token=&#039;.$token);Request Payload$response = $client-&gt;request(&#039;POST&#039;, &#039;/api/user&#039;, [
    &#039;headers&#039; =&gt; [
        &#039;Accept&#039; =&gt; &#039;application/json&#039;,
    ],
    &#039;form_params&#039; =&gt; [
        &#039;api_token&#039; =&gt; $token,
    ],
]);Bearer Token$response = $client-&gt;request(&#039;POST&#039;, &#039;/api/user&#039;, [
    &#039;headers&#039; =&gt; [
        &#039;Authorization&#039; =&gt; &#039;Bearer &#039;.$token,
        &#039;Accept&#039; =&gt; &#039;application/json&#039;,
    ],
]);امیدوارم مقاله آموزنده‌ای بوده باشه. https://rp76.ir/blog/post/%D8%A7%D8%AD%D8%B1%D8%A7%D8%B2-%D9%87%D9%88%DB%8C%D8%AA-api-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%B3%D8%A7%D8%AF%D9%87 </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Mon, 07 Mar 2022 07:58:12 +0330</pubDate>
            </item>
                    <item>
                <title>صف های لاراولی</title>
                <link>https://virgool.io/laravel-community/%D8%B5%D9%81-%D9%87%D8%A7%DB%8C-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84%DB%8C-ouve424h0lmw</link>
                <description>صف های لاراولیبیشتر  وقت‌ها توی پروژه‌هامون یک سری کار داریم که باید توی پس‌زمینه سایت اجرا  بشه یا از کاربران زمان زیادی رو می‌گیره برای همین لاراول صف هارو ارائه  داده که میتونیم ازش استفاده کنیم. توی این آموزش نحوه‌ی استفاده از job و ‌queue رو قراره با هم یاد بگیریم.قبل از هرکاری توی فایل .envQUEUE_CONNECTION=syncرو بهQUEUE_CONNECTION=databaseتغییر بدید، البته از کانکشن های دیگه ای هم میتوانید استفاده کنید ولی من توی این آموزش فقط database رو آموزش میدم. وقتی از database استفاده می‌کنید قطعا به یک جدول هم نیاز داریدphp artisan queue:table
php artisan migrateهمه صف هایی که ساخته  میشن به صورت پیشفرض توی مسیر app/Jobs ساخته میشن، نگران نباشید اگه هنوز  نتونستید پیداش کنید کافیه دستور ‍‍‍‍php artisan make:job ProcessPodcast رو اجرا کنید، یادتون نره اسمشو عوض کنید ها... قبل از هرکاری بذارید با ساختار job آشنا بشیم&lt;?php
namespace App\Jobs;
use App\Models\Podcast;
use App\Services\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The podcast instance.
*
* @var \App\Models\Podcast
*/
protected $podcast;
/**
* Create a new job instance.
*
* @param App\Models\Podcast $podcast
* @return void
*/
public function __construct(Podcast $podcast)
{
$this-&gt;podcast = $podcast;
}
/**
* Execute the job.
*
* @param App\Services\AudioProcessor $processor
* @return void
*/
public function handle(AudioProcessor $processor)
{
// Process uploaded podcast...
}
}خب همینطور که می‌بینید دوتا تابع داریم به اسم های __construct وhandle. زمانی که یک صف شروع به کار می‌کنه تابع handle صدا زده میشه از تابع __construct هم برای ارسال اطلاعات به job استفاده می‌کنیم. توی این مثال مدل رو به صورت مستقیم به jobارسال کردیم با بهره‌گیری از SerializesModels که توی Job استفاده شده.وقتی  که مدل رو به job ارسال می‌کنید فقط شناسه اون مدل ارسال میشه که باعث  میشه داده کمتری توی دیتابیس ذخیره‌ بشه و زمانی که صف اجرا میشه داده  تازه‌تری بارگذاری میشه.لاراول توی job ها هم ازmiddlewareبهره برده که میتونید باهاش از اجرای چند باره یک صف جلوگیری کنید، فقط کافیه متدmiddleware&#x60; رو توی job بسازید و اون یک آرایه برگردونید.use Illuminate\Queue\Middleware\WithoutOverlapping;
/**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [new WithoutOverlapping($this-&gt;user-&gt;id)];
}خب هر صفی بالاخره باید دوباره برگرده به لیست که اگر میخواید تأخیری این وسط اعمال کنید باید releaseAfter اضافه کنید./**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [(new WithoutOverlapping($this-&gt;order-&gt;id))-&gt;releaseAfter(۶۰)];
}اگر هم می‌خواید به سرعت برگرده توی صف می‌تونید dontRelease استفاده کنید./**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [(new WithoutOverlapping($this-&gt;order-&gt;id))-&gt;dontRelease()];
}اگر توی حالت های بالا خطایی رخ بده job دوباره به صف برنمی‌گرده به اصطلاح release نمیشه که باید از expireAfter استفاده کنید که بعد مدت زمان خاصی دوباره صف اجرا بشه./**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [(new WithoutOverlapping($this-&gt;order-&gt;id))-&gt;expireAfter(۱۸۰)];
}حالا که job رو ساختیم وقتشه ازش استفاده کنیم، برای این کار باید job رو dispatch کنیم.public function store(Request $request)
{
$podcast = Podcast::create(...);
// ...
ProcessPodcast::dispatch($podcast);
}ورودی dispatch به constructor ارسال میشه. اگر بخواید برای dispatch کردن job شرطی داشته باشید می توانید از کد های زیر استفاده کنید.ProcessPodcast::dispatchIf($accountActive, $podcast);
ProcessPodcast::dispatchUnless($accountSuspended, $podcast);اگر نیاز دارید که توی اجرای job هاتون تاخیری ایجاد کنید باید از زیر استفاده کنید که ۱۰ دقیقه دیرتر job شروع به کار می‌کنه.ProcessPodcast::dispatch($podcast)-&gt;delay(now()-&gt;addMinutes(۱۰));بعضی وقت ها نیاز دارید صفی که ساخته میشه به سرعت پردازش بشه که از dispatchSync استفاده می‌کنیم که در واقع هیچ صفی ساخته نمیشه و تابع handle توی job به صورت مستقیم صدا زده میشه.ProcessPodcast::dispatchSync($podcast);&#x60;امیدوارم آموزش مفیدی بوده باشه! https://rp76.ir/blog/post/%D8%B5%D9%81-%D9%87%D8%A7%DB%8C-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84%DB%8C </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Sat, 26 Feb 2022 08:46:29 +0330</pubDate>
            </item>
                    <item>
                <title>اعتبار سنجی سفارشی در لاراول</title>
                <link>https://virgool.io/@Rp76/%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1-%D8%B3%D9%86%D8%AC%DB%8C-%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-gg7wdbnrpb8t</link>
                <description>اعتبار سنجی سفارشی در لاراولسیستم اعتبار‌سنجی لاراول بدون شک یکی از بهترین ویژگی های این فریم‌ورک هست که هر میتونه ازش استفاده کنه.این سیستم با قوانین زیادی طراحی شده که توی راهنمای لاراول به صورت دقیق بهش اشاره شده.داشتم توی اینترنت برای خودم یه چرخی میزدم یه سوال Quera پیدا کردم که سوال به این شکل بودعلی در حال پیاده‌سازی سیستم ثبت‌نام برای یک مرکز آموزشی است و باید سیستمی را پیاده‌سازی کند تا متقاضیان ثبت‌نام عکسی را در سیستم آپلود کنند.شما باید قوانین احراز هویت زیر را روی عکس ها اعمال کنید:فایل عکس الزامی است.فایل باید حتما عکس و به فرمت‌های jpeg,jpg,png باشند.شما باید قانون ‍‍‍‍(rule) جدیدی را در برنامه تعریف کنید تا فقط امکان آپلود عکس با نام‌های به فرمت [عدد]File مثل File۱.png و ‍‍File۳۴۲.png و... را بدهد و اگر نام فایل به این فرمت نبود و زبان سایت انگلیسی بود، خطای file name is incorrect و اگر زبان سایت فارسی بود خطای نام فایل صحیح نیست را نمایش دهد.برای انجام دادن ۲تا قانون اول برای احراز هویت خب کار سختی پیش رومون نیست فقط کافیه که بگیم$request-&gt;validate([  
  &amp;quotfile&amp;quot=&gt;[&#039;required&#039;,&#039;image&#039;,&amp;quotmimes:jpeg,jpg,png&amp;quot]  
]);ولی برای قانون سوم نمیشه به همین راحتی عمل کرد... برای بررسی قانون سوم قبل از هر کاری باید به Rule جدید به پروژه خودمون اضافه کنیمphp artisan make:rule RuleNameدستور بالا برای ما یک فایل php توی مسیر app/Rules می‌سازه.&lt;?php  

namespace App\Rules;  

use Illuminate\Contracts\Validation\Rule;  

class FileName implements Rule  
{  
  /**  
 * Create a new rule instance. * * @return void  
  */  
  public function __construct()  
 {  //  
  }  

  /**  
 * Determine if the validation rule passes. * * @param string $attribute  
  * @param mixed $value  
  * @return bool  
  */  
  public function passes($attribute, $value)  
 {  //  
  }  

  /**  
 * Get the validation error message. * * @return string  
  */  
  public function message()  
 {  return &#039;The validation error message.&#039;;  
 }}برای بررسی شرط باید متد passes و برای بازگشت پیام خطا باید متد message رو بازنویسی کنید. متد passes دو ورودی داری که به ترتیب نشان دهنده نام فیلد و دیتای ورودی هست. چون ورودی ما فایل هست، کلاس فایل یکسری متد داره که به ما کمک می‌کنه راحت تر با فایل کار کنیمstore و move برای ذخیره عکسget برای گرفتن محتوای فایلgetClientOriginalExtension برای گرفتن پسوند فایل ارسالیgetClientOriginalName برای گرفتن اسم فایل ارسالیبرای این خواسته آخرین Rule رو برطرف کنیم باید یکم هم ریجکس استفاده کنیم و باید بررسی کنیم کهشروع اسم فایل با File باشهپایان اسم عدد باشه به هر تعدادیمتد passes به این صورت بازنویسی میشه/**  
 * Determine if the validation rule passes. * * @param string $attribute  
  * @param mixed $value  
  * @return bool  
  */  
public function passes($attribute, $value): bool  
{  
  /**  
 * @var $value UploadedFile  
  */  
  $fileName=str_replace(&#039;.&#039; . $value-&gt;getClientOriginalExtension(), &amp;quot&amp;quot, $value-&gt;getClientOriginalName());  

  return preg_match(&amp;quot/^File\d+$/&amp;quot, $fileName);  
}اول امدم به php این رو فهموندم که $value از نوع Uploadfile هست توی خط بعدش امدم پسوند فایل رو از اسم فایل کم کردم و توی خط بعدی به وسیله regex چک کردم اون روپارامتر های ریجکس هم به ترتیب زیر هستند^ برای بررسی کردن اول خطFile هم ثابت ما هست\d برای پیدا کردن عدد+هم روی پارامتر قبلی اعمال میشه که میگه از پارامتر قبلی حداقل باید یکی وجود داشته باشه$ برای بررسی کردن انتهای خطخب حالا Rule ما کامل شده و باید استفادش کنیم که طرز استفادش به صورت زیر هست$request-&gt;validate([  
  &amp;quotimg&amp;quot =&gt; [&#039;required&#039;, &amp;quotmimes:jpg,png,jpeg&amp;quot, new \App\Rules\FileName]  
]);امیدوارم که ساده توضیح داده باشم و متوجه این آموزش شده باشید. https://rp76.ir/blog/post/%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1-%D8%B3%D9%86%D8%AC%DB%8C-%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84 </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Wed, 16 Feb 2022 00:01:19 +0330</pubDate>
            </item>
                    <item>
                <title>۴ قانون اعتبارسنجی لاراول برای تصاویر و عکس ها</title>
                <link>https://virgool.io/laravel-community/%DB%B4-%D9%82%D8%A7%D9%86%D9%88%D9%86-%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1%D8%B3%D9%86%D8%AC%DB%8C-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AA%D8%B5%D8%A7%D9%88%DB%8C%D8%B1-%D9%88-%D8%B9%DA%A9%D8%B3-%D9%87%D8%A7-fizai8mbysh3</link>
                <description>۴ قانون اعتبارسنجی لاراول برای تصاویر و عکس هافریم‌ورک محبوب لاراول توی همه زمینه ها راهی رو جلو روی ما قرار داده که کار مارو ساده تر کرده امروز می‌خوایم چهار تا از اعتبارسنجی های لاراول رو برای فایل های تصویری بررسی کنیم!imageبدون شک ساده ترین اعتبارسنجی برای تصویر image هست.public function rules()
{
    return [
        &#039;uploaded_photo&#039; =&gt; &#039;image&#039;,
    ];
}فایل تحت تأیید باید یک تصویر (jpeg، png، bmp، gif، یا svg) باشد.mimesاگر پسوند هایی که بالا گفته شد برای شما زیاد هست می‌تونید به صورت خاصی اون هارو محدود کنیدpublic function rules()
{
    return [
        &#039;photo&#039; =&gt; &#039;mimes:jpeg,png&#039;,
    ];
}sizeزمانی که یک رشته رو با size مورد بررسی قرار میدید طول رشته رو بررسی میکنه ولی اگر فایل اپلود شده باشه بر اساس حجم فایل رو مورد بررسی قرار میده.public function rules()
{
    return [
        &#039;photo&#039; =&gt; &#039;image|size:۱۰۲۴&#039;, // ۱ MB
    ];
}dimensionsاعتبار سنجی دقیق تری هم وجود دارد که می‌تونید حداقل/حداکثر عرض/ارتفاع تصویر را محدود کنید.public function rules()
{
    return [
        &#039;photo&#039; =&gt; &#039;dimensions:min_width=۱۰۰,min_height=۱۰۰,max_width=۱۰۰۰,max_height=۱۰۰۰&#039;, 
    ];
}نه تنها این، شما می توانید نسبتی مانند ۳/۲ را مشخص کنید که ۶۰۰×۴۰۰ و ۳۰۰×۲۰۰ و غیره را پوشش می دهد:public function rules()
{
    return [
        &#039;photo&#039; =&gt; &#039;dimensions:ratio=۳/۲&#039;, 
    ];
}در نهایت، حتی می‌توانید عرض+ارتفاع+نسبت را ترکیب کنید که یکم پیچیده‌تر میشهuse Illuminate\Validation\Rule;

Validator::make($data, [
    &#039;avatar&#039; =&gt; [
        &#039;required&#039;,
        Rule::dimensions()-&gt;maxWidth(۱۰۰۰)-&gt;ratio(۳/۲),
    ],
]);امیدوارم که آموزنده بوده باشه. https://rp76.ir/blog/post/%DB%B4-%D9%82%D8%A7%D9%86%D9%88%D9%86-%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1%D8%B3%D9%86%D8%AC%DB%8C-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AA%D8%B5%D8%A7%D9%88%DB%8C%D8%B1-%D9%88-%D8%B9%DA%A9%D8%B3 </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Wed, 12 Jan 2022 15:44:12 +0330</pubDate>
            </item>
                    <item>
                <title>۱۳ درسی که آرزو داشتم زودتر باهاش روبرو می‌شدم</title>
                <link>https://virgool.io/@Rp76/%DB%B1%DB%B3-%D8%AF%D8%B1%D8%B3%DB%8C-%DA%A9%D9%87-%D8%A2%D8%B1%D8%B2%D9%88-%D8%AF%D8%A7%D8%B4%D8%AA%D9%85-%D8%B2%D9%88%D8%AF%D8%AA%D8%B1-%D8%A8%D8%A7%D9%87%D8%A7%D8%B4-%D8%B1%D9%88%D8%A8%D8%B1%D9%88-%D9%85%DB%8C-%D8%B4%D8%AF%D9%85-xicjjgpoholb</link>
                <description>۱۳ درسی که آرزو داشتم زودتر باهاش روبرو می‌شدمرسی که آرزو داشتم زودتر باهاش روبرو می‌شدمیادگیری برنامه نویسی سخته. ۸ سال پیش که شروع کردم به یادگیری همش دلم می‌خواست که بیخیالش بشم ولی خب  تمام تلاش خودمو کردم و دوام آوردم و الان برنامه نویسی رو خیلی دوست  دارم.انتخاب زبانشاید  باورتون نشه، اما زبان های متعددی توی دنیای برنامه نویسی هست فقط کافیه  یکی رو برای شروع انتخاب کنید و بعد از اون یادگیری بقیه خیلی ساده میشه  براتون.مهم نیست که چه زبانی رو انتخاب می‌کنید، مهم اینه که تا دیر نشده شروع کنید.درک مفهموم برنامه نویسی۱۰۰٪  وقتی دارید یک زبان رو شروع می‌کنید دلتون می‌خواد که سریع تر به نتیجه  برسید ولی این باعث میشه که مفاهیم اصلی اون زبان رو یاد نگیرید و بعد ها  به مشکل بخورید!استفاده از کلاس های آنلاینکلاس های آنلاین باعث می‌شوند که زندگیتون رو ذخیره کنید و تایم بیشتری برای خودتون داشته باشید.برنامه ریزی برای آموزشتوی برنامه روزانه خودتون حداقل ۲۰ دقیقه تا ۱ ساعت برای یادگیری چیز های جدید وقت بذارید! زندگی در جریانه و علم با سرعتی باور نکردنی در حال توسعه هست، پس وقتشه که خودت رو با روزی ۲۰ دقیقه آماده پیشرفت کنی.تمرین، تمرین، تمرینخب  فقط خوندن یا دیدن فیلم های آموزشی کافی نیست باید چیز هایی که فراگرفتید  رو روی کاغذ بیارید و باهاشون برنامه درست کنید، هرچند بدرد نخور! این باعث میشه که دستورات همیشه در دسترستون باشند!تسلیم نشیداولش  خیلی سخته، درک نکردن مفاهیم و متوجه نشدن خطا های سیستم باعث میشه که شما  فکر کنید برای این کار ساخته نشدید و کنار بکشید ولی اگر تحمل کنید حتما  سوپرایز می‌شید که چقدر سریع با این مشکلات دستو پنجه نرم کردید.چرخ رو از اول اختراع نکنیدمن  با این گزینه اصلا موافق نیستم ولی خب همیشه هم نباید چرخ رو ساخت باید از  چرخ های قبلی استفاده کنید ولی درنظر داشته باشید که این باعث میشه خلاقیت  از بین بره!استفاده از command line رو یاد بگیریداین گزینه خیلی مهمه شاید اولش سخت باشه ولی ساده تر از اونیه که همه توی ذهن دارن! شاید اولش پیچیده بنظر برسه اما وقتی که بهش مسلط شدید فراموش کردنش سخت تر از یادگیریشه.مهارت اجتماعیشاید شما برنامه نویس خوبی باشید ولی بدون داشتن مهارت های اجتماعی در نهایت یک کارمند ساده بیشتر نمی‌شید و از شغلتون زده میشید! اگر بتونید خودتون رو پرزنت کنید خود به خود ۵% بالا تر از بقیه هستید!نمونه کاربدون  شک داشتن نمونه کار های قوی و حرفه ای همون چیزیه که یک کارفرما نیاز داره  ببینه تا بتونه درباره شما یک تصمیم درست بگیره و بهتون اعتماد کنه!بنویسیددرباره مسیری که طی کردید و می‌کنید بنویسید و با افراد دیگه که هم مسیر شما هستید تعامل برقرار کنیدکسب درآمد کنیدمنتظر این نباشید که حرفه ای بشید و بعد شروع به کار کردن کنیدهدف گذاریبرای  رسید به هدف اصلیتون هدف گذاری های کوچیک انجام بدید تا مسیر رو دلچسب تر  کنید برای خودتون، هدف های بزرگ دست نیافتنی تر هستند و این شمارو خسته  میکنه!هیچ کس حرفه ای به دنیا نمیاد.راهی زیادی برای رسیدن به موفقیت هست، فقط یک راه منحصر به فرد وجود نداره، خودت باید راهش رو پیدا کنی. خودت رو به چالش بکش ولی با کسی مقایسه نکن خودت رو.</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Sun, 09 Jan 2022 20:54:13 +0330</pubDate>
            </item>
                    <item>
                <title>چرا لاراول بهترین فریم ورک Php هست</title>
                <link>https://virgool.io/@Rp76/%DA%86%D8%B1%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%A8%D9%87%D8%AA%D8%B1%DB%8C%D9%86-%D9%81%D8%B1%DB%8C%D9%85-%D9%88%D8%B1%DA%A9-php-%D9%87%D8%B3%D8%AA-lko1gzbdmsp6</link>
                <description>چرا لاراول بهترین فریم ورک Php هستچرا لاراول بهترین فریم ورک Php هستفریم  ورک هایی متعددی برای PHP طراحی و استفاده شده مثل Laravel, Codeigniter,  CakePhp, Yii, Zend و Symfony. تمام این فریم ورک‌ها قابلیت توسعه پذیری بالایی دارند و امکانات زیادی  برای توسعه وبسایت و وب اپلیکیشن به ما ارائه میدن، اما بعد از کار با همه  این ها من فهمیدم که لاراول یک سر و گردن بالا تر از این هاست.توی  این مقاله می‌خوام چندتا از ویژگی‌های باحال لاراول رو باهاتون به اشتراک  بذارم که راحت تر بتونید فریم‌ورک مد نظر خودتون رو انتخاب کنید.Cli یا Command Line Interfaceیکی  از جذاب ترین قابلیت‌های لارول که اون رو متمایز میکنه بدون شک Cli اون  هست که علاوه بر راهنمای خوبی که داره با رنگ بندی ها متنوع شمارو از  اتفاقات پیشرو باخبر میکنه!چرا لاراول بهترین فریم ورک Php هستBlade Template engineلاراول با بهره گیری از متور ‌Blade به شما کمک می‌کنه که راحت  تر کد های PHP و HTML خودتون رو با هم ادغام کنید که معادل های زیادی که  کار کردن با PHP رو توی HTML برای شما ساده تر میکنه، مثل کد پایین@if (count($records) === ۱)
    I have one record!
@elseif (count($records) &gt; ۱)
    I have multiple records!
@else
    I don&#039;t have any records!
@endifEloquent ORM supportsمثل تموم فریم ورک های دیگه لارول هم از ORMپشتیبانی می‌کنه اما Helper های بیشتری داره و تعامل با دیتابیس رو راحت تر می‌کنه.&lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * Get all of the tags for the post.
     */
    public function tags()
    {
        return $this-&gt;morphToMany(Tag::class, &#039;taggable&#039;);
    }
}CSRF TOKENخب بذارید اول بهتون توضیح بدم که جعل درخواست میان وبگاهی یا cross-site request forgeries چی هست اصلا. این نوع حمله به XSRF معروف هست که مهاجم با استفاده از اون میتونه افراد  رو وادار به کاری کنه تمایل به انجام اون رو ندارند مثلا حذف یک یا چند پست  و یا حتی ارسال یک مقاله. چطوری میشه جلوی این حملات رو گرفت؟ در لاراول با تعریف یک توکن بخصوص برای هر درخواست و بررسی اون از این نوع  حملات جلوگیری میشه که کار توسعه رو برای افراد ساده تر می‌کنه.&lt;form method=&amp;quotPOST&amp;quot action=&amp;quot/profile&amp;quot&gt;  
    @csrf  

    &lt;!-- Equivalent to... --&gt;  
    &lt;input type=&amp;quothidden&amp;quot name=&amp;quot_token&amp;quot value=&amp;quot{{ csrf_token() }}&amp;quot /&gt;  
&lt;/form&gt;امیدوارم از مقاله خوشتون آمده باشه. https://rp76.ir/blog/post/%DA%86%D8%B1%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%A8%D9%87%D8%AA%D8%B1%DB%8C%D9%86-%D9%81%D8%B1%DB%8C%D9%85-%D9%88%D8%B1%DA%A9-php-%D9%87%D8%B3%D8%AA </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Sun, 09 Jan 2022 20:49:20 +0330</pubDate>
            </item>
                    <item>
                <title>برنامه نویس ها، منطقی ترین ها بعد از وکلا!</title>
                <link>https://virgool.io/fboard/%D8%B1%D9%88%D8%B2-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-%D9%85%D8%A8%D8%A7%D8%B1%DA%A9-cjrelz7btxt0</link>
                <description>به دعوت از داتین میخواهم به مناسبت روز برنامه نویس ، در مورد افرادی که زندگیشون روی منطق و الگوریتم جلو میره براتون یکم سخنرانی کنم!برنامه نویس ها، منطقی ترین ها بعد از وکلا!اول میخواستم درباره این که چطوری برنامه نویسی رو شروع کردم و برنامه نویس شدم بنویسم، چون ساده تر بود! ولی به خودم گفتم تو اصلا کی هستی که برای بقیه جذاب باشه این داستان، دیدم کم بیراه نمیگه برای همین موضوع رو عوضش کردم و الان دارم با گوشیم رشته های از قبل ساخته شده توی ذهنم رو روی ورق میارم، ورقی از نوع &quot;دیجیتال&quot;.اکثر برنامه نویس ها کتاب های زیادی در مورد اینکه چطوری یه کد بزنند که بقیه افراد ازش سر در بیارن رو خوندن، توی این کتاب ها اکثرا روی ساده نویسی اجزا مانور میدن و خیلی خوبه که شما هم این قوانین رو رعایت کنید که اعضای تیم گیج نشن یا حداقل کمتر دچار سردرگمی بشند.توی اولین مرحله این به شما کمک میکنه که توی یه گروه پذیرفته بشید.جادی میگه :&quot; هکر کسی هست که ابزار هاشو میشناسه&quot; ، بنظرمن برنامه نویس هم همینه.یک برنامه نویس باید همه زیر و بم محیطی که داره توش کار میکنه و محیطی که قرار هست برنامه اش توی اون کار کنه رو خوب بشناسه.محیطی که شما توی اون کار میکنی یکسری قابلیت هایی داره مثل جستجو بر اساس عبارت باقاعده یا multi .cursorکه به شما این اجازه رو میده سریع تر از هرکس دیگه‌ای روی فایل‌هاتون مانور بدید و این باعث میشه توی چشم بقیه افراد تیم حرفه ای تر بنظر بیاید.حالا که حرفه ای تر بنظر رسیدید وقتشه که شاه بیت حرفه ای شدن رو براتون رو کنم &quot;گیت&quot;.اشتباه نکنید گیت هاب یا گیت لب رو نمی‌گم، گیت یه برنامه هست که فایل های شما رو track می‌کنه، اگر تغییری هم ایجاد شد این تغییرات رو ذخیره می‌کنه و از این طریق کار توسعه تیمی رو راحت تر می‌کنه.حالا که حرفه‌ای تر شدیم باید یکم هم تنبل تربشیم که بقیه ازما حساب ببرند!چطور میشه اینکار رو کرد؟خیلی ساده هست باید بیاید از دانشی که دارید نهایت استفاده رو ببرید و تسک های روتین خودتون رو یکم جذاب تر کنید، مثلا اگر شما هر روز باید یک فایل خاص رو به یک ایمیل خاص ارسال کنید لازم نیست هر روز این کار انجام بدید و بعد از یک مدت از کارتون زده بشید و دیگه لذت نبرید از شغلتون، بیاید و یک برنامه کوچیک درست کنید و این وظیفه رو به اون بدید حالا اگر شما فراموش هم کنید برنامه کار خودش رو می‌کنه و توی دید مدیر خودتون آدم وظیفه شناس تری می‌شید و احتمال ترفیع گرفتنتون هم زیاد میشه.زبان هم خیلی مهمه چه زبان های برنامه نویسی چه زبان های کشور های خارجی.من خودم دنبال یادگیری زبان روسی هستم. حتما می‌گید آخه بدرد چکاری می‌خوره این زبا! باید بگم که هر زبانی رو برای کاری ساختند. کسی که می‌خواد موزیسین بشه باید زبان نت هارو بدونه حالا اگر دوست دارید هکر بشید باید بتونید از منابع مختلف که زبان از های انگلیسی و روسی تشکیل شدند استفاده کنید : البته بیشتر روسی چون روسیه یکی از کشورهایی هست که هک کردن و کسب درآمد از اون قانونی هست، پس تولید محتوا هم مشکلی نداره.ارتباط گرفتن با اعضای تیم یکی از مهم ترین چیز هایی هست که هر شخص میتونه داشته باشه، البته شما غصه هیچ چیزی رو نباید بخورید شما با یک تیم عادی سروکار ندارید. یک تیم فوق حرفه‌ای که تقریبا علایق نزدیک به یکدیگر دارید و ارتباط با این افراد به شدت ساده هست، پس نترسید و سلام کنید...در آخر هم باید بگم:&quot; Just Start it then, do it &quot;</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Mon, 13 Sep 2021 10:24:47 +0430</pubDate>
            </item>
                    <item>
                <title>Role and Permission</title>
                <link>https://virgool.io/@Rp76/role-and-permission-f3kzgky9ccdq</link>
                <description>Role and Permissionهیچ عنوان درخوری نتونستم پیدا کنم برای این پست؛ پس تصمیم گرفتم انگلیسی رو بغل کنم. ببخشید! ?.فکر  نکنم نیاز باشه زیاد درباره این پست حرف بزنم. فقط باید بگم یکی از  اصلی‌ترین قسمت‌های سایت‌ها همین قسمت هست؛ چون مدیران نمی‌خوان که همه  بتونند هرکاری که امکانش هست رو انجام بدند.شاید این روشی که من امروز بهتون می‌خوام نشون بدم بهینه‌ترین روش نباشه اما یه راهی هست برای برطرف کردن نیازمون.شروع کارنیاز نیست که بگم اولین کار درست کردن یک پروژه لاراولی هست چون خودتون خوب می‌دونید.قبل  از هر چیزی نیاز داریم که توی جدول User یک تعداد تغییر انجام بدیم و بعد  از اون یک جدول جدید درست کنیم به اسم Role که اصلی‌ترین قسمت این آموزش رو  این جدول قراره انجام بده.User Table :Php artisan make:migration &amp;quotadd role_id to users&amp;quotSchema::table(&#039;users&#039;, function (Blueprint $table) {
   $table-&gt;unsignedBigInteger(&amp;quotrole_id&amp;quot)-&gt;after(&amp;quotid&amp;quot);
});Role Table :php artisan make:model Role -mSchema::create(&#039;roles&#039;, function (Blueprint $table) {
    $table-&gt;id();
    $table-&gt;string(&amp;quotname&amp;quot);
    $table-&gt;longText(&amp;quotscope&amp;quot);
    $table-&gt;softDeletes();
    $table-&gt;timestamps();
});با کد بالا هم Model رو ساختیم هم Migration رو.دوست داشتید می‌تونید Seeder هم بسازید که کارتون برای اولش ساده‌تر بشه.پیاده‌سازیبعد از مراحل بالا، ساخت Middleware برای بررسی درخواست‌ها هست.php artisan make:middleware RoleManagerpublic function handle(Request $request, Closure $next, string $scope = &#039;&#039;){
    $scopes = json_decode(Auth::user()-&gt;role-&gt;scope);
    if (!in_array($scope, $scopes))
        abort(403);
    return $next($request);
}کد  بالا از شما یه مجوز می‌گیره و بعد از کاربر می‌خواد مجوزهایی که داره رو  بده بهش. چک می‌کنه ببینه مجوزی که ما دادیم رو کاربر داره یا نه!یادتون نره که Middleware رو داخل فایل app/Http/Kernel.php اضافه کنید.protected $routeMiddleware = [
    .
    .
    .
    &#039;role&#039; =&gt; RoleManager::class,
];طرز استفاده هم به این صورته:Route::get(&amp;quotroutename&amp;quot,[Controller:class,&amp;quotfunctionName&amp;quot])-&gt;name(&amp;quotroute.name&amp;quot)-&gt;middleware(&amp;quotrole:permission_name);کد بالا هم که پر واضح هست پس نیازی به توضیح نداره.این قسمت تقریباً اضافه‌کاری هست با این حال خیلی کمک می‌کنه توی پروژه.به Model یوزر یک تابع اضافه می‌کنیم که دقیقاً مثل Middleware بالا هست کارش.public function may($scope){
    $scopes = json_decode($this-&gt;role-&gt;scope);
    if (in_array($scope, $scopes))
        return true;
    return false;
}با این کد دیگه نیاز نیست هردفعه که خواستید کاربر رو بررسی کنید هی کد بالا رو بنویسید.یادتون نره بین جدول User , Role رابطه برقرار کنید.public function role(): BelongsTo{
    return $this-&gt;belongsTo(Role::class);
}پایاندیگه تموم شد فکر نکنم زیاد سخت بوده باشه با این روش می‌تونید Routeهای پروژه رو فیلتر کنید.اگر خواستید قسمتی از سایت رو برای کاربران نمایش ندید بر اساس این Permissionها می‌تونید توی Blade خودتون به این صورت عمل کنید:@if ( Auth::user()-&gt;may(&amp;quotpermission_name&amp;quot) )
    //some html or blade code
@endifیا اگر بخواید دیگه خیلی کارخودتون رو ساده کنید توی یکی از Providerهای پروژه خودتون کد زیر رو اضافه کنید.پشنهاد من فایل app/Providers/AppServiceProvider.php هست.Blade::if(&#039;may&#039;, function ($scope) {
    return Auth::user()-&gt;may($scope);
});حالا با کمک این کد دیگه نیاز نیست از اون @if بالا استفاده کنید و فقط کافیه بنویسید:@may (&amp;quotpermission_name&amp;quot)
    //some html or blade code
@endmayامیدوارم از این مقاله خوشتون آمده باشده و کارتون رو ساده کرده باشه. https://rp76.ir/article/Role-and-Permission </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Tue, 01 Jun 2021 09:36:20 +0430</pubDate>
            </item>
                    <item>
                <title>آمار بازدید پست‌های من در سال ۹۹</title>
                <link>https://virgool.io/@Rp76/%D8%A2%D9%85%D8%A7%D8%B1-%D8%A8%D8%A7%D8%B2%D8%AF%DB%8C%D8%AF-%D9%BE%D8%B3%D8%AA-%D9%87%D8%A7%DB%8C-%D9%85%D9%86-%D8%AF%D8%B1-%D8%B3%D8%A7%D9%84-%DB%B9%DB%B9-ch8mzdn8gggu</link>
                <description>در طول تاریخ از اعداد استفاده کردیم تا اغلب داد و ستد کنیم و آن‌چیزی که شمردنی است را بشماریم. برای هر عدد واحد درست کردیم تا عددهای زندگی قاطی نشوند و از اعداد، شفاف‌تر استفاده کنیم؛ مثلا وقتی می‌گوییم ده هزار تومان به پول اشاره داریم و وقتی می‌گوییم ده هزار بلیط به بلیط!روز به روز که در زندگی جلو‌تر رفتیم عددها فرقی نکردند ولی این واحدها بودند که زیاد شدند. واحد کریپتو، واحد اصله درخت، واحد فاصله و …«واحد» یک توافق عمومی است برای شمردن؛ تا همانطور که گفتم شمردن‌ها قاطی نشود. مشاهده افراد دارای ثروت (اجتماعی یا مالی) به من ثابت کرده اینکه چه چیزی را بشماریم از اینکه چطور بشماریم مهم‌تر است. هرکس با واحد خاصی مسائل زندگی را می‌شمارد. اینطور به نظرم آمده که مشخص کردن واحد یعنی مشخص کردن اینکه من در زندگی برای چه چیزهایی ارزش قائلم و می‌خواهم چه چیزهایی را در زندگی بشمارم. https://cdn.virgool.io/annual-report/1399/dcuklifzyxfc-bD5q5.mp4 اعدادی که بدون واحد ثبت کردمبه ویدیویی که ویرگول برایم ساخته که نگاه می‌کنم میبینم که در سال ۹۹، من در مجموع ۹,۱۷۰ کلمه در ویرگول نوشتم و منتشر کردم و مخاطبین، پست‌های من را ۸۱۶ مرتبه پسندیدند و  ۱۱۷ بار هم نظر خود را روی پست‌های من به اشتراک گذاشتند. در سال ۹۹، ۲۱۱ نفر در ویرگول من را دنبال کردند تا پست‌های بعدیم را بخوانند. این اعداد نشان میدهند من کاری کرده‌ام. هرکدام به واحدی وصل هستند. از خودم می‌پرسم من کدام واحد را شمارش کرده‌ام؟ کدامیک از واحدهای بالا از همه برای من مهم‌تر است؟ ادامه ویدیو را می‌بینم.آمار از اثر بیرونی می‌گویندطبق آمار پست‌های من ۵,۸۶۴ بار خوانده شدند و ۵۳۴,۴۱۵ ثانیه صرف مطالعه آنها شده است، که با توجه به جمعیتی که در ایران به اینترنت دسترسی دارند، ویرگول به من می‌گوید که توانستم  ۰/۰۰۷۳۲۶۷۷۵ ثانیه، سرانه مطالعه دیجیتال کشور را بالا ببرم.از طرف دیگر ویرگول به من می‌گوید که اگر قرار بود پست‌هایم را چاپ و به دست تک تک خوانندگان برسانم باید ۱۷,۰۶۲ کاغذ مصرف می‌کردم.آن عددهای کوچک ابتدای ویدیو حالا تبدیل شده‌اند به عددهای بزرگ به اینکه من جلوی مصرف این تعداد کاغذ را گرفتم یا به اینکه من  ۰/۰۰۷۳۲۶۷۷۵ ثانیه، سرانه مطالعه دیجیتال کشور را جابه جا کرده‌ام. واحد این عددها برای من ملموس‌تر است.واحد نوشتن چیست؟همه عددهای بالا و همینطور اثر بیرونی که روی خوانندگان و همینطور در مقیاس بزرگتر طبیعت و جامعه اطرافم گذاشتم اعدادی هستند که من دوستشان دارم و به آنها افتخار می‌کنم. اگر چنین ویدیویی دست شما نیز رسید به شما بابت تک تک اعداد تبریک می‌گویم.اثر هر نوشته تا حدودی معلوم است، اگر بنویسید جلوی قطع درخت را می‌گیرید، به سرانه مطالعه کشور اضافه می‌کنید و خوانندگانی جذب می‌کنید که شما را از طریق نوشته‌هایتان می‌شناسند و …به نظرم می‌رسد که نوشته‌های من و شما واحد ندارند ولی اثر بیرونی دارند.</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Tue, 23 Mar 2021 14:00:06 +0430</pubDate>
            </item>
                    <item>
                <title>ای کاش زندگی ctrl+z داشت</title>
                <link>https://virgool.io/@Rp76/%D8%A7%DB%8C-%DA%A9%D8%A7%D8%B4-%D8%B2%D9%86%D8%AF%DA%AF%DB%8C-ctrlz-%D8%AF%D8%A7%D8%B4%D8%AA-d6exvgxm9kbe</link>
                <description>چه‌طور با گیت پل‌های پشت سر خراب نمی‌شوند
ای کاش زندگی ctrl+z داشتچه‌طور با گیت پل‌های پشت سر خراب نمی‌شوندبارها شده که برای خرابکاری نکردن توی یک پروژه، رفته‌ایم و کل پروژه رو توی یک پوشه‌ی دیگه کپی کرده‌ایم، به عنوان پشتیبان!این کار یه‌کم زمان‌بر هست و حجم زیادی هم برای این کار نیازه. به‌علاوه بعد از گذشت مدتی کلاً فراموش می‌کنید که این فایل چیه، برای چه کاری هست و اصلاً چرا اینجا گذاشتیمش؟مشکل اصلی از جایی شروع میشه که برای نسخه‌های مختلف بخواید این کارو رو انجام بدید که واقعاً کار خیلی بیهوده‌ای هست.توی این مقاله می‌خوام درباره‌ی یک برنامه به اسم Git باهاتون حرف بزنم که کارش مدریت نسخه‌های مختلف از پروژه و فایل‌های شما هست. بله! این برنامه فقط برای برنامه‌نویس‌ها نیست، برای همه‌ی افراد قابل‌استفاده هست.گیت- Gitیک نوع سیستم مدیرت نسخه هست که می‌تونه تغییرات شما رو تشخیص بده و فقط قسمت‌های جدید رو ذخیره کنه، و نه فایل رو به‌صورت کامل. گیت با این قابلیت به شما اجازه میده به‌صورت گروهی روی فایل‌های یک پروژه کار کنید.قبل از هر چیزی باید این برنامه رو که لینوس تروالدز درستش کرده دانلود کنید.Initاولین دستور init هست که شروع می‌کنه به اضافه کردن فایل‌های شما به لیستی که بعدها می‌تونید به‌وسیله‌ی اون تغییرات فایل‌هاتون رو پیدا کنید. در واقع این دستور یک مخزن یا repository درست می‌کنه.git initStatusبعد از ساخت مخزن می‌تونید با این دستور وضعیت فایل‌های خودتون رو بررسی کنید.Git statusaddحالا وقت اون رسیده که به مخزن خالی‌ای که داریم یک فایل رو اضافه کنیم. این دستور به شما اجازه میده که به Git بگید یک فایل رو به مخزن اضافه کنه یا فایل‌های ویرایش‌شده رو توی مخزن ویرایش کنه، برای حذف کردن هم به همین صورت.Git add filename // اضافه کردن یک فایل
Git add –A // اضافه کردن همه‌ی فایل‌هاCommitبعد از اضافه کردن فایل‌ها باید تأیید کنید که فایل‌ها توی مخزن ذخیره بشن. این دستور برای ویرایش، حذف یا اضافه به یک صورت عمل می‌کنه.برای تأیید و اضافه کردن فایل‌ها به یک پیام هم نیاز داریم مثل کد زیرGit commitکد بالا باعث میشه برنامه‌ی پیش‌فرض ویرایش متن باز بشه و ازتون بخواد یک متنی رو وارد کنید و بعد از بسته شدنش، دستور بالا به ادامه‌ی کار خودش می‌پردازه، که به‌صورت تک‌خطی هم میشه این کار رو انجام داد.Git commit –m “text message”Logحالا که فایل‌ها رو commit کردیم شاید نیاز بشه ببینم کِی چیکار کردیم؛ پس می‌تونیم گزارش commitهای خودمون رو بگیرمGit log // با این دستور گزارش‌ها با تمام جزیات بارگذاری می‌شوند
Git log --oneline // با این دستور از جزئیات چشم‌پوشی می‌کنیم.گیت بعد از نصب در Command prompt یا cmd در دسترس هست و در هر مسیری می‌تونید از برنامه استفاده کنید.برای شروع کار تا همین‌جا می‌تونه برای همه‌ی ما معجزه کنه و یه کم از تاریکی‌ای که داخلش بودیم به سمت نور کشیده می‌شیم.امیدوارم که تونسته باشم به‌صورت ساده‌ای این موضوع رو برای شما باز کرده باشم.لطفاً من رو با نظرهای خودتون راهنمایی کنید که بتونم مقاله‌های سازنده‌تری تولید کنم. https://rp76.ir/article/ای-کاش-زندگی-ctrlz-داشت </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Mon, 08 Mar 2021 10:28:22 +0330</pubDate>
            </item>
                    <item>
                <title>5 ترفند HTML که هیچ‌کس در مورد آن‌ها صحبت نمی‌کند</title>
                <link>https://virgool.io/CodeLovers/5-%D8%AA%D8%B1%D9%81%D9%86%D8%AF-html-%DA%A9%D9%87-%D9%87%DB%8C%DA%86-%DA%A9%D8%B3-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-%D8%A2%D9%86-%D9%87%D8%A7-%D8%B5%D8%AD%D8%A8%D8%AA-%D9%86%D9%85%DB%8C-%DA%A9%D9%86%D8%AF-pirv9whubupj</link>
                <description>5 ترفند HTML که هیچ‌کس در مورد آن‌ها صحبت نمی‌کند5 ترفند HTML که هیچ‌کس در مورد آن‌ها صحبت نمی‌کندهمه طراحان سایت باید از html استفاده کنن فارغ از این که از چه زبان و  یا فریم‌ورکی استفاده می‌کنن.     زبان‌ها و فریم‌ورک‌های زیادی تولید و از دور خارج میشن ولی در آخر این  Html هست که می‌مونه و همه باید از اون پیروی کنن تا بتونن سایت‌های  خودشون رو راه بندازن.تعدادی از امکانات سایت‌ها توسط زبان‌های دیگه مثل جاوااسکریپ  پیاده‌سازی میشن که از نظر من پیاده‌سازی این امکانات با Html کار ساده‌تر و  سریع‌تری است اما کمتر کسی پیدا میشه که از این امکانات صحبت کنه و ترجیح  میدن از زبان‌های دیگه برای پیاده‌سازی این قابلیت‌ها استفاده کنن، در این  مقاله قراره ۵ تا از جذاب‌ترین قابلیت‌های Html رو بهتون نشون بدم که برق  از کلتون می‌پرونه!Lazy Loadبعضی اصطلاحات قابل ترجمه نیستند از نظر من و این یکی از همون اصطلاحات  هست، Lazy Load به این معنی هست که عکس‌های سایت شما به تدریج بارگذاری  بشوند تا بازده سایت شما بالاتر بره و کاربران از لود نشدن سایت شما شاکی  نشن.در صفحات اینترنت حجم اصلی صفحات رو عکس‌ها تشکیل میدن که با امکان  Html می‌تونید سرعت سایت خودتون رو به صورت چشم‌گیری افزایش بدید.&lt;img src=&amp;quotimage.png&amp;quot loading=&amp;quotlazy&amp;quot alt=&amp;quot…&amp;quot width=&amp;quot200&amp;quot height=&amp;quot200&amp;quot&gt;پشنهاد کلماتقطعاً موتورهای جستجو رو دیده‌اید که با فشار اولین حرف از کلمه مد نظر  خود، ترندهای مربوطه رو به شما نشون میده و جستجو کردن رو برای شما  ساده‌تر می‌کنه‫.‬پیاده سازی این قابلیت به درک مناسبی از جاوااسکریپ نیاز داره که هرکسی  از عهده اون برنمیاد اماHtml یک قابلیت باحال داره به اسم datalist که به  شما کمک می‌کنه این ویژگی جالب رو به صفحات خودتون اضافه کنید و جستجو رو  برای کاربران ساده‌تر کنید‫.‬‬&lt;label for=&amp;quotcountry&amp;quot&gt;Choose your country from the list:&lt;/label&gt;
    &lt;input list=&amp;quotcountries&amp;quot name=&amp;quotcountry&amp;quot id=&amp;quotcountry&amp;quot&gt;
    
    &lt;datalist id=&amp;quotcuntries&amp;quot&gt;
        &lt;option value=&amp;quotUK&amp;quot&gt;
        &lt;option value=&amp;quotGermany&amp;quot&gt;
        &lt;option value=&amp;quotUSA&amp;quot&gt;
        &lt;option value=&amp;quotJapan&amp;quot&gt;
        &lt;option value=&amp;quotIndia&amp;quot&gt;
    &lt;/datalist&gt;Picture Tagدر عصر اینترنت و گوشی‌های هوشمند داشتن صفحات ریسپانسیو یکی از  ملزومات سایت‌ها شده است که در سئوی سایت شما هم تأثیر به‌سزایی دارد، اما  عکس‌های سایت کار رو برای طراحان و برنامه‌نویسان این حوزه دشوار کرده‫.‬یک قابلیت باحال Html هست که به شما در حل کردن این مشکل کمک می‌کنه به  اسم Picture که نمونه کد رو می‌تونید پایین ببینید؛ که خیلی شبیه audio,  video هست&lt;picture&gt;
        &lt;source media=&amp;quot(min-width:768px)&amp;quot srcset=&amp;quotmed_flag.jpg&amp;quot&gt;
        &lt;source media=&amp;quot(min-width:495px)&amp;quot srcset=&amp;quotsmall_flower.jpg&amp;quot&gt;
        &lt;img src=&amp;quothigh_flag.jpg&amp;quot alt=&amp;quotFlags&amp;quot style=&amp;quotwidth:auto;&amp;quot&gt;
    &lt;/picture&gt;Base Urlمن خودم به‌شخصه از این قابلیت زیاد استفاده نمی‌کنم چون امکانش هست  توی یک صفحه بخواید از ده‌ها آدرس مختلف استفاده کنید ولی گفتن این قابلیت  خالی از لطف نیست.&lt;head&gt;
        &lt;base href=&amp;quothttps://www.twitter.com/&amp;quot target=&amp;quot_blank&amp;quot&gt;
    &lt;/head&gt;
    
    &lt;body&gt;
    &lt;img src=&amp;quotelonmusk&amp;quot alt=&amp;quotElon Musk&amp;quot&gt;
    &lt;a href=&amp;quotBillGates&amp;quot&gt;Bill Gate&lt;/a&gt;
    &lt;/body&gt;Document refresherیکی از قدیمی‌ترین کدهای Html هست که بیشتر به‌درد انجمن‌ها می‌خوره که  نخواید هر ثانیه صفحه رو رفرش کنید که پست‌های جدید رو دریافت کنید‫.‬از اسم تگ پیدا هست که چیکار قراره بکنه؛ پس زیاد توضیح نمیدم و فقط میگم صفحه رو بعد از گذشت چند ثانیه به‌روزرسانی می‌کنه‫.‬&lt;meta http-equiv=&amp;quotrefresh&amp;quot content=&amp;quot4; URL=&#039;https://google.com&#039; /&gt;سخن نهاییHtml و Css بسیار قدرتمند هستند و شما می‌تونید با استفاده از این دو، سایت‌های خارق‌العاده‌ای رو طراحی کنید‫.‬یادگیری هر چیزی و مهارت در آن به زمان، وقت و تمرین نیاز داره و Html از قاعده مستثنی نیست. https://rp76.ir/article/5-%D8%AA%D8%B1%D9%81%D9%86%D8%AF-HTML-%DA%A9%D9%87-%D9%87%DB%8C%DA%86%E2%80%8C%DA%A9%D8%B3-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-%D8%A2%D9%86%E2%80%8C%D9%87%D8%A7-%D8%B5%D8%AD%D8%A8%D8%AA-%D9%86%D9%85%DB%8C%E2%80%8C%DA%A9%D9%86%D8%AF </description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Fri, 19 Feb 2021 08:55:07 +0330</pubDate>
            </item>
                    <item>
                <title>نحوه ارسال ایمیل در Laravel با استفاده از Gmail</title>
                <link>https://virgool.io/laravel-community/%D9%86%D8%AD%D9%88%D9%87-%D8%A7%D8%B1%D8%B3%D8%A7%D9%84-%D8%A7%DB%8C%D9%85%DB%8C%D9%84-%D8%AF%D8%B1-laravel-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-gmail-glvxma8cgwnp</link>
                <description>نحوه ارسال ایمیل در Laravel با استفاده از Gmailوه ارسال ایمیل در Laravel با استفاده از Gmailنحوه ارسال ایمیل در Laravel با استفاده از Gmailتاحالا شده بخواید ایمیل ارسال کنید ولی ندونید باید چیکار کنید؟یا شاید هم بتونید ایمیل ارسال کنید ولی هیچ سریس Smtp در اختیار ندارید و کارتون با شکست مواجه شده.توی این آموزش سعی دارمکه بهتون نشون بدم چطوری میشه برنامه های لاراولی که طراحی کردید رو با smtp جیمیل خودتون میزبانی کنید.ایمیل های ارسالی با سرور های smtp به عنوان spam علامت گذاری نمی شوند و ایمیل ها راحت تر به مقصد میرسند.مرحله 1: سرور Gmail SMTP را در برنامه لاراول پیکربندی کنیدلاراول از فایل config / mail.php برای ذخیره جزئیات استفاده شده در ارسال نامه استفاده می کند.این  پرونده حاوی تنظیماتی مانند MAIL_DRIVER ، MAIL_HOST ، MAIL_PORT و غیره  است. برای ارسال موفقیت آمیز ایمیل ، باید این اطلاعات را تنظیم کنیم.برای  اضافه کردن این اطلاعات نیازی به ویرایش این فایل نداریم،فقط این اطلاعات  رو در فایل .env که در مسیر اصلی پروژه هست اضافه میکنیم.MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=nullقسمت بالا را مانند نمونه زیر ویرایش میکنیمMAIL_DRIVER=smtp
MAIL_HOST=smtp.googlemail.com
MAIL_PORT=465
MAIL_USERNAME=ENTER_YOUR_EMAIL_ADDRESS(GMAIL)
MAIL_PASSWORD=ENTER_YOUR_GMAIL_PASSWORD
MAIL_ENCRYPTION=sslمرحله 2: حساب Google خود را پیکربندی کنیدوارد حساب Google Email خود شوید و روی دکمه حساب Google کلیک کنید. این دکمه هنگامی که بر روی عکس نمایه در داشبورد Gmail خود کلیک می کنید ، نشان داده می شود.پس  از ورود به صفحه حساب من.نحوه ارسال ایمیل در Laravel با استفاده از Gmailابتدا تایید ۲ مرحله‌ای حساب خود را فعال کنید.و بعد از اون از گزینه App passwords یک گذرواژه برای خودتون ایجاد کنید و از این گذرواژه توی فایل .env پروژتون استفاده کنید.نحوه ارسال ایمیل در Laravel با استفاده از Gmailمرحله 3: از برنامه لاراول خود ایمیل ارسال کنیددر این مرحله ، همه تنظیمات اساسی انجام شده است. اکنون می توانیم برخی کدهای PHP لاراول را برای ارسال ایمیل بنویسیم. برای  شروع ، هر کنترل کننده دلخواهی ایجاد کنید که در آن منطق ارسال نامه مورد  استفاده قرار گیرد ، سپس در این کنترل کننده کدهای خود را با استفاده از  قطعه کد زیر به عنوان راهنما بنویسید.$to_name = ‘RECEIVER_NAME’;
$to_email = ‘RECEIVER_EMAIL_ADDRESS’;
$data = array(‘name’=&gt;”Ogbonna Vitalis(sender_name)”, “body” =&gt; “A test mail”);
Mail::send(‘emails.mail’, $data, function($message) use ($to_name, $to_email) {
$message-&gt;to($to_email, $to_name)-&gt;subject(Laravel Test Mail’);
$message-&gt;from(‘SENDER_EMAIL_ADDRESS’,’Test Mail’);در کد بالا ما از template خود با نام emails.mail استفاده کردیم که این فایل در پوشه view\email\mail.blade.php هست.فایل نمونه ما باید حاوی کد هایی برای تست ایمیل باشد که در زیر یک نمونه از اون رو مشاهده میکنید.Hello {{ $name }},
{{body}}خب دیگه کار تمومه  و میتونید به سادگی ایمیل ارسال کنید و مطیعن باشیید که مقصد میرسهامیدوارم این آموزش رو دوست داشته باشید٬ نظر یادتون نره.</description>
                <category>رضا پارسیان | سازنده PromoSMS.ir</category>
                <author>رضا پارسیان | سازنده PromoSMS.ir</author>
                <pubDate>Tue, 01 Dec 2020 21:29:50 +0330</pubDate>
            </item>
            </channel>
</rss>