<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های مهراد صادقی</title>
        <link>https://virgool.io/feed/@mehradsadeghi</link>
        <description>برنامه‌نویس بَک‌اِند، عاشق موسیقی</description>
        <language>fa</language>
        <pubDate>2026-04-14 09:07:31</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1796/avatar/2xJb0I.jpg?height=120&amp;width=120</url>
            <title>مهراد صادقی</title>
            <link>https://virgool.io/@mehradsadeghi</link>
        </image>

                    <item>
                <title>چطور در آروان‌کلاد با ساختمان‌داده‌ و الگوریتم‌های بهینه مشکل حجم زیاد اطلاعات را حل کردیم</title>
                <link>https://tech.arvancloud.ir/metric-exporter-kcbica7jtnni</link>
                <description>لاگ‌ها در ۸ بهمن‌ماه ۱۴۰۳، آروان‌کلاد اختلالی را در محصول متریک‌اکسپورتر تجربه کرد که بر اکثر مشتریان تأثیر گذاشت. اشکال از این قرار بود که کاربران امکان دریافت متریک‌های دامنه‌ی خود را نداشتند و با  HTTP Timeout مواجه میشدند.در این پست توضیح میدهیم چه اتفاقی افتاد و برای جلوگیری از این واقعه چه اقداماتی انجام دادیم. همینطور امیدوارم اطلاعات ارایه‌ شده در این پست برای سایر مهندسین (حتی اگر از این سرویس استفاده نمیکنند) مفید واقع شود.پیش‌زمینهشبکه آروان‌کلاد یک سیستم توزیع شده در سطح جهانی است و خدمات مختلفی را ارایه میدهد. هر قسمت از هر بخش از این سیستم Event Log هایی تولید میکند که جزییات اتفاقاتی که در هر بخش از سیستم رخ داده را شامل میشود، برای نمونه لاگی که به ازای هر ریکوئست ایجاد میشود.سی‌دی‌ان آروان‌کلاد روزانه نزدیک به یک میلیون لاگ ایجاد، ارسال و پردازش و متریک‌های دامنه را تولید میکند، که به همین دلیل چالش‌های متنوعی نیز در این بین گریبانگیر توسعه‌دهندگان خواهد بود.معماریسیستم لاگ CDN (متریک‌ اکسپورتر) متشکل از یک پایپ‌لاین با ۴ استیج بوده که هر جز نقش ویژه‌ای دارند. استیج اول (A) لاگ‌های تولید‌شده توسط پروکسی CDN را دریافت میکند و روی کافکا (به عنوان مسیج بروکر) میریزد. استیج دوم (B) لاگ‌ها را از کافکا خوانده، بر اساس الگو‌هایی که به آن داده شده تغییراتی روی آنها بوجود می‌آورد تا سایر بخش‌ها بتوانند از لاگ‌ها بهره‌برداری کنند. استیج سوم که به آن LogForwarder هم میگوییم وظیفه‌ی اساسی ارسال لاگ را برعهده دارد و چهارمین استیج با نام Metric Exporter لاگ‌هایی که استیج سوم آماده‌سازی کرده (در کافکا) را برداشته، تجمیع و پروسس‌های مورد نظر را روی آن انجام داده و کاربر در نهایت با صدا زدن اندپویت HTTP متریک‌هایش را دریافت میکند.شایان ذکر است که کامپوننت Metric Exporter هیچ External Storage ی ندارد و اطلاعات را در مموری نگه میدارد تا بیشترین پرفورمنس برای آپدیت، حذف، اضافه و تحویل متریک‌ها به مشتریان وجود داشته باشد. همینطور تنها کانسیومر Stage B لاگ‌فرورادر نیست و کانسیومرهای دیگری بر حسب نیاز مسیج‌های این تاپیک را میخوانند. به همین ترتیب LogForwarder علاوه بر ارسال لاگ به مقاصد مختلف مانند SysLog Server، انواع S3 ها و ... ، یکی از مقاصدش کافکا و تاپیک مورد نظر Metric Exporter است.معماری متریک‌اکسپورتر آروان‌کلادچه اتفاقی افتاددر تاریخ ۷ بهمن نسخه جدیدی منتشر کردیم که امکان اسنپ‌شات گرفتن از آخرین وضعیت متریک‌ها را ایجاد کند. در تاریخ ۸ بهمن متوجه شدیم تعداد زیادی از درخواست‌های کاربران Timeout شده و سیستم دچار اختلال گردیده است. اختلال در واقع افزایش مموری (RAM) تا حدی بود که اپ توان پردازش را از دست میداد. طبیعتا اولین حدسمان این بود که مشکل از آخرین فیچری است که به برنامه اضافه کردیم، اما بعد از کالبدشکافی‌های مفصل در محیط استیجینگ متوجه شدیم قابلیت Persistency که اضافه شده بود در واقع کمک میکرد تا مشکل اصلی زودتر از موعد خودش را نشان دهد.پر شدن مموری و ری‌استار‌ت‌های خودکار اپ پر شدن مموری به صورت غیرقابل پیش‌بینی تا هر اندازه‌ای که به آن ظرفیت بدهیم ریشه‌یابیبه کمک محیط استیجینگ و شبیه‌سازی حالت رخ داده، مشکل اصلی را در استفاده نادرست از ساختمان‌داده‌ و الگوریتم‌های غیر بهینه برای نگه‌داری مقادیر مختلف، تشخیص دادیم. ساختار به این شکل بود که متریک‌ها تا بینهایت (تعداد بسیار بسیار زیاد) میتوانستند تولید شوند و این امر خارج از کنترل ما بود. همین موضوع باعث میشد رفتار سیستم پیش‌بینی‌پذیر نباشد و اختلالات مشابه رخ بدهد.چه کردیممهترین قدم تغییر ساختمان‌های داده و الگوریتم‌های مربوط به آنها به انواع بهینه‌تر است به طوری که رفتار برنامه‌ را پیش‌بینی‌پذیر کنیم. برای نمونه استفاده از الگوریتم SpaceSaving که یک روش کارآمد برای تخمین فرکانس پرتکرارترین اقلام در یک جریان داده (Stream) است. این الگوریتم از یک تعداد محدود شمارنده (Counters) استفاده می‌کند و مقدار تقریبی تکرار اقلام را نگه می‌دارد. نمونه‌ کدی که برای پیاده‌سازی الگوریتم SpaceSaving نوشتیم:type Entry struct {
   Value string // The value of the element
   Count int    // The count of the element
   index int    // The index of the element in the heap
}

// PriorityQueue implements heap.Interface and holds Entries
type PriorityQueue []*Entry

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
   // we want Pop to give us the lowest count, so less means more here.
   return pq[i].Count &lt; pq[j].Count
}

func (pq PriorityQueue) Swap(i, j int) {
   pq[i], pq[j] = pq[j], pq[i]
   pq[i].index = i
   pq[j].index = j
}

func (pq *PriorityQueue) Push(x interface{}) {
   n := len(*pq)
   entry := x.(*Entry)
   entry.index = n
   *pq = append(*pq, entry)
}

func (pq *PriorityQueue) Pop() interface{} {
   old := *pq
   n := len(old)
   entry := old[n-1]
   entry.index = -1 // for safety
   *pq = old[0 : n-1]
   return entry
}

// SpaceSaving tracks top-k elements
type SpaceSaving struct {
   k        int
   elements map[string]*Entry
   pq       PriorityQueue
}

func newSpaceSaving(k int) *SpaceSaving {
   return &amp;SpaceSaving{
      k: k,
      elements: make(map[string]*Entry),
      pq: make(PriorityQueue, 0, k),
   }
}

func (ss *SpaceSaving) Add(value string) {
   if entry, exists := ss.elements[value]; exists {
      entry.Count++
      heap.Fix(&amp;ss.pq, entry.index)
   } else {
      if ss.pq.Len() &lt; ss.k {
         entry := &amp;Entry{
            Value: value,
            Count: 1,
         }
         heap.Push(&amp;ss.pq, entry)
         ss.elements[value] = entry
      } else {
         min := heap.Pop(&amp;ss.pq).(*Entry)
         delete(ss.elements, min.Value)
         min.Value = value
         min.Count++
         heap.Push(&amp;ss.pq, min)
         ss.elements[value] = min
      }
   }
}

func (ss *SpaceSaving) TopK() []*Entry {
   entries := make([]*Entry, len(ss.pq))
   copy(entries, ss.pq)

   // sort the slice based on count
   sort.Slice(entries, func(i, j int) bool {
      return entries[i].Count &gt; entries[j].Count
   })

   return entries
}از سایر اقدامات میتوان به بهبود سیستم مانیتورینگ اشاره کرد. همینطور بهبود اساسی محیط استیجینگ و تست‌های با لود بالا در این محیط برای اطمینان از عملکرد صحیح برنامه.کاهش قابل‌توجه مصرف مموری و ثابت شدن نرخ تغییرات آنروبه‌جلودر صورتی که SpaceSaving به طور کامل جواب کار مارا ندهد روش‌های دیگری هم برای بهینه سازی داریم از جمله Fixed-size Time Buckets و Circular Buffer. همینطور افزایش متریک‌های داخلی اپ به منظور مانیتور بهتر آن و الرت‌های دقیق‌ برای همین موضوع باید در دستور کار قرار بگیرد.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Mon, 17 Mar 2025 18:50:15 +0330</pubDate>
            </item>
                    <item>
                <title>اصول CSP از Tony Hoare - الهام‌بخش طراحی Concurrency در زبان برنامه‌نویسی Go</title>
                <link>https://virgool.io/codenevis/tony-hoare-csp-votfcg3risji</link>
                <description>تصویر Tony Hoare اصول CSPاندیشمند برجسته علوم کامپیوتر Tony Hoare، در سال ۱۹۷۸ مفهوم Communicating Sequential Processes (CSP) را معرفی کرد؛ مدلی که تأثیر عمیقی بر طراحی سیستم‌های هم‌زمان (Concurrent Systems) داشت. این مدل سه اصل کلیدی دارد:اجرای ترتیبی پردازش‌هاهر پردازش به گونه‌ای طراحی میشود که به صورت ترتیبی (Sequential) و مستقل اجرا شود. این اصل سادگی در طراحی و پیش‌بینی‌پذیری رفتار هر فرآیند (پردازش) را تضمین میکند.استفاده از پردازش‌گرها (Processes) برای جابجایی داده‌ها، به‌جای حافظه مشترک (Shared Memory)به جای به‌اشتراک‌گذاری مستقیم حافظه که منجر به پیچیدگی در هم‌زمانی (Concurrency) میشود، پروسس‌ها از طریق کانال‌های ارتباطی (Channels) اطلاعات را ارسال و دریافت میکنند. این روش، ایمنی و قابل اطمینان بودن سیستم را افزایش میدهد.مقیاس‌پذیری با افزودن پروسس‌های مشابهبه جای طراحی پیچیده برای مدیریت مقیاس‌پذیری، سیستم میتواند با افزودن فرآیندهای (Processes) مشابه (مانند یک الگوی تکرارشونده) توسعه و مقیاس پیدا کند. این اصل، بهره‌وری و انعطاف سیستم را بهبود میبخشد.پیاده‌سازی اصول CSP در زبان برنامه‌نویسی Goزبان برنامه‌نویسی Go که توسط گوگل در سال ۲۰۰۹ توسعه یافت، در پیاده‌سازی مدل Concurrency اش مستقیماً از اصول CSP الهام گرفته است. سه ویژگی برجسته در Go نشان‌دهنده استفاده از این اصول هستند:گوروتین‌ها (Goroutines): گوروتین‌ها واحدهای سَبُکی برای اجرای ترتیبی (Sequential) کد هستند که اجرای مستقل هر پروسس را بر اساس اصل اول تضمین می‌کنند.کانال‌ها (Channels): Go به جای به‌اشتراک‌گذاری مستقیم حافظه، از کانال‌ها برای ارسال و دریافت داده میان گوروتین‌ها استفاده میکند که اصل دوم را به خوبی اجرا میکند.سادگی مقیاس‌پذیری: طراحی گوروتین‌ها و کانال‌ها به گونه‌ای است که میتوان با افزودن گوروتین‌های بیشتر و بدون پیچیدگی اضافی، سیستم را مقیاس‌پذیر کرد؛ چیزی که اصل سوم CSP را تحقق میبخشد.زبان Go با بهره‌گیری از این اصول، زبان ساده، سریع و کارآمدی برای توسعه سیستم‌های Concurrent ارائه میدهد. به همین دلیل این زبان به انتخاب اول بسیاری از مهندسان نرم‌افزار برای ساخت برنامه‌های توزیع‌شده و مقیاس‌پذیر تبدیل شده است.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 17 Jan 2025 09:58:19 +0330</pubDate>
            </item>
                    <item>
                <title>آیا نوشتن تست، فرآیند توسعه نرم‌افزارتان را واقعا کندتر می‌کند ؟</title>
                <link>https://tech.arvancloud.ir/faster-development-with-tests-tmzjcz7yx1to</link>
                <description>در حوزه نرم‌افزار تفکری قالب شده مبنی بر اینکه نوشتن تست (Automated Test) وقت‌گیر بوده و ننوشتن تست باعث سریعتر پیش رفتن کارها می‌شود. در این نوشته سعی دارم از تجارب شخصی‌ام در این رابطه نوشته و توضیح دهم چرا چنین تفکری در اکثر موارد اشتباه است.چرا فکر می‌کنیم نوشتن تست، سرعت توسعه را کند می‌کند ؟همیشه وقتی صحبت از تست‌نویسی می‌شود، شاید اولین تصویری که در ذهن مخاطب نقش می‌بندد نوشتن صدها خط کدِ تست در قالب ده‌ها Test Case است، آن‌هم برای یک اندپوینت ساده و ناچیز HTTP. حالا تصور کنید یک پروژه با بیش از صد اندپوینت دارید، پس حتما صدها تست‌کِیس و هزاران تست خواهید داشت که نوشتن آنها روزها و هفته‌ها زمان می‌برد.شما به مدیرتان می‌گویید برای بالا بردن کیفیت پروژه باید تست بنویسیم، او به چشمان شما زُل می‌زند و با چهره‌ای نسبتا عصبانی و لحنی تَحَکُم آمیز به شما می‌گوید:فقط کارو بزن بره، نمی‌خواد تست بنویسی، باید به دِدلاین‌ها برسیم.خب به نظر، حق با مدیر شماست. اما اگر برای نوشتن تست، مجبور نباشیم روزها و هفته وقت بگذاریم چطور ؟نوشتن فقط یک تست چقدر زمان می‌برد ؟تصور کنید یک اندپوینت HTTP را پیاده‌سازی کرده‌اید که متد آن POST بوده و Payload ی را در Body نیز باید قرار دهید، همینطور در Header آن نیز مقداری را برای این اندپوینت باید ارسال کنید. برای تست آن اگر قصد بر نوشتن Automated Test نداشته باشید، احتمالا از یک کلاینت HTTP مانند Postman استفاده می‌کنید.پست‌مَن را باز می‌کنید،‌ یک ریکوئست جدید در آن ایجاد می‌کنید، متد را روی POST قرار می‌دهید، آدرس (مسیر) اندپوینت را وارد می‌کنید، وارد تب Body شده و مقادیر آن را وارد می‌کنید، وارد تب Header شده و مقادیر آن را نیز وارد می‌کنید، و در نهایت کلید Send را زده تا ریسپانس را ببینید و فرضا از 200 بودن کد HTTP مطمئن شوید.شاید تمام این فرآیند حدودا یک دقیقه از شما زمان‌ ببرد.حالا می‌خواهیم دقیقا همین پروسه را در قالب یک Automated Test بنویسیم. یک فایل Test Case جدید در پروژه ایجاد میکنیم (احتمالا فایل Example را Copy Paste می‌کنیم)، فانکشن زیر را در آن می‌نویسیم:public function test_making_an_api_request()
{
    $this-&gt;post(&#039;/api/something&#039;, [&#039;name&#039; =&gt; &#039;mehrad&#039;], [&#039;Authorization&#039; =&gt; &#039;Bearer some_token&#039;])-&gt;assertStatus(200);
}و در نهایت در ترمینال کامند مربوط به اجرای تست‌ها را ران می‌کنیم.به نظر شما این‌کار چقدر زمان می‌برد ؟ بعید است بیشتر از یک دقیقه زمان ببرد.اگر بخواهیم موارد دیگری مانند اطلاعات درون دیتابیس را نیز چک کنیم، همچنان از نظر زمان تفاوت خاصی نخواهد داشت. فرض کنیم بعد از دیدن نتیجه درخواست در پست‌من، کلاینت دیتابیس خود را باز می‌کنید و از صحت اطلاعات اطمینان حاصل می‌کنید. در زمان نوشتن تست هم چنین کاری را با اضافه کردن این Assertion می‌توانید انجام دهید:$this-&gt;assertDatabaseHas(&#039;users&#039;, [
    &#039;name&#039; =&gt; &#039;mehrad&#039;
]);که از نظر زمانِ انجام، تفاوت خاصی باهم ندارند.نوشتن یک تست چه فایده‌ای دارد ؟به این سناریو توجه کنید:تصور کنید ۵۰ اندپوینت در پروژه خود دارید. اگر برای آنها تست ننویسید قاعدتا ۵۰ ریکوئست در پست‌من به ازای هرکدام از این اندپوینت‌ها باید داشته باشید. مدیر شما به سراغتان آمده و از شما می‌خواهد لاجیک (منطق) یکی از اندپوینت‌های موجود را تغییر دهید و شما همین کار را می‌کنید. به عنوان یک برنامه‌نویس مسئولیت‌پذیر حدس می‌زنید که شاید تغییری که در کد داده‌اید Side Effect هایی داشته باشد و به همین دلیل تمام ۵۰ اندپوینتی که در پست‌من دارید را یکبار تست می‌کنید تا مطمئن شوید همه‌چیز سر جای درستش است. نیم ساعت بعد یک باگ کریتیکال به شما ریپورت می‌شود و باید سریع تغییراتی جدید در کد ایجاد کنید. از آنجایی که برنامه‌نویس متعهدی هستید دوباره همه اندپوینت‌ها را تست می‌کنید. روز بعد تسک جدیدی به شما اختصاص داده می‌شود و باید یک اندپوینت جدید به پروژه اضافه کنید، بعد از انجام اینکار دوباره تمام اندپوینت‌ها را اجرا می‌کنید و عملا هر نوع توسعه‌ای که در پروژه می‌دهید، باید یکبار تک تک اندپوینت‌ها را برای اطمینان به صورت Manual (دستی) تست کنید. حالا تصور کنید از همان ابتدای پروسه توسعه، به ازای هر اندپوینتی که نوشته بودید، همان یک تستِ اصطلاحا Happy Path (تستهایی که فقط حالت و شرایط صحیح را تست می‌کنند) را می‌نوشتید. به ازای هر تغییری که دوباره در برنامه ایجاد می‌کردید، به ازای هر اندپوینت جدیدی که اضافه می‌کردید و ...، فقط کافی بود با یک کامند در ترمینال یکدور تست‌ها را ران کنید تا از صحت بقیه بخش‌های پروژه اطمینان حاصل کنید.همانطور که می‌بینید نوشتن تست سرعت کار ما را نتنها کاهش نمی‌دهد،‌ بلکه افزایش می‌دهد. وقتی از تست نویسی صحبت می‌کنیم، منظور این نیست که از همان ابتدا صدها تست‌کیس بنویسیم. باید شرایط پروژه، نوع پروژه و پارامترهای دیگری را در نظر گرفت.اگر دِدلاین های کوتاه مدت دارید، به تست‌های Happy Path اکتفا کنید. نوشتن آنها شما را در ادامه توسعه نجات خواهند داد. اگر ددلاین‌های آزادتری دارید تست‌های Corner Case (تست‌هایی که حالت‌های خاصِ برنامه را تست می‌کنند) را نیز بنویسید.  سناریوهای پیچیده‌ترسناریو‌ی اولتصور کنید چیزی که باید تست کنید، صرفا یک اندپوینت نیست، و باید یک فلویی از اندپوینت‌ها را مورد تست قرار دهید. مثلا در اندپوینت اول کاربر باید ثبت‌نام شود و یک کد تایید که برای مدت ۳۰ ثانیه معتبر است برایش ساخته شود، در اندپوینت بعدی باید کد تایید را وارد کند تا آدرس ایمیلش تایید شود، و در اندپوینت بعد باید اطلاعات تکمیلی‌اش را کامل کند تا از این پس بتواند از پنل و داشبورد سایت ما استفاده کند.تستِ چنین فلویی با پست‌من سخت و خسته‌کننده خواهد شد، زیرا هم در حین توسعه همین اندپوینت‌ها، و هم در ادامه کار پروژه که تغییری در بقیه بخش‌های پروژه ایجاد می‌کنید، باید بارها و بارها این فلو را به ترتیب و به صورت دستی در پست‌من اجرا کنید. در مقابل با داشتن Automated Test برای چنین فلویی، همیشه باخیال راحت‌تر و سرعت بیشتری می‌توانید بخش‌های جدید را توسعه دهید و یا در کدهای فعلی تغییر ایجاد کنید.سناریوی دومتصور کنید در پروژه‌‌ای مشغول به کار هستید که معماری پیچیده‌تری دارد. مثلا از سه دیتابیس همزمان استفاده می‌کند و اندپوینت‌هایی که در پروژه وجود دارند، بعضا روی دو یا هر سه دیتابیس تغییراتی ایجاد می‌کنند.تست کردن اندپوینت‌های چنین پروژه‌ای به صورت Manual به شدت طاقت‌فرسا و زمان‌بر خواهد بود. همینطور احتمال خطای انسانی در این شرایط بیشتر وجود دارد. در مقابل با داشتن Automated Test سرعت تست و توسعه پروژه به شدت افزایش می‌یابد و احتمال خطا نیز کاهش خواهد یافت.سناریوی سوماگر تجربه کار تیمی، به شکلی که چند نفر دقیقا روی یک سورس‌کد کار کنند را داشته باشید، احتمالا با این چالش مواجه شده‌اید که تغییرات شما کار همکارتان، یا تغییرات آن‌ها کار شما را خراب کرده باشد. با بیشتر شدن تیم‌های نرم‌افزاری چنین دغدغه‌هایی هر روز بیشتر خواهد شد و راه توسعه صحیح در این شرایط، داشتن Automated Test است، تا هر تغییری که در کد می‌دهیم، به واسطه تست‌ها مطمئن باشیم که کار سایر اعضای تیم دچار مشکل نمی‌شود و از صرفِ ساعت‌ها وقت برای دیباگِ پروژه جلوگیری کنیم.سناریوی چهارمتصور کنید به تازگی وارد پروژه‌ای شده‌اید که سورسی لِگِسی (Legacy) داشته و دارای میلیون‌ها خط کد بوده که طی چند سال برنامه‌نویس‌های مختلف روی آن کار کرده‌اند. در چنین شرایطی اگر Automated Test در پروژه وجود نداشته باشد، هر تغییری که به عنوان عضو جدید در پروژه می‌دهید، به احتمال خیلی خیلی زیاد Side Effect هایی را در سایر بخش‌های پروژه ایجاد می‌کند که ساعت‌ها و حتی روز‌ها برای دیباگ از شما زمان خواهد برد.سناریوی پنجمتصور کنید خودتان به صورت انفرادی پروژه‌ای را از صفر شروع کرده‌اید و نسبت به تمام اجزای پروژه تسلط دارید. بعد از مدتی توسعه (فرضا بعد از ۱۰ ماه) ناگزیر یکسری از ریز جزییات پروژه از حافظه شما خارج شده و در زمان توسعه یا تغییر در بخش‌های مختلف، می‌بینید که باگ‌هایی ایجاد می‌کنید (که شما را درگیر ساعت‌ها دیباگینگ می‌کند). در این شرایط هم داشتن Automated Test ها به شکل قابل توجهی به شما کمک می‌کنند تا سرعت و دقت کارتان افزایش بیابد.سناریوی ششمترکیب دو یا سه مورد از سناریوهای بالا.توصیه‌ای برای پروژه‌هایی که هیچ تستی ندارندوقتی پروژه‌ای مدت‌ها توسعه داده شده و هیچ تستی ندارد، انگیزه توسعه‌دهندگان آن برای پرداخت این بدهی فنی هر روز کمتر خواهد شد. شاید دلیل این موضوع حجم زیاد این بدهی فنی باشد.در این شرایط می‌توانید کار تست نویسی را فقط برای توسعه‌های جدید انجام دهید. همانطور که بالاتر نیز اشاره شد، تست‌های Happy Path برای فیچر‌های جدیدی که توسعه می‌دهید بنویسید. در همین حین با برنامه‌ریزی تست‌های Happy Path برای سایر بخش‌های پروژه نیز بنویسید تا به مرور زمان و بعد از چند ماه تمام پروژه تست‌های Happy Path داشته باشد. بعد از آن با همین روش می‌توانید تست‌های Corner Case را نیز اضافه کنید.جمع‌بندیدر این نوشته توضیح داده شد که چرا نوشتن تست بر عکس تصور قالب، باعث افزایش سرعت توسعه ما خواهد شد. شاید در بعضی شرایط (برای نمونه پروژه‌هایی که یک برنامه‌نویس به صورت مقطعی انجام داده و بعد از تحویل کار سرنوشت پروژه دقیقا مشخص نخواهد بود و مثال‌هایی از این دست) نوشتن Automated Test صرفه‌ی اقتصادی نداشته باشد. اما به طور کلی اگر به اصول و ابزارهای اینکار تسلط داشته باشید، سرعت توسعه شما افزایش یافته و آینده پروژه مطمئن‌تر خواهد بود.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Tue, 04 Jan 2022 21:19:35 +0330</pubDate>
            </item>
                    <item>
                <title>چند خطی درباره‌ی آنچه از تاریخ شی‌گرایی نمی‌دانید</title>
                <link>https://virgool.io/@mehradsadeghi/alan-kay-oop-f5nalpergoq3</link>
                <description>image source: https://www.colorado.edu/atlas/alan-kay-2019در دهه ۱۹۶۰ میلادی دکتر Alan Kay واژه‌ی مشهور Object Oriented Programming را وارد دنیای نرم‌افزار کرد. گرچه پیش از آن مفهوم Object وجود داشت، اما اَلِن کِی کسی بود که ایده برنامه‌نویسی شکل شی‌گرا را ارایه داد.در منابع مختلف آموزشی چهار اصل Encapsulation ، Inheritance ، Polymorphism  و Abstraction به عنوان اصول و پایه‌های شی‌گرایی معرفی می‌شوند، درحالیکه این موارد صرفا روش‌‌هایی برای پیاده‌سازی تعریفی‌ست که اَلِن کِی از OOP داشت.در مورد ایده اَلِن کِی ابهامات مختلفی وجود داشت و بر همین اساس زبان‌های برنامه‌نویسی به اشکال گوناگون ایده‌ی OOP را پیاده سازی کردند. در کنفرانسی در سال ۱۹۹۷ اَلِن کِی چنین می‌گوید:I made up the term ‘object-oriented’, and I can tell you I didn’t have C++ in mind.در سال ۲۰۰۳ ایمیل‌هایی بین Stefan Ram و اَلِن کِی رد و بدل شد. اَلِن کِی در قسمتی از این ایمیل‌ها می‌گوید:I’m sorry that I long ago coined the term “objects” for this topic because it gets many people to focus on the lesser idea. The big idea is messaging.یکی از سوالاتی که استفان از اَلِن پرسید چنین بود که:What does &quot;object-oriented [programming]&quot; mean to you?و در پاسخ اَلِن کِی چنین می‌گوید:OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I&#x27;m not aware of them.او با توجه به سابقه تحصیلی ریاضیات و زیست‌شناسی‌ای که داشت، هر آبجکت را به یک سلول زیستی (یک سرور) در یک شبکه تشبیه کرد که تنها راه ارتباط آنها ارسال پیام (messaging) است. همچنین ما نمی‌دانیم درون یک سرور چه می‌گذرد (local retention and protection and hiding of state-process)، و عناصر آن تا جای امکان، از وضعیت بعدی خودشان بی‌خبر هستند (extreme late-binding).ایده OOP از پروژه ARPANET (که پایه‌های اینترنت امروزی است) در ذهن اَلِن کِی شکل گرفته بود. در همین راستا زبان برنامه‌نویسی Smalltalk بوسیله او و تیمش ساخته شد که دقیقا ایده وی از شی‌گرایی را پیاده‌سازی می‌کرد.منابع:https://amirrezaghaderi.com/fa/blog/on-oophttp://www.purl.org/stefan_ram/pub/doc_kay_oop_enhttps://www.youtube.com/watch?v=oKg1hTOQXoYhttps://ovid.github.io/articles/alan-kay-and-oo-programming.htmlhttps://ovid.github.io/articles/alan-kay-and-missing-messages-a-follow-up.htmlhttp://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.htmlhttp://worrydream.com/EarlyHistoryOfSmalltalk</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 26 Mar 2021 20:28:31 +0430</pubDate>
            </item>
                    <item>
                <title>آمار بازدید پست‌های من در سال ۹۹</title>
                <link>https://virgool.io/@mehradsadeghi/%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-fjhigmjy0c6d</link>
                <description>در طول تاریخ از اعداد استفاده کردیم تا اغلب داد و ستد کنیم و آن‌چیزی که شمردنی است را بشماریم. برای هر عدد واحد درست کردیم تا عددهای زندگی قاطی نشوند و از اعداد، شفاف‌تر استفاده کنیم؛ مثلا وقتی می‌گوییم ده هزار تومان به پول اشاره داریم و وقتی می‌گوییم ده هزار بلیط به بلیط!روز به روز که در زندگی جلو‌تر رفتیم عددها فرقی نکردند ولی این واحدها بودند که زیاد شدند. واحد کریپتو، واحد اصله درخت، واحد فاصله و …«واحد» یک توافق عمومی است برای شمردن؛ تا همانطور که گفتم شمردن‌ها قاطی نشود. مشاهده افراد دارای ثروت (اجتماعی یا مالی) به من ثابت کرده اینکه چه چیزی را بشماریم از اینکه چطور بشماریم مهم‌تر است. هرکس با واحد خاصی مسائل زندگی را می‌شمارد. اینطور به نظرم آمده که مشخص کردن واحد یعنی مشخص کردن اینکه من در زندگی برای چه چیزهایی ارزش قائلم و می‌خواهم چه چیزهایی را در زندگی بشمارم. https://cdn.virgool.io/annual-report/1399/enw2yny3nrur-UFjDU.mp4 اعدادی که بدون واحد ثبت کردمبه ویدیویی که ویرگول برایم ساخته که نگاه می‌کنم میبینم که در سال ۹۹، من در مجموع ۱,۰۲۰ کلمه در ویرگول نوشتم و منتشر کردم و مخاطبین، پست‌های من را ۳۶ مرتبه پسندیدند و  ۱۳ بار هم نظر خود را روی پست‌های من به اشتراک گذاشتند. در سال ۹۹، ۲۸ نفر در ویرگول من را دنبال کردند تا پست‌های بعدیم را بخوانند. این اعداد نشان میدهند من کاری کرده‌ام. هرکدام به واحدی وصل هستند. از خودم می‌پرسم من کدام واحد را شمارش کرده‌ام؟ کدامیک از واحدهای بالا از همه برای من مهم‌تر است؟ ادامه ویدیو را می‌بینم.آمار از اثر بیرونی می‌گویندطبق آمار پست‌های من ۲,۵۸۸ بار خوانده شدند و ۲۹۴,۵۰۸ ثانیه صرف مطالعه آنها شده است، که با توجه به جمعیتی که در ایران به اینترنت دسترسی دارند، ویرگول به من می‌گوید که توانستم  ۰/۰۰۴۰۳۷۶۷۵ ثانیه، سرانه مطالعه دیجیتال کشور را بالا ببرم.از طرف دیگر ویرگول به من می‌گوید که اگر قرار بود پست‌هایم را چاپ و به دست تک تک خوانندگان برسانم باید ۸,۶۱۰ کاغذ مصرف می‌کردم.آن عددهای کوچک ابتدای ویدیو حالا تبدیل شده‌اند به عددهای بزرگ به اینکه من جلوی مصرف این تعداد کاغذ را گرفتم یا به اینکه من  ۰/۰۰۴۰۳۷۶۷۵ ثانیه، سرانه مطالعه دیجیتال کشور را جابه جا کرده‌ام. واحد این عددها برای من ملموس‌تر است.واحد نوشتن چیست؟همه عددهای بالا و همینطور اثر بیرونی که روی خوانندگان و همینطور در مقیاس بزرگتر طبیعت و جامعه اطرافم گذاشتم اعدادی هستند که من دوستشان دارم و به آنها افتخار می‌کنم. اگر چنین ویدیویی دست شما نیز رسید به شما بابت تک تک اعداد تبریک می‌گویم.اثر هر نوشته تا حدودی معلوم است، اگر بنویسید جلوی قطع درخت را می‌گیرید، به سرانه مطالعه کشور اضافه می‌کنید و خوانندگانی جذب می‌کنید که شما را از طریق نوشته‌هایتان می‌شناسند و …به نظرم می‌رسد که نوشته‌های من و شما واحد ندارند ولی اثر بیرونی دارند.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Mon, 22 Mar 2021 11:57:13 +0430</pubDate>
            </item>
                    <item>
                <title>چطور در لاراول به شکلی درست کوئری‌ خود را بر اساس URL Query String فیلتر کنیم</title>
                <link>https://tech.arvancloud.ir/laravel-filter-querystring-v61hgupba5y0</link>
                <description>نمونه ای از کد غیر اصولیاحتمالا با شرایطی مواجه شده‌اید که می‌خواستید بر اساس پارامترهایی که در query string آدرس وجود دارد، کوئری‌های خود را فیلتر کنید و بعد از انجام اینکار و توسعه بیشتر پروژه، با کدی شبیه به کد تصویر بالا مواجه شدید.این روش خروجی لازم را به شما می‌دهد ولی روش اصولی یا اصطلاحا یک good practice نیست.چرا روش بالا اصولی نیست ؟زمانی که تعداد پارامترهای ‌query string افزایش پیدا می‌کند، تعداد این if ها در کد زیاد شده که این به خودی خود بعد از ماه‌ها توسعه پروژه، شما را با یک کد بزرگ که به سختی قابل نگهداری است روبرو می‌کند.اشکال دیگری که در این کد وجود دارد این هست که اصل دوم از اصول SOLID را نقض می‌کند.بطور خلاصه طبق اصل دوم سالید باید برنامه را طوری طراحی کنیم که برای اضافه کردن امکانی جدید، مجبور به دستکاری کدهای قبلی نباشیم.در واقع اصل دوم سالید تلاش می‌کند ما را از دستکاری کدهایی که به درستی کار می‌کنند منع کند تا اشکالی در برنامه فعلی ایجاد نکنیم.در ادامه توضیح اِشکال مربوط به تصویر ابتدای متن، هر بار که نیاز به فیلتر نمودن پارامتر جدیدی در query string باشد، مجبور هستیم در کدهای قبلی دست برده و تغییراتی در آن ایجاد کنیم، که احتمال تولید باگ نیز به همین ترتیب بالا می‌رود.چه روشی بهتر است ؟برای حل اشکالات بالا، باید روشی طراحی کرد که به ما امکان جداسازی منطق هر بخش از فیلترهای query string را بدهد، به شکلی که اگر نیاز به فیلتر جدیدی داشتیم، در قالب یک متد جدید (جدای از کدهای قبلی) بتوان این فیلتر را اضافه کرد و در نهایت تاثیرش را خروجی کوئری دیتابیس ببینیم.به همین منظور پکیجی برای فریم‌ورک لاراول نوشته‌ام که علاوه بر ایجاد ساختار مورد نظر برای افزودن فیلترها، تعدادی فیلتر پر کاربرد نیز در آن تعبیه شده که در ادامه به توضیح آنها می‌پردازم. پکیج Laravel Filter Query String۱. ابتدا با دستور زیر پکیج را در پروژه خود نصب کنید:$ composer require mehradsadeghi/laravel-filter-querystring ۲. سپس ترِیتِ FilterQueryString را در مدل مورد نظر خود use کنید. همینطور پراپرتی‌ای به نام filters را به مدل خود اضافه کنید که حاوی آرایه‌ایست از فیلرتهای مورد نظر شما.برای نمونه در مدل User چنین کدی خواهیم داشت:use Mehradsadeghi\FilterQueryString\FilterQueryString;

class User extends Model
{
    use FilterQueryString;
    protected $filters = [];
    ...
}۳. برای اِعمال فیلترها در کوئری خود، باید متد filter را در eloquent query استفاده کنید. برای نمونه:User::select(&#039;name&#039;)-&gt;filter()-&gt;get();فیلترهای موجودSortComparisonsInLikeWhere clauseبه منظور توضیح هر فیلتر، تصور کنید جدول users ی با این اطلاعات داریم:و کوئری ما در هر مثال نیز به این ترتیب است:User::filter()-&gt;get();فیلتر Sortاین فیلتر در واقع معادل order by در sql است که به شکل منعطفی در پکیج FilterQueryString می‌توان از آن استفاده کرد.قاعده استفاده:?sort=field
?sort=field,sort_type
?sort[0]=field1&amp;sort[1]=field2
?sort[0]=field1&amp;sort[1]=field2,sort_type
?sort[0]=field1,sort_type&amp;sort[1]=field2,sort_typeدر فایل User.php:protected $filters = [&#039;sort&#039;];مثال:https://example.com?sort=created_atخروجی:توجه داشته باشید که وقتی نوع sort را تعیین نمی‌کنید، این مقدار به طور پیش‌فرض asc خواهد بود.مثالی دیگر:https://example.com?sort[0]=age,desc&amp;sort[1]=created_at,descخروجی:فیلترهای Comparisonsاین فیلترها که جنبه مقایسه‌ای دارند شامل ۶ مورد می‌باشند:greatergreater_or_equallessless_or_equalbetweennot_betweenقاعده استفاده:?greater=field,value
?greater_or_equal=field,value
?less=field,value
?less_or_equal=field,value
?between=field,value1,value2
?not_between=field,value1,value2در فایل User.php:protected $filters = [
    &#039;greater&#039;,
    &#039;greater_or_equal&#039;,
    &#039;less&#039;,
    &#039;less_or_equal&#039;,
    &#039;between&#039;,
    &#039;not_between&#039;
];مثالی از فیلتر greater:https://example.com?greater=age,20خروجی:مثالی از فیلتر not_between:https://example.com?not_between=age,21,30خروجی:فیلتر Inاین فیلتر معادل where in در sql است.قاعده استفاده:?in=field,value1,value2,...در فایل User.php:protected $filters = [&#039;in&#039;];مثال:https://example.com?in=name,mehrad,rezaخروجی:فیلتر Likeاین فیلتر معادل like &#039;%value%&#039;در sql است.قاعده استفاده:?like=field,value
?like[0]=field1,value1&amp;like[1]=field2,value2در فایل User.php:protected $filters = [&#039;like&#039;];مثال:https://example.com?like=name,mehخروجی:مثال:https://example.com?like[0]=name,meh&amp;like[1]=username,darخروجی:فیلتر پیش‌فرض Where Clauseبطور کلی زمانی که در query string یکی از فیلترهای معرفی شده در بالا موجود نباشد، پارامتر و مقدار آن در where کوئری قرار می‌گیرد. این فیلتر مناسب زمانی‌ست که می‌خواهید یکی از ستون‌های جدول خود را مستقیما فیلتر کنید.قاعده استفاده:?field=value
?field1=value&amp;field2=value
?field1[0]=value1&amp;field1[1]=value2
?field1[0]=value1&amp;field1[1]=value2&amp;field2[0]=value1&amp;field2[1]=value2تصور کنید می‌خواهیم ستون‌های name ، username و age را فیلتر کنیم.در فایل User.php:protected $filters = [&#039;name&#039;, &#039;username&#039;, &#039;age&#039;];مثال:https://example.com?name=mehradخروجی:مثال:https://example.com?age=22&amp;username=dariush123خروجی:مثال:https://example.com?name[0]=mehrad&amp;name[1]=dariushخروجی:مثال:https://example.com?name[0]=mehrad&amp;name[1]=dariush&amp;username[0]=mehrad123&amp;username[1]=reza1234خروجی:فیلترهای سفارشیاز طریق فیلترهای سفارشی شما این امکان را دارید تا فیلترهای خود را در قالب متدهایی در مدل خود تعریف کنید. این امکان به رعایت اصل دوم سالید کمک می‌کند، به این صورت که به ازای هر فیلتر جدید، متدی جدید می‌نویسیم و نیازی به ایجاد تغییر در کدهای قبلی نیست.برای نمونه فرض کنید فیلتری با نام all_except نیاز داریم که تمام کاربران به بجز کاربری که نام آن وارد می‌شود را بر‌می‌گرداند:در فایل User.php:protected $filters = [&#039;all_except&#039;];

public function all_except($query, $value) {
    $query-&gt;where(&#039;name&#039;, &#039;!=&#039;, $value);
}برای آزمایش فیلتر اضافه شده:https://example.com?all_except=mehradتوجه کنید که متدهایی که به عنوان فیلتر تعریف می‌کنید بالاترین اولویت را دارند و حتی این امکان وجود دارد که فیلترهای موجود را override کنید.برای نمونه می‌خواهیم فیلتر in را به گونه‌ای تغییر دهیم که فقط و فقط سه مقدار را بپذیرد:در فایل User.php:protected $filters = [&#039;in&#039;];

public function in($query, $value) {
    $exploded = explode(&#039;,&#039;, $value);
    if(count($exploded) != 4) {
        // throwing an exception or whatever you like to do
    } 
    $field = array_shift($exploded);
    $query-&gt;whereIn($field, $exploded);
}نمونه‌ای دیگر از کاربردهای خوب فیلترهای سفارشی زمانی‌ست که می‌خواهید نام ستون‌های جدول را مستقیما به کاربر (در query string) نمایش ندهید. برای نمونه فرض کنید می‌خواهیم بجای username از by استفاده کنیم:در فایل User.php:protected $filters = [&#039;by&#039;];

public function by($query, $value) {
    $query-&gt;where(&#039;username&#039;, $value);
}سپس:https://example.com?by=dariush123خروجی:به عنوان توصیه برای جلوگیری از شلوغ شدن مدل از متدهای فیلترینگ، می‌توانید trait ی ساخته و فیلترهای آن مدل را در آن قرار دهید.همینطور می‌توانید در گیت‌هاب پکیج Laravel Filter Query String را مشاهده کنید.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 31 Jul 2020 19:57:34 +0430</pubDate>
            </item>
                    <item>
                <title>درآمدی بر Serialize در PHP</title>
                <link>https://virgool.io/@mehradsadeghi/php-serialize-casrzxjvc6id</link>
                <description>تصویر از Blake Connally در Unsplashنزدیکترین معادل فارسی برای واژه Serialize مرتب‌سازی یا پشت سر هم قرار دادن است. در برنامه‌نویسی وقتی صحبت از Serialize می‌کنیم، در واقع منظور ایجاد شکلی قابل ذخیره از یک مقدار است. مقادیری مانند string ها، int ها و سایر دیتا تایپ های ساده به راحتی قابل ذخیره سازی روی مموری، فایل یا جابجایی در سطح شبکه هستند، اما زمانی که به ذخیره یا انتقال یک آبجکت نیاز داریم چطور می‌توانیم اینکار را انجام دهیم ؟ اینجاست که Serialize به ما کمک می‌کند مقادیر را بدون تغییر در نوع و ساختار، ذخیره یا جابجا کنیم.سریالایز به عمل قرار دادن یک از سری بیت ها در کنار هم، بر اساس قاعده‌ای مشخص  گفته می‌شود.  منظور از قاعده‌ای مشخص‌ در واقع فرمتی است که در سریالایز از آن استفاده می‌شود. JSON، YAML، XML و دیگر فرمت ها می‌توانند به عنوان فرمتی برای سریالایز مورد استفاده قرار گیرند.در PHP فانکشنی به نام &#x60;serialize&#x60; برای همین منظور وجود دارد :&lt;?php
$serialized = serialize([1, 2, 3, 4, 5]);
echo $serialized;خروجی کد بالا به این صورت خواهد بود :a:5:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;}نمونه‌ای از سریالایز یک آبجکت :&lt;?php

class SomeClass {
    
    private $somePrivateProperty;
    public $somePublicProperty;

    public function somePublicMethod() {
        // ...
    }

    private function somePrivateMethod() {
        // ...
    }
}

$serialized = serialize(new SomeClass);
echo $serialized;خروجی کد بالا به این صورت خواهد بود :O:9:&amp;quotSomeClass&amp;quot:2:{s:30:&amp;quotSomeClasssomePrivateProperty&amp;quotN;s:18:&amp;quotsomePublicProperty&amp;quotN;}همانطور که می‌بینید فرمت سریالایز در PHP به این صورت است. برای کسب اطلاعات بیشتر در مورد این فرمت، از این پاسخ در استک‌اُوِر‌فلو استفاده نمایید.نحوه Un-Serialize کردن مقدار Serialize شدههمانطور که برای سریالایز، فانکشن &#x60;serialize&#x60; را داریم، برای بازگرداندن آن فانکشنی به نام &#x60;unserialize&#x60; وجود دارد.در مثال پیشین :print_r(unserialize($serialized));خروجی کد بالا به این صورت خواهد بود :SomeClass Object
(
    [somePrivateProperty:SomeClass:private] =&gt; 
    [somePublicProperty] =&gt; 
)همانطور که واضح است کلاس ما دوباره بازگشته و قابل استفاده است.اگر از علاقه‌مندان به فریم‌ورک محبوب لاراول باشید، احتمالا با قابلیت Job/Queue در این فریم‌ورک کار کرده‌اید. در واقع اتفاقی که در Job های لاراول می‌افتد این است که تمام کلاس Job ی که نوشته‌اید سریالایز می‌شود و تحت عنوان یک Job در Queue قرار می‌گیرد. و در هنگام اجرای آن Job مقدار سریالایز شده از دیتابیس خوانده شده، Un-Serialize شده و سپس متد &#x60;handle&#x60; آن اجرا می‌شود.منابع :https://www.php.net/manual/en/function.serialize.phphttps://en.wikipedia.org/wiki/Serialization#Serialization_formatshttps://stackoverflow.com/questions/8641889/how-to-use-php-serialize-and-unserialize</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Mon, 20 Jan 2020 23:59:14 +0330</pubDate>
            </item>
                    <item>
                <title>چطور PHP کار Autoloading را انجام می‌دهد و نقش Composer در آن چیست ؟</title>
                <link>https://virgool.io/@mehradsadeghi/%DA%86%D8%B7%D9%88%D8%B1-php-%DA%A9%D8%A7%D8%B1-autoloading-%D8%B1%D8%A7-%D8%A7%D9%86%D8%AC%D8%A7%D9%85-%D9%85%DB%8C%D8%AF%D9%87%D8%AF-%D9%88-%D9%86%D9%82%D8%B4-composer-%D8%AF%D8%B1-%D8%A2%D9%86-%DA%86%DB%8C%D8%B3%D8%AA-gt5j52r4mahc</link>
                <description> تصویر از Elly Johnsonاگر با زبان PHP برنامه‌نویسی شی‌گرا انجام داده و از آبجکت‌ها استفاده کرده باشید، حتما با موضوع لود کردن فایل‌ها (کلاس‌ها) ی مختلف روبرو شده‌اید. به طور عادی کافیست همه کلاس‌های مورد نظرمان را در ابتدای اسکریپتمان لود کنیم. مشکل این راه این است که در طول برنامه احتمال دارد بنا بر شرایطی از بعضی از کلاس‌هایی که لود کرده‌ایم استفاده نکنیم و یا بخواهیم تحت شرایطی خاص کلاسی را لود کنیم. در این صورت به قابلیتی به نام Autoloading نیاز داریم.فرض کنید دایرکتوری‌ای به نام test داریم و در آن فایلی با نام index.php و دایرکتوری دیگری با نام src داریم که شامل کلاس‌های ما شده و در آن دایرکتوری دو کلاس A و B داریم.ساختار فایل‌هابرای استفاده از کلاس‌های  A و B در فایل index.php صرفا کافیست آنها را require کنیم :&lt;?php
require_once &amp;quotA.php&amp;quot
require_once &amp;quotB.php&amp;quot
$a = new A();
print_r(get_included_files());خروجی این کد به این صورت خواهد بود :Array 
(
    [0] =&gt; /home/index.php
    [1] =&gt; /home/A.php
    [2] =&gt; /home/B.php
)همانطور که می‌بینید کلاس B هم لود شده است درحالیکه از آن استفاده نکرده‌ایم. راه حل بهتر استفاده از Autoloading است.&lt;?php
function autoloader($class) {
    require_once(&#039;src/&#039;.$class.&#039;.php&#039;);
}
spl_autoload_register(&#039;autoloader&#039;);

$a = new A();

print_r(get_included_files());در این حالت Autoloader پی‌اچ‌پی به صورت خودکار هر زمانی که در اسکریپتمان از کلاس A استفاده کردیم، بر اساس منطقی که در فانکشن &#x60;autoloader&#x60; نوشته‌ایم، این کلاس را لود و مورد استفاده قرار می‌دهد.خروجی کد بالا به این صورت خواهد بود :Array
(
    [0] =&gt; /home/index.php
    [1] =&gt; /home/A.php
)نکته‌ای که در اینجا وجود دارد این است که نام کلاس‌ها و نام فایل‌ها باید یکسان باشند و در هر فایل فقط یک کلاس وجود داشته باشد.اما Composer چیست و چطور Autoloading را انجام می‌دهد ؟یکی از کارهای اصلی Composer مدیریت پکیج‌ ها در PHP بوده که احتمالا در پروژه های مختلف با آن کار کرده‌اید. اما کار مهم دیگری که Composer انجام می‌دهد مربوط به Autoload کلاس های مورد استفاده ما در برنامه است.در مسیر اصلی (دایرکتوری test) فایلی با نام composer.json بسازید و آن را به این صورت کامل کنید :{
    &amp;quotautoload&amp;quot: {
         &amp;quotclassmap&amp;quot: [
            &amp;quotsrc/&amp;quot
        ]
    }
}سپس در ترمینال (خط فرمان) خود دستور &#x60;composer update&#x60; را وارد کرده تا دایرکتوری vendor ساخته شود.حال فایل index.php را به این صورت تغییر می‌دهیم :&lt;?php
require_once __DIR__.&amp;quot/vendor/autoload.php&amp;quot

$a = new A();
$b = new B();

print_r(get_included_files());اگر به خروجی این کد نگاه کنید می‌بینید که فایل های A و B به صورت خودکار توسط Composer در اسکریپتمان لود شده‌اند. در واقع Composer از همان فانکشن &#x60;spl_autoload_register&#x60; استفاده می‌کند، اما بسیار مفصل‌تر. برای مشاهده دقیق تر جزئیات در دایرکتوری &#x60;vendor/composer&#x60; کلاس‌ های autoload.php ، autoload_real.php و ClassLoader.php را مشاهده نمایید.در اینجا ما از حالت &#x60;classmap&#x60; در Composer استفاده کردیم (به فایل composer.json توجه کنید). این حالت ساده ترین بوده و جزئیات آن را در کلاس &#x60;autoload_classmap.php&#x60;  می‌توانید ببینید. این فایل یک آرایه که شامل نام کلاس ها و مسیرشان است را باز می‌گرداند و هر بار که کلاس جدید به اسکریپتمان اضافه می‌کنیم باید یکبار دستور &#x60;composer update&#x60; را وارد کنیم تا این آرایه بروز شود.اما روش های دیگری از ‌Autoloading در Composer وجود دارد که فریم ورک معروف Laravel نیز از آن استفاده می‌کند و آن PSR-4 است.{
    &amp;quotautoload&amp;quot: {
        &amp;quotpsr-4&amp;quot: {
            &amp;quotSrc\\&amp;quot: &amp;quotsrc/&amp;quot
        }
    }
}این روش امکان استفاده از از کلید namespace در PHP را به ما می‌دهد که کار لود کلاس ها را بسیار ساده کرده و هر بار با اضافه کردن کلاسی جدید نیازی به وارد کردن دستور &#x60;composer update&#x60; نداریم. جزئیات این روش در فایل &#x60;autoload_psr4.php&#x60; است.برای نمونه :&lt;?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable {
...در واقع مسیری که جلوی namespace می‌نویسیم به شکل path پشت نام کلاس مورد نظر قرار گرفته و از یکتا بودن آن اطمینان حاصل می‌شود و به این ترتیب Composer به صورت داینامیک در زمان ران تایم کلاس مورد نظر را لود می‌کند (به همین دلیل هر بار با اضافه کردن کلاسی جدید مانند حالت classmap نیازی به وارد کردن دستور &#x60;composer update&#x60; نداریم).همینطور دستور use به ما کمک می‌کند تا در برنامه مجبور نباشیم مسیر و نام کلاسمان را تکرار کنیم و در زمانی که قصد استفاده از از دو کلاس همنام با مسیرهای متفاوت را داریم، با استفاده از use می‌توانیم نام مستعاری (alias) به کلاس‌مان بدهیم و از آن نام در برنامه استفاده کنیم.منابع :http://php.net/manual/en/language.oop5.autoload.phphttp://php.net/manual/en/function.spl-autoload-register.phphttp://php.net/manual/en/function.get-included-files.phphttps://getcomposer.org/doc/04-schema.md#autoloadhttps://www.php-fig.org/psr/psr-4https://dev.to/blocksbylukas/the-magic-behind-autoloading-php-files-using-composer-1e19https://medium.com/tech-tajawal/php-composer-the-autoloader-d676a2f103aa</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Sun, 19 Jan 2020 12:07:58 +0330</pubDate>
            </item>
                    <item>
                <title>اصطلاحات stubs و drivers در تست نرم‌افزار چه مفهومی دارند</title>
                <link>https://virgool.io/@mehradsadeghi/stubs-and-drivers-osgtef5goiin</link>
                <description>عکس از Irvan Smithدر توسعه نرم‌افزار، تست از اهمیت بالایی برخوردار می‌باشد. تصور کنید درتست‌هایی که می‌نویسید، تست شما وابسته به یکی از ماژول‌ها، فانکشن‌ها و یا بخشی از برنامه باشد، که آن بخش هنوز توسعه داده نشده، و به هر طریق، آن بخش در لحظه فعلی برای شما قابل استفاده نیست.در این شرایط از چه امکانی در تست‌نویسی می‌توان استفاده کرد ؟اِستاب‌ها (Stubs)اِستاب‌ها در واقع شبیه‌سازی‌ای از قطعه کد، فانکشن، ماژول و یا هر بخشی از برنامه شما هستند که تستی که می‌نویسید به آن وابسته است، و این ماژول واقعا برنامه‌نویسی نشده و کار شما را متوقف کرده‌ است.برای نمونه تصور کنید دو ماژول در برنامه شما وجود دارد. ماژول اول Login و ماژول دوم Dashboard نام دارد و منطق برنامه به این صورت است که پس از لاگین شدن کاربر، باید به صفحه Dashboard هدایت شود.حال فرض کنید توسعه‌ی ماژول Login تمام شده و برای تست شدن به وجود ماژول Dashboard نیاز دارد؛ اما ماژول Dashboard هنوز توسعه داده نشده و آماده استفاده نمی‌باشد.در این شرایط برنامه‌نویس با نوشتن قطعه کدی، وجود صفحه Dashboard را شبیه‌سازی می‌کند تا بتواند ماژول Login را تست کند. &lt;?php

class DashboardTest {

    public function show() {
        return &#039;dashboard is ready&#039;;
    }
}

class UserTest {

    public function testIfLoginWorksFine() {

        $userData = [
         &#039;username&#039; =&gt; &#039;mehrad&#039;,
          &#039;password&#039; =&gt; &#039;secret&#039;
        ];

        $response = $this-&gt;post(&#039;login&#039;, $userData);

        $response-&gt;assertSee(&#039;dashboard is ready&#039;);
    }
} در این سناریو، Dashboard نوشته شده در واقع یک Stub است.اِستاب‌ها در واقع در تست‌های به اصطلاح بالا به پایین استفاده می‌شوند.تست‌های بالا به پایین به تست‌هایی گفته می‌شود که در آن‌ها ماژول‌های سطح پایین‌تر که هنوز توسعه داده نشده‌اند را شبیه‌سازی می‌کنیم، در حالیکه توسعه‌ی ماژول‌های سطح بالا تمام شده است.  درایوِرها (Drivers) درایوِرها شباهت زیادی به استاب‌ها دارند؛ به این معنی که درایورها نیز در واقع شبیه‌سازی‌ای از قطعه کد، فانکشن، ماژول و یا هر بخشی از برنامه شما هستند که تستی که می‌نویسید به آن وابسته است، و این ماژول واقعا برنامه‌نویسی نشده و کار شما را متوقف کرده‌ است.اما تفاوت آن با استاب در این است که در تست‌های به اصطلاح پایین به بالا مورد استفاده قرار می‌گیرند.تست‌های پایین به بالا به تست‌هایی گفته می‌شود که در آن‌ها ماژول‌های سطح بالاتر که هنوز توسعه داده نشده‌اند را شبیه سازی می‌کنیم، در حالیکه توسعه‌ی ماژول‌های سطح پایین‌ تمام شده است. </description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Sun, 26 May 2019 01:30:30 +0430</pubDate>
            </item>
                    <item>
                <title>سند RFC چیست و چگونه اینترنت را تحت تاثیر قرار می‌دهد</title>
                <link>https://virgool.io/@mehradsadeghi/what-is-rfc-afzircwhknyk</link>
                <description>عکس از Annie Sprattسند RFC (بطور کامل  Request For Comments) یک پیش‌نویس رسمی از طرف سازمان IETF یا همان (Internet Engineering Task Force) می‌باشد که در آن مشخصات یک تکنولوژی بطور خاص توضیح داده شده است.زمانی که یک RFC به تصویب می‌رسد، به یک استاندارد رسمی برای آن تکنولوژی تبدیل می‌شود.سندهای RFC در ابتدا برای پروتکل APPANET (که امروزه به آن اینترنت می‌گوییم) استفاده شدند و از آن پس در تمام تکنولوژی‌های زیرساختی اینترنت استفاده می‌شوند.برای نمونه پروتکل SSL که پیش از این توضیحاتی در مورد آن داده بودم، تحت یک RFC به تایید رسید و منتشر شد.یک استاندارد در اینترنت زمانی به تصویب می‌رسد که یک RFC در کمیته‌های مربوطه مورد بحث و بازبینی قرار گیرد تا زمانیکه آخرین نسخه از آن تایید شود. در این هنگام دیگر هیچ نظر (Comment) و تغییری مورد پذیرش نیست.عملا اگر نیاز به برزورسانی و تغییری در یک پروتکل باشد، باید RFC های جدیدتری به تصویب برسد. برای نمونه پروتکل FTP در RFC 114 در آوریل 1971 منتشر شد. سپس در RFC 765 در سال 1980 و در نهایت در RFC 959 دستخوش تغییراتی شد.این مطلب ترجمه‌ای از وب‌سایت techopedia بود و برای کسب اطلاعات بیشتر در مورد RFC ها می‌توانید از ویکی‌پدیا استفاده نمایید.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Sun, 26 May 2019 01:15:52 +0430</pubDate>
            </item>
                    <item>
                <title>چند خطی در مورد پروتکل‌های HTTPS - SSL - TLS</title>
                <link>https://virgool.io/@mehradsadeghi/%DA%86%D9%86%D8%AF-%D8%AE%D8%B7%DB%8C-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-%D9%BE%D8%B1%D9%88%D8%AA%DA%A9%D9%84%D9%87%D8%A7%DB%8C-https-ssl-tls-ehbamqnsuiae</link>
                <description>عکس از Chris Panasاگر از دوستداران توسعه وب هستید حتما اصطلاحاتی مانند پروتکل HTTPS، پروتکل SSL و TLS به گوشتان خورده. در این نوشته کوتاه سعی دارم تفاوت این پروتکل‌ها را به صورت مختصر شرح دهم.پروتکل HTTPSپروتکل HTTPS تا حد زیادی همان پروتکل HTTP است، با این تفاوت که اطلاعات در آن به صورت امن جابجا می‌شود.پروتکل HTTPS برای امن سازی اطلاعات از پروتکلی دیگر به نام SSL (که در نسخه جدید، آن را با نام TLS می‌شناسیم) استفاده می‌کند.در‌واقع HTTPS از یک پروتکل دیگر درون خود برای رمزگذاری اطلاعات استفاده می‌کند.پروتکل‌های SSL/TLSشرکت Netscape (که در مقاله چند خطی در مورد اِکما اسکریپت به یکی از دستاوردهای آن اشاره کردم) در سال 1995 پروتکل SSL را (Secure Sockets Layer) تولید کرد. این پروتکل از نسخه 2 ارائه شد و به دلیل مشکلات امنیتی‌ای که داشت به سرعت نسخه سوم آن در همان سال منتشر شد. سپس در سال 1999 که رقابت بین مرورگر مایکروسافت و سایر مرورگرها بالا گرفته بود، الزام برای بدست گرفتن استاندارد سازی این پروتکل (و استفاده همه شرکت‌ها از آن) احساس می‌شد.به همین دلیل شرکت Netscape در اواخر سال 1999 کنترل کامل این پروتکل را در اختیار IETF (یک سازمان استاندارد سازی داوطلبانه در وب) قرار داد.در همان سال با توسعه SSL سازمان IETF نام این پروتکل را به TLS یا همان Transport Layer Security نسخه 1 تغییر داد. در سال 2006 نسخه 1.1 ، در سال 2008 نسخه 1.2 و در سال 2018 نسخه 1.3 از این پروتکل منتشر شده است.بطور خلاصه SSL پروتکل رمزگذاری بر روی اطلاعات بود که توسط شرکت Netscape توسعه داده شد و پس از آنکه این شرکت استاندارسازی این پروتکل را به IETF سپرد نام آن به TLS تغییر پیدا کرد. همینطور پروتکل HTTPS در حال حاضر از TLS برای امن سازی اطلاعات درون خود استفاده میکند.این نوشته خلاصه ای از مطالب وب‌سایت‌های howhttps.works و wikipedia بوده که در صورت علاقه‌مندی بیشتر می‌توانید از طریق همین لینک‌ها به مطالعه ادامه دهید.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Sun, 26 May 2019 01:07:06 +0430</pubDate>
            </item>
                    <item>
                <title>مقدمه ای بر Bytecode و Opcode در زبان Solidity</title>
                <link>https://virgool.io/@mehradsadeghi/introduction-to-solidity-bytecode-and-opcode-ongcahunsh52</link>
                <description>Photo by Patrick Lindenberg هرچقدر که در Smart Contract ها عمیق‌تر می‌شویم بیشتر با اصطلاحاتی چون PUSH1 ، SSTORE ، MSTORE و ... مواجه می‌شویم.این‌ها دقیقا چه هستند و آیا ما باید به آنها اهمیت دهیم ؟برای درک درست این اصطلاحات باید در Ethereum Virtual‌ Machine یا همان EVM عمیق‌تر شویم.زبان Solidity از نوع زبان‌های High Level Language است. ما آن را می‌فهمیم ولی ماشین آن را نمی‌فهمد. زمانی که ما یکی از کلاینت‌های اِتِریوم مانند geth را نصب می‌کنیم، EVM خودکار با آن نصب می‌شود. در واقع EVM یک سیستم عامل سبک می‌باشد که اختصاصا برای اجرای Smart Contract ها ساخته شده است.وقتی ما کدهای Solidity را کامپایل می‌کنیم، کدها به Bytecode تبدیل می‌شوند و این همان چیزیست که ماشین می‌فهمد.این یک نمونه Smart Contract بسیار ساده است :pragma solidity ^0.4.11;contract MyContract {
    uint i = (10 + 2) * 2;
}اگر این Smart Contract را در Remix اجرا نمایید، با کلیک بر روی دکمه details اطلاعات زیر را می‌بینیم :Solidity Bytecode and Opcodesاین بخش کامپایل شده‌ی کدهای Solidity است : 60606040525b600080fd00a165627a7a7230582012c9bd00152fa1c480f6827f81515bb19c3e63bf7ed9ffbb5fda0265983ac7980029این چیزی نیست جز یک عدد بر مبنای شانزده (هگزا)، که از کدهایی که در Contract نوشتیم بدست آمده است و به آن Bytecode گفته می‌شود.در همین پنجره (details) در بخش Web3 Deploy چنین چیزی می‌بینیم :...
   {
     from: web3.eth.accounts[0], 
     data: &#039;0x606060405260186000553415601357600080fd5b5b60368060216000396000f30060606040525b600080fd00a165627a7a7230582012c9bd00152fa1c480f6827f81515bb19c3e63bf7ed9ffbb5fda0265983ac7980029&#039;, 
     gas: &#039;4300000&#039;
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== &#039;undefined&#039;) {
         console.log(&#039;Contract mined! address: &#039; + contract.address + &#039; transactionHash: &#039; + contract.transactionHash);
    }
 })در نهایت چیزی که از Contract ما بر روی شبکه اِتِریوم قرار می‌گیرد همین عدد هگزا ای است که در فیلد data می‌بینید و برای این عمل به پرداخت  4,300,000 gas نیاز دارد.در واقع EVM با همه چیز به عنوان یک مقدار هگزا برخورد می‌کند. اگر تابحال برایتان سوال پیش آمده که چرا در ابتدای آدرس اَکانت های اِتِریوم یا هَشِ تراکنش‌ها &quot;0x&quot; را می‌بینیم، دلیل آن همین است.در واقع &quot;0x&quot; به این معنی است که مقداری که در جلوی آن قرار می‌گیرد، یک عدد بر مبنای شانزده است.وجود &quot;0x&quot; الزامی نیست، چراکه همانطور که گفته شد EVM با همه مقادیر به صورت هگزا برخورد می کند.همینطور عباراتی به شکل زیر را می‌بینیم :PUSH1 0x60 PUSH1 0x40 MSTORE PUSH1 0x18 PUSH1 0x0 SSTORE CALLVALUE ISZERO PUSH1 0x13 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST JUMPDEST PUSH1 0x36 DUP1 PUSH1 0x21 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x60 PUSH1 0x40 MSTORE JUMPDEST PUSH1 0x0 DUP1 REVERT STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 SLT 0xc9 0xbd STOP ISZERO 0x2f LOG1 0xc4 DUP1 0xf6 DUP3 PUSH32 0x81515BB19C3E63BF7ED9FFBB5FDA0265983AC798002900000000000000000000به این بخش Operation Code یا همان Opcode گفته می‌شود.این بخش برای انسان قابل خواندن است ولی درک آن بسیار مشکل می باشد. تمام این Operation ها در واقع معادلی در مبنای شانزده دارند. بطور مثال معادل MSTORE مقدار 0x52 می باشد و یا SSTORE معادل 0x55 می‌باشد. در ریپازیتوری گیت‌هاب اِتِریوم می‌توانید لیست کامل Opcode ها را مشاهده نمایید.ماشین EVM از نوع Stack Machine می‌باشد. برای درک ساده‌ی اِستَک‌ها تصور کنید قطعات نان را در فِر قرار می‌دهید. طبیعتا قطعه نان آخری که در فِر قرار داده‌اید را، در هنگام خارج کردن نان‌ها، اول از همه بیرون خواهید آورد. در علوم کامپیوتر به این فرآیند Last In First Out یا همان LIFO گفته می‌شود.در محاسبات ریاضیاتی، ما چنین عمل می‌کنیم :۱۰ + ۲ * ۲
ابتدا ۲ را در ۲ ضرب نموده و سپس با ۱۰ جمع می‌کنیمدر Stack Machine اصول LIFO به این شکل عمل می‌کنند :Stack Machine : 2 2 * 10  + به این معنی که : ابتدا ۲ را در اِستَک قرار بده، سپس عدد ۲ بعدی را قرار بده و بعد از آن عملیات ضرب را انجام بده. حاصل آن ۲ می‌شود که در راس اِستَک قرار می‌گیرد. سپس عدد ۱۰ را در اِستَک قرار بده (بعد از ۴) و این دو عدد را با هم جمع کن. مقدار نهایی استک ۱۴ خواهد بود. عمل وارد کردن داده در استک PUSH و عمل خارج کردن داده POP نام دارد. در Opcode ـی که بالا تر دیدم تعداد زیادی PUSH1 وجود دارد که به معنی قرار دادن ۱ بایت از داده ای مشخص در اِستَک می باشد. (در ادامه این مورد با مثال‌های متعدد بیشتر توضیح داده می‌شود)در نتیجه، این عبارت :PUSH1 0x60به معنی قرار دادن ۱ بایت با مقدار &quot;0x60&quot; در اِستَک می‌باشد. تصادفا مقدار هگزایِ عملیات PUSH برابر با &quot;0x60&quot; است که اگر عبارت غیر الزامی &quot;0x&quot; را حذف کنیم، Bytecode بدست آمده برابر با &quot;6060&quot; می‌شود.یک قدم پیش تر برویم :PUSH1 0x60 PUSH1 0x40 MSTOREبا نگاهی به لیست Opcode ها، می‌بینیم که MSTORE (هگزا : 0x52) دو ورودی می‌گیرد و خروجی‌ای ندارد. Opcode بالا بدین معنی است :PUSH1 0x60 : مقدار 0x60 را وارد اِستَک کن2. PUSH1 0x40 :مقدار 0x40 را وارد اِستَک کن3. MSTORE 0x52 :به مقدار 0x60 از فضای حافظه را اختصاص بده و به نقطه 0x40 برو(در ادامه توضیح ساده تری از این Opcode می‌بینید)نتیجه نهایی Bytecode اینچنین خواهد بود :Result : 6060604052در حقیقت ما همیشه مقدار &quot;6060604052&quot; را در ابتدای بایت کدهای Solidity می‌بینیم و دلیل این موضوع این است که Smart Contract ها با این Opcode راه اندازی (Bootstrap) می‌شوند.در Opcode بالا، مقدار 0x60 در مبنای ده برابر ۹۶ و مقدار 0x40 در مبنای ده برابر ۶۴ است. در نتیجه Opcode بالا به این معنی است که :۹۶ بایت از حافظه را تخصیص بده و مکان پوینتر را به ابتدای ۶۴ اُمین بایت تغییر بده.در EVM داده‌ها در سه بخش می‌توانند ذخیره شوند : اِستَک : که نمونه آن PUSH می‌باشد و بالا تر مثال آن را دیدیمحافظه تصادفی (RAM) : که نمونه آن MSTORE در Opcode ها می‌باشدحافظه دیسک : که نمونه Opcode آن SSTORE استدر اِتِریوم برای ذخیره داده در حافظه دیسک باید gas پرداخت شود و به همین دلیل ذخیره داده در دیسک گران‌ترین و ذخیره داده در اِستَک ارزان‌ترین است.زبان Assemblyنوشتن کامل Smart Contract با Opcode ها امکان پذیر است و برای این منظور زبان اسمبلی Solidity ساخته شده است. طبیعتا نوشتن در این حالت بسیار سخت تر است، ولی برای نوشتن Contract هایی که در آن‌ها باید در مصرف gas صرفه جویی شود و یا زمانی که کاری می‌خواهید انجام دهید که اجرای آن در Solidity امکان پذیر نیست، استفاده از زبان اسمبلی Solidity کارا خواهد بود.در انتهابرای شروع به نوشتن Smart Contract ها نیازی به دانستن Opcode ها نداریم. اما دانستن آنها علاوه بر اینکه دانش ما را در این زمینه بالا می‌برد، در هنگام Error Handling (که به خوبی در EVM انجام نمی‌شود) بسیار مفید می باشد. نویسنده : Bernard Peh</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 26 Oct 2018 22:19:06 +0330</pubDate>
            </item>
                    <item>
                <title>شیوه‌هایی بهتر در PHP</title>
                <link>https://virgool.io/Software/php-best-practices-rddp8o7gr9wr</link>
                <description>شیوه‌هایی بهتر در PHP در هر زبان برنامه‌نویسی‌ای مفهومی به نام Best Practice یا همان روش ایده‌آل وجود دارد، که معمولا این روش از بین چند روشی که برای انجام یک کار میتوان به‌کار بست انتخاب می‌شود.اینکه چرا باید از Best Practice ها استفاده نمود، دلایل مختلفی از جمله مسائل امنیتی، عملکردی (Performance) و ... می‌تواند داشته باشد.۱. ذخیره کلمات عبوراز جمله روش‌هایی که برای ذخیره کلمات عبور استفاده می‌شود، استفاده از الگوریتم‌های MD5 و SHA1 است که این روش‌ها امنیت کافی برای ذخیره کلمات عبور را ندارند.برای ذخیره کلمات عبور از فانکشن password_hash استفاده کنید، چراکه از جدیدترین و بهترین مدتهای هَش سازی استفاده می‌کند.&lt;?php
    // Hash the password.  $hashedPassword will be a 60-character string.
    $hashedPassword = password_hash(&#039;mypassword&#039;, PASSWORD_DEFAULT);
 
    password_verify(&#039;the wrong password&#039;, $hashedPassword); // false
    password_verify(&#039;mypassword&#039;, $hashedPassword); // true
?&gt;۲. اتصال به دیتابیسبرای اتصال به دیتابیس از درایور PDO استفاده کنید. این درایور به دیتابیس‌های مختلفی می‌تواند متصل شود و به صورت OOP قابل استفاده است. در PDO می‌توانید از فانکشن‌های Prepend برای جلوگیری از حملات SQL Injection استفاده نمایید.&lt;?php
try {
    $link = new \PDO(&#039;mysql:host=your-hostname;dbname=your-db;charset=utf8mb4&#039;,
    &#039;your-username&#039;,
    &#039;your-password&#039;,
        array(
            \PDO::ATTR_ERRMODE =&gt; \PDO::ERRMODE_EXCEPTION,
            \PDO::ATTR_PERSISTENT =&gt; false
        )
    );

    $handle = $link-&gt;prepare(&#039;select Username from Users where UserId = ? or Username = ? limit ?&#039;);
    
    $handle-&gt;bindValue(1, 100, PDO::PARAM_INT);
    $handle-&gt;bindValue(2, &#039;Bilbo Baggins&#039;);
    $handle-&gt;bindValue(3, 5, PDO::PARAM_INT);
    $handle-&gt;execute();
    
    $result = $handle-&gt;fetchAll(\PDO::FETCH_OBJ);
    foreach($result as $row) {
        print($row-&gt;Username);
    }
} catch(\PDOException $ex) {
    print($ex-&gt;getMessage());
}
?&gt;۳. تگ شروع و پایان PHPاز تگ‌های &lt;? ?&gt; و یا &lt;? =?&gt; استفاده نکنید و بجای آن از شکل کامل &lt;? php?&gt; استفاده کنید. با اینکه شکل کوتاه راحت‌تر به نظر می‌رسد ولی بطور پیش‌فرض در تنظیمات PHP غیرفعال است و برای استفاده از آنها پارامتر short_open_tag باید فعال شود. همینطور ممکن است در سروری که از آن استفاده می‌کنید امکان فعال‌سازی این پارامتر وجود نداشته باشد.حالت =?&gt; بدون نیاز به فعال بودن  short_open_tag کار می‌کند و برای استفاده از آن مشکلی وجود ندارد.۴. استفاده از autoloadروش قدیمی autoload کردن کلاس‌هایی که لود نشده‌اند استفاده از فانکشن function __autoload() {}می‌باشد. مشکل در استفاده از این فانکشن آنجاست که اگر کتابخانه‌ای را وارد پروژه کنید که از این فانکشن استفاده می‌‌کند؛ در این صورت با تداخل (conflict) مواجه خواهید شد.روش مناسب و صحیح در autoload کردن، تعیین نامی منحصربه‌فرد برای فانکشنی که کار autoload را در کد شما انجام می‌دهد و سپس ثبت آن درspl_autoload_register()است. &lt;?php
// First, define your auto-load function.
function MyAutoload($className) {
    include_once($className . &#039;.php&#039;);
}

// Next, register it with PHP.
spl_autoload_register(&#039;MyAutoload&#039;);

// Try it out!
// Since we haven&#039;t included a file defining the MyClass object, our auto-loader will kick in and include MyClass.php.

// For this example, assume the MyClass class is defined in the MyClass.php file.
$var = new MyClass();
?&gt;۵. سینگِل‌کوتِیشِن در مقابل دابِل‌کوتِیشِندر PHP سینگِل‌کوتِیشِن‌ها ( &#x27; ) تجزیه (parse) نمی‌شوند، به این معنی که هر کاراکتری که بین آنها قرار دهید مستقیما چاپ می‌شود. در مقابل دابِل‌کوتِیشِن‌ها ( &quot; ) تجزیه می‌شوند و این امکان را دارند تا متغیر بین آنها قرار گیرد. همینطور کاراکترهایی مانند n\ یا t\ در دابِل‌کوتِیشِن‌ها قابلیت اجرایی دارند.دابِل‌کوتِیشِن‌ها در لحظه‌ی اجرای برنامه ارزیابی (evaluate) می‌شوند، در حالیکه سینگِل‌کوتِیشِن‌ها اینچنین نیستند و به همین دلیل سینگِل‌کوتِیشِن‌ها از نظر عملکرد بهتر هستند. معمولا این تفاوت در عملکرد، در نرم‌افزارهای بسیار بزرگ قابل لمس است و در اکثر پروژه‌ها تفاوتی بین آنها احساس نمی‌شود.۶. استفاده از const در مقابل فانکشن defineتفاوت‌های const و define :۱. ()define در زمان run time تعریف می‌شود درحالیکه const در زمان compile time. به همین دلیل const با کمی performance بهتر همراه است (که این موضوع در نرم افزارهای معمول به چشم نمی‌خورد).۲. از ()define برای تعریف ثوابت در کلاس‌ها نمی‌توان استفاده کرد، همینطور ()define ثابت را در بلاکِ GLOBAL قرار می‌دهد.۳. امکان استفاده از عملگرهای بیتی در ()define وجود دارد.۴. از ()define در بلاک‌هایی مانند if می‌توان استفاده نمود درحالیکه از const نمی‌توان. &lt;?php 
 // Let&#039;s see how the two methods treat namespaces
 namespace MiddleEarth\Creatures\Dwarves; 
 const GIMLI_ID = 1; 
 define(&#039;MiddleEarth\Creatures\Elves\LEGOLAS_ID&#039;, 2); 

echo(\MiddleEarth\Creatures\Dwarves\GIMLI_ID);  // 1
echo(\MiddleEarth\Creatures\Elves\LEGOLAS_ID);  // 2; note that we used define(), but the namespace is still recognized 
 
// Now let&#039;s declare some bit-shifted constants representing ways to enter Mordor. 
define(&#039;TRANSPORT_METHOD_SNEAKING&#039;, 1 &lt;&lt; 0); // OK! 
const TRANSPORT_METHOD_WALKING = 1 &lt;&lt; 1; // Compile error! const can&#039;t use expressions as values 

// Next, conditional constants. define(&#039;HOBBITS_FRODO_ID&#039;, 1); 
if($isGoingToMordor) { 
    define(&#039;TRANSPORT_METHOD&#039;, TRANSPORT_METHOD_SNEAKING); // OK!    
    const PARTY_LEADER_ID = HOBBITS_FRODO_ID // Compile error: const can&#039;t be used in an if block 
} 
    
// Finally, class constants 
class OneRing { 
    const MELTING_POINT_CELSIUS = 1000000; // OK!
    define(&#039;MELTING_POINT_ELVISH_DEGREES&#039;, 200); // Compile error: can&#039;t use define() within a class 
} 
?&gt; عملا استفاده از ()define انعطاف بیشتری در برنامه‌نویسی به شما می‌دهد مگر اینکه بخواهید در کلاس‌های خود از ثابت استفاده کنید که در این صورت باید از const استفاده کنید. همینطور const خوانایی بیشتری به کدهای شما می‌دهد.۷. عبارات با قاعده در PHPدر PHP دو روش برای کار با عبارات با قاعده (Regex) وجود دارد. PERL که فانکشن‌های آن با *_preg شروع می‌شوند و POSIX که فانکشن‌های آن با *_ereg شروع می‌شوند.POSIX از نسخه 5.3 PHP منسوخ شد و به همین دلیل باید از خانواده *_preg استفاده نمایید.۸. ارسال ایمیل در PHPفانکشن ()mail از فانکشن‌های موجود در هسته‌ی PHP است که استفاده از آن مشکلات امنیتی دارد. به همین دلیل برای ارسال ایمیل باید از کتابخانه PHPMailer استفاده نمود. این کتابخانه‌ی متن‌باز بسیار محبوب بوده و در استفاده از آن نیازی به نگرانی در مورد مسائل امنیتی نیست.&lt;?php
// Include the PHPMailer library
require_once(&#039;phpmailer-5.2.7/PHPMailerAutoload.php&#039;);

// Passing &#039;true&#039; enables exceptions.  This is optional and defaults to false.
$mailer = new PHPMailer(true);

// Send a mail from Bilbo Baggins to Gandalf the Grey
// Set up to, from, and the message body.  The body doesn&#039;t have to be HTML; check the PHPMailer documentation for details.

$mailer-&gt;Sender = &#039;bbaggins@example.com&#039;;
$mailer-&gt;AddReplyTo(&#039;bbaggins@example.com&#039;, &#039;Bilbo Baggins&#039;);
$mailer-&gt;SetFrom(&#039;bbaggins@example.com&#039;, &#039;Bilbo Baggins&#039;);
$mailer-&gt;AddAddress(&#039;gandalf@example.com&#039;);
$mailer-&gt;Subject = &#039;The finest weed in the South Farthing&#039;;
$mailer-&gt;MsgHTML(&#039;&lt;p&gt;You really must try it, Gandalf!&lt;/p&gt;&lt;p&gt;-Bilbo&lt;/p&gt;&#039;);

// Set up our connection information.
$mailer-&gt;IsSMTP();
$mailer-&gt;SMTPAuth = true;
$mailer-&gt;SMTPSecure = &#039;ssl&#039;;
$mailer-&gt;Port = 465;
$mailer-&gt;Host = &#039;my smtp host&#039;;
$mailer-&gt;Username = &#039;my smtp username&#039;;
$mailer-&gt;Password = &#039;my smtp password&#039;;

// All done!
$mailer-&gt;Send();
?&gt;۹. اعتبارسنجی آدرس ایمیلاغلب برنامه‌نویسان PHP از Regex هایی پیچیده برای بررسی اعتبار فرمت ایمیل‌ها استفاده می‌کنند. اما برای این اعتبارسنجی راه بسیار راحت‌تری وجود دارد.&lt;?php
filter_var(&#039;sgamgee@example.com&#039;, FILTER_VALIDATE_EMAIL); // Returns &quot;sgamgee@example.com&quot;. This is a valid email address.
filter_var(&#039;sauron@mordor&#039;, FILTER_VALIDATE_EMAIL); // Returns boolean false! This is *not* a valid email address.
?&gt;منبع :  phpbestpractices</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Wed, 01 Aug 2018 22:52:25 +0430</pubDate>
            </item>
                    <item>
                <title>چند خطی در مورد اِکما اسکریپت</title>
                <link>https://virgool.io/@mehradsadeghi/ecmascirpt-frxu8dqkgnxe</link>
                <description>سلام به همه دوستاندوست دارم توضیحات ساده و کوتاهی در رابطه با اِکما اسکریپت بدم، چون بارها دیدم و شنیدم که دوستان نمی‌دونن اکما اسکریپت چی هست، به چه معناست و از کجا اومده.درآمدی بر JavaScriptدر سال ۱۹۹۵ میلادی بود که JavaScript معرفی شد تا صفحات وبِ پویاتری برای کاربران ایجاد کند. در اون زمان JavaScript در مرورگری به نام Navigator Browser از شرکت Netscape کار می‌کرد. بزرگترین مزیت JavaScript این بود که کاربرها رو قادر می‌ساخت بدون ریلود شدن صفحه وب برای هر عملی، بتونن با وب‌سایت‌ها تعامل داشته باشن. جاوا و جاوا اسکریپت عملا هیچ ارتباطی باهم ندارند.جاوا اِسکریپت در ابتدا با نام LiveScript معرفی شد و محبوبیت چندانی نداشت. در همین حال (در دهه نود میلادی)‌ زبان جاوا از محبوبیت فراوانی برخوردار بود. به همین دلیل بود که با مقاصد تجاری و رشدِ توجه به این زبان، نام LiveScript به JavaScript تغییر پیدا کرد.در این زمان استاندارد سازی، الگوهای اجرایی، و تمام قواعدی که زبان JavaScript را برای اجرا در مرورگرها آماده می‌ساخت توسط شرکت Netscape تعیین می‌شد؛ و با پیشرفت وب، تعداد مرورگرهای بیشتری از JavaScript پشتیبانی می‌کردند.بالاخره زمانی رسید که پروژه Navigator Browser در شرکت Netscape متوقف شد و هر یک از شرکت‌هایی که در مرورگرهایشان از JavaScript پشتیبانی می‌کردند دچار سردرگمی برای استاندارهایی که باید در JavaScript رعایت کنند شده بودند.اِکما (ECMA) :سازمان اِکما ( European Computer Manufacturers Association ) از زمان متوقف شدن پروژه Navigator Browser عهده‌دار استاندارد سازی JavaScript شد، که این استاندارد EcmaScript نام دارد.از این پس همه نام JavaScript و EcmaScript رو دقیقا یکسان به حساب میارن، درحالی‌که در واقع اِکما سازمان معرفی استاندارهای JavaScript هست و استاندارد ورژن‌های مختلف این زبان رو ارائه می‌کنه.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 12 Jan 2018 16:25:17 +0330</pubDate>
            </item>
                    <item>
                <title>موی‌هایم، بلندپروازی را به من یادآور می‌شوند</title>
                <link>https://virgool.io/@mehradsadeghi/pursue-your-dreams-cnsu1kja0lcv</link>
                <description>منمدتی‌ست موی‌هایم را کوتاه نمی‌کنم. این موضوع اطرافیانم را به واکنش‌های متفاوتی وا داشته است. بعضی موافق، بعضی مخالف؛ بعضی دوستش دارند و بعضی حتی نمی‌توانند به من نگاه کنند.اما واقعا چه اهمیتی دارد که دیگران چه نظری دارند. مردمِ من عادت به اظهار نظر در هر موردی کرده‌اند، و در این مورد حریم خصوصی و غیر خصوصی نمی‌شناسند.موی‌هایم هر روز بلندتر می‌شوند و دیدنشان به من انگیزه‌ای دوچندان می‌دهد. هر روز با دیدنشان این جمله در ذهنم طنین‌انداز می‌گردد که تو آزاد هستی، آزادی تا هرکجایی که می‌خواهی قد بکشی و پرواز کنی. همچون موی‌هایت، که اینطور آزادانه می‌رویند، بی‌هیچ واهمه‌ای.ترس چیزی‌ست که مردمِ من به خورد مغزم دادند؛ روراست باشیم، به خورد همه‌مان داده‌اند.از کودکی به ما یاد دادند که ریسک نکنیم، بلند پرواز نباشیم، تحصیلات عالیه تنها راه موفقیت است، به هنر اهمیت ندهید، کار کارمندی برای خود دست‌وپا کنید، از خط عابر عبور نکنیم و در صفوف نایستید تا شهروندی زرنگ‌تر به نظر آیید، حقوق یکدیگر را به طرق مختلف زیر پا بگذارید چون شما ارجح‌تر هستید، به عقاید یکدیگر احترام نگذارید چراکه فقط این ما هستیم که بر حق سخن می‌گوییم و ...مرا نجات دهیدبیشتر ابعاد شخصیتی یک کودک، در حدود هشت سال ابتدایی زندگی‌اش شکل می‌گیرد. بد نیست به هشت سال ابتدایی زندگی خود بیاندیشید (گرچه مقداری از آن را بخاطر نخواهید آورد)......واقعا چطور می‌توانیم از کودکی که به او، رعایت حقوق هم‌نوعش را نیاموخته‌ایم، توقع داشته باشیم روزی وی به فرزندش رعایت حقوق دیگران را بیاموزد!واقعا چطور می‌توانیم از کودکی که در قالب فکری‌اش، زندگی‌ای بدون ریسک، ثابت‌ و کارمندانه را نهادینه کرده‌ایم، توقع داشته باشیم کارآفرین آینده کشورش باشد!واقعا مگر می‌شود جامعه‌ای پویا داشته باشیم، تا زمانی‌که اذهان را می‌میرانیم... ؟!روزی فریاد خواهم زداما در بین تمام این هیاهو، روزنه‌های امیدی وجود دارد. راهی برای خلاصی از تمام این ناخوش‌آیندی‌ها.خبر خوش آن است که این شما هستید که باید سرنوشت خود را بسازید.هرکَس صاحب قُله‌ایستقُله زندگی هرکَسی با دیگری متفاوت است، شما وظیفه فتح قُله زندگی خود را دارید.موفق‌ترین انسان‌ها در این کُره خاکی، کسانی‌اند که از کودکی روحیه‌ی تلاشگری داشته‌اند. یاد گرفته‌اند که می‌توانند. به داستان‌سرایی درباره کلیشه‌ها نمی‌پردازم؛ چراکه همه میدانیم استیو جابز، مارک زاکِربِرگ، ایلان ماسک، جِف بِزوس و بسیاری دیگر چطور با خودباوری جهان اطرافشان را تحت تاثیر قرار دادند.موفق بودن به این معنی نیست که پول‌دارترین باشید، موفقیت یعنی آنچه شما را برمی‌انگیزاند را کشف کنید و برایش تمام لحظاتتان را زندگی کنید. زیرا فقط در این صورت است که در پایان، به گذشته خود افتخار می‌کنید و حسرت هیچ لحظه‌ی از دست رفته‌ای را نخواهید خورد.زندگی را دوست داشته باشید، اگر شغل، درس و تحصیل و بطور کلی هر فعالیتی دارید که انجامش، پیش از خواب، انگیزه زودتر بیدار شدن را به شما نمی‌دهد، بدانید که در مسیر اشتباهی قرار دارید.شما آن‌چیزی را بدست می‌آورید که برای آن تلاش می‌کنیدهمه ما مجبوریم در مقاطعی از زندگی، چه برای معیشت و یا به هر دلیل دیگری فعالیتی متناقض با علایقمان انجام دهیم، اما حواسمان باشد که این به عادتی که بلای جان رویاهایمان است بدل نشود.بله، تمام آنچه خواندید با هر بار مشاهده‌ی موی‌هایم به من یادآوری می‌شوند. موی‌هایم به من یادآوری می‌کنند که اگر در زندگی رها نباشم و تحت تاثیر پیرامون (مانند نظرات دیگران) زندگی کنم، به انسانی لبریز از استعداد و هیجان در کالبد یک کارمند ساکن بدل‌ خواهم شد.و در آخر فراموش نکنیم که برای داشتن چیزهایی که تابه‌حال نداشته‎‌ایم، باید کارهایی بکنیم که تابه‌حال نکرده‌ایم.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 05 Jan 2018 17:11:37 +0330</pubDate>
            </item>
                    <item>
                <title>یک لقمه Sass دور هم</title>
                <link>https://virgool.io/JavaScript8/scss-basics-zmwdxicslzpr</link>
                <description>سلام به همه دوستاندر این مقاله دوست دارم در مورد Sass توضیحاتی بدم تا با قابلیت‌های بسیار خوب و حرفه‌ای‌ش آشنا بشید.اگر در برنامه‌نویسیِ فرانت‌اِند تازه کار هستید و یا حتی اگر حرفه‌ای، احتمالا واژه‌ی Sass به گوشتون خورده.در توسعه‌ی فرانت‌اِند بعد از اینکه مدیریت CSS ها در پروژه‌های بزرگ سخت شده بود ، و کار کدنویسی رو تا حدی طاقت‌فرسا می‌کرد، تکنولوژی‌هایی مثل Sass و LESS بوجود اومدن تا کار استایل‌دهی رو بسیار کاراتر، لذت‎بخش‌تر و ساده‌تر کنند.در این بین شاید کلمه SCSS هم به گوشتون خورده باشه، که به اعتقاد اکثریت هیچ تفاوتی با Sass نداره و یکی هستند. درواقع در ابتدا Sass معرفی شد، اما Syntax (سینتَکس) اون به راحتیه CSS نبود و تا حدی پیچیدگی‌هایی داشت. پسوند فایل (به طور مثال) sample در Sass به این صورت نوشته می‌شه :sample.sassبرای اینکه سینتَکس Sass ساده‌تر و بیشتر به CSS شبیه بشه SCSS معرفی شد؛ که مخفف Sassy CSS یا Standard CSS هست؛ که در اون فایل فرضی sample به این صورت ساخته می‌شه :sample.scssپیش‌پردازشگری، راه چاره‌ی توسعه‌ای بهتر :راه حل Sass پیش‌پردازشگری‌ (Pre Processing) هست. یعنی تمام کدی‌هایی که در Sass می‌نویسیم در نهایت پردازش شده و به CSS تبدیل می‌شوند. چراکه در نهایت مرورگر‌ها برای استایل‌دهی CSS رو می‌فهمند؛ نه Sass.اما بریم سراغ معرفی تعدادی از ویژگی‌های مفید در SCSS (برای ساده‌تر شدن مطلب از بیان کدهای Sass صرف نظر می‌کنم و مستقیما SCSS رو توضیح می‌دم)۱. متغیر، گمشده‌ای در CSS :یکی از مزیت‌های بزرگ SCSS نسبت به CSS امکان تعریف متغیرهاست. متغیرها در SCSS به این صورت قابل تعریف هستند :$primary-color: #333;CSS :body {
    font: 100% Helvetica, sans-serif;
    color: #333;
}SCSS :$font-stack : Helvetica, sans-serif;
$primary-color: #333;
body {
    font: 100% $font-stack;
    color: $primary-color;
 }در اینجا شاید براتون این سوال پیش بیاد که در کد SCSS تعداد خطوط کد ما بیشتر از تعداد خطوط کدی هست که در CSS داریم، پس چه دلیلی برای استفاده از SCSS وجود داره ؟!درسته هست که در اینجا تعداد خطوط کدهای SCSS بیشتر هستند. اما در یک پروژه واقعی، کار به همینجا ختم نمی‌شه.مثلا تصور کنید یک قالب که دارای سه صفحه هست رو باید کدنویسی کنید، که در این قالب، دو رنگ، یکی Primary Color  و دیگری Secondary Color هستند و در اکثر اِلِمان‌های صفحه از این دو رنگ استفاده شده. حالا به هر دلیلی تصمیم بر تغییر یکی از این دو رنگ می‌گیرید. اگر با CSS خام کار استایل‌دهی را انجام داده باشید باید در تک تکِ اِلِمان‌ها رنگ را تغییر دهید که به احتمال بسیار زیاد اینکار با باگ‌هایی مواجه خواهد شد. اما اگر بر اساس SCSS استایل‌دهی را انجام داده باشید فقط کافیست رنگ متغیرتان را تغییر دهید تا این تغییر در همه‌ی اِلِمان‌ها اِعمال شود. ۲. زیبایی کدها با قابلیت Nesting :  آنچنان این ویژگی زیبا و لذت‌بخش هست که ترجیح میدم قبل از هر توضیحی ابتدا به کدهای زیر توجه کنـیــد :CSS :nav ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
nav li {
    display: inline-block;
}
nav a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
}SCSS :nav {
    ul {
        margin: 0;
        padding: 0;
        list-style: none;
    }
    li { display: inline-block; }
    a {
        display: block;
        padding: 6px 12px;
        text-decoration: none;
    }
}قابلیت تودرتویی (Nesting) در کم‌تر نوشتن کدها به شما کمک می‌کند. فرزند هر اِلِمان در توی اِلِمان پدر نوشته می‌شود، که خوانایی بالایی برای برنامه‌نویس ایجاد کرده و در یک کلام واقعا زیباست. ۳. کدنویسی هوشمندانه‌تر با استفاده از عملگرها :به کدهای زیر توجه کنید :CSS :.container {
    width: 100%;
}
article[role=&quot;main&quot;] {
    float: left;
    width: 62.5%;
}
aside[role=&quot;complementary&quot;] {
    float: right;
    width: 31.25%;
}SCSS :.container { width: 100%; }
article[role=&quot;main&quot;] {
    float: left;
    width: 600px / 960px * 100%;
}
aside[role=&quot;complementary&quot;] {
    float: right;
    width: 300px / 960px * 100%;
}در SCSS همانند اکثر زبان‌های برنامه‌نویسی می‌توان از عملگرهایی مثل جمع ، تفریق ، ضرب و تقسیم استفاده نمود. ۴. استایل‌دهی حرفه‌ای تر با Mixins :قابلیت جذاب و البته کاربردی دیگر در SCSS که شباهت زیادی به فانکشن‌ها دارند، Mixins ها هستند.CSS :.box {
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    -ms-border-radius: 10px;
    border-radius: 10px;
}SCSS :@mixin border-radius($radius) {
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    -ms-border-radius: $radius;
    border-radius: $radius;
}
.box { @include border-radius(10px); }همونطور که می‌بینید یکبار میکسینی رو تعریف می‌کنیم و می‌تونیم بارها از اون استفاده کنیم. این ویژگی SCSS هم در کمتر شدن حجم کدهایی که باید بنویسیم بسیار موثر هست. ۵. فانکشن‌ها :بله. ویژگی جذاب دیگر در SCSS فانکشن‌ها هستند.CSS :.container {
  width 100px;
}SCSS :@function add-padding($base-value, $coef) {
    @return $base-value * $coef
}
.container {
   width: add-padding(10px, 2)
}    همونطور که می‌بینید بین فانکشها و میکسینز شباهت زیادی وجود داره. تفاوت اصلی اونها در این هست که فانشکن‌ها مقداری رو به عنوان خروجی بازمی‌گردونن ولی میکسینز صرفا کدی رو در محلی که include می‌شه، برای ما جایگزین می‌کنه.فکر می‌کنم تا حد مناسبی آشنایی مقدماتی با SCSS پیدا کرده باشید. قابلیت‌های بسیار دیگر از جمله Extend ها، حلقه‌ها، عبارات شرطی و... در SCSS وجود دارند که خارج از بحث معرفی (که در این مقاله به اون پرداختم) وجود داره و شما با مراجعه به وب‌سایت رسمی scss-lang می‌تونید با اونها آشنا بشید.</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 29 Dec 2017 22:30:59 +0330</pubDate>
            </item>
                    <item>
                <title>کارهایی که دوستان موفقم کنار گذاشتند (بخش پایانی)</title>
                <link>https://virgool.io/@mehradsadeghi/things-my-successful-friends-gave-up-2-r5gyd9tmr7tr</link>
                <description>در بخش نخست از این مقاله به هشت نکته اشاره کردم، و بدون اتلاف وقت به بیان ادامه مطلب می‌پردازم.۹. عدم اعتماد به مردم را کنار گذاشتندشما نمی‌توانید رُم را بسازید اگر افرادی برای کار تیمی نداشته باشید. دوستان موفق من به مردم باور دارند و تیمشان را عاقلانه انتخاب می‌کنند. آنها استعدادهای خالص را کشف می‌کنند و عاشقانه آن را صیقل می‌دهند تا مانند یک الماس بدرخشد. دوستان موفق من می‌خواهند رهبران بیشتری خلق کنند، بجای آنکه تنها خودشان رهبری کنند.دوستان موفق من می‌توانند عیوب یک شخص را ببینند و نوری که به شدت در تلاش برای نمایان شدن در آنها وجود دارد را درک کنند. آنها عاشق کمک به انسان‌هایی هستند که تمایل به دگرگونی دارند، و بر این باورند که هر کسی می‌تواند موفق باشد.۱۰. افکار منفی را کنار گذاشتندجنگ جهانی سوم مانند جنگ‌های جهانی قبل در میدان جنگ رخ نداده؛ بلکه در اذهان ما رخ داده است - تیم دِنینگدوستان موفق من ذهنی اصول‌گرا و منظم دارند، که مرکز جهان آنهاست، و می‌دانند که شروع تمام موفقیت‌ها در این مکان اتفاق می‌افتد. آنها هر روز ذهنشان را تمرین می‌دهند تا از پاسخ‌های منفی‌گرایانه‌ی پیش‌فرض ذهن به امور مختلف جلوگیری کنند.بجای درگیر شدن، دوستان موفق من هرکاری می‌کنند تا از این دسته از افکار مانند ابرهایی گذران در آسمان، عبور کنند. آنها صرفا نظاره‌گرِ افکاری هستند که وارد ذهنشان می‌شود و تصمیم می‌گیرند که بر روی همان معدود افکار مثبتی که وارد ذهنشان شده تمرکز کنند.انرژی و افکار مثبت۱۱. مزخرفات را کنار گذاشتندزندگی پر از اتفاقات بی‌معناست. دوستان موفق من انتخابی هوشیارانه؛ در کنار گذاشتن این اتفاقات داشته‌اند. کارهایی که خدمتی به آنها نمی‌کند، مانند اخبار، را کنار گذاشته‌اند.موفق بودن در اینکه به مهملات اجازه ندهید مانع مسیرتان شوند، مرکزیت پیدا می‌کند. شما باید از ناملایمت‌هایی که در مسیرتان می‌بینید عبور کنید تا به شیرینی طلایی‌ای که مایه‌ی کامل شدن شماست، برسید.آستانه اهمیت دادن به ناخوشایندی‌ها را باید همیشه در حداقل ممکن نگاه دارید، تا موفق باشید.با مسائل بی‌‌ارزشِ زندگی خود یا دیگران کنار نیایید. این تغییر را برای زندگی بهتر در خود ایجاد کنید و کاری که افراد موفق توصیه می‌کنند را انجام دهید : یک عادت برای آنکه همیشه از مزخرفات دوری جویید در خود ایجاد کنید، تا به جزیره‌ی رویاها به نام مقصود برسید. این همان جزیره‌ایست که همه ما برای ادامه حیاتمان دوست داریم در آن زندگی کنیم.۱۲. مدام شکست خوردن را کنار گذاشتندشکست خوردن درسی ساده است که به شما نشان می‌دهد چه چیزی شما را موفق نخواهد کرد - تیم دِنینگدوستان موفق من اجازه نمی‌دهند شکست آنها را متوقف کند. شکست به دوستان موفق من چیزهایی که نمی‌دانستند را می‌آموزد. شکست مترادف با تحصیل است، بجای آنکه آن را یک تجربه منفی تلقی کنیم. ۱۳. مجرد ماندن را کنار گذاشتنددوستان موفق من فهمیدند که مجرد ماندن یک افسانه است. شریک زندگی آنها کسی‌ست که در تمام اوقات چالش‌برنگیز زندگی آنها را حمایت کرده است، و طبیعت موفق آنها را تقویت می‌نماید.دوستان موفق من می‌دانند که برای بازگشت به خانه، نیاز به یک همسر خوب دارند.دوستان موفق من می‌دانند که عشق چیزی‌ست که تمام ناراحتی‌های زندگی را، قابل تحمل می‌سازد.باید مراقب باشید که هدف از آمدنمان روی این کُره، یعنی عشق را فراموش نکنیم.۱۴. نقاب زدن را کنار گذاشتندبرعکس دیگران، دوستان موفق من نقاب‌ها را برداشته‌اند. آنها از آسیب‌پذیر بودن خوشحال‌ند و بیشترِ داستان‌های شخصی‌شان را بیان می‌کنند. تقلبی بودن برای آنها از بدترین جرم‌هاست.۱۵. اهمیت به نظر دیگران درباره‌شان را کنار گذاشتنددوستان موفق من هیچ اهمیتی به اینکه دیگران درباره‌شان چه نظری دارند نمی‌دهند. آنها در تلاش برای تحت تاثیر قرار دادن دیگران نسبت به خودشان نیستند. به همین دلیل ترسی از شکست خوردن ندارند.۱۶. تسلیم شدن را کنار گذاشتنددوستان موفق من دریافتند که نمی‌توان سه ماه روی موضوعی کار کرد و بعد گفت من به اندازه کافی جذب اینکار نشدم و از ادامه آن انصراف می‌دهم.دوستان موفق من اهل انصراف دادن نیستند. آنها تمام سختی‌ها و درگیری‌ها را به جان می‌خرند تا عنوان &quot;موفق&quot; را بدست آورند. چنین چیزی به راحتی بدست نمی‌آید. آنها این مورد را بیش از دیگر مواردی که در پیش اشاره کردم انجام می‌دهند، یعنی &quot;تسلیم نمی‌شوند&quot;.انصراف یه گزینه برای آنها نیست و اجازه می‌دهند شور و عشقی که دارند تمام موانع را از پیش‌رو بردارد. آنها دیوانه‌وار تلاش می‌کنند تا شکست نخورند، و هیچ چیز نمی‌تواند مانع آنها شود.آیا شما می‌توانید خود را با این طرز تفکر سازگار کنید و به دوستان موفق خود ملحق شوید... ؟نویسنده : Tim Denningترجمه از مهراد</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 22 Dec 2017 21:13:28 +0330</pubDate>
            </item>
                    <item>
                <title>کارهایی که دوستان موفقم کنار گذاشتند (بخش نخست)</title>
                <link>https://virgool.io/@mehradsadeghi/things-my-successful-friends-gave-up-y2si5yaka564</link>
                <description>یک لحظه بنشینید و به کارهایی که دوستان موفقتان در مقایسه با دوستان همیشه نالان و ناکامتان انجام می‌دهند، فکر کنید. اگر دوست موفقی ندارید، به نکاتی که با شما به اشتراک می‌گذارم توجه کنید.دوستان موفق شما متفاوت می‌اندیشند، متفاوت صحبت می‌کنند، و ده برابر سخت‌تر از دوستان ناکام شما کار می‌کنند. موفقیت ساده‌تر از آن چیزی‌ست که فکرش را می‌‌کنید، اما باید اشخاص صحیح را الگوی خود قرار دهید. دوستان مغلوب شما کسانی هستند که ذهن شما را با دروغ تغذیه می‌کنند.آنها به شما می‌گویند که نمی‌توانید (فلان کار را) انجام دهید، خیلی سخت است، یا اینکار هیچ معنی و منطقی ندارد. به دوستان موفقتان گوش بسپارید.یک‌بار برای همیشه از دوستان ناکامتان طلاق بگیرید. سرنوشت شما انجام کارهای بزرگ است.و اما کارهایی که دوستان موفق من کنار گذاشتند :۱. باور به اینکه نمی‌توانند دنیا را متحول سازند را کنار گذاشتنددوستان موفق من معتقدند که مهم نیست کجا به دنیا آمده‌اید، چقدر تحصیلات دارید، یا با چقدر پول شروع کرده‌اید. موفقیت در باور در توانایی شما بر اینکه می‌توانید دنیا را تغییر دهید، نهفته است. همه ما قدرت انجام کارهای باورنکردنی و شگفت‌انگیز را داریم.ما به این نیاز نداریم که به ما بگویند ارزشش را داریم، یا لیاقت شگفت‌انگیز بودن را داریم یا نه. دوستان موفق من اجازه می‌دهند باور درونیشان آنها را به سمت دیدگاهی برای داشتن دنیایی بهتر هدایت کند. دوستان موفق من باور دارند که می‌توانند بخشی از تغییرات مثبتی باشند که در نهایت باعث ارتقاء بشریت به سطح بالاتری می‌شود.۲. تکیه بر شانس را کنار گذاشتندشانس موضوعی برای آماده شدن در مواجه با فرصت‌هاست - اُپرا وینفرِیشانس بی‌پرده افسانه‌ای بیش نیست. دوستان موفق من اعتقاد به شانس را مدت‌هاست که کنار گذاشته‌اند و آن را با تلاش جایگزین کرده‌اند.دست‌به‌کار شو و منتظر زمان مناسب نباش؛ چراکه هیچگاه زمانی مناسب برای انجام کاری نیست. تو مسئول موفقیت خود هستی. شانس و بخت‌آزمایی نمی‌توانند تو را موفق و ثروتمند کنند، اما ذهنت می‌تواند.۳. خاراندن زخم‌ها را کنار گذاشتنددوستان موفق من به دنبال فرار از ناخوشایندی‌ها نیستند، در عوض وقتی با مشکلی روبرو می‌شوند مانند بولدوزِر به دل آن هجوم می‌آورند، و بجای آنکه با دوستان ناکام خود به عیاشی بپردازند، مشغول چیدن ستاره‌ها، متناسب با اهداف و دیدگاه‌هایشان می‌شوند.آنها از دنیا ناامید نمی‌شوند، بلکه بر روی اینکه چقدر برای محقق شدن رویاهایشان باید سخت‌تر تلاش کنند تمرکز می‌کنند. بجای آنکه ناکامی‌هایشان را با خاراندن زخم‌هایشان فراموش کنند، زخم‌ها را رها می‌کنند تا رنج آن در ذهنشان حک شود و مطمئن شوند که درس‌های لازم را از آن گرفته‌اند.۴. افراد منفی‌گرا را کنار گذاشتندبیش از هرچیز، دوستان موفق من دوستان ناکامشان را کنار گذاشته‌اند. آنها دیگر نمی‌نشینند و به حرف کسانی که در هیچ موردی ایده‌ای ندارند گوش نمی‌دهند.دوستان موفق من از دوستان مغلوب خود دوری می‌جویند و با آنها به گونه‌ای رفتار می‌کنند که گویی بیماری مالاریا دارند.تنها زمانی دوستان موفق من وقت خود را با دوستان نامکشان می‌گذرانند که بدانند آنها برای تغییر اوضاعِ زندگیشان تصمیم جدی گرفته‌اند، نسبت به تصمیمشان متعهد هستند و درخواست یاری کرده‌اند. دوستان موفق من به کمک به دیگران و به اشتراک‌گذاری تجربیاتشان معتقد هستند.اجازه ندهید اشخاص منفی‌گرا به شما بگویند که دنیا چگونه است. خودتان آن را کشف کنید.هر قطعه از نقشه‌ای که راه زندگی را به شما نشان می‌دهد را از دوستان موفق خود بگیرید، دانسته‌های آنها را باهم ترکیب کنید، از منابع، درست استفاده کنید، و درنهایت برنامه‌‌‌هایتان را اجرایی کنید.۵. هدر دادن زمان را کنار گذاشتندکار امروز را به فردا انداختن چیزی‌ست که دوستان موفق من واقعا در انجام آن بد هستند. آنها به چیزی که می‌توانند بدست آورند ایمان دارند و برای رسیدن به هدفشان دست به‌کار می‌شوند. آنها طوری با زندگی برخورد می‌کنند که انگار تک تک لحظات آن ارزشمند است، و نمی‌خواهند حتی یک ثانیه را از دست بدهند.زمانی‌که دوستان موفق من پیر می‌شوند و مویشان سپید گشته، می‌خواهند به زمانی که در زندگی سپری کرده‌اند افتخار کنند. در حالت ایده‌آل می‌خواهند در دنیا تغییر مهمی ایجاد کرده باشند. آنها می‌خواهند زمانی‌که وارد اتاقی می‌شوند، به‌خاطر راه و روشی که در زندگی‌شان برگزیده‌اند تشویق شوند.۶. مصرف‌گرایی را کنار گذاشتندبجای آنکه کل روز را صرف تماشای ویدئو در یوتیوب کنند، دوستان موفق من خلق کردن را جایگزینِ مصرف‌گرایی کرده‌اند. آنها بجای آنکه وقتشان را صرف نشستن و تماشای موفقیت دیگران کنند، تاجایی‌که زمان دارند، وقتشان را صرف انجام آنچه باید انجام شود می‌کنند.به عنوان یک قانون بیش از ۵۰ درصد از زمان خود را برای خلق چیزهای جدید، و بقیه را صرف مصرف‌گرایی بکنید.۷. خودخواهی را کنار گذاشتنددوستان موفق من، دیدگاه، خانواده و اهدافشان را نسبت به هر امر دیگری در اولویت قرار می‌دهند. همچنین آنها به‌شدت بر خدمت به دیگران تمرکز دارند. به عبارتی ساده : فقط برای خودشان زندگی نمی‌کنند.۸. هدر دادن پول را کنار گذاشتندپول یکی از تفاوت‌های کلیدی‌ست. اشخاص موفق بخش اعظمی از درآمدشان را سرمایه‌گذاری می‌کنند.نویسنده : Tim Denningترجمه از مهراد</description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Fri, 22 Dec 2017 03:55:06 +0330</pubDate>
            </item>
                    <item>
                <title>چرا لاراول یک فریم‌ورک مبتنی بر MVC نیست ، و باید MVC را فراموش کنید !</title>
                <link>https://virgool.io/laravel-community/is-laravel-based-on-mvc-or-not-zcg2jxt1e4to</link>
                <description>در نیمه دوم سال 2017 قرار داریم ، و بسیاری اصرار بر پیاده‌سازی الگوی MVC در فریم‌ورک‌هایی همچون لاراول یا سیمفونی دارند ، درحالیکه اینها فریم‌ورک‌های مبتنی بر MVC نیستند (منظور MVC خالص است) . اما پیش از ورود به این مساله اجازه دهید که یکبار برای همیشه ببینیم MVC چیست.آشنایی با MVC :رینسکاگ (Trygve Reenskaug) مدل MVC را در اواخر دهه هفتاد میلادی به منظور توسعه بیشتر Smalltakl-80 (یک زبان برنامه نویسی مبتنی بر شی‌ گرایی) اختراع کرد.ایده و هدف این الگو ، استفاده در کامپوننت‌های کوچک بود.یک CheckBox را تصور کنید ؛این CheckBox دارای :یک مدل (model) : که مسئول ذخیره اطلاعات است ، در این مثال CheckBox یا تیک دارد یا ندارد.یک ویو (view) : که نمایش گرافیکی CheckBox را بر عهده دارد. این ویو به اطلاعات مدل برای اینکه بداند چطور نمایش داده شود نیاز دارد. همینطور کاربر برنامه را از طریق ویو می‌تواند ببیند.یک کنترلر (controller) : که عمل کاربر را مورد بررسی قرار می‌دهد (مثلا کاربر تیک CheckBox را می‌زند) و model را آپدیت می‌کند.زمانی که تغییرات در مدل رخ داد ، ویو آپدیت می‌شود. ساختار سه لایه‌ی MVC  در اینجا می‌توانید رابطه بین این سه لایه را ببینید. اما مورد مهمتر این است که کاربر چطور اطلاعات را از ویو می‌گیرد و اعمال وی بوسیله کنترلر مورد پردازش قرار می‌گیرد.به همین دلیل سال‌ها پیش درک MVC برای من سخت بود ، زیرا : MVC برای نمایش کامپوننت‌های کوچک طراحی شده بود ، نه برای نرم افزارهای مدرن تحت وب.  حیات MVC در عصر حاضر امروزه برای توسعه موفقیت‌آمیز نرم‌افزارهای تحت وب ، به لایه‌های بیشتری نیاز داریم. به عنوان نمونه در MVC :روشی برای فهماندن روت‌ها (routes) که وظیفه بررسی URL ها و اختصاص آن به متدها و فانکشن‌‌‌ها را دارند ، را نداریم.راهی برای نمایش برنامه‌های میانی (middleware) که وظیفه محدوده کردن قسمتی مشخص از برنامه بر اساس وضعیت کاربر را دارند ، را نداریم.یک برنامه مدرن برای نمایش اطلاعات به چیزی بیش از مدل (model) نیاز دارد.  فکر میکنم به همین دلیل در ویکی‌پدیا ، هرچقدر که بخش‌های مختلف وب تغییر میکرد ، مفاهیم MVC نیز تغییر کرده است ؛ که این تغییرات نیازهای نرم‌افزارهای مدرن را منعکس می‌کنند.  بطور مثال در ویکی پدیا گفته شده که یک مدل : مستقیما وظیفه اداره کردن اطلاعات ، منطق و قوانین (اصول) برنامه را بر عهده دارد. ویو : خروجی یا گرافیک مربوط به نمایش اطلاعات است. کنترلر : یک ورودی را می‌پذیرد و آن را به دستوراتی برای مدل و ویو تبدیل می‌کند.این مفاهیم خیلی کلی (عمومی) هستند ، و ابزار لازم برای ساخت نرم افزارهای پیشفرته را به شما نمی‌دهند.به عنوان مثال ، اکثریت معتقدند Model همان دیتابیس است ، اما 90 درصد نرم افزارها به &quot;منطق&quot; بیشتر از ذخیره اطلاعات نیاز دارند.همانطور که Taylor Otwell (خالق Laravel) اشاره می‌کند : توئیت Taylor Otwell در توئیتر هیچ راهی برای گنجاندن تمام جنبه‌های یک نرم‌افزار غول‌پیکر در آن سه لایه وجود ندارد. به همین دلیل فریم‌ورک‌هایی مثل لاراول یا سیمفونی MVC نیستند. لاراول فریم‌ورک مبتنی بر MVC نیستدر سوالی که مستقیما از Taylor Otwell در این مورد پرسیده شد :پاسخ خالق لاراول به این سوال که آیا لاراول یک فریم ورک مبتنی بر MVC است یا نه گرچه در نسخه چهارم لاراول سه پوشه معروف controller ، models ، views مشاهده می‌شود ، ولی در نسخه پنجم این فریم ورک :فولدری با نام models دیگر وجود ندارد. به جای آن پوشه app قرار گرفته که می‌توانید نرم افزار خود را در آن ساختار ببخشید.پوشه Controllers قسمت کوچکی از لایه Http است. همینطور در این لایه Middleware ها نیز وجود دارند. در پوشه Requests نیز روت‌ها قابل دسترسی هستند.پوشه views نیز به بخشی از پوشه resources تبدیل شده است.در پوشه app ، لایه‌هایی چون Events ، Listeners ، Exceptions ، Jobs و ... نیز وجود دارد. همانطور که میبینید ، با اینکه از Models ، Views و Controllers استفاده می‌شود ، اما ساختار لاراول MVC نیست ، زیرا به لایه‌های بیشتری برای سازماندهی تمام ابعاد خاص نرم افزار شما نیاز دارد.  ادامه به استفاده از MVC  و مقاومت در برابر تغییررابرت مارتین - مهندس نرم‌افزارساختار  MVC یک معماری (در نرم‌افزار) نیست  به ناگهان خود را در میان اقیانوسی می‌یابی، به شدت سردت شده و در حال غرق شدن هستی که تکه چوبی شناور در کنار خود می‌بینی. چه می‌کنی ؟ به آن میچسبی تا چند دقیقه بیشتر زنده بمانی.اقیانوس همان &quot;وب&quot; است ، تکه چوب همان MVC ، و برنامه شما شناور است.MVC به شما اجازه می‌دهد که نرم افزارتان را بسازید ، درست مانند آن تکه چوب که به شناور ماندن شما کمک می‌کرد. اما واقعا MVC برای چنین کاری (توسعه نرم افزارها و وب سایت های بزرگ) ساخته شده است ؟ نه ؟ پس چرا از آن استفاده می‌کنید ؟امروزه به چه چیزی برای ساخت نرم‌افزارهای تحت وب نیاز است ؟طبق گفته Taylor Otwell :   هیچگاه یک &quot;معماری‌&quot; شگفت‌انگیز برای توسعه وب ندیده‌‌ام. صرفا نرم‌افزارهایتان را به روشی معقول بسازید. متاسفانه برای نرم‌افزارهای مختلف ، یک روش مشخص وجود ندارد. شما باید بر اساس نیازهای نرم افزارتان ، یعنی اینکه به ریپازیتوری نیاز دارد یا نه ، به middleware نیاز دارد یا نه ، به interface ها نیاز دارد یا نه و... روش مناسب را انتخاب کنید. نویسنده :‌ Kali Dass ترجمه از مهراد </description>
                <category>مهراد صادقی</category>
                <author>مهراد صادقی</author>
                <pubDate>Thu, 21 Dec 2017 04:44:05 +0330</pubDate>
            </item>
            </channel>
</rss>