<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های vahiiiid</title>
        <link>https://virgool.io/feed/@vahiiiid</link>
        <description>Web Developer</description>
        <language>fa</language>
        <pubDate>2026-04-15 02:53:23</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/22361/avatar/bfcqv3.jpeg?height=120&amp;width=120</url>
            <title>vahiiiid</title>
            <link>https://virgool.io/@vahiiiid</link>
        </image>

                    <item>
                <title>کدوم برنامه نویس ها روی پروژمون بیشتر کامیت داشتند؟</title>
                <link>https://virgool.io/@vahiiiid/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%A8%D8%A8%DB%8C%D9%86%DB%8C%D9%85-%DA%A9%D8%AF%D9%88%D9%85-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-%D9%87%D8%A7-%D8%B1%D9%88%DB%8C-%D9%BE%D8%B1%D9%88%DA%98%D9%85%D9%88%D9%86-%D8%A8%DB%8C%D8%B4%D8%AA%D8%B1-%DA%A9%D8%A7%D9%85%DB%8C%D8%AA-%D8%AF%D8%A7%D8%B4%D8%AA%D9%86%D8%AF-hfpy2rxmtgh7</link>
                <description>مقایسه میزان کامیت های برنامه نویس های یک پروژهتا حالا شده به این فکر کنید که کدوم برنامه نویس ها تا حالا روی پروژه ای که روی اون کد میزنید کد زدند؟یا اینکه هر برنامه نویس چه قدر تا به حال روی پروژه کد زده و کدوم برنامه نویس بیشتر تاحالا commit داشته؟گیت یک کامند برای این سوال ها داره که shortlog هست:git shortlogاجرای این کامند بدون option اسم برنامه نویس، تعداد کل commit  و commit message رو چاپ میکنه.کی بیشترین کامیت رو داشته؟حالا اگر بخواهیم به صورت descending بر اساس تعداد commit و به صورت خلاصه فقط تعداد commit و ایمیل و اسم هر برنامه نویس رو ببینیم با ۳ تا option زیر اجرا میکنیم:git shortlog -nseبا زدن این کامند شما  دارید مشاهده میکنید که به ترتیب کدوم برنامه نویس ها بیشترین commit رو در پروژه شما از روز اول داشتندممکن هست هر برنامه نویس در طی مدتی که روی پروژه کار کرده روی چند تا سیستم عامل commit زده و مثلا کانفیگ هایی که داشته متفاوت بوده پس  براساس متفاوت بودن اسم و ایمیلی که توی کانفیگ گیت وارد کرده بوده تمام commit هاش باهم جمع نمیشوند که با نگاه کردن به لیست خروجی این کامند خودتون متوجه قضیه خواهید شد. مثلا یک برنامه نویسی به اسم Vahiiiid شاید 100 تا commit با ایمیل A و ۲۰۰ تا commit با همین اسم ولی  ایمیل ‌B  داشته باشه.در این اسپرینت یا در یک بازه زمانی هر برنامه نویس چقدر کامیت داشته؟کافیه از option هایی که برای فیلتر زمان گیت روی کامند هاش داره استفاده کنید مثلا در ۴ هفته اخیر چقدر commit هر شخصی داشته است:git shortlog -nse --after=&amp;quot4 weeks ago&amp;quot
git shortlog -nse --before=&amp;quot2021-09-01&amp;quot --after=&amp;quot2021-08-01&amp;quotاولین کامیت های پروژه چی بوده و کی زده؟شاید اگر در یک پروژه ای مشغول کار هستید که چند سالی از شروع نوشتن و نگه داریش میگذره و اسم آدم های مختلفی رو شنیدید، بخواهید بدونید پروژه دقیقا چه روزی شروع شده، چه کسی و چه commit هایی رو برای اولین بار زدند: git log  --reverseبعد از دستور بالا میتونید hash commit اول رو بردارید و با دستور های زیر کل فایل های اون commit رو ببینید و تفاوتشون رو هم متوجه بشید:git ls-files &lt;commit-id&gt; 
git show &lt;commit-id&gt;همون طور که همه میدونیم تعداد commit بالا صرفا مشخص نمیکنه که یک شخصی بیشتر کار کرده یا  در یک بازه زمانی یکسان برنامه نویس بهتری بوده و این زمانی بیشتر نمود پیدا میکنه که معمولا تیم ها convention برای اینکه چه زمانی یک commit جدید بزنند ندارند.زدن commit برای هر تغییر فایل یا زدن تنها یک commit برای یک فیچر بزرگ هر دو bad practice هستند و این موارد میتونه به همراه خیلی چیزهای دیگه مثل commit message درست گذاشتن از طریق تعریف یک team convention طبق best practice های موجود حل بشه.من قصد دارم یک سری پست در مورد گیت توی ویرگول و سایت شخصیم بزارم اگر این پست براتون مفید بود لطفا لایک کنید تا بدونم باید ادامه بدم.</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Thu, 09 Sep 2021 18:02:51 +0430</pubDate>
            </item>
                    <item>
                <title>بهترین روش استفاده از الستیک سرچ در لاراول؟</title>
                <link>https://virgool.io/@vahiiiid/%D8%A8%D9%87%D8%AA%D8%B1%DB%8C%D9%86-%D8%B1%D9%88%D8%B4-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D8%A7%D9%84%D8%B3%D8%AA%DB%8C%DA%A9-%D8%B3%D8%B1%DA%86-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-ncuxvjeilqcl</link>
                <description>معرفی ۳ روش استفاده از elastic search در پروژه های laravelتا به حال پروژه ی لاراول خودتون رو به الستیک سرچ متصل کردید؟ اگر نه، باید بدونید روش های مختلفی برای این کار وجود داره و اگر آره شاید روش شما روش مناسبی نیست!در ادامه پست باهم ۳ روش استفاده از الستیک سرچ رو می بینیم!اما ابتدا برای کسایی که از الستیک سرچ استفاده نکردند و نمیدونند که اصلا به اون نیاز دارند یا نه و یا فکر میکنند که یادگیری الستیک سرچ خیلی چیز جدید و ترسناکی هست باید یه سری مطالب رو بگم.تعریف elastic searchElasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.خوب به زبان ساده یعنی یک پروژه ای هست که دیتا های شما رو تحت عنوان داکیومنت داخل یک سری ایندکس روی RAM نگه میداره و از طریق  api هایی که در اختیار شما قرار میده اجازه میده که با استفاده از سینتکس json روی اون ها کوئری بزنید و خیلی خیلی سریع و در حد real time دیتا ها رو بازیابی کنید.چه استفاده هایی میتونه داشته باشه؟هرجایی که نیاز دارید با حجم زیادی از داده کار کنید و اقدام به ذخیره سازی اونها کنید و برای شما پردازش اون داده مثلا برای نمایش نمودارها و گزارش های مختلف یا سرچ های خیلی سریع و پیچیده مهم بود الستیک سرچ میتونه کاربرد داشته باشه.چه چالش هایی معمولا برای استفاده از Elastic Search وجود داره؟زمانی که تصمیم گرفتیم با توجه به نیاز پیش اومده از الستیک سرچ استفاده کنیم کلی سوال و چالش مطرح میشه!چه دیتا هایی رو روی الستیک سرچ نگه دارم؟دیتا ها رو روی دیتابیس دیگری هم نگه دارم یا فقط الستیک سرچ؟چطوی دیتا رو بین دیتابیس اصلی و الستیک سرچ با تغییرات لحظه ای سینک نگه دارم؟اگر تغییرات دیتا ها زیاد بود ارتباط بین سرویس و الستیک سرچ به چه صورتی باشه که به مشکل نخورم؟چطوری به الستیک سرچ متصل بشم و api ها رو صدا بزنم؟کوئری های الستیک سرچ رو که به صورت json هست چطوری و کجای پروژه بسازم که نگه داریش راحت باشه؟آیا راهی وجود داره که این کوئری های بعضا زیاد و تودر تو رو داخل کد نداشته باشیم؟وکلی سوالی و چالش دیگه ...ما به طور خاص قصد داریم با بررسی چند روش و مقایسه اونها باهم این چالش ها رو تا حدی برطرف کنیم :)چطوری Laravel رو به Elastic Search متصل کنم؟ ۳ روش رو برای اتصال به الستیک سرچ در مجموع میشه استفاده کرد:روش Low Level Client: ساده ترین روش اتصال به الستیک سرچ که در تمام پروژه های پی اچ پی میشه استفاده کرد روش Low Level Client هست. توی این روش میشه با استفاده از composer اقدام به نصب پکیج official خود elastic برای php  کرد و یا از پکیج Elastica استفاده کنیم و صرفا صدا زدن api های الستیکمون رو از طریق اون انجام بدیم و با دانش خودمون از الستیک سرچ باید اقدام به نوشتن انواع کوئری های لازم برای انجام عملیات CRUD روی ایندکس هامون کنیم.روش High Level Client:همونطوری که مشخص هست نسبت به روش قبلی برتری داره و اون این هستش که دیگه نیاز نیست خودمون با استفاده از آرایه های تو در توی پی اچ پی و تبدیل اون به json اقدام به کوئری نویسی کنیم و این کار از طریق پکیج هایی که نصب کردیم و استفاده میکنیم انجام میشه. اما چطوری؟به سادگی استفاده از Model های لاراول و متدهای Eloquent میتونید به همون صورت اقدام به انجام عملیات های مختلف روی ایندکس و داکیومنت های خودتون کنید و یا از کامند های لاراولی پکیج استفاده کنید.روش Laravel Scout:این روش که استفاده از پکیج Scout هست علاوه بر مزیت های روش High Level Client به ما این امکان رو میده که  با انجام یک سری کانفیگ ها و یک سری optimization هایی که انجام میدیم  اقدام به automatic کردن sync بودن داکیومنت های خودمون کنیم!اما باید بدونیم که Scout به صورت پیش فرض برای Algolia نوشته شده و باید از driver دیگه ای که برای Elastic Search هست استفاده کنیم.معرفی دوره استفاده از الستیک سرچ در لاراول https://itsalireza.com/product/%D9%81%DB%8C%D9%84%D9%85-%D8%A7%D9%85%D9%88%D8%B2%D8%B4%DB%8C-%D8%A7%D9%84%D8%B3%D8%AA%DB%8C%DA%A9-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84/?utm_source=virgool&amp;utm_medium=referral&amp;utm_campaign=content_virgool مطالبی که در بالا گفته شد بخشی از دوره استفاده از الستیک سرچ در لاراول هستش که توی اون سعی شده ضمن معرفی ELK Stack اقدام به بررسی، نصب و استفاده از روش های مختلف کنیم که در این پست به اونها اشاره کردیم.هر کدوم از روش ها ابتدا معرفی و بعد از نصب و کانفیگ اونها از امکانات اصلی هر کدوم به صورت عملی توی لاراول استفاده میشه و باهم خروجی ها رو توی Kibana هم میبینیم و در پایان با توجه به نیاز پروژه خودتون می تونید از هرکدوم استفاده کیند.پیش نیاز دوره دانش کمی از لاراول هست و حتی بدون آشنایی با الستیک سرچ با توجه به روشی که گفته میشه و  مثال هایی که زده میشه می تونید کارهای مقدماتی اون مثل ساخت ایندکس، Sync نگه داشتن داکیومنت ها، CRUD روی اون ها  و جستجو های ابتدایی رو انجام بدید.ویدیو معرفی دوره استفاده از الستیک سرچ در لاراول https://aparat.com/v/3Sevd در آخر هم دمتون گرم که این پست رو خوندید دوستان:)امیدوارم مفید بوده باشه</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Fri, 16 Apr 2021 14:41:46 +0430</pubDate>
            </item>
                    <item>
                <title>برای ورژن ۶ لاراول آماده شوید!</title>
                <link>https://virgool.io/laravel-community/%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D9%88-%D9%BE%D8%B1%D8%B4-%DB%8C%DB%8C%D9%87%D9%88%DB%8C%DB%8C-%D8%A8%D9%87-%D9%88%D8%B1%DA%98%D9%86-%DB%B6-vu0soxznhwgi</link>
                <description>به زودی شاهد ورژن ۶ خواهیم بود ;) اگر منتظر بودید یا بودیم که ورژن 5.9 لاراول تا سه هفته دیگه به دستمون برسه و بعد از 5.5  یک ورژن جدید ‌LTS داشته باشیم، این انتظار سرانجام نداره !!!! چون لاراول داره میره روی ورژن ۶. آخه چرا؟؟؟؟الگوی فعلی ورژن دهی لاراول چطوری هست؟ورژن بندی لاراول بعد از سال ۲۰۱۳ تا امروز به این صورت بود:                                                                paradigm.major.minorطبق این الگو هر ۶ ماه یعنی ماه های ۲ و ۸ میلادی یک نسخه major ارائه می شد مثل لاراول ۵.۶ ، ۵.۷ یا آخرین اونها یعنی ۵.۸. این نسخه ها دارای تغییراتی بودند که برای ارتقا به اونها از نسخه های قدیمی می بایست upgrade note رو می خوندیم و از breaking changes ها مطلع می شدیم. اما تقریبا هر هفته هم یک نسخه minor داده می شد که ‌breaking changes نداشتند و با خیال راحت آپدیت می کردیم و بعضی از باگ های فریمورک رو رفع می کرد آخرین نسخه minor هم از ۵.۸.۲۹ به ۵.۸.۳۰ بود.هم چنین هر ۲ سال هم یک نسخه LTS داشتیم مثل ۵.۱ ، ۵.۵ و البته ۵.۹ که هیچ وقت release نمیشه!تاریخچه ورژن های لاراول رو می تونیم اینجا ببینیم:تاریخچه ورژن های لاراولچه ویژگی جدیدی در ورژن ۶ قراره داشته باشیم؟اتفاق جدیدی که قرار هست تا ۳ هفته دیگه برای اولین بار در کنفرانس آمستردام laraconf بیفته مربوط به نسخه paradigm میشه.لاراول زمانی نسخه paradigm رو جا به جا می کنه که یک paradigm shifting اتفاق بیفته یعنی تغییراتی در architecture و یا  conventions که این اتفاق از ورژن ۴ به ۵ انجام شد و همان طور که به یاد دارید تغییرات مهمی در ساختار لاراول ایجاد شد.در این ۴ سال هیچ نسخه paradigm از لاراول روی github در حال توسعه نبود و هیچ توضیحی هم در مورد تغییرات احتمالی ورژن ۶ داده نشده بود و الان که همه منتظر نسخه ۵.۹ بودیم ظاهرا تا ۳ هفته دیگه و بعد از کنفرانس آمستردام نسخه ۶ رو خواهیم داشت اون هم بدون هیچ paradigm shifting روی کد ها!!!پس چرا داره ورژن paradigm رو بالا میبره؟دلیل اینکه لاراول داره میره روی ورژن ۶ دقیقا همین سیستم ورژن دهی خودش هست!! قرار هست به زودی لاراول هم مثل اکثر فریمورک ها و نرم افزار های مطرح دیگه مثل react از روش استاندارد ورژن دهی SemVer استفاده کنه پس با این تغییر لاراول داره میره روی ورژن ۶.اگر علاقه دارید می توانید روش ورژن دهی semantic versioning رو مشاهده کنید این نوع ورژن دهی باعث میشه که با سرعت بیشتری یک نسخه به این صورت داشته باشیم ۷.۰.۰  ، ۸.۰.۰ ، ۹.۰.۰ و ....البته باید صبر کنیم تا بعد از 30 آگوست که کنفرانس ۲ روزه تموم بشه و همه چیز مشخص بشه. ( اگر پولتون میرسه میتونید با ۷۵۰ یورو با مالیات تو کنفرانس شرکت کنید ;) )این جواب taylor otwell توی توییتر در مورد ورژن دهی جدید هست که میگه هر ۶ ماه یه ورژن major خواهیم داشت!!! (عدد کم نیاریم خوبه :دی)شاید semver باعث بشه نگهداری از package هایی که برای لاراول نوشته میشه راحت تر بشه! چون هر ورژن major جدید یعنی دیگه با api های ورژن قبل compatible نیست!البته همراه با ورژن ۶ لاراول از وب سایت جدیدش به علاوه لوگو جدید و هم چنین vapor رونمایی می کنه که باید جالب باشه :)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Mon, 05 Aug 2019 12:46:25 +0430</pubDate>
            </item>
                    <item>
                <title>از static method در کلاس های js استفاده می کنید؟</title>
                <link>https://virgool.io/@vahiiiid/%D8%A7%D8%B2-static-method-%D8%AF%D8%B1-%DA%A9%D9%84%D8%A7%D8%B3-%D9%87%D8%A7%DB%8C-js-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D9%85%DB%8C-%DA%A9%D9%86%DB%8C%D8%AF-kjv11legljse</link>
                <description>javascript static method توی این پست یه توضیح سریع از static method در جاوا اسکریپت و موارد کاربرد اون رو با هم می بینیم.روش تعریف و استفاده از static method که در ES6 اضافه شده در کد زیر اومده است تا خیلی زود بریم سر اصل مطلب:نحوه صدا زدن متد static در جاوا اسکریپت  همان طور که در کد بالا مشخص هست کافیه  بااستفاده از کلمه static اون رو داخل class تعریف کنیم و به روش زیر هم می تواند صدا زده شود:نحوه صدا زدن متد static در جاوا اسکریپتخوب نکته ی مهم در اینه که متد static برای صدا زده شدن نیاز به ساخت شی از کلاس ندارد و اصلا نباید از روی شی صدا زده شود! چون اون متد رو شناسایی نمیکنه و خطا میخوریم!پس باید به صورتی که در کد مشاهده می کنید از اون استفاده کنیم و صدا زدن static method ها از روی خود کلاس امکان پذیر هست.اگر به صورت دقیق تر بخواهیم بررسی کنیم در واقع متد از نوع static به prototype کلاس شما اضافه نمیشه و می تونید با بررسی proto شی ساخته شده مطمئن شوید که متد static رو نمی بینید چون این متد به کلاس شما اضافه شده است نه به prototype کلاس پس نمیتونیم از طریق شی صدا بزنیمش.نکته ی مهم جملات بالا !همان طور که متوجه شدید داخل متد static ما به صفات شی دسترسی نداریم! و نباید از اونها استفاده کنیم.بنابراین فرض کنیم اگر یک property داخل کلاس خودمون به اسم name داشته باشیم و داخل متد static اون رو به صورت this.name صدا بزنیم مقدار undefined می گیریم!!اما چگونه داخل متد های دیگر static method رو صدا بزنیم؟نحوه ی صدا زدن static method از توابع دیگر کلاس صدا زدن متدهای static از توابع دیگر با استفاده از this.staticClassName امکان پذیر نیست بلکه باید همان طور که در کد بالا مشاهده می کنیم از this.constructor استفاده کنیم.موارد کاربرد static method ها در جاوا اسکریپتاگر به سورس کد های مهم نگاه بندازیم می بینیم که بیشترین استفاده از static method ها به عنوان توابع helper هست. در مواردی نیز به عنوان جایگزینی برای constructor ها می توانند استفاده شوند مثلا زمانی که قصد ساخت یک شی از کلاسی رو دارید.برای مثال کد زیر رو نگاه کنید که از static method به عنوان یک helper برای مقایسه ۲ تا شی از همان کلاس استفاده کرده است:استفاده از static method به عنوان helper نوشتن متد static برای مقایسه object ها یکی از موارد مرسوم هست به این دلیل که ما در کلاس خودمون به متدی نیاز داریم که صرفا برای صفات شی خاصی نیست از طرفی به صورت کلی تر می خواهیم کد هایی رو در یک wrapper و مربوط به همین کلاس داشته باشیم پس در این مورد و موارد مشابه static method ها می تونند راهگشا باشند.مثال دیگری رو ببینیم که به عنوان جایگزین constructor می تونیم از متد static استفاده کنیم:ساخت شی از کلاس با استفاده از static method استفاده از static method در این کد به ما این امکان را داده است که اگر نخواستیم یک article با عنوان مشخص و تاریخ ایجاد کنیم از طریق متد createTodays یک article به تاریخ امروز و بدون عنوان ایجاد کنیم.خوب در این پست نحوه ی تعریف و استفاده از متد های static در جاوا اسکریپت رو دیدیم و برای موارد بیشتر می تونید لینک زیر رو مشاهده کنید: https://javascript.info/static-properties-methods </description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Wed, 31 Jul 2019 16:54:43 +0430</pubDate>
            </item>
                    <item>
                <title>هر آنچه که باید از Redis بدونیم (۲)</title>
                <link>https://virgool.io/@vahiiiid/%D9%87%D8%B1-%D8%A2%D9%86%DA%86%D9%87-%DA%A9%D9%87-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A7%D8%B2-redis-%D8%A8%D8%AF%D9%88%D9%86%DB%8C%D9%85-%DB%B2-wrmx75wmidv5</link>
                <description>Redis data types در قسمت قبلی این سری آموزشی با Redis آشنا شدیم، در این قسمت می خواهیم انواع data type های Redis رو باهم ببینیم و البته دستورات مهم هر کدوم رو بررسی کنیم. همان طور که در پست قبل گفته شد داشتن Data Type  های مختلف یکی از مهمترین و متمایز ترین ویژگی های Redis می باشد و یادگیری اون ها یک جوری یادگیری عملی Redis هست پس امیدوارم در پایان این پست بتوانید از Redis به صورت عملی در پروژه خود استفاده کنید:)اگر پست اول این سری آموزشی را نخواندید پیشنهاد می کنم از لینک زیر ابتدا آن را بخوانید: https://virgool.io/@vahiiiid/%D9%87%D8%B1-%D8%A2%D9%86%DA%86%D9%87-%DA%A9%D9%87-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A7%D8%B2-redis-%D8%A8%D8%AF%D9%88%D9%86%DB%8C%D9%85-%DB%B1-gyhxrnxtcju5 شما بعد از خواندن مجموعه پست های Redis موارد زیر را یاد خواهید گرفت:آشنایی با Redis و موارد کاربرد آننصب و راه اندازی Redis و معرفی رابط های برنامه نویسی اون در زبان های مختلفاستفاده از Redis-cliپیکربندی Redisمقایسه Redis با Memcachedآشنایی با Data Type های اصلی Redisتمرین دستورات مهم هر کدام از Data Type های Redisبررسی نکات پیشرفته تر در Redisپیاده سازی آمار بازدید کاربران در ‌ Redis و Laravelدر ادامه این پست به ۲ مورد آشنایی با Data Type های اصلی Redis و تمرین دستورات مهم هر کدام از Data Type ها می پردازیم.خوب همانطور که در پست قبل هم گفته شد Redis تنها یک دیتا بیس ذخیره کننده ی key value به صورت ساده نیست بلکه می تواند انواع مختلفی از ساختار های داده ای را به عنوان value در خود ذخیره کند که از این رو می توان Redis را یک data structures server نیز نامگذاری کرد.منظور از value ساده این هست که علاوه بر داده های رشته ای  (string) می توان ساختار های داده ای پیچیده تری را هم در آن نگه داشت، این ساختار های پیچیده در ۵ دسته ی اصلی در Redis پشتیبانی می شوند:stringsListsSetsSorted setsHashesدر ادامه هر کدام از این ۵ مورد را بررسی می کنیم و با دستورات اختصاصی آن ها آشنا می شویم.برای اجرای هر کدام از  دستوراتی که در ادامه می آید، باید ابتدا وارد redis cli شوید و این کار را با دستور زیر در ترمینال خود انجام دهید:$ redis-cli۱. نوع Stringsدر واقع ساده ترین نوع داده ای هست که Memcached نیز تنها از آن پشتیبانی می کند. در واقع وقتی string را به عنوان value ذخیره می کنید یک map بین string و string دارید.برای ساخت و یا در یافت string در ‌Redis کافی هست از ۲ دستور زیر استفاده نمایید:&gt; set mykey somevalue
OK
&gt; get mykey
&quot;somevalue&quot;اگر یک key از قبل تعریف شده باشد و مجدد آن را set کنید برروی اولی تنها value را جایگزین می کند.از موارد استفاده این نوع داده ای شاید بتوان ذخیره فایل های html را مثال زد تا با cache کردن آنها بتوان مجدد به آنها دسترسی داشت و دوباره render نشوند.جالب هست که Redis می تواند تا مقدار 512 مگابایت به ازای هر یک string ذخیره کند.۲. نوع Listsاین نوع برای داشتن لیستی از رشته ها هست. دقیقا لیستی که شما بتوانید از ابتدا یا انتهای آن مقادیر خود را اضافه و یا کم کنید.برای مثالی از کاربرد آن و وضوح بیشتر، یک timeline و یا یک تاریخچه چت رو در نظر بگیرید. باید به تریتب پیام ها ی  رد و بدل شده بین ۲ کاربر را نگه دارید و یا برای timeline پست های منتشر شده مثل همین پست های ویرگول که یک ترتیبی بر اساس تاریخ وجود دارد.این نوع لیست را در Redis می توان با نوع Lists و با کمک دستورات زیر ایجاد کرد:LPUSH mylist aیک لیست به نام mylist ساختیم و مقدار a  را به ابتدای آن اضافه کردیم. حالا میخواهیم به انتهای لیست هم مقداری اضافه کنیم: RPUSH mylist cالان یک لیست داریم که ۲ تا مقدار داخل آن هست و می توان با همین ۲ دستور مقادیر دیگری را هم اضافه کرد:LPUSH mylist b
LPUSH mylist dبعد از اجرای ۴ دستور بالا هم اکنون به ترتیب زیر لیستی به نام mylist داریم:1) &quot;d&quot;
2) &quot;b&quot;
3) &quot;a&quot;
4) &quot;c&quot; از آنجایی که LPUSH به ابتدای لیست اضافه می کند، در لیست بالا مشخص هست که مقدار ابتدایی لیست چرا &quot;d&quot; هست.خوب حالا می خواهیم با دستور زیر مقدار ابتدای لیست را بگیریم:&gt; LRANGE mylist 0 0
1) &quot;d&quot;دستور LRANGE می تواند با توجه به مقدار ابتدایی و انتهایی که به آن می دهیم به ترتیب مقادیر داخل List   را به ما برگرداند. در مثال بالا از خانه 0 تا 0 یعنی تنها اولین مقدار لیست و در مثال پایین می توانیم تمام ۴ مورد رو بگیریم:&gt; LRANGE mylist 0 3
1) &quot;d&quot;
2) &quot;b&quot;
3) &quot;a&quot;
4) &quot;c&quot;برای گرفتن یک مقدار از ابتدا و یا انتهای لیست و حذف آن باید به صورت زیر با دستورات POP کار کنیم:&gt; LPOP mylist 
&quot;d&quot;
&gt; LRANGE mylist 0 3
1) &quot;b&quot;
2) &quot;a&quot;
3) &quot;c&quot;در ابتدا با LPOP مقدار ابتدای لیست را که &quot;d&quot; بود را گرفتیم و آن از لیست حذف شد. همین کار با دستور RPOP برای انتهای لیست قابل انجام هست:&gt; RPOP mylist 
&quot;c&quot;
&gt; LRANGE mylist 0 3
1) &quot;b&quot;
2) &quot;a&quot;توی این لیست تا دلتان می خواهد می تونید مقدار اضافه کنید چون  Redis می تواند بیش از ۴ میلیارد المان در هر لیست نگه داری کند. ۳. نوع Setsشاید اگر لیستی از رشته ها را بخواهید بسازید از List استفاده کنید ولی اگر لیستی بخواهید که ترتیب در آن مهم نباشدبخواهید که مقادیر تکراری وارد لیست شما نشوند از هر کجای لیست که خواستید با سرعت خیلی بالا مقادیر را بگیرید بررسی کنید که آیا مقداری که دنبال آن هستید در این لیست هست یا خیر باید از Sets استفاده کنید.در واقع نوع داده ای Sets در Redis برای داشتن یک collection از رشته ها به عنوان مقادیر هست با این ویژگی مهم که دیگر نیاز به بررسی وجود این مقدار در collection نیست و هر چند بار که یک مقدار تکراری را به Set اضافه کنیم همان یک مقدار را در collection خودمون داریم.یکی دیگه از ویژگی های جالب Set این هست که شما می توانید چند تا Set را در Redis باهم Union کنید و از اونها استفاده کنید. از موارد پر کاربرد Set می توان به محاسبه ی تعداد کاربران یکتای بازدید کننده از سایت اشاره کرد به این صورت که یک Set از مقادیر ip تمام کاربران بازدید کننده داریم و از آنجایی که این مقادیر تکراری نمی باشد می توان با محاسبه تعداد آنها به بازدید یکتای سایت خود برسیم.پس با دستورات زیر می توانیم بیش از ۴ میلیارد مقدار متفاوت را در یک ‌Set اضافه کنیم:&gt; SADD myset &quot;Hello&quot;
  1
&gt; SADD myset &quot;World&quot;
  1
&gt; SADD myset &quot;World&quot;
  0در مثال بالا با دستور SADD یک Set به نام myset ساختیم و مقدار &quot;Hello&quot; و &quot;World&quot; رو ابتدا به آن اضافه کردیم و مقدار 1 را به صورت integer دریافت کردیم که نشان می دهد مقادیر به Set اضافه شد اما در دستور بعدی مجدد مقدار &quot;World&quot; را اضافه کردیم که مقدار 0 را بر گرداند که چون مقداری تکراری بود.با دستور SCARD می تونیم از تعداد مقادیر موجود در Set ساخته شده آگاه شویم:&gt; SCARD myset
2همان طور که انتظار داشتیم مقدار ۲ را برگرداند و &quot;World&quot; تنها یک بار وارد شده بود.با دستور SMEMBERS می تونیم تمام مقادیر داخل Set را بگیریم:&gt; SMEMBERS myset
1) &quot;World&quot;
2) &quot;Hello&quot;بررسی وجود یک مقدار در داخل Set با دستور SISMEMEBER انجام میشه:&gt; SISMEMBER myset &quot;one&quot;
0
&gt; SISMEMBER myset &quot;World&quot;
1همان طور که مشخص هست باز هم مقدار 1 و یا 0 به ترتیب برای وجود داشتن و یا وجود نداشتن مقدار داده شده در Set بر می گرداند.برای حذف یک مقدار هم از دستور SREM استفاده می کنیم:&gt; SREM myset &quot;World&quot;
1 توجه داشته باشید که برای دستورات SADD و SREM به جای دادن یک مقدار می توانید هم زمان در یک دستور چند مقدار را حذف و یا اضافه کنید.۴. نوع Sorted Setsهمان طور که از اسم این نوع داده مشخص هست شبیه Sets هست یعنی یک collection از مقادیر رشته ای بدون تکرار، اما بر خلاف Set می توان در Sorted Set یک مقدار به عنوان Score به هر المان داد.با این مقدار می توانیم از کمترین به بیشترین score المان های خودمون رو مرتب کنیم و این نکته را هم باید بدونیم که بر خلاف مقادیر المان ها، score ها می توانند تکراری هم باشند.برای مثالی از کاربرد این نوع داده می توانیم لیستی از task ها را در نظر بگیریم که تکراری نیستند و هر کدام یک درجه اهمیتی دارند. حالا می توانیم این لیست را از هر کجایی که نیاز داریم مرتب کنیم.ساخت یک Sorted Set با دستور ZADD قابل انجام هست:&gt;ZADD myzset   1  &quot;one&quot;
1
&gt; ZADD myzset  2  &quot;two&quot;
1
&gt; ZADD myzset  3  &quot;three&quot; 
1خوب یک Sorted Set با نام myzset ساختیم و ۳ تا مقدار one, two, three رو با  socre هایی به ترتیب 1,2,3 به آن اضافه کردیم.حالا اگر بخواهیم score مقدار two را ببینیم با دستور ZSCORE خواهیم داشت:&gt; ZSCORE myzset &quot;two&quot;
&quot;2&quot;در زمان استفاده از Sorted Set، احتمالا مواقعی نیاز داریم که المان هایی را که بین ۲ تا score وجود دارند را بگیریم یعنی کاری که با دستور پایین انجام دادیم:&gt;  ZRANGE myzset 2 3
1) &quot;two&quot;
2) &quot;three&quot;بین ۲ تا مقدار 2 و 3 به عنوان score در myzset این ۲ المان وجود داشت.حذف یک مقدار از Sorted Set با دستور ZREM قابل انجام هست:&gt; ZREM myzset &quot;two&quot;
1۵. نوع Hashesآخرین نوع داده ای که در Redis بررسی میکنیم بسیار می تواند پر کاربرد باشد و البته کار راه انداز!اگر می خواهید داخل هر key یک object نگه دارید Hash دقیقا پاسخ نیاز شماست.هر Hash داخل Redis این امکان رو به شما می دهد که به ازای هر key یک map از رشته هایی به صورت key value را نگه دارید یعنی دقیقا همان چیزی که از object انتظار دارید.از موارد کاربرد آن می توان به نگه داشتن اطلاعات کاربران لاگین شده به سیستم اشاره کرد. فرض کنید به ازای هر کاربری که به سیستم شما لاگین می شود یک key از نوع Hash بسازید و داخل آن اطلاعاتی مثل نام، ایمیل، تلفن و هر چیزی که نیاز دارید نگه داری کنید.بیایید همین مثال بالا را در redis cli اجرا کنیم، پس یک key به اسم user و مقدار id اون در دیتابیس که فرض می کنیم ۱۰۰۰ باشد می سازیم و مقادیری که می خواهیم را در آن نگه می داریم:&gt; HMSET user:1000 username vahiiiid  password 1234 age 26
OKخوب همان طور که دیدید این کار با دستور HMSET انجام شد و مقادیری مثل username, password و age از کاربر نگه داری شد.حالا اگر تمام این اطلاعات کابر را بخواهیم کافی هست دستور زیر را اجرا کنیم:&gt; HGETALL user:1000 
1) &quot;username&quot; 
2) &quot;vahiiiid&quot; 
3) &quot;password&quot;
4) &quot;1234&quot; 
5) &quot;age&quot;
6) &quot;26&quot;برای تغییر یک مقدار از Hash می توانیم به صورت زیر عمل کنیم:HSET user:1000 password 12345اگر فقط مقدار یک فیلد را بخواهیم بگیریم می توانیم از HGET استفاده کنیم:&gt; HGET user:1000 age
&quot;26&quot;با دستور HEXISTS هم می توان از وجود یک فیلد در Hash اطلاع پیدا کنیم:&gt; HEXISTS user:1000 age
1بررسی دستورات بیشتر هر Data Typeخوب در این پست با ۵ تا از Data Type های اصلی Redis آشنا شدیم و برخی از دستورات مهم تر هر کدوم رو به علاوه مورد کاربردی هر کدام را دیدیم اما در کنار این دستورات Redis دارای تعداد خیلی زیادی دستور دیگر برای هر نوع Data Type هست که شما می توانید  آنها را در document خود Redis در اینجا بخوانید.پایان قسمت ۲همان طور که مشخص هست بخش خیلی مهمی از یادگیری Redis دانستن Data Type ها و نحوه ی استفاده از اونها هست که امیدوارم تو این پست تونسته باشم خوب بیانشون کرده باشم و قطعا با تمرین زیاد و استفاده از اونها می توان دانش بسیار بهتری از تجربه کار با هر کدوم به دست آورد.در پست بعدی و آخرین پست این سری سعی می کنم به یک سری موضوعات پیشرفته تر در Redis بپردازم و یک پیاده سازی  آمار بازدید با Redis در لاراول داشته باشیم.</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Wed, 08 May 2019 16:07:23 +0430</pubDate>
            </item>
                    <item>
                <title>هر آنچه که باید از Redis بدونیم (۱)</title>
                <link>https://virgool.io/@vahiiiid/%D9%87%D8%B1-%D8%A2%D9%86%DA%86%D9%87-%DA%A9%D9%87-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A7%D8%B2-redis-%D8%A8%D8%AF%D9%88%D9%86%DB%8C%D9%85-%DB%B1-gyhxrnxtcju5</link>
                <description>Redis  در مجموعه ای از چند پست ساده قصد دارم موارد اصلی دیتابیس Redis رو بنویسم.سعی می کنم در این پست ها به تفکیک فقط مواردی رو ذکر کنم که به نظر برای کار کردن با Redis ضروری میاد و شما قطعا بعد از خواندن آنها می توانید شناخت خوبی از Redis به دست بیاورید و با آن کار کنید.مطمئنا Redis در چند سال اخیر یکی از پرکاربرد ترین تکنولوژی ها بوده و داخل کشور ما هم اگر نگیم تمام پروژه های بزرگ ولی در اکثر آن ها مورد استفاده قرار گرفته است.با توجه به ویژگی های خوبی که Redis ارائه می دهد در کنار سادگی و performance بالایی که دارد به یک ابزار کار راه انداز برای کاربرد های مختلف تبدیل شده است و همیشه یکی از گزینه های روی میز برای اجرای feature های جدید پروژه ها هست، پس یادگیری اون یکی از مهم ترین نکات رزومه هر برنامه نویس سمت سرور می تواند باشد.شما بعد از خواندن مجموعه پست های Redis موارد زیر را یاد خواهید گرفت:آشنایی با Redis و موارد کاربرد آننصب و راه اندازی Redis و معرفی رابط های برنامه نویسی اون در زبان های مختلفاستفاده از Redis-cli پیکربندی Redisمقایسه Redis با Memcachedآشنایی با Data Type های اصلی Redisتمرین دستورات مهم هر کدام از Data Type های Redisبررسی نکات پیشرفته تر در Redisپیاده سازی آمار بازدید کاربران در ‌ Redis و Laravelدر ادامه این پست به ۵ مورد ابتدایی از این لیست می پردازیم.خوب Redis دقیقا چیست؟در واقع Redis یک ذخیره ساز ساختار های داده ای در RAM هست:) یعنی چی؟ساختار های داده ای یا Data Structure می توانند یک رشته ساده و یا یک لیستی از داده ها باشند که Redis اونها رو توی RAM برای ما نگه داری می کنه و می تونیم با سرعت بالا اون ها رو بازیابی کنیم. از آنجایی که داده ها رو ذخیره و بازیابی می کند یک نوع دیتابیس هست و چون توی RAM نگه می داره اصطلاحا             in-memory Database نام گزاری می شود. اما برای هر داده ای که در Redis ذخیره می کنیم یک key یا کلید داریم و زمان بازیابی با استفاده از این key هست که به داده خودمون که همان value هست می رسیم و بنابر این Redis یک key value database هست.پس Redis یک دیتابیس NoSql می باشد اما علاوه بر استفاده از Redis به عنوان دیتا بیس با توجه به ویژگی های اون که در ادامه پست ها با اونها کامل آشنا می شویم می توانیم Redis رو به عنوان Cache و Message Broker هم استفاده کنیم.آیا نگه داری داده ها در RAM باعث از دست رفتن آنها نمی شود؟خوب این سوالی هست که هر تازه کاری باید در ابتدا بپرسه! آیا از آنجایی که Redis داده ها را روی RAM نگه می دارد،  بعد از خاموش و روشن شدن و یا هر اتفاق غیر قابل پیش بینی که بیافتد و RAM سیستم خالی شود داده های ما پاک می شوند؟ خیر، Redis برای نگه داری دائمی داده ها آنها را با توجه به تنظیماتی که ما برای آن مشخص می کنیم به دیسک اصلی سیستم منتقل می کند و بعد از پاک شدن RAM دوباره می تواند آنها را منتقل کند و کار را از سر بگیرد.این ویژگی باعث شده اصطلاحا به آن on-disk persistence  بگویند و این کار را می تواند در سطوح مختلفی انجام دهد. این سطوح شامل موارد زیر می شوند:۱. روش RDB: اگر قصد back up گیری از داده های خود به صورت فایل های جداگانه در فاصله های زمانی مشخص و بعد از تعداد مشخصی تغییر  را داشته باشید می توانید از این روش استفاده کنید و کافی است به Redis بگویید که در چه بازه های زمانی به صورت تکراری و تا چه مدت از داده ها back up بگیرد. برای مثال هر ۳۰ دقیقه و به مدت ۳۰ روز از داده ها ی خود می توانید back up بگیرید و در هر زمان که مشکلی پیش آمد آنها را برگردانید. در واقع RDB مخفف Redis Database Backup می باشد به این معنی که هر بار از کل دیتا بیس یک dump می گیرد و نگه می دارد.پس در این روش ممکن هست داده هایی رو از دست بدهید و اگر در لحظه داده های شما مهم هستند بهتر هست از روش بعدی استفاده کنید.۲. روش AOF: این روش مخفف Append Only File هست به معنی اینکه یک بار فایل RDB را می سازد و با هر تغییر می تواند به آن فایل اضافه کند و به این صورت اگر چه شاید کمی کند تر باشد ولی برای داده های حساس تر گزینه بهتری هست.این روش قادر است با استفاده از fsync بعد از هر بار درج و یا تغییر یک key جدید در Redis آن را ذخیره کند.۳. غیر فعال کردن Persistence Mode به طور کلی و back up نگرفتن۴. استفاده ترکیبی از RDB و AOFنصب Redisاز آنجایی که Redis برروی اکثر سیستم های عامل نصب خواهد شد، می توانید با توجه به نوع سیستم عاملی که استفاده می کنید اقدام به دانلود و نصب آخرین نسخه آن کنید.هم اکنون نسخه 5.0.4 آن قابل نصب هست.نصب نسخه ی stable آن در ubuntu:$ wget http://download.redis.io/releases/redis-5.0.4.tar.gz
$ tar xzf redis-5.0.4.tar.gz
$ cd redis-5.0.4
$ makeهم چنین شما می تونید از طریق apt هم به سادگی آن را نصب کنید و فقط باید بررسی کنید که کدام ورژن از Redis برای شما نصب خواهد شد:$ sudo apt install redis-serverاستفاده از Client برای زبان های مختلفهمان طور که در این لینک می توانید مشاهده کنید تقریبا برای تمامی زبان های مهم برنامه نویسی که در دنیا رایج هستند Client استفاده از Redis نوشته شده است.برای مثال در زبان PHP تعداد زیادی Redis Client وجود دارد که معروف ترین اونها phpredis و Predis هست.بنا براین شما با هر زبان برنامه نویسی در حال کد زدن هستید به راحتی می توانید به دیتا بیس Redis خود متصل شوید و دستورات خودتون رو اجرا نمایید.ورود به Redis Cli و بررسی وضعیت سرویس Redisبعد از نصب Redis و برای اطمینان از نصب موفق و بالا بودن سرویس می توانید با زدن دستور زیر به redis cli وارد شوید و آن را بررسی نمایید:$ redis-cliبعد از اجرای دستور بالا به محیط اجرای دستورات redis وارد می شوید و برای بررسی شرایط می توانید ping را تایپ کرده و اجرا نمایید و در جواب pong بر بگیرید:127.0.0.1:6379&gt; ping
PONGفایل پیکربندی Redis بعد از نصب برای پیکربندی ‌Redis می توانید به سراغ فایل redis.conf بروید که اگر از سیستم عامل ubuntu استفاده می کنید در آدرس etc/redis/redis.conf/ می توانید آن را پیدا کنید.شما از طریق اعمال تغییرات در این فایل و یا دستورات command line می توانید تمامی تنظیمات Redis از جمله پورت مورد استفاده آدرس bind شدهانتخاب روش persistence که در بالا خواندیم و هر نوع تنظیم دیگری را انجام دهید.برای مثال برای فعال کردن AOF می توانید مقدار appendonly  را در فایل خود به yes تغییر دهید:appendonly no
# The name of the append only file &#40;default: &quot;appendonly.aof&quot;&#41;
appendfilename &quot;appendonly.aof&quot;فقط باید دقت کنید که اگر تا به حال از RDB استفاده می کردید و appendonly رو فعال کنید و بروید روی AOF و بعد Redis رو ریستارت کنید نمی تواند فایل رو پیدا کند و داده های شما رو sync نمی کند.همین کار رو از طریق cli هم می توانید انجام دهید:config set appendonly yesبه صورت پیش فرض Redis از RDB استفاده می کند و مقادیر زیر در فایل config وجود دارد که می گوید هر چند وقت و با چند تغییر اقدام به back up گیری کند:save 900 1
save 300 10
save 60 10000می توانید این مقادیر پیش فرض رو در فایل config خود پیدا کنید و تغییر دهید که در اینجا مشخص هست که باید بعد از گذشت ۹۰۰ ثانیه یعنی معادل ۱۵ دقیقه اگر ۱ تغییر انجام شده بود back up بگیرد و همین طور ۲ مورد پایین تر آن که در سریع ترین حالت یعنی هر ۱ دقیقه اگر ۱۰۰۰۰ تغییر داشتیم back up بگیر.مقایسه memcached و redisاز آنجایی که هر دوی این ها برای موارد مشترکی مانند cache می توانند استفاده شود همواره مقایسه ای بین آنها انجام می شود اما با توجه به تغییرات Redis در ورژن های بالاتر تقریبا انتخاب Redis امری بدیهی هست.در پارامتر های زیادی از جنبه های مختلف می توان این دو رو بررسی کرد اما به طور خاص در این ۳ پارامتر که در ادامه اشاره می شود Redis کاملا برتر هست:تفاوت بزرگ آنها در نوع داده هایی هست که نگه می دارند. memcached فقط توانایی ذخیره نوع ساده رشته را به عنوان مقدار دارد در صورتی که Redis دارای ۵ نوع Data Type اصلی هست که در پست بعدی با آنها آشنا خواهیم شد. از آنجایی که Redis دارای Data Type های بیشتری هست استفاده از آن می تواند باعث سهولت در نگه داری ساختار های داده ای پیچیده تر و کاربرد های متفاوت تری بشود.تفاوت بعدی در بحث Memory usage هست که Redis عملکرد بهتری داد به خصوص در بحث آزاد سازی سریع فضای RAM استفاده شده بعد از flush کردن داده ها.مورد بعدی persistence هست که همان طور که در بالا دیدیم Redis به صورت پیش فرض در خودش مکانیزم های کاملی برای آن دارد در صورتی که Memcached نیاز به ابزار های 3rd party  برای dump گرفتن داده ها دارد.البته ناگفته نماند که در بعضی موارد هم مانند سرعت خواندن و نوشتن و یا Scaling این دو بسیار به هم نزدیک هستند و برتری خاصی حس نمی شود.چند مورد بیشتر در مورد Redis که باید بدانیم:با زبان C نوشته شده استاز Lua Scripting پشتیبانی می کندبه صورت پیش فرض replication دارددارای partitioning از طریق Redis Cluster هستپورت پیش فرض اون 6379 هستبه صورت open source و تحت License BSD نگه داری می شودخوب در این پست با مفاهیم اصلی و ابتدایی Redis آشنا شدیم و در پست بعدی می رویم سراغ معرفی Data Type ها و استفاده عملی از Redis .هر آنچه که باید از Redis بدونیم (۲)اگر این پست برای شما مفید بود لایک یادتون نره :) </description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Sat, 04 May 2019 16:09:02 +0430</pubDate>
            </item>
                    <item>
                <title>هر آنچه که باید از php trait  بدونیم</title>
                <link>https://virgool.io/@vahiiiid/%D9%87%D9%85%D9%87-%DB%8C-%D8%A7%D9%88%D9%86-%DA%86%DB%8C%D8%B2%DB%8C-%DA%A9%D9%87-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-php-trait-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A8%D8%AF%D9%88%D9%86%DB%8C%D9%85-wds7ck5qteuh</link>
                <description>php trait ویژگی های عالی trait ها در ارث بری، اونها رو به المان های پرکاربرد زبان php تبدیل کرده است.این پست رو نوشتم تا تمام موارد کاربردی trait ها رو  یک جا بتونیم بخونیم و در زمان طراحی ساختار  برنامه oop خودمون و یا refactor کردن اونها از trait ها استفاده کنیم.ابتدا تعریف traitدر واقع trait یک روش ارث بری دیگر در کنار روش ارث بری از کلاس هست، به این معنی که trait ها المان هایی در php هستند که می توان با نوشتن و ارث بری از آنها در کلاس های مختلف اصطلاحا کد های reusable داشته باشیم و چندین و چند باره method های خودمون رو ننویسیم.چرا به trait نیاز داریم وقتی می توان همین کار را با class انجام داد؟ از آنجایی که php یک زبان single inheritance هست به این معنی که فقط می توان از یک کلاس ارث بری (extends) کرد پس اگر شما دارید یک کلاس جدید می نویسید که به ۲ تا کلاس دیگر به عنوان parent نیاز دارد این مورد در php امکان پذیر نیست. پس چطوری این کار رو انجام دهیم؟؟؟این جا هست که trait ها به این اندازه پرکاربرد شده اند یعنی جایی که به جای نوشتن class ما trait می نویسیم و میتوان چند تا از trait ها رو در class خودمون use کنیم.مشاهده syntax ابتدایی trait همان طور که در کد زیر می بینید trait به سادگی با کلمه  trait  تعریف می شود و شما مجاز هستید تا انواع property و method ها رو در آن بنویسید. یعنی دقیقا همان کاری که در نوشتن یک class انجام می دهید اما با این تفاوت که از trait نمی توان instance گرفت و تنها باید در class های دیگر use شود.در کد زیر یک trait به اسم CreatesApplication  ساختیم که یک متد به اسم createApplication دارد :&lt;?php

trait CreatesApplication
{
    public function createApplication()
    {
        $app = require __DIR__.&#039;/../bootstrap/app.php&#039;;
        return $app;
    }
}حالا می خواهیم از این trait  ارث بری کنیم و از متد createApplication استفاده کنیم که به صورت زیر تنها کافی هست در class خودمون  use CreatesApplication رو بنویسیم:&lt;?php

 class TestCase extends BaseTestCase
{
    use CreatesApplication;
}پس اگر از کلاس TestCase یک object  بسازیم می توان متد createApplication را روی اون صدا زد.موارد پیشرفته تر در trait هایکی از مواردی که در تست ها و یا مصاحبه های php مصاحبه کننده ها ترجیح می دهند از مصاحبه شوند بپرسند همین trait هستش پس در ادامه این پست با هم موارد پیچیده تر از trait رو خواهیم دید!چند trait با متد هم نامالویت یا precedence در trait ها از آن جایی مهم هست که ما می توانیم چند trait را در کلاس خودمون use کنیم و ممکن هست این trait ها دارای متد ها ی هم اسمی باشند که باید ببینیم کدام یکی از آنها اجرا خواهند شد؟اگر در چنین وضعیتی باشیم و متد هم نام را روی object صدا بزنیم یک fatal error خواهیم گرفت :|پس باید ضمن اطلاع از این مورد در زمان use کردن این trait ها در کلاس به صورت زیر مشخص کنیم که الویت چگونه رعایت شود و کدام متد صدا زده شود:&lt;?php
trait A {
    public function smallTalk() {
        echo &#039;a&#039;;
    }
    public function bigTalk() {
        echo &#039;A&#039;;
    }
}

trait B {
    public function smallTalk() {
        echo &#039;b&#039;;
    }
    public function bigTalk() {
        echo &#039;B&#039;;
    }
}
در کد بالا هر دو trait دارای متدهای smallTalk و bigTalk هستند پس در کد زیر وقتی از آنها use می کنم به php می گوییم که اگر smallTalk رو خواستی از B استفاده کن و اگر  bigTalk رو خواستی از A استفاده کنم و اینجوری به خطا نخواهیم خورد:class Talker {
    use A, B {
 B::smallTalk insteadof A;
 A::bigTalk insteadof B;
    }
}متد هم نام در trait و classاگر در مثال بالا در خود  کلاس Talker هم متد bigTalk رو نوشته بودیم چه اتفاقی می افتاد؟در اینجا php بدون اینکه error بدهد می رود و از متد خود class استفاده می کند و به این صورت ما متد bigTalk  رو در trait از دست می دهیم.حالا فرض کنیم ما به متد bigTalk از ‌B هم نیاز داریم پس در این صورت باید این متد رو به یک اسم دیگر به class خودمون اضافه کنیم که خواهیم داشت:class Aliased_Talker {
    use A, B {
 B::smallTalk insteadof A;
 A::bigTalk insteadof B;
 B::bigTalk as talk;
    }

    public function bigTalk() { 
                echo &#039;bigTalk&#039;;     
   }
}حالا اگر یک object از کلاس Aliased_Talker بسازیم و talk رو روی اون صدا بزنیم در واقع متد bigTalk از B رو اجرا می کنیم.ساخت یک trait از trait های دیگربا این ویژگی می توانیم به جای  استفاده از چند trait آنها رو در یک trait داشته باشیم و یک trait جدید بسازیم و از اون داخل class خودمون استفاده کنیم:&lt;?php
trait Hello {
    public function sayHello() {
        echo &#039;Hello &#039;;
    }
}

trait World {
    public function sayWorld() {
        echo &#039;World!&#039;;
    }
}

trait HelloWorld {
    use Hello, World;
}

class MyHelloWorld {
    use HelloWorld;
}در این مثال ۲ تا trait با اسم های Hello و World داشتیم و  با استفاده از آنها یک trait به اسم HelloWorld  ساختیم و وقتی که HelloWorld رو داخل کلاس MyHelloWorld استفاده کردیم در واقع هر دو trait های Hello و World رو خواهیم داشت. در کد زیر استفاده از کلاس بالا رو می بینیم:$o = new MyHelloWorld();
$o-&gt;sayHello();
$o-&gt;sayWorld();
//output-&gt; Hello World!تغییر visibility متد های trait در زمان استفاده از آنفرض کنید از یک trait در کلاس خودتون استفاده می کنید اما نمی خواهید متد شما همان visibility را داشته باشد که در trait هست. برای مثال در کد زیر ما می خواهیم که متد sayHello به صورت protected باشد و نه public تا فقط در کلاس و child های این کلاس بتوانند آن را صدا بزنند پس طبق کد زیر این کار رو انجام می هیم:&lt;?php
trait HelloWorld {
    public function sayHello() {
        echo &#039;Hello World!&#039;;
    }
}
// Change visibility of sayHello
class MyClass1 {
    use HelloWorld { sayHello as protected; }
}نوشتن abstract  در traitدر نوشتن trait ها ما می توانیم متد های abstract بنویسیم تا مانند abstract class آنها را در زمان استفاده از trait پیاده سازی کنیم:&lt;?php
trait Hello {
    public function sayHelloWorld() {
        echo &#039;Hello&#039;.$this-&gt;getWorld();
    }
    abstract public function getWorld();
}حالا اگر از Hello در کلاس خودمون استفاده کنیم باید متد getWorld رو پیاده سازی کنیم:)موارد دیگر از ویژگی های trait هادر trait ها علاوه بر method می توان property هم داشتدر trait ها می توانیم static members و یا  static methods  داشته باشیمبا توجه به ویژگی هایی که دیدیم trait ها برای refactor کردن کلاس های پیچیده که تعداد متد ها ی اونها خیلی زیاد شده است عالی خواهند بوداین ها موارد ی بود که باید تو ذهنمون باشه تا تو طراحی ها و کد نویسی هامون بهتر و بیشتر از trait ها استفاده کنیم چون همون طوری که دیدیم واقعا برای ارث بری المان های خیلی خوب و قوی به نظر می رسندامیدوارم این پست برای شما مفید باشه:)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Sun, 14 Apr 2019 17:34:58 +0430</pubDate>
            </item>
                    <item>
                <title>توضیح سریع OpCache و نحوه ی استفاده از اون رو در یک پست بخون ;)</title>
                <link>https://virgool.io/@vahiiiid/%D8%AA%D9%88%D8%B6%DB%8C%D8%AD-%D8%B3%D8%B1%DB%8C%D8%B9-opcache-%D9%88-%D9%86%D8%AD%D9%88%D9%87-%DB%8C-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D8%A7%D9%88%D9%86-%D8%B1%D9%88-%D8%AF%D8%B1-%DB%8C%DA%A9-%D9%BE%D8%B3%D8%AA-%D8%A8%D8%AE%D9%88%D9%86-vsbpzlxtmicn</link>
                <description>راه اندازی سریع opcache در اینجا سعی کردم هر چیزی که از OpCache و نحوه ی استفاده از اون توی php نیاز هست بدونیم رو به صورت سریع و کاربردی توی یک پست توضیح بدم ;)چیه این OpCacheخوب اول بگیم که OpCache در واقع یک Bytecode Caching Engine هست که php از ورژن 5.5 به بعد به صورت built-in در خودش داره.پس اگر تاقبل از اون از APC و یا Xcache استفاده می شد دیگه نیازی به اونها نداریم.دقیقا OpCache چی کار میکنه برای ما؟دقیقا عملکرد سایت ما رو optimize می کنه :)))اسکریپت های php برای اجرا در زمان runtime ابتدا به bytecode کامپایل می شوند پس در هر بار اجرای یک script این تبدیل زمان بر  انجام خواهد شد. خوب این جا هست که OpCache به کمک می آید و بعد از یک بار کامپایل کد های ما، اونها رو cache میکنه روی RAM (ویا روی یک فایل رو دیسک) و می توانیم در دفعات بعدی بدون نیاز به کامپایل مجدد فقط bytecode ها رو اجرا کنیم.آیا ارزش دارد که از OpCache استفاده کنیم؟ بله قطعا!اگر سایت شما تعداد بالایی درخواست را در هر ثانیه پاسخ می دهد و زمان پاسخ دهی برای شما مهم هست OpCache یکی از مواردی هست که حتما باید از اون استفاده کنید.اما این که به چه میزان OpCache سایت ما را بهینه می کند کاملا بستگی به شرایط دارد و script های مختلف بهره متفاوتی از OpCache می برند برای مثال اگر شما در کدتون اتصال زمان بر و کوئری سنگینی برروی دیتابیس دارید این مورد تاثیر زیادی روی میانگین زمان پاسخ درخواست های سایتتون داره.با توجه به شرایط به طور میانگین OpCache میتونه تا حدود ۵۰٪ میانگین زمان پاسخ دهی به درخواست ها را کم کند! ;)در لینک های زیر می توانید نتایج دقیق از بررسی میزان تاثیر گزاری OpCache در سایت های مختلف رو ببینید:لینک ۱لینک ۲لینک ۳همان طوری که در نتیجه ی بررسی های این ۳ تا سایت مشخص هست قطعا استفاده از OpCache تاثیر خیلی زیادی در عملکرد سایت ما خواهد داشت پس در ادامه نحوه ی استفاده از اون رو باهم ببینیم.چطوری OpCache رو فعال کنیم؟همان طور که گفته شد OpCache در ورژن ۵.۵ به بعد در ‌php وجود داره و تنها کاری که شما برای فعال کردن و تنظیم اون نیاز دارید انجام دهید از طریق فایل php.ini هست.ابتدا php.ini نسخه ی فعلی php خودتون رو پیدا کنید و اون رو با ویرایشگری که دوست دارید باز کنید.خط پایین را در این فایل پیدا کنید و اون رو از comment با پاک کردن ; خارج کنید و مطمئن شوید مقدار آن ۱ به معنی enable باشد.opcache.enable=1چطوری OpCache رو تنظیم کنیمحالا برای تنظیم موارد اصلی OpCache مقادیر زیر رو داریم که با توجه به پروژه خودتون اونها رو می توانید مقدار دهی کنید:opcache.revalidate_freq=0
opcache.validate_timestamps=0 (comment this out in your dev environment)
opcache.max_accelerated_files=7963
opcache.memory_consumption=192توضیح directive های بالا برای تنظیم OpCache:۱) مقدار opcache.revalidate_freq در واقع مشخص می کند که دوره ی بررسی script های cache شده به چه صورت باشد؟اگر مقدار اون ۰ باشد OpCache در هر درخواست که به سرور برسد بررسی میکند که آیا script تغییر داشته است یا خیر. برای محیط develop مقدار ۰ میتواند استفاده شود اما در محیط production برمبنای ثانیه میتوانید به آن مقدار دهید که script های cache شده را بررسی کند و اگر نیاز بود مجدد cache کند.۲) مقدار  opcache.validate_timestamps می تواند ۰ و یا ۱ باشد.اگر ۱ به معنای enable باشد یعنی مقدار  opcache.revalidate_freq رو بخون و طبق توضیحی که در بالا دادیم عمل کن اما اگر برابر ۰ باشد کلا  opcache.revalidate_freq را ندید می گیرد و فقط در زمانی که سرویس رو restart کنیم cache ها را بررسی می کند!۳) مقدار opcache.max_accelerated_files محدودیت تعداد فایلی را که می تواند cache کند رو مشخص می کند که خوب با توجه به پروژه خودتون و تعداد فایل های php باید مقدار دهی شود برای مثال اگر شما 7155 تا فایل php دارید مقدار 7200 می توانید بدهید.برای دریافت تعداد فایل php خودتون هم از دستور زیر در لینوکس و در دایرکتوری پروژه استفاده کنید:find . -type f -print | grep php | wc -l۴) و اما در آخر مقدار opcache.memory_consumption میزان RAM اختصاص داده شده به OpCache رو مشخص می کند، مقداری که ما دادیم برابر 192 مگابایت هست.بعد از تغییر این خطوط در php.ini و ذخیره اون ابتدا وب سرور و fpm رو restart کنید تا OpCache فعال شود.اگر در کد php خودتون خواستید وضعیت OpCache رو ببینید از opcache_get_status استفاده کنید که یک آرایه بر می گرداند و شامل اطلاعاتی مانند وضعیت فعال یا غیر فعال بودن OpCache, میزان RAM مصرف شده و یا میزان RAM خالی باقی مانده از حداکثر تخصیص داده شده می باشد.ابزار گرافیکی بررسی وضعیت OpCacheبرای مشاهده وضعیت OpCache یعنی میزان RAM مصرف شده، تعداد فایل Cache شده و ... ابزار های گرافیکی تقریبا زیادی وجود دارد که ساده ترین اونها opcache-status هست که توسط Rasmus Lerdorf نوشته شده و بسیار ساده و در یک صفحه اطلاعات مهمی را که نیاز دارید از وضعیت OpCache به شما می دهد:تصویری از opcache-status  نحوه ی نصب opcache-status هم خیلی ساده هست فقط کافی هست اون رو دانلود کنید که تنها یک فایل به اسم opcache.php می باشد و  در مرورگر خود این فایل را باز کنید و مطابق تصویر بالا اون رو ببینید.wget https://raw.github.com/rlerdorf/opcache-status/master/opcache.phpنتیجه گیریدر این پست دیدیم که OpCache یک cache کننده ی اسکریپت های کامپایل شده php به bytecode هست و می تونه زمان پاسخ دهی درخواست ها و تعداد درخواست های پاسخ دهی شده در هر ثانیه رو با توجه به شرایط پروژه بسیار بهبود بده.هم چنین روش نصب و پیکربندی اون رو در php ورژن 5.5 به بعد دیدیم و  تنظیمات مهم تر اون رو باهم مرور کردیم و در آخر هم یک ابزار گرافیکی ساده برای مشاهده وضیعت OpCache نصب کردیم.امیدوارم این پست برای شما مفید بوده باشه :)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Sun, 07 Apr 2019 13:57:36 +0430</pubDate>
            </item>
                    <item>
                <title>آمار بازدید مطالب من در سال ۹۷</title>
                <link>https://virgool.io/@vahiiiid/%D8%A2%D9%85%D8%A7%D8%B1-%D8%A8%D8%A7%D8%B2%D8%AF%DB%8C%D8%AF-%D9%85%D8%B7%D8%A7%D9%84%D8%A8-%D9%85%D9%86-%D8%AF%D8%B1-%D8%B3%D8%A7%D9%84-%DB%B9%DB%B7-nj9oaqbh3qca</link>
                <description>من در سال گذشته، در مجموع ۱۸ مقاله در ویرگول منتشر کردم. در طول این سال مقالات من ۳۱۵ مرتبه لایک شدند و ۴۶ نظر نیز بر روی آن‌ها ارسال شد. با مطالعه این مقالات، ۵۳ نفر تصمیم گرفتند تا من را در ویرگول دنبال کنند تا از مقالات بعدی من باخبر شوند.مخاطبیندر طول این سال، مقالات من توسط ۲,۹۰۷ نفر در ویرگول مطالعه شده است. مدت زمانی که این افراد در حال مطالعه‌ی آن‌ها بوده‌اند برابر با ۲۲۸,۷۰۶ ثانیه است. اگر فرض کنیم در حال حاضر جمعیت ایران ۸۰ میلیون نفر است، این یعنی من توانسته‌ام سرانه مطالعه کشورم ایران را ۰/۰۰۲۸۵۹ ثانیه افزایش دهم. شاید بتوانیم این عدد را به «اثر پروانه‌ای» تشبیه کنیم؛ چرا که هر کدام از نویسندگان در ویرگول توانسته‌ایم عددی کوچک را به سرانه مطالعه کشور اضافه کنیم اما مجموعِ تک تکِ این اعداد، یک عدد بزرگ شده است. من در کنار سایر کاربرانِ ویرگول توانستیم در سال ۹۷، سرانه مطالعه ایران را ۴/۱۲۲۳۴۳ ثانیه افزایش دهیم.می‌توانیم برای سال ۹۸، اتفاقات بزرگتری را رقم بزنیم.ویدیوی آمار مخاطبین من را ببینید: https://cdn.virgool.io/annual-report-97/vyg8jxqctcrk-coir.mp4 </description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Thu, 28 Mar 2019 00:02:39 +0430</pubDate>
            </item>
                    <item>
                <title>معرفی symbol در جاوا اسکریپت</title>
                <link>https://virgool.io/JavaScript8/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-symbol-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-f5ezyiqmmvrw</link>
                <description>متغیر های نوع symbol در ES6همون طوری که در پست انواع متغیر در جاوا اسکریپت و نحوه بررسی آنها توضیح داده شد در ES6 یک نوع متغیر جدید از دسته ی primitive معرفی شد که در این پست میتونیم بیشتر با اون آشنا بشیم.ادامه متن شامل این موارد هست:معرفی و نحوه ی ساخت symbolموارد کاربرد symbolبررسی Well-known symbols نوع shared symbol۱. معرفی و نحوه ی ساخت symbolدر حقیقت symbol یک نوع متغیر primitive یعنی شبیه number، string، و ... هست با این تفاوت بزرگ که دارای یک identifier به صورت یکتا هستش به این معنی که وقتی شما یک متغیر از نوع symbol دارید جاوا اسکریپت این اطمینان رو به شما میدهد که هیچ متغیر دیگری این identifier رو نداره.به صورت زیر می توانیم یک متغیر به نام symbol از نوع symbol بسازیم.let symbol = Symbol(&#039;debug&#039;)
console.log (symbol)دقت کنیم که برای ساخت symbol از کلمه new نباید استفاده کنیم زیرا یک factory function هستش و نه یک constructor function.خوب خروجی اون به صورت زیر هست:Symbol(debug)در مثال بالا در زمان ساخت symbol کلمه debug که اصطلاحا description یا توضیح Symbol هست، به صورت اختیاری داده شد پس میتوان symbol ها را بدون description تعریف کرد، ولی اگر شما چند Symbol داشته باشید زمان debug کردن با description ها راحت تر خواهید بود.این را به یاد داشته باشید که description فقط برای توضیح Symbol هست و مقدار اون نیست و از اون جایی که هر Symbol دارای id یکتای خودش هست پس هیچ دو Symbol با هم برابر نیستند حتی اگر description آنها برابر باشه:let symbol1 = Symbol(&#039;debug&#039;);
let symbol2 = Symbol(&#039;debug&#039;);
console.log(symbol1 == symbol2); // falseپس تا اینجا دیدیم که متغیرها از نوع Symbol چطوری ساخته میشوند و دیدیم هر کدوم یک id یکتا دارند و باهم برابر نیستند.۲. موارد کاربرد symbolخوب این نوع متغیر ویژگی بزرگی به ما در ارتباط با تعریف property های یک object میده که باعث میشه اصطلاحا بتونیم یک سری meta data توی object نگه داریم. برای این کار باید property های object خودمون رو از نوع Symbol تعریف کنیم که در زیر داریم:let age = Symbol( );
let obj = {
     name : &#039;vahid&#039;,
     [ age ] : 90 
};در اینجا اول یک متغیر از نوع Symbol به اسم age ساختیم که بعدا از اون برای ساخت یک property در obj استفاده کریم اما این نوع property چه قدرتی به ما میدهد؟اگر روی obj توابع پرکاربردی مثل Object.keys اعمال کنید ویا حلقه ی for in روی اون بزنیم age رو نخواهیم گرفت! پس این نوع property ها اصطلاحا iterator نیستند و در حلقه ها hide میشوند و خوب برای بعضی داده هایی که میخواهیم تغییر نکنند بسیار پرکاربرد هستند.فرض کنیم یک property به اسم createdAt میخواهیم در object خودمون نگه داریم و زمانی که object رو به توابع دیگر پاس میدهیم این مقدار را تغییر ندهند پس کافی هست از نوع Symbol اون رو تعریف کنیم.۳. بررسی Well-known symbolsخود هسته ی جاوا اسکریپت یک سری Symbol داره که به عنوان Well-Known شناخته میشوند(البته اکثرا نمیشناسن این ها رو ولی بزار بگن well-known :دی ) و اینجا میتونید لیست اونها و توضیحات هرکدوم رو ببینید.پس به صورت built-in جاوا اسکریپت یک سری Symbol برای خودش داره که با هر کدوم یک کاری در object ها انجام میده که یک موردش رو اینجا باهم می بینیم:توی این مثال ما میخواهیم Symbol.toPrimitive رو بررسی کنیم که یک Well-Known Symbol هست و جاوا اسکریپت اون رو به object اضافه کرده تا زمانی که برای مثال میخواهم دو نوع متغیر رو باهم جمع کنیم این رو صدا بزنه تا نوع اون ها رو یکی کنه تا با هم جمع بشن.کد زیر رو ببینید که در پشت ماجرا داره این Symbol.toPrimitive رو صدا میزنه و جلوتر با هم اون رو override خواهیم کرد:let numbers = [ 1, 2, 3 ];
console.log( numbers  +  1 ); 
// &quot; 1,2,31 &quot;خروجی کد بالا &quot; 1,2,31 &quot; شد و همان طوری که میدونید بعد از تبدیل آرایه که نوع اون تو جاوا اسکریپت object هست به string اون رو با ۱ جمع کرد اما ما میخواهیم بهش بگیم که اگه خواستی object رو به primitive تبدیل کنی یعنی دقیقا همین Symbol.toPrimitive رو صدا بزنی فقط مقدار عددی ۳ رو برگردون:numbers[ Symbol.toPrimitive ] = function( ){ return 3; }
console.log( numbers + 1 ); 
//4خوب ما میدونستیم که آرایه numbers به صورت built-in یک property از نوع Symbol در خودش داره که موقع تبدیل این آرایه به primitive صدا زده میشه و فقط اون رو با تابع خودمون جایگزین کردیم و عدد ۳ رو برگردوندیم و خروجی هم مقدار ۴ گرفتیم.بقیه Well-Known Symbol ها رو میتونید در لینک ارائه شده بخونید.۴. نوع shared symbolاما زمان هایی در کد نویسی نیاز داریم که دو یا چند symbol با هم به صورت اشتراکی یک مقدار رو داشته باشند برای این کار باید از متد ()for. برای ساخت اونها استفاده کنیم.در مثال زیر هم نحوه ی تعریف اونها و هم مثالی از مورد استفاده اونها میبینیم:let symbol1 = Symbol.for(&#039;age&#039;);
let person = {
name: &#039;vahid&#039;
}

function makeAge( person ){
	let ageSymbol = Symbol.for(&#039;age&#039;);
	person.[ageSymbol] = 90;
	}

makeAge(person);
console.log( person[symbol1] );
//90همان طور که مشخص هست درتابع  makeAge یک symbol به اسم ageSymbol داریم که به object ورودی تابع اضافه میکنیم و در root هم میخواهیم به اون property دسترسی داشته باشیم پس کافی هست هر دو symbol  ما shared باشند.یعنی هر دو متغیر symbol1 و ageSymbol به صورت shared و با متد ()for. تعریف شدند پس با هر کدوم به property مورد نظر دسترسی خواهیم داشت.امیدوارم این پست مفید بوده باشه ;) لطفا لایک یادتون نره :) </description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Thu, 07 Mar 2019 18:26:16 +0330</pubDate>
            </item>
                    <item>
                <title>توضیح ساده prototype در جاوا اسکریپت</title>
                <link>https://virgool.io/JavaScript8/%D8%AA%D9%88%D8%B6%DB%8C%D8%AD-%D8%B3%D8%A7%D8%AF%D9%87-prototype-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-vn8zyn6fu9uq</link>
                <description>جاوا اسکریپت و ارث بری مخصوص به خودش! در جاوا اسکریپت چند تا مبحث پایه ای وجود داره که در ابتدا فهم اونها کمی سخته و باعث میشه بعضی موقع ها واقعا گیج بشیم و یه حرفایی هم پشتش بزنیم :Dیکی از اون مباحث قطعا ارث بری و بحث prototype هست، همون طوری که می دونید کلی آموزش هم توی این زمینه وجود داره که البته من خودم اوایل هر کدوم رو می خوندم بیشتر گیج می شدم، شاید چون خیلی زیادی توضیح داده بودن شایدم البته من گیج بودم نمیدونم ;)!! این پست رو نوشتم تا سعی کنم به زبان ساده، فقط prototype رو توضیح بدم!خوب ما توی برنامه خودمون نیاز به ارث بری داریم، این کار توی جاوا اسکریپت بیشتر از طریق prototype انجام می شه و نه مثل اکثر زبان ها با class، البته به نظر بعد از یک مدت کار با اون خیلی هم چیز باحال تری هست!(می دونم جاوا اسکریپت class هم داره :دی) هر object در جاوا اسکریپت قطعا prototype داره و فقط هم یک prototype داره نه بیشتر!حالا این prototype چیه؟ prototype رو یک property به اسم __proto__ در object خودتون در نظر بگیرید که فقط ۲ نوع مقدار میتونه بگیره:مقدار nullیک object دیگرپس همه object های شما یک property به اسم __proto__ دارند.این property مثل والد برای object شما هستش، پس می تونیم property های اون رو به راحتی صدا بزنیم!‌ چطوری؟وقتی property یک object را صدا می زنیم چه اتفاقی می افته؟برای مثال obj.name رو داریم: ابتدا در obj دنبال name می گرده اگر نبود میره توی prototype از obj و دنبال اون می گرده و اگه بود که صداش می کنه و اگر نبود باز هم به صورت تکرار پذیر سراغ prototype از prototype بعدی می رود تا در نهایت prototype دیگری وجود نداشته باشد و اگر پیدا نکرد خطا می ده!به صورت تکرار پذیر سراغ prototype از prototype بعدی می رود از اونجایی که برنامه نویس فقط با دیدن کد یاد می گیره، توضیح کافیه و بریم توی کد ببینیم:بررسی افزودن prototypeطبق توضیحات بالا ما ۲ تا object داریم به نام های person و staff که person رو به عنوان prototype برای staff طبق کد زیر اضافه کردیم:staff.__proto__ = person; همون طوری که مشخص هست شئ staff دارای greeting نیست اما ()staff.greeting اجرا شد و خطا نگرفتیم، دلیلش این بود که person رو به عنوان prototype به staff دادیم پس از اون ارث بری کرد یعنی بعد از اینکه توی staff این property وجود نداشت رفت و در person دنبال اون گشت.استفاده از ()Object.create برای مشخص کردن prototypeدر production نباید از __proto__ استفاده کرد چون در interface اصلی جاوا اسکریپت تا قبل از ES6 به صورت رسمی وجود نداره و به روش زیر باید prototype رو به object بدیم:استفاده از Object.create به جای __proto__پیش فرض prototype برای object هابه صورت پیش فرض جاوا اسکریپت Object.prototype رو به عنوان prototype تمام object هایی که می سازیم تعریف میکنه:بررسی prototype پیش فرضهمان طوری که میدونیم Object.prototype یک سری property های پرکاربردی مثل hasOwnProperty و ... تو خودش داره که در زیر می بینید:Object.prototypeساخت object از روی constructor function و یک تفاوتاما یک استثنا خیلی معروف وجود داره اون هم ساخت object از روی constructor function هاست که دیگه Object.prototype رو به عنوان prototype خودشون ندارند:ساخت object با استفاده از constructor functionتوی این حالت prototype یک object هست که به عنوان constructor توی خودش تابعی که از روش object ساختیم رو داره:بررسی prototype یک object ساخته شده از روی constructor function همون طوری که توی کد مشخص هست داخل __proto__ به عنوان proto برای این object هم Object.prototype رو داریم .به نظر این مباحث نکات اصلی در مورد prototype بود که نوشتم اگر چیزی رو به نظرتون باید اضافه کنم در کامنت ها بنویسید ;)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Sun, 03 Mar 2019 19:48:01 +0330</pubDate>
            </item>
                    <item>
                <title>سوال جالبی که گوگل در مصاحبه جاوا اسکریپت می پرسه</title>
                <link>https://virgool.io/JavaScript8/%D8%B3%D9%88%D8%A7%D9%84-%D8%AC%D8%A7%D9%84%D8%A8%DB%8C-%DA%A9%D9%87-%DA%AF%D9%88%DA%AF%D9%88%D9%84-%D8%AF%D8%B1-%D9%85%D8%B5%D8%A7%D8%AD%D8%A8%D9%87-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%D9%BE%DB%8C%D8%AA-%D9%85%DB%8C-%D9%BE%D8%B1%D8%B3%D9%87-kqhkdcapjktg</link>
                <description>سوال مصاحبه ای معروف جی اس سوال باحال و معروفی از جاوا اسکریپت وجود داره که توی مصاحبه های استخدامی گوگل، آمازون و ... زیاد پرسیده شده.سوالخروجی کد زیر چیست؟const arr = [10, 12, 15, 21];for ( var i = 0; i &lt; arr.length; i++ ) { setTimeout( function () { console.log( &#x27;Index: &#x27; + i + &#x27;, element: &#x27; + arr[ i ] ); }, 3000);}اگر جواب این سوال رو میتونید بگید پس روی چند تا از مسائل پایه ای جاوا اسکرپیت مثل closure، scope setTimeout تسلط کافی دارید:)جواب سوالاین کد ۴ بار خروجی زیر رو چاپ میکنه:Index: 4, element: undefinedمراحل اجرای کدطول آرایه arr برابر ۴ هست پس i در ۴ مرتبه برابر ۰ و ۱ و ۲ و ۳ می باشد و در بار آخری که بررسی می شود برابر ۴ می باشد.از طرف دیگر توابع closure در جاوا اسکریپت از متغیر های scope بالایی خود مطلع هستند. یعنی تابعی که به صورت closure به setTimeout می دهیم مقدار i که آخرین بار قبل از گذشت ۳ ثانیه برابر ۴ شده بود رو داره.پس ۴ بار این تابع اجرا می شود و هر بار i را که برابر ۴ و سپس [arr[4 که undefined هست رو چاپ می کند.</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Wed, 27 Feb 2019 18:46:18 +0330</pubDate>
            </item>
                    <item>
                <title>شما هم وقتی کد می زنید موزیک گوش می کنید؟</title>
                <link>https://virgool.io/@vahiiiid/%D8%B4%D9%85%D8%A7-%D9%87%D9%85-%D9%88%D9%82%D8%AA%DB%8C-%DA%A9%D8%AF-%D9%85%DB%8C-%D8%B2%D9%86%DB%8C%D8%AF-%D9%85%D9%88%D8%B2%DB%8C%DA%A9-%DA%AF%D9%88%D8%B4-%D9%85%DB%8C-%DA%A9%D9%86%DB%8C%D8%AF-wab2mucwoe0c</link>
                <description>گوش دادن به موسیقی هنگام برنامه نویسیمن به شخصه اکثر اوقاتی که کد می زنم در حال گوش کردن به انواع موسیقی هستم و همیشه برام سوال بود که چرا بعضی ها به موسیقی گوش نمیکنند!! یه بررسی روی این مسئله کردم و مواردی رو که بهشون رسیدم رو توی این پست با شما هم به اشتراک گذاشتم که امیدوارم مفید باشه:)گوش دادن به موزیک هنگام کد زدن برنامه نویس ها یکی از مطالبی هست که کلی توی اینترنت در موردش صحبت شده و کلی هم نظرات مختلف وجود داره. همون طوری که میدونیم اکثر برنامه نویس ها به دلایل زیر ترجیح میدن وقتی کد می زنند به موزیک گوش کنند: تمرکز بالاتر، با حذف صدا های اضافه مثل زنگ تلفن، صحبت همکارها و یا هر صدای دیگه ای مثل صدای حرکت صندلی هابالارفتن سرعت کد زدندیر تر خسته شدن، کد زدن با انرژی و انگیزه بالاتر برای مدت طولانی ترکاهش استرس و فشار کار و وضعیت پروژهعدم مواجه شدن با سوالاتی که میتونند تمرکز رو به هم بزنندو یک سری مزیت های دیگه ....اما یک بررسی جالب در کتاب productive در رابطه با موسیقی گوش دادن برنامه نویس ها انجام شده است که نتیجه ی جالبی دارد، productive یکی از کتاب هایی هست که Bill Gates تمام مدیر های Microsoft رو ملزم به خواندن اون میکنه.در این بررسی برنامه نویس ها به دو گروه تقسیم شده اند که گروه اول در background موزیک گوش می دهند و گروه دوم اونهایی هستند که موزیک گوش نمی دهند.به هر دو گروه task هایی داده شد و مشاهده شد که نتیجه انجام task ها با هم تفاوتی ندارند، تا این که توی تعداد خیلی زیادی task این نکته ظاهر شد که برنامه نویس هایی که به موزیک گوش نمی دادند نکته ای را در بعضی task ها رعایت کردند، که برنامه نویسان گروه دیگر که به موسیقی گوش می دادند رعایت نکردند. اما با این که این مشاهدات در تعداد بالای آزمایش روی تعداد زیادی برنامه نویس مشخص شد، اگر شما همین الان در شرکت Microsoft در حال کد زدن به موسیقی گوش کنید هیچ کس هدفون رو از گوش شما برنمیداره:) اما دلیل این تفاوت چی بوده؟همون طوری که می دونید اکثر کارهای روزانه ما با سمت چپ مغز انجام میشه و موزیک در سمت راست پردازش میشه. اما زمان هایی که شما یک راه جدید به ذهنتون می رسه و احتمالا با خودتون میگید &quot;آهان&quot; دقیقا با طرف راست مغز خودتون کار رو انجام دادید.خوب پس به این علت هست که در آزمایش انجام شده برنامه نویس هایی که موسیقی گوش نمیکردند تونسته بودند بهتر عمل کنند.با توجه به مواردی که گفته شد و فوایدی که موسیقی گوش کردن هنگام کد زنی داره شاید بتونیم به یک راه حل جامع تری برسیم: وقتی task را میخواهیم شروع کنیم یعنی همون موقعی که باید فکر کنیم از چه راه حلی استفاده کنیم یا داریم ریشه ی bug رو پیدا میکنیم و .... (که معمولا این موارد را احتمالا روی کاغذ هم یادداشت میکنم در ابتدا) می توانیم به موسیقی گوش ندهیم تا تمام نیم کره ی راست مغز خود را و تمام خلاقیتمون رو برای حل مسئله استفاده کنیم.وقتی شروع به کد زدن میکنیم و بیشتر موارد با سمت چپ مغز پردازش میشوند میتونیم به موسیقی گوش کنیم و با سرعت و تمرکز بالاتری کد بزنیم.اما چه موسیقی گوش دهیم؟موسیقی های بی کلام معمولا گزینه های مناسب تری هستند، اما اکثر برنامه نویس ها به موسیقی با کلام علاقه دارند که خوب اونها هم دسته بندی مختلفی دارند.گفته می شود موسیقی ها کلام داری که متن بسیار آشنایی برای شما دارند و یا موسیقی هایی که به شدت به آنها علاقه دارید گزینه های مناسبی برای گوش دادن هنگام کد زدن نیستند چون احتمالا باعث عدم تمرکز شما می شوند.در پایان یک سایت جالب رو برای موسیقی گوش دادن برنامه نویس ها دیدم که میزارم براتون باحاله:)http://musicforprogramming.netشما هم نظرتون رو در مورد موسیقی گوش دادن و یا نوع موسیقی که گوش میدید تو کامنت ها بنویسید:)اگر از این پست خوشتون اومد لطفا لایک یادتون نره:))</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Sat, 23 Feb 2019 13:33:20 +0330</pubDate>
            </item>
                    <item>
                <title>بررسی مفهوم bubbling و نحوه عملکرد event ها در جاوا اسکریپت</title>
                <link>https://virgool.io/JavaScript8/%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D9%85%D9%81%D9%87%D9%88%D9%85-bubbling-%D9%88-%D9%86%D8%AD%D9%88%D9%87-%D8%B9%D9%85%D9%84%DA%A9%D8%B1%D8%AF-event-%D9%87%D8%A7-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-dsmuola9ddcg</link>
                <description>بیان ساده مفهوم bubbling در جاوا اسکریپت یکی از مفاهیم پایه ای جاوا اسکریپت در مورد نحوه عملکرد event ها bubbling هست که در این پست به زبان ساده اون رو شرح داده ام.در واقع event bubbling به شرایطی اشاره دارد که یک event، روی یک المان nested در المان دیگر اتفاق افتاده است و هر دوی آنها روی همان event دارای event handler هستند. خوب حالا event bubbling مشخص میکند که کدام handler اول صدا زده شود.نحوه ی الویت بندی صدا زده شدن event handlersبرای مشخص شدن موضوع بیایید به یک مثال ساده نگاه کنیم:&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;...&quot;&gt;&lt;img src=&quot;...&quot; alt=&quot;&quot;&gt;&lt;/a&gt;
    &lt;li&gt;&lt;a href=&quot;...&quot;&gt;&lt;img src=&quot;...&quot; alt=&quot;&quot;&gt;&lt;/a&gt;
        ...
    &lt;li&gt;&lt;a href=&quot;...&quot;&gt;&lt;img src=&quot;...&quot; alt=&quot;&quot;&gt;&lt;/a&gt;
&lt;/ul&gt;در اینجا فرض کنید یک event از نوع click روی img tag که داخلی ترین tag در هر سطح هست داشته باشیم.پس img رو طبق تعاریف جاوا اسکریپت event target می نامیم و اگر بخواهیم تمامی والدین اون رو تا window نام ببریم خواهیم داشت:IMG, A, LI, UL, BODY, HTML, document, windowخوب به ترتیب از سمت چپ به راست مسیر پیمایش event ما در node های صفحه می باشد که اصطلاحا propagate کردن گفته می شود و اگر هر کدوم از این node ها دارای event یکسان با event اتفاق افتاده روی IMG باشند، صدا زده می شوند.برای وضوح بیشتر فرض کنید:۱.  شما روی تگ IMG یک event handler دارید که اگر کلیک شد عکس را به صورت بزرگ در modal نمایش دهید۲.  هم چنین یک event handler هم روی li دارید که اگر کلیک شد اطلاعات بیشتری از این ردیف رو به کاربر نشون بدید.خوب طبق تعریف ما اگر برروی IMG کیلیک کنیم هر دوی این event handler ها صدا زده میشوند!چطوری از صدا زده شدن handler های دیگه جلوگیری کنیم؟ فرض کنیم در مثال بالا نمی خواهیم با کلیک روی IMG به صورت پیش فرض جاوا اسکریپت بقیه handler ها را صدا بزند.برای این کار کافی هست در تابعی که به عنوان eventListener روی IMG اضافه کردیم از propagate شدن بیشتر جلوگیری کنیم:function imgOnClickEventListener(event){
    if(event.bubbling){
        event.stopPropagation();
    }
    console.log(&#039;event fired!!!&#039;);
}
imgSelected.addEventListener(&#039;click&#039;, imgOnClickEventListener);در کد بالا یک تابع به اسم imgOnClickEventListener داریم و اون رو به عنوان listerner به img اضافه کردیمش و هنگام کلیک روی img جاوا اسکریپت این تابع را صدا میزند و object از نوع event اتفاق افتاده را به عنوان ورودی به اون پاس میده. مقدار ورودی imgOnClickEventListener دارای یک property به اسم bubbling هست که یک مقدار boolean ما برمی گرداند و اگر true باشد بعد از اجرای این تابع باید سایر listener ها را نیز صدا بزند که خوب در این صورت اگر تابع stopPropagation رو صدا کینم از این کار منصرف میشه و سایر listener ها اجرا نمی شوند.چگونه الویت اجرای listener ها را جا به جا کنیم؟در مثال بالا فرض کنید می خواهیم نه تنها هر دوی listener هایی که روی img و li تعریف کردیم اجرا شوند بلکه با کلیک روی img ابتدا li اجرا شود و بعد img.خوب برای این کار باید در زمان اضافه کردن listener برای li ورودی سوم addEventListener رو true بدهیم تا مشخص کنیم که این listener در روند اجرای bubbling الویت بیشتری دارد:liSelected.addEventListener(&#039;click&#039;, liOnClickEventListener, true);خوب الان اتفاقی که میخواهیم می افتد و با کلیک روی img اول تابع liOnClickEventListener صدا زده میشود و بعد imgOnClickEventListener.بررسی دقیق تر نحوه ی پیمایش event ها در جاوا اسکریپتخوب تا اینجا در حالت ساده گفته شد که چطوی event listener ها صدا زده می شوند و چطوی میتونیم الویت آنها را جابه جا کنیم یا از صدا زدن سایر listener ها مطلع شویم و یا از آن جلو گیری کنیم.اما ببینیم این کار ها در جاوا اسکریپت چگونه مدیریت میشوند، برای این مورد باید ۳ تا تعریف زیر رو بدونیم:نحوه ی اجرای فاز های صدا زدن event listener هاCapture PhaseTarget PhaseBubbling Phaseخوب بیایید همون مسیر مثال قبلی رو در نظر بگیریم:IMG, A, LI, UL, BODY, HTML, document, window ۱. اولین فازی که اجرا می شود Capture هست، در این فاز از بالا به پایین node ها پیمایش می شوند اون هایی که الویت بالا تری در خواست داده باشند شناسایی و اجرا می شوند. یعنی همون کاری که ما با liOnClickEventListener انجام دادیم و  با true دادن پارامتر سوم تابع addEventListener الویت بالاتری رو درخواست کردیم.پس تمام listener ها از این نوع  رو در این فاز اجرا میکند و فراموش نکنیم در این فاز top down می باشد یعنی از window که بالاترین سطح جاوا اسکریپت هست به پاییین پیمایش می شود تا به event target node برسه.۲. فاز دوم Target هست یعنی دقیق میبینه که روی کدوم node این event رخ داده و listener اون رو صدا میکند.۳. فاز سوم هم Bubbling هست که در مثال ابتدایی باهم دیدیم، در این فاز از target event node به بالا همه ی node های این مسیر رو که دارای event handler یکسان هستند رو پیدا و دونه دونه به ترتیب از پایین به بالا اون ها رو صدا میزند یعنی به صورت down top عمل می کند، برعکس فاز اول.خوب فکر میکنم با تعریف این ۳ فاز کاملا مشخص شده باشه که جاوا اسکریپت چه سیستمی برای صدا زدن event listener ها داره و میتونیم از موارد نا خواسته توی برنامه ای که مینویسیم جلو گیری کنیم.امیدورام این پست برای شما مفید بوده باشه :)اگر این پست رو دوست داشتید لطفا لایک بفرمایییید ;)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Wed, 20 Feb 2019 11:51:57 +0330</pubDate>
            </item>
                    <item>
                <title>انواع متغیر در جاوا اسکریپت و نحوه بررسی آنها</title>
                <link>https://virgool.io/JavaScript8/%DA%86%D8%B7%D9%88%D8%B1%DB%8C-data-type-%D9%87%D8%A7%DB%8C-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%B1%D9%88-%D8%A8%D9%87%D8%AA%D8%B1-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%DA%A9%D9%86%DB%8C%D9%85-zqwziwbdp6je</link>
                <description>بررسی نوع متغیر در JSهمون طوری که می دونید جاوا اسکریپت یک زبان dynamically typed  یا loosely typed هست یعنی  وقتی متغیر تعریف میکنیم نیازی نیست قبلش مشخص کنیم چه نوع مقداری میخواهیم داخلش نگه داریم یا موقعی که یک متغیر مثلا از نوع عددی داریم و میخواهیم مقدارش رو تغییر بدیم به نوع دیگری مثل string به راحتی میتوانیم این کار رو انجام دهیم.(البته پیشنهاد میکنم برای تمیز تر بودن، خوانایی بالاتر و جلوگیری از خطا های احتمالی وقتی یک متغیر در کد های جاوا اسکریپت خودتون تعریف و مقدار دهی کردید، دیگه مقداری از نوع متفاوت بهش ندید!)اما در بعضی زبان ها مثل جاوا که اصطلاحا strictly typed هستند شما باید نوع متغیر خودتون رو مشخص کنید! خوب تا اینجاش که به نظر این ویژگی جاوا اسکریپت عالیههه ! اما .......جاوا اسکریپت !!!!!!!!!!!!!!!!!!!بررسی نوع متغیر ها و مقادیر اونها یکی از مهمترین قسمت های برنامه نویسی هست و این مورد در جاوا اسکریپت با توجه به نکته ای که گفتیم کمی پیچیده تر هم میشه مخصوصا اگر بدونیم جاوا اسکریپت کلی رفتار متفاوت در شناسایی انواع مختلف متغیر ها داره که در ادامه با هم اونها رو میبینیم ;)بررسی Data Type های جاوا اسکریپت:جاوا اسکریپت ۶ نوع متغیر داره(تا قبل ES6) که به صورت زیر هستند:1. String2. Number3. Boolean4. null5. undefined6. Object شاید انتظار داشتیم Array و یا Function رو هم تو این لیست ببینیم ولی اونها تنها پیاده سازی خاصی از object  هستند! اینجاست که میگن:In JavaScript, objects are king. یه نکته ای رو هم اضافه کنم، در ES6 یک نوع جدید به اسم Symbol هم اضافه شده که پس در مجموع ۷ نوع متغیر شدند که به دو دسته تقسیم می شوند:دسته اول primitive types: یعنی تمام ۶ نوع اول به جز object، این نوع از متغیر ها مقادیر ساده ای را در حافظه نگه میدارند.دسته دوم reference type:شامل object که مجموعه ای از داده هایی هست که با name و value شناسایی می شوند.استفاده از typeof برای شناسایی نوع متغیر:با استفاده از typeof می تونیم نوع متغیر رو تشخیص دهیم تا باتوجه به نوع و مقدار اون یک عملیات خاص رو انجام بدیم یا تصمیم گیری در روند کدمون داشته باشیم. اما این مورد همیشه هم طبق اون چیزی که انتظار داریم عمل نمیکنه! پس باید کاملا رفتار اون رو درک کنیم.یک مثال ساده از typeof:var aNum = 1;
var bNum = 1.5;
console.log(typeof aNum);
console.log(typeof bNum);

//output
aNum -&gt; &#039;number&#039;
bNum -&gt; &#039;number&#039;خوب ۲ تا متغیر داشتیم یکی عدد صحیح و یکی عدد اعشاری که هر دوی اونها رو از نوع number شناسایی کرد پس همون طور که دیدیم نوع float و integer نداریم و همه ی اعداد در جاوا اسکریپت از نوع number هستند.اما چند تا از موارد کمی عجیب از typeof رو با هم ببینیم:typeof null === &#039;object&#039;;
output -&gt; trueخوب این یکی از مواردی هست که از ابتدای جاوا اسکریپت بوده و هست و خواهد بود! پس انتظار نداشته باشید typeof روی null به شما &#x27;null&#x27; برگردونه چون قراره object بگیرید!یک نمونه دیگه هم در مورد آرایه ها هست که دوباره object در جواب typeof میگیریم:typeof [1,2,3] === &#039;object&#039;;
output -&gt; trueبرای دیدن جزئیات بیشتر و لیست کامل تر این موارد به سایت mozilla بروید.خوب تا همین جا مشخص شد که در خیلی از مواقع فقط بررسی typeof نمیتونه کارساز باشه و باید در کنار اون از مواردی دیگر هم استفاده کنیم.استفاده از instanceof:یکی از مواردی که برای بررسی نوع متغیر خیلی کارساز هست instanceof هست، فرض کنیم میخواهیم بررسی کنیم که متغیری که داریم حتما آرایه باشه پس به صورت زیر این کار رو انجام میدیم:[1,2,3] instanceof Array;
output -&gt; trueبه جز instanceof هم چنین ۲ روش دیگر برای بررسی دقیق تر نوع متغیر وجود دارد که استفاده از constructor و یا صدا زدن toString روی object هست که در پست های دیگه اونها رو هم توضیح میدم.اما وقتی typeof برای null خروجی &#x27;object&#x27; میدهد چطوری null رو بررسی کنیم:function isNull(value) {
    return value === null;
}همان طور که در تابع isNull بالا دیدیم استفاده از ۳ تا علامت مساوی به جای دو تا یعنی === به جای == علاوه بر مقدار متغیر ها، نوع آنها را با هم بررسی میکند که خوب در جاوا اسکریپت بهتر هست که بسته به شرایط کدمون از ۳ تا علامت استفاده کنیم و همون طوری که اینجا دیدیم کارساز بود.نمونه ای دیگر از بررسی با ۳ تا مساوی:console.log(undefined == null); // true
console.log(undefined === null); // falseجاوا اسکریپت و NaN!:زمانی که اعمال ریاضی در جاوا اسکریپت انجام میدیم، هرموقع که مقادیر ورودی ما قابلیت انجام عمل ریاض رو نداشته باشنید احتمالا جواب NaN میگیریم که یعنی Not a Number ! اما این NaN خودش رفتار عجیبی داره که با هم میبینیم!!شما اگر مواردی مثل: تقسم ۰ با ۰ تقسیم Infinity با ‌Infinity ضرب صفر در Infinityاستفاده از متغیر غیر قابل تبدیل به عدد در محاسبات ریاضی و....انجام دهید NaN دریافت خواهید کرد که اگر typeof از آن بگیرید!:typeof NaN; 
output -&gt; &#039;number&#039;بله number گرفتیم و یکم عجیب تر از اون:NaN == NaN;
output -&gt; falseو اما روش بررسی NaN بودن جواب یک محاسبه ریاضی:var x;            // undefined
isNaN(NaN);       //true
isNaN(x);         // true
isNaN(undefined); // true
isNaN(&quot;a&quot;);       // true
isNaN(2);       // false
isNaN(&quot;2&quot;);       // false
isNaN(true);  // false
isNaN(false); // falseخوب همون طوری که دیدیم isNaN به نظر تابع قابل اعتمای میاد :D فقط یادتون باشه که Boolean ها number نیستند حتی اگر در بعضی جا ها به عدد تبدیل میشوند یعنی مثل مثال زیر که به عدد میتوان اونها رو تبدیل کرد:Number(true);  // 1
Number(false); // 0اما typeof مقادیر متفاوتی از انواع مغیر هایی که در جاوا اسکریپت دیدیم رو هم برمیگردونه:typeof 1n === &#039;bigint&#039;; // true
typeof BigInt(&#039;1&#039;) === &#039;bigint&#039;; // true

typeof function() {} === &#039;function&#039;;در آخر چند تا از خروجی های typeof در موارد مختلف رو با هم ببینیم:console.log(typeof &quot; &quot;); // &quot;string&quot;
console.log(typeof 0); // &quot;number&quot;
console.log(typeof Infinity); // &quot;number&quot;
console.log(typeof NaN); // &quot;number
console.log(typeof true); // &quot;boolean&quot;
console.log(typeof false); // &quot;boolean&quot;
console.log(typeof undefined); // &quot;undefined&quot; 
console.log(typeof null); // &quot;object&quot; 
console.log(typeof Symbol()); // &quot;symbol&quot;
console.log(typeof [ ]); // &quot;object&quot;
console.log(typeof Array(5)); // &quot;object&quot; 
console.log(typeof function() {}); // &quot;function&quot;
console.log(typeof new Date); // &quot;object&quot;
console.log(typeof {}); // &quot;object&quot;
console.log(typeof new Object); // &quot;object&quot;نتیجه گیری:در این پست با سیستم data type در جاوا اسکریپت آشنا شدیم و دیدیم که چه نوع متغیر هایی داریم و چطوری با استفاده از typeof می تونیم اونها رو بررسی کنیم و همین طور دیدیم که با توجه به بعضی خروجی های گمراه کننده typeof چطور از روش های دیگری استفاده کنیم.لطفا اگر این پست برای شما مفید بود لایک یادتون نره:)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Sat, 16 Feb 2019 13:02:47 +0330</pubDate>
            </item>
                    <item>
                <title>مرورگر ها چطوری کد های جاوا اسکریپت رو اجرا میکنند؟</title>
                <link>https://virgool.io/@vahiiiid/%D9%85%D8%B1%D9%88%D8%B1%DA%AF%D8%B1-%D9%87%D8%A7-%DA%86%D8%B7%D9%88%D8%B1%DB%8C-%DA%A9%D8%AF-%D9%87%D8%A7%DB%8C-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%B1%D9%88-%D8%A7%D8%AC%D8%B1%D8%A7-%D9%85%DB%8C%DA%A9%D9%86%D9%86%D8%AF-jhnxbxb1uglh</link>
                <description>نحوه ی اجرای کد ها در جاوا اسکریپت با hosting یکی از اولین چیز هایی که هر تازه کار جاوا اسکریپت باید کامل یادش بگیره hoisting هست! پس اگر اون رو بلد نیستید این پست رو تا آخر بخونید تا در زمان اجرای کد هاتون از اون غافلگیری های معروف جاوا اسکریپت رو تجربه نکنید !!جاوا اسکریپت در زمان کامپایل یک ذره متفاوت از اون چیزی که به نظر میاد عمل می کنه :در زمان کامپایل تمامی تعاریف متغیر ها و تعاریف توابع شما اصطلاحا hoisted میشن و به بالای کد کشیده میشن! برای درک بهتر این موضوع به مثال زیر نگاه کنید:console.log(myName);
var myName = ‘vahid’;اینجا یک متغیر به نام myName تعریف کرده ایم حالا طبق چیزی که گفتیم جاوا اسکریپت قبل از اجرای کد myName را میاره در بالاترین سطح کدمون که درواقع میشه به صورت زیر:var myName;
console.log(myName);
myName = ‘vahid’;خوب حالا فهمیدیم که چرا میتونیم یک متغیر رو قبل از تعریفش مثلا console.log بگیریم!اما یک نکته ای باید به یاد داشته باشیم اینه که جاوا اسکریپت تنها تعریف یا declaration متغیر رو hoist میکنه و نه مقدار دهی به اون رو، پس اگر کد زیر رو اجرا کنیم مقدار undefined رو تو console میبینیم:console.log(myName);
var myName = ‘vahid’;

//output -&gt; undefinedهمون طوری که می دونید اگر متغیر hoist یا lift نشده بود ما خطای Uncaught ReferenceError: myName is not defined میخوردیم و اجرای کد متوقف میشد ولی اینجا متغیر رو میشناسه ولی مقدار دهی نشده است.خوب اگه بخواهیم جمع بندی کنیم نحوه ی کامپایل کد های جاوااسکریپت رو این طوری باید در نظر بگیریم هنگام کد زدن:فرض می کنیم کد های جاوا اسکریپت ۲ بار خوانده می شوند، در بار اول کل کد خوانده می شود و هرچی تعریف متغیر و تابع هست رو میشناسه و به بالای کد میاره اما در بار دوم خط به خط اون ها رو اجرا میکنه(مقدار دهی هم این جا انجام میشه) و اینجوری کل فایل اجرا می شود.اما یک مثالی ار hoist شدن توابع رو هم با هم ببینیم:hello();
function hello(){
    console.log(&#039;Hello! I Was Hoisted to top! :D&#039;);
}

//output -&gt; Hello! I Was Hoisted to top! :Dطبق روالی که با هم دیدیم اینجا اول تابع hello به بالای فایل منتقل میشه و بعد موقع اجرا در بار دوم اول تابع تعریف میشهه و هنگام صدا زدن اون دیگه مشکلی نیست!اگر می خواهید راحت تر تو ذهنتون بمونه بار اول اجرای کد رو اینجوری در نظر بگیرید که هر چی متغیر و تابع هست تعریف میشه و دیگه درگیر اومدنشون به بالای کد نشید و فقط این رو یادتون باشه که مقدار متغیر ها بار دوم داده میشه! اگر این نکته رو در نظر نگیرید مثل کد زیر به خطا میخورید:hello();
var hello = function hello(){
    console.log(&#039;Hello! I Was Hoisted to top! :D&#039;);
}

//output -&gt; Uncaught TypeError: hello is not a function این تکه کد شبیه مثال قبلی بود ولی error گرفتیم! دلیلش هم اینه که اینجا ما تابع رو assign کردیم به یک متغیر به نام hello و اون رو بالاتر صدا زدیم. خوب الان شما میدونید جاوا اسکریپت تو بار اول متغیر hello رو تعریف میکنه ولی مقدار نمیده بهش و undefined هست پس بار دوم که میخواهد کد ها رو خط به خط اجرا کند میرسه به ;()hello و طبیعتا خطا میگیریم.کل  مفهوم hoisting همین بود ولی خیلی خیلی مهمه که وقتی کد میزنیم اون رو تو ‌‌ذهنمون داشته باشیم.شاید بعضی از دست خط های جاوا اسکریپت رو دیده باشید که تمام متغیر هاشون و هم چنین توابع رو بالای کد تعریف میکنند و  بعدا اون ها رو مقدار دهی میکنند که با این کار کد خودشون رو خیلی شبیه زمان اجرای اون میکنند که خوب کار جالبی به نظر میاد و میتونه error های احتمالی رو خیلی کمتر کنه.امیدوارم تونسته باشم مفهوم hoisting رو خوب توضیح بدم :) اگر چیزی رو  از قلم انداختم لطفا تو کامنت ها  بنویسید:)اگر هم براتون مفید بود لایک یادتون نره ;) </description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Tue, 12 Feb 2019 12:40:38 +0330</pubDate>
            </item>
                    <item>
                <title>php Code Refactoring Series - part10</title>
                <link>https://virgool.io/@vahiiiid/php-code-refactoring-series-part10-izlpgpe4wn3e</link>
                <description>سری پست های اصلاح کد ها در پی اچ پی اگر با سری پست های اصلاح کد های پی اچ پی آشنایی ندارید و یا سایر قسمت ها را نخوانده اید از اینجا شروع کنید: https://virgool.io/@vahiiiid/php-code-refactoirng-series-introduction-pckzxvccjw6f این پست یک مقدار متفاوت با شماره های قبلی هست و میخوام php-fig رو با هم ببینیم که چی هست و از یکی از استاندارد های اون برای تمیز کردن کد هامون استفاده کنیم و یک سری جزئیات دیگه :).اگر برنامه نویس php هستید قطعا با استاندارد هایی که از طرف php-fig یا همون گروه استاندارد سازی معروف PHP Framework Interop Group ارائه می شود آشنایی دارید، یا حداقل اسم بعضی از استاندارد های پر کاربرد اون مثل PSR-4 به گوشتون خورده! بله دقیقا همون استانداردی که composer برای پیاده سازی Autoloading از اون پیروی میکنه و شما توی کد های خودتون یا هر فریم ورکی که از composer برای لود فایل ها استفاده می کند استفاده کرده اید. اما PSR-4 تنها یکی از استاندارد های موجود هست و هر کدوم از استاندارد های ارائه شده در زمینه متفاوتی از هم دیگه هستند.این استاندارد ها در زبان های دیگه مانند جاوا نیز وجود دارد، برای مثال Java Specification Requests استاندارد های زبان جاوا هستند که توسط گروه Java Community Process ارائه میشه.یکم بیشتر در مورد PHP Framework Interop Group بدونیماین گروه در سال ۲۰۰۹ با هسته اولیه ۵ نفره شکل گرفته است و تا به تعداد زیادی استاندارد در زمینه های مختلف رو ارائه کرده اند که حدود ۱۲ تای اونها توی لیست Accepted یعنی نهایی شده قرار دارند.ساختار اسم گذاری استاندارد ها به این صورت هست که با psr که مخفف PHP Standard Recommendation هست شروع می شوند و با عددی که بعد از اون میاد شماره گزاری شده اند.در اینجا می توانید لیست اونها رو ببینید و با کلیک روی هر کدوم جزئیات هر استاندارد رو کامل تر بخونید.اساس کار این گروه به این صورت هست که برنامه نویس هایی از فریم ورک های فعال php جمع شده اند که الان  حدود ۲۰ نفری هستند و سعی می کنند یک سری استاندارد هایی برای نوشتن کد های php در زمینه هایی  مثل Message Interface , Coding Style Guide، Autoloading Standard و ... ایجاد کنند.بعد از شکل دهی یک استاندارد که معمولا توسط یک نفر انجام می شود اون رو به رای می گذارند و اگر طبق پروتوکل رای گیری جالبی که دارند رای بیاورد به عنوان یکی از استاندارد های ACCEPTED به لیست اضافه می شود در غیر این صورت استاندارد یا رد میشود یا اعضای گروه در مورد اون بحث و گفتگو میکنند تا اون رو کامل تر کنند که توی اکثر فریمورک ها و cms های موجود استفاده بشه.اگر می خواهید لیست اعضای فعلی و سابق php-fig رو ببییند اینجا کلیک کنید، همون طوری که تو لیست می بینید Taylor Otwell و Fabien Potencier توسعه دهنده های اصلی فریم ورک های لاراول و سیمفونی هم عضو های سابق این گروه بوده اند.متن پایین ایده اصلی این گروه طبق گفته ی رسمی خودشون هست:ایده این گروه که شامل نمایندگان پروژه های اصلی پی اچ پی یعنی فریم ورک ها و cms ها است این هست که در مورد مشترکات میان پروژه ها بحث کنیم و راه هایی را که بتوانیم با هم بهتر کار کنیم، پیدا کنیم.  اما ما بسیار آگاه هستیم که بقیه جامعه پی اچ پی نیز از این استاندارد ها استفاده خواهند کرد. بنابر این هر کس از این استاندارد ها استفاده کند قطعا راضی خواهد بود اما هیچ کس در گروه نمی خواهد شما را به عنوان یک برنامه نویس مجبور کند که چگونه برنامه خود را بنویسید.خوب فکر میکنم اطلاعات خوبی در مورد php-fig کسب کردیم بیایید یکی از استاندارد های اون رو که اتفاقا از اولین استاندارد های ثبت شده گروه هم هست رو باهم ببینیم:استاندارد استایل دهی به کد ها یا PSR-2: Coding Style Guideهدف این استاندارد همون طوی که مشخص است یکسان سازی نوشتن کد ها هست تا با صرف کم ترین زمان ممکن بتونیم کد های هم دیگه رو بخونیم و متوجه بشیم.برای مثال آیا تا به حال با خودتون فکر کردید نوشتن هر خط را تا چند کاراکتر نهایتا جلو ببرم که طولانی نشود؟آیا بلاک های کلاس خودتون رو در همان خط تعریف کلاس باز میکنید یا خط بعدی؟ در مورد شرط ها و حلقه ها چطور؟ بستن بلاک ها چی؟شایدم بعضی موقع ها که دارید تابع تعریف میکنید و تعداد ورودی ها زیاد هستند به این فکر کردید که اوکیه این تعداد ورودی یا نه؟خوب PSR-2 کلی جزئیات داره که این جور مسائل رو حل کنه و راحت بتونیم توی یک پروژه که تعدادی زیادی برنامه نویس وجود دارد کارکنیم و راحت دست خط هم دیگه رو بخونیم و چشممون به کدها کاملا آشنا باشه و کار عجیب غریبی از کسی نبینیم.یک نکته ای که باید اشاره کنم در مورد خواندن جزئیات هر استاندارد، از اونجایی که تمام نکات گفته شده داخل هر استاندارد با الویت یکسانی نیستند بنابراین از یک سری کلمات برای مشخص کردن میزان سخت گیری در رعایت کردن هر کدوم استفاده میشود.برای مثال ممکن هست بهتر باشد که یک موردی رعایت شود ولی مورد دیگری باشد که حتما باید رعایت شود پس با مفاهیم کلمات زیر باید حتما آشنا باشید که به ترتیب از الویت اجرای بالا به پایین هستند:“MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL”اما نکته آخر که جای خوشحالی داره اینه که کافیه شما این استاندارد رو روی محیطی که دارید توش کد می زنید تنظیم کنید تا خودکار برای شما تمام فایل ها تون رو مرتب کنه. مثلا اگر از phpstorm استفاده می کنید به راحتی می تونید توی قسمت File-&gt;Settings برید و  از اونجا Code Style رو از لیست باز کنید و روی PHP کلیک کنید و طبق عکس زیر Predefined Style رو روی PSR1/PSR2 بزارید.نحوه اضافه کردن psr-2 به عنوان code style در phpstormحالا داخل هر فایلی که هستید کافی هست کلید های Ctrl+Alt+l رو بزنید تا phpstrom کد های شما رو بر اساس psr-2 مرتب کنه.دلیل اینکه به جای psr-2 اینجا PSR1/PSR2 رو داشتیم این هست که psr-2 در واقع تکمیل کننده استاندارد قبلی خودش یعنی psr-1  هست پس حتما نگاهی هم به psr-1  بندازید.اما یک چیز باحال تر از این! وقتی شما  روی پروژه های بزرگ تر contribute می کنید حتی نیازی نیست که کد ها رو  قبل از ارسال مرتب کنید چون سرویس های آنلاینی هستند مثل styleci که این کار رو اتوماتیک انجام می دهند. برای مثال شما یک pull request روی پروژه github باز می کنید، ابتدا تمام کد های تغییر یافته طبق استاندارد psr-2 اصلاح می شوند و بعد pull request تایید می شود، خیلی خوبه نه؟ این جوری تعداد زیادی برنامه نویس باهم یک پروژه رو جلو می برند و هیچ سردردی هم برای خوندون merge ها نداریم و میتونیم با سرعت بیشتری بفهمیم هر کسی چه تغییراتی روی branch خودش داشته.خلاصه مطالب این پست:معرفی php-fig و psrبررسی استاندارد psr-2تنظیم این استاندارد برروی phpstormمعرفی ابزار آنلاین code stylingلطفا نظرتون رو توی کامنت ها بنویسید تا این سری پست های اصلاح کد های پی اچ پی رو با هم دیگه کامل تر کنیم.معرفی و مشاهده سایر پست های اصلاح کد های پی اچ پیراستی لایک هم لطفااااااا یادتون نره :)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Sun, 10 Feb 2019 17:26:10 +0330</pubDate>
            </item>
                    <item>
                <title>php Code Refactoring Series - part9</title>
                <link>https://virgool.io/@vahiiiid/php-code-refactoring-series-part9-qk7vzvc3oums</link>
                <description>سری پست های اصلاح کد ها در پی اچ پی  اگر با سری پست های اصلاح کد های پی اچ پی آشنایی ندارید و یا سایر قسمت ها را نخوانده اید از اینجا شروع کنید: https://virgool.io/@vahiiiid/php-code-refactoirng-series-introduction-pckzxvccjw6f در این پست با هم راه های مختلف نوشتن توابع variadic رو در پی اچ پی می بینیم تا بتونیم ضمن نوشتن این گونه توابع از داشتن توابع با تعداد زیاد ورودی هم راحت شویم تا کد تمیز تری داشته باشیم. اما variadic دقیقا چه تابعی هست؟تابع variadic یعنی تابعی که تعداد ورودی های متغیری میتونه بگیره.احتمالا شما هم در برنامه های خود با نوشتن توابعی مواجه شده اید که تعداد ورودی آنها زیاد هست (بیش از ۳ ورودی) و همان طور که میدونید همیشه به عنوان یکی از best practice های برنامه نویسی این مورد مطرح می شود که توابع نباید تعداد زیادی ورودی بگیرند، خوب راه حل های زیادی برای حل این مشکل وجود دارد:۱. استفاده از آرایه به عنوان ورودی یک راه حل ساده می تونه این باشه که ورودی تابع را یک آرایه بگیریم و هنگام صدا زدن تابع تمام ورودی های مورد نیاز رو یک آرایه کنیم و به تابع بفرستیم این مورد بسیار مرسوم هست و بزرگترین مشکل این روش  عدم آگاهی از مقادیر مورد نیاز تابع هست و کسی که می خواهد تابع شما رو صدا بزند حتما باید بیاد و کد شما رو ببینه و بفهمه که آرایه رو چه شکلی باید بسازه که تابع به خوبی کار کنه که خوب خیلی از مواقع راه حل خوبی نیست.۲. استفاده از توابع داخلی پی اچ پی راه حل دوم استفاده از توابع داخلی پی اچ پی هست که می تونند ورودی های تابع رو بدون مشخص کردن آنها جمع آوری کنند و در قالب آرایه یا هر مقداری به ما بدهند. اینجا ۳ تا از توابع پرکاربرد برای این کار رو می بینید:func_num_args()func_get_arg()func_get_args() در تکه کد زیر نحوه استفاده از تابع ()func_get_args رو می بینید که میتونه هر تعداد ورودی که به تابع پاس داده میشه رو در قالب یک آرایه به مابدهد و اینجا هم داکیومنت اون رو تو سایت پی اچ پی می تونید بخونید: function adder()
{
    $sum = 0;

    foreach (func_get_args() as $number)
    {
        $sum += $number;
    }
    
    return $sum;
}

// هردو کد زیر کار خواهند کرد
adder(1,2);
adder(1,2,3,4,5,6,7);دو تابع دیگر یعنی ()func_num_args و ()func_get_arg می تونند همزمان با هم استفاده شوند و مکمل یکدیر باشند به این صورت که func_num_args تعداد ورودی های پاس داده شده به تابع رو مشخص کند و بر اساس اون می تونیم هرکدوم از ورودی ها رو با پاس دادن ایندکس به func_get_arg مثل کد زیر دریافت کنیم:function adder()
{
    $sum = 0;
    //تعداد ورودی ها رو دریافت میکنیم
    $numberOfArgs = func_num_args();

    //می توینم از یک حلقه به تعداد ورودی ها استفاده کنیم و هر دفعه یک مقدار ورودی رو دریافت کنیم
    for ($i = 0; $i &lt; $numberOfArgs; $i++) {
        $sum += func_get_arg($i);
    }

    return $sum;
}

// هردو کد زیر کار خواهند کرد
adder(1,2);
adder(1,2,3,4,5,6,7);۳. استفاده از ویژگی splat operator یک روش دیگر استفاده از ویژگی splat operator هست که در پی اچ پی 5.6 معرفی شد. از اینجا می تونید داکیومنت اون رو مشاهده کنید و به صورت زیر هم می تونیم از اون استفاده کنیم:function adder(...$numbers)
{
    $sum = 0;

    foreach ($numbers as $number)
    {
        $sum += $number;
    }

    return $sum;
}

// هردو کد زیر کار خواهند کرد
adder(1,2);
adder(1,2,3,4,5,6,7);در اینجا numbers$... تمامی ورودی های پاس داده شده به تابع رو جمع میکنه و در قالب یک آرایه با نام numbers$ می تونیم از اونها استفاده کنیم. همان طور که دیدید استفاده از splat operator بسیار راحت هست و پی اچ پی مانند سایر زبان ها این ویژگی رو به صورت اختصاصی برای نوشتن و یا صدا زدن توابع variadic به وجود آورده است. پس با استفاده از این ۳ روش تونستیم تابع خودمون رو بنویسیم و تعداد زیادی ورودی هم نداشته باشیم،  اما در بین این راه حل ها هم قطعا اگر از پی اچ پی ورژن 5.6 و یا بالاتر استفاده می کنید بسته به شرایط کدتون می تونید از روش اول و یا سوم استفاده کنید و روش دوم با توجه به قدرت و راحتی splat operator به نظر دیگه کاربردی نخواهد داشت.لطفا نظرتون رو توی کامنت ها بنویسید تا این سری پست های اصلاح کد های پی اچ پی رو با هم دیگه کامل تر کنیم.معرفی و مشاهده سایر پست های اصلاح کد های پی اچ پیراستی لایک هم لطفااااااا یادتون نره :)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Sat, 26 Jan 2019 13:31:20 +0330</pubDate>
            </item>
                    <item>
                <title>php Code Refactoring Series - part8</title>
                <link>https://virgool.io/@vahiiiid/php-code-refactoring-series-part8-adxqnzfnorb0</link>
                <description>سری پست های اصلاح کد ها در پی اچ پی اگر با سری پست های اصلاح کد های پی اچ پی آشنایی ندارید و یا سایر قسمت ها را نخوانده اید از اینجا شروع کنید: https://virgool.io/@vahiiiid/php-code-refactoirng-series-introduction-pckzxvccjw6f یکی از ویژگی هایی که در پی اچ پی ۷ اضافه شد null coalescing operator بود که بسیار پر استفاده و پر کابرد هست و به ما هم برای اصلاح و تمیز کردن کد ها کمک خواهد کرد.این ویژگی برای جایگزین شدن به جای ترکیب استفاده از تابع ()isset و ternary اضافه شده یعنی به جای کد زیر می تونیم از null coalescing استفاده کنیم:$username = isset($_GET[&#039;username&#039;]) ? $_GET[&#039;username&#039;] : &#039;not passed&#039;;به صورت زیر می توان کد بالا رو نوشت:$username = $_GET[&#039;username&#039;] ?? &#039;not passed&#039;;خیلی ساده چک می کنه اگر یک متغیر تعریف نشده باشد و یا null باشد مقدار جدیدی را جایگزین می کند.از اونجایی که این ویژگی syntax کوتاهی دارد و خوانایی کد رو بالا می برد خیلی خوبه که از اون تو کد ها استفاده کنیم.اما بیاید یک نمونه از کاربرد اون رو با هم ببینیم:یکی از جاهایی که میشه از اون کمک گرفت برای config های پیش فرض توی کدمون هست مثلا فرض کنیم آرایه ای داریم که مقادیر پیش فرض برای run شدن پروژه رو نگه می داریم و اگر مثلا کاربر پورت مورد نظر رو وارد نکند ما از مقدار پیش فرض خودمون استفاده می کنیم:public function up(array $config)
{
    return new App(
        $config[&#039;ip&#039;] ?? APP::DEFAULT_IP,
        $config[&#039;port&#039;] ?? APP::DEFAULT_PORT,
        $config[&#039;retry_after&#039;] ?? 60
    );
}همان طوری که در کد بالا می بینید با استفاده از null coalescing تونستیم هر مقداری که به عنوان ورودی کانفیگ برای تابع ارسال نشده را جایگزین کنیم با مقادیر پیش فرض.تنها نکته ای که باید در ذهن داشته باشید این هست که null coalescing فقط در حالت null و یا زمانی که متغیر تعریف نشده false می شود و مقدار دوم را برمی گردونه پس حتی زمانی که متغیر شما برابر false باشد، 0 باشد یا هر مقدار دیگری داشته باشد مقدار خود متغیر رو برمیگردونه.حواستون باشه که null coalescing صحت متغیر شما رو بررسی نمیکنه!اگر برای حالت های دیگر مانند false و یا  0 بودن (بررسی صحت داده) نیاز به بررسی متغیر داشتید می توانید از ویژگی ternary به صورت زیر استفاده نمایید:$username = $result ? : &#039;خطایی در عملیات رخ داده است &#039;;در آخر تکه کد زیر با خروجی اون رو مشاهده کنید که کاملا گویای این نکته و تفاوت این دو ویژگی هست:$a = false ?? &#039;a&#039;
$b = false ?: &#039;b&#039;

output:
$a -&gt; false
$b -&gt; &#039;b&#039;لطفا نظرتون رو توی کامنت ها بنویسید تا این سری پست های اصلاح کد های پی اچ پی رو با هم دیگه کامل تر کنیم.معرفی و مشاهده سایر پست های اصلاح کد های پی اچ پیراستی لایک هم لطفااااااا یادتون نره :)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Mon, 21 Jan 2019 15:32:29 +0330</pubDate>
            </item>
                    <item>
                <title>php Code Refactoring Series - part7</title>
                <link>https://virgool.io/@vahiiiid/php-code-refactoring-series-part7-ifhhgctoz4gi</link>
                <description>سری پست های اصلاح کد ها در پی اچ پیاگر با سری پست های اصلاح کد های پی اچ پی آشنایی ندارید و یا سایر قسمت ها را نخوانده اید از اینجا شروع کنید: https://virgool.io/@vahiiiid/php-code-refactoirng-series-introduction-pckzxvccjw6f در ادامه پست های اصلاح کد های پی اچ پی این بار بیایید یک مورد خیلی کوچیک رو برای ساخت یک شی از کلاس و صدا زدن متدی از اون رو بررسی کنیم. پس به کد زیر رو یه نگاهی بندازید:$mailObject = new PendingMail($this);
$result =  $mailObject-&gt;cc($users);
return $result;همان طوری که تو کد مشخص هست اینجا ما قصد داریم از کلاس PendingMail فقط متد cc رو صدا بزنیم تا کاربرانی که قصد cc کردن در این ایمیل رو داریم اضافه کنیم و نتیجه رو برگردونیم.خوب پی اچ پی یک ویژگی در نسخه 5.4 اضافه کرد اون هم صدا زدن متد کلاس هنگام ساخت شی هست که می تواند به ما کمک کند که ۳ خط کد بالا را به صورت زیر بنویسیم:return (new PendingMail($this))-&gt;cc($users);نکته کوچیکی بود ولی زمانی که هدف از ساخت شی تنها و تنها صدا زدن یک متد از اون هست کاربردی هست و کمک میکنه کد ما ساده تر باشه.لطفا نظرتون رو توی کامنت ها بنویسید تا این سری پست های اصلاح کد های پی اچ پی رو با هم دیگه کامل تر کنیم.معرفی و مشاهده سایر پست های اصلاح کد های پی اچ پیراستی لایک هم لطفااااااا یادتون نره :)</description>
                <category>vahiiiid</category>
                <author>vahiiiid</author>
                <pubDate>Mon, 21 Jan 2019 14:46:04 +0330</pubDate>
            </item>
            </channel>
</rss>