<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>بایگانی‌های بک‌اند | نوین هاب</title>
	<atom:link href="https://tarahanenovin.ir/blog/category/%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C/%D8%A8%DA%A9%D8%A7%D9%86%D8%AF/feed/" rel="self" type="application/rss+xml" />
	<link>https://tarahanenovin.ir/blog/category/برنامه-نویسی/بکاند/</link>
	<description>بلاگ طراحان نوین</description>
	<lastBuildDate>Thu, 20 Aug 2026 10:58:48 +0000</lastBuildDate>
	<language>fa-IR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</generator>
	<item>
		<title>بهینه سازی Query های پیچیده SQL Server در پروژه‌های با حجم تراکنش بالا</title>
		<link>https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-query-%d9%87%d8%a7%db%8c-%d9%be%db%8c%da%86%db%8c%d8%af%d9%87-sql-server-%d8%af%d8%b1-%d9%be%d8%b1%d9%88%da%98%d9%87%d9%87%d8%a7%db%8c/</link>
					<comments>https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-query-%d9%87%d8%a7%db%8c-%d9%be%db%8c%da%86%db%8c%d8%af%d9%87-sql-server-%d8%af%d8%b1-%d9%be%d8%b1%d9%88%da%98%d9%87%d9%87%d8%a7%db%8c/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[بهینه سازی]]></category>
		<category><![CDATA[بهینه سازی کوئری]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=319</guid>

					<description><![CDATA[<p>در پروژه‌های پرتراکنش، کندی SQL Server معمولاً فقط به پیچیده بودن Query مربوط نیست. ترکیبی از ایندکس نامناسب، قفل شدن رکوردها، اجرای مکرر Query، برآورد اشتباه تعداد رکوردها و طراحی نادرست تراکنش می‌تواند زمان پاسخ را از چند میلی ثانیه به چند ثانیه افزایش دهد. در این آموزش، به جای توصیه‌های کلی، یک مسیر عملی برای پیدا کردن و اصلاح Queryهای کند در SQL Server ارائه می‌شود. قبل از تغییر Query، مشکل را اندازه گیری کنید اولین اشتباه در بهینه سازی SQL Server این است که بدون مشاهده Execution Plan یا آمار اجرای Query، شروع به تغییر کد کنیم. دو دستور زیر را فعال کنید: SET STATISTICS IO ON; SET STATISTICS TIME ON; -- Query مورد نظر SELECT * FROM Sales.Orders WHERE CustomerId = 1250; SET STATISTICS IO OFF; SET STATISTICS TIME OFF; خروجی این دستورات اطلاعات مهمی در اختیار شما قرار می‌دهد: تعداد Logical Read تعداد Physical Read زمان CPU زمان سپری شده تعداد Scan و Seek مقدار خواندن از حافظه یا دیسک تفاوت Logical Read و Physical Read Logical Read تعداد صفحات ۸ کیلوبایتی خوانده شده از Buffer Pool است. مقدار زیاد آن معمولاً نشانه اسکن گسترده یا ایندکس نامناسب است. Physical Read نشان می‌دهد SQL Server مجبور شده داده را از دیسک بخواند. در سیستم‌های پرتراکنش، Physical Read بالا می‌تواند باعث رقابت شدید روی دیسک شود. در SSMS، برای مشاهده Execution Plan واقعی از کلیدهای زیر استفاده کنید: Ctrl + M سپس Query را اجرا کنید. در Plan به این موارد توجه داشته باشید: Table Scan Index Scan Key Lookup Sort پرهزینه Hash Match هشدارهای مربوط به Implicit Conversion اختلاف بین Estimated Rows و Actual Rows بر اساس مستندات رسمی مایکروسافت، پایش مداوم Queryها، Execution Planها و Runtime Statistics پایه تصمیم گیری صحیح برای بهینه سازی است. راهنمای مانیتورینگ و بهینه سازی SQL Server در Microsoft Learn ۱. Query را با فیلتر قابل استفاده برای ایندکس بنویسید SQL Server زمانی می‌تواند از ایندکس به شکل مؤثر استفاده کند که شرط WHERE روی خود ستون قابل جستجو باشد. Query نامناسب SELECT OrderId, TotalAmount FROM Sales.Orders WHERE YEAR(OrderDate) = 2026; در این حالت، تابع YEAR روی ستون اجرا شده و SQL Server ممکن است مجبور شود تعداد زیادی از رکوردها را بررسی کند. Query اصلاح شده SELECT OrderId, TotalAmount FROM Sales.Orders WHERE OrderDate &#62;= '20260101' AND OrderDate &#60; '20270101'; این روش به SQL Server اجازه می‌دهد محدوده ایندکس را مستقیماً جستجو کند. چند نمونه رایج دیگر نامناسب WHERE CONVERT(date, CreatedAt) = '2026-08-20' مناسب WHERE CreatedAt &#62;= '20260820' AND CreatedAt &#60; '20260821' نامناسب WHERE ISNULL(Status, 0) = 1 مناسب WHERE Status = 1 در صورت نیاز، مقدار NULL را جداگانه مدیریت کنید: WHERE Status = 1 OR Status IS NULL; ۲. برای Queryهای پرتکرار ایندکس ترکیبی بسازید فرض کنید Query اصلی سیستم سفارش‌ها به شکل زیر است: SELECT OrderId, CustomerId, TotalAmount, CreatedAt FROM Sales.Orders WHERE CustomerId = @CustomerId AND Status = @Status AND CreatedAt &#62;= @FromDate AND CreatedAt &#60; @ToDate ORDER BY CreatedAt DESC; یک ایندکس مناسب می‌تواند این باشد: CREATE INDEX IX_Orders_Customer_Status_CreatedAt ON Sales.Orders ( CustomerId, Status, CreatedAt DESC ) INCLUDE ( OrderId, TotalAmount ); چرا ترتیب ستون‌ها مهم است؟ در این مثال: CustomerId و Status برای فیلتر برابری استفاده می‌شوند. CreatedAt برای فیلتر بازه‌ای و مرتب سازی استفاده می‌شود. ستون‌های OrderId و TotalAmount در بخش INCLUDE قرار گرفته‌اند تا SQL Server برای تکمیل نتیجه به جدول اصلی مراجعه نکند. ستون‌هایی که در WHERE و JOIN استفاده می‌شوند، معمولاً کاندیدهای اصلی بخش کلیدی ایندکس هستند. ستون‌هایی که فقط در SELECT قرار دارند، اغلب برای INCLUDE مناسب‌ترند. ۳. مشکل Key Lookup را برطرف کنید فرض کنید این ایندکس وجود دارد: CREATE INDEX IX_Orders_CustomerId ON Sales.Orders(CustomerId); و Query زیر اجرا می‌شود: SELECT OrderId, CustomerId, TotalAmount, CreatedAt, Status FROM Sales.Orders WHERE CustomerId = @CustomerId; SQL Server ابتدا رکوردها را از ایندکس پیدا می‌کند، اما برای خواندن سایر ستون‌ها به جدول اصلی برمی گردد. این عملیات در Execution Plan با عنوان Key Lookup نمایش داده می‌شود. اگر Query پرتکرار است، ایندکس را پوششی کنید: CREATE INDEX IX_Orders_CustomerId_Covering ON Sales.Orders(CustomerId) INCLUDE ( OrderId, TotalAmount, CreatedAt, Status ); چه زمانی Covering Index نسازیم؟ Covering Index همیشه بهترین راه حل نیست. ایجاد ایندکس بزرگ باعث افزایش هزینه این عملیات می‌شود: INSERT UPDATE DELETE عملیات نگهداری ایندکس مصرف فضای دیسک مصرف حافظه فقط برای Queryهای پرتکرار و حساس به زمان پاسخ، از این روش استفاده کنید. ۴. از SELECT * در مسیرهای پرترافیک استفاده نکنید Query نامناسب SELECT * FROM Sales.Orders WHERE CustomerId = @CustomerId; این Query به تمام ستون‌ها وابسته است. در نتیجه: حجم داده بیشتری از دیسک خوانده می‌شود. امکان استفاده از Covering Index کاهش می‌یابد. انتقال داده بین SQL Server و برنامه افزایش پیدا می‌کند. تغییر ساختار جدول می‌تواند رفتار Query را تغییر دهد. Query بهتر SELECT OrderId, CustomerId, Status, TotalAmount, CreatedAt FROM Sales.Orders WHERE CustomerId = @CustomerId; در APIها و صفحات لیست، فقط ستون‌هایی را دریافت کنید که واقعاً نمایش داده می‌شوند. ۵. Pagination را با Keyset انجام دهید در جدول‌های بزرگ، استفاده از OFFSET برای صفحات انتهایی بسیار پرهزینه است. روش پرهزینه SELECT OrderId, CreatedAt, TotalAmount FROM Sales.Orders ORDER BY CreatedAt DESC, OrderId DESC OFFSET 500000 ROWS FETCH NEXT 50 ROWS ONLY; SQL Server برای رسیدن به صفحه مورد نظر باید تعداد زیادی رکورد را مرتب و رد کند. روش Keyset Pagination در این روش، آخرین رکورد صفحه قبلی را به Query بعدی ارسال می‌کنیم: DECLARE @LastCreatedAt datetime2 = '2026-08-15 12:30:00'; DECLARE @LastOrderId bigint = 987654; SELECT TOP (50) OrderId, CreatedAt, TotalAmount FROM Sales.Orders WHERE CreatedAt &#60; @LastCreatedAt OR ( CreatedAt = @LastCreatedAt AND OrderId &#60; @LastOrderId ) ORDER BY CreatedAt DESC, OrderId DESC; برای این Query ایندکس زیر مناسب است: CREATE INDEX IX_Orders_CreatedAt_OrderId ON Sales.Orders(CreatedAt DESC, OrderId DESC) INCLUDE ( TotalAmount ); این روش برای جدول‌های سفارش، تراکنش مالی، گزارش رخدادها و لاگ‌های حجیم عملکرد پایدارتری دارد. ۶. مراقب Parameter Sniffing باشید SQL Server معمولاً هنگام اولین اجرای Stored Procedure، مقدار پارامترها را بررسی کرده و بر اساس آن Execution Plan می‌سازد. اگر توزیع داده یکنواخت نباشد، یک Plan ممکن است برای یک مقدار مناسب و برای مقدار دیگر بسیار ضعیف باشد. فرض کنید یک مشتری فقط ۱۰ سفارش دارد، اما مشتری دیگری چند میلیون سفارش ثبت کرده است: CREATE OR ALTER PROCEDURE Sales.GetCustomerOrders @CustomerId bigint AS BEGIN SET NOCOUNT ON; SELECT OrderId, CreatedAt, TotalAmount, Status FROM Sales.Orders WHERE CustomerId = @CustomerId; END; ممکن است Plan ساخته شده برای مشتری کم تراکنش، هنگام اجرای Query برای مشتری بزرگ مناسب نباشد. راه حل اول: بازکامپایل در همان اجرا SELECT OrderId, CreatedAt, TotalAmount, Status FROM Sales.Orders WHERE CustomerId = @CustomerId OPTION (RECOMPILE); این روش برای Queryهایی مناسب است که: تعداد اجرای آنها بسیار زیاد نیست. اختلاف حجم داده بین پارامترها زیاد است. زمان ساخت Plan نسبت به هزینه اجرای اشتباه کمتر است. راه حل دوم: استفاده از OPTIMIZE FOR UNKNOWN SELECT OrderId, CreatedAt, TotalAmount, Status FROM Sales.Orders WHERE CustomerId = @CustomerId OPTION (OPTIMIZE FOR UNKNOWN); در این روش SQL Server از مقدار واقعی پارامتر برای ساخت Plan استفاده نمی‌کند و برآورد عمومی‌تری انجام می‌دهد. راه حل سوم: متغیر محلی DECLARE @LocalCustomerId bigint = @CustomerId; SELECT OrderId, CreatedAt, TotalAmount, Status FROM Sales.Orders WHERE CustomerId = @LocalCustomerId; این روش گاهی مشکل را کاهش می‌دهد، اما ممکن است برآورد SQL Server را ضعیف کند. بنابراین باید با Execution Plan و آمار واقعی آزمایش شود. ۷. Implicit Conversion را حذف کنید تبدیل ضمنی نوع داده می‌تواند مانع استفاده صحیح از ایندکس شود. فرض کنید نوع ستون CustomerId از نوع bigint است: CREATE TABLE Sales.Orders ( OrderId bigint NOT NULL, CustomerId bigint NOT NULL ); اما برنامه مقدار را به صورت nvarchar ارسال می‌کند: WHERE CustomerId = N'1250' ممکن است SQL Server مجبور به تبدیل نوع داده شود. در Execution Plan، هشدار CONVERT_IMPLICIT را بررسی کنید. روش صحیح نوع پارامتر در برنامه و Stored Procedure باید با نوع ستون یکسان باشد: CREATE OR ALTER PROCEDURE Sales.GetOrders @CustomerId bigint AS BEGIN SET NOCOUNT ON; SELECT OrderId, CreatedAt, TotalAmount FROM Sales.Orders WHERE CustomerId = @CustomerId; END; در پروژه‌های .NET نیز نوع پارامتر را صحیح مشخص کنید: command.Parameters.Add("@CustomerId", SqlDbType.BigInt).Value = customerId; ۸. JOIN را با ستون‌های درست و ایندکس مناسب اجرا کنید فرض کنید Query زیر برای نمایش سفارش‌های مشتری اجرا می‌شود: SELECT o.OrderId, o.CreatedAt, c.CustomerName, o.TotalAmount FROM Sales.Orders AS o INNER JOIN Sales.Customers AS c ON c.CustomerId = o.CustomerId WHERE o.Status = 1 AND o.CreatedAt &#62;= @FromDate; ایندکس‌های پیشنهادی: CREATE INDEX IX_Orders_Status_CreatedAt_CustomerId ON Sales.Orders(Status, CreatedAt, CustomerId) INCLUDE ( OrderId, TotalAmount ); و در جدول مشتری: CREATE UNIQUE INDEX UX_Customers_CustomerId ON Sales.Customers(CustomerId) INCLUDE ( CustomerName ); از JOIN غیرضروری جلوگیری کنید اگر هیچ ستونی از جدول مشتری استفاده نمی‌شود، این JOIN را حذف کنید: SELECT o.OrderId, o.TotalAmount FROM Sales.Orders AS o INNER JOIN Sales.Customers AS c ON c.CustomerId = o.CustomerId WHERE o.Status = 1; نسخه ساده‌تر: SELECT OrderId, TotalAmount FROM Sales.Orders WHERE Status = 1; هر JOIN اضافی می‌تواند هزینه CPU، حافظه و I/O را افزایش دهد. ۹. به جای IN بزرگ از روش مناسب استفاده کنید روش مشکل ساز SELECT OrderId, TotalAmount FROM Sales.Orders WHERE OrderId IN ( 100001, 100002, 100003, 100004 ); برای تعداد کم شناسه مشکلی ایجاد نمی‌کند، اما در برنامه‌های پرترافیک و فهرست‌های بزرگ، بهتر است از Table-Valued Parameter استفاده شود. تعریف نوع جدولی CREATE TYPE Sales.OrderIdList AS TABLE ( OrderId bigint NOT NULL PRIMARY KEY ); Stored Procedure CREATE OR ALTER PROCEDURE Sales.GetOrdersByIds @OrderIds Sales.OrderIdList READONLY AS BEGIN SET NOCOUNT ON; SELECT o.OrderId, o.CustomerId, o.TotalAmount, o.Status FROM Sales.Orders AS o INNER JOIN @OrderIds AS ids ON ids.OrderId = o.OrderId; END; این روش نسبت به ساختن رشته‌های طولانی و Dynamic SQL قابل کنترل‌تر و امن‌تر است. ۱۰. LIKE را برای جستجوی متنی درست انتخاب کنید Query قابل استفاده از ایندکس WHERE CustomerName LIKE @Search + N'%' Query پرهزینه WHERE CustomerName LIKE N'%' + @Search + N'%' در حالت دوم، SQL Server معمولاً نمی‌تواند از ایندکس معمولی برای پیدا کردن ابتدای عبارت استفاده کند. برای جستجوی واقعی در متن‌های بزرگ، Full-Text Search گزینه مناسب‌تری است: CREATE FULLTEXT CATALOG CustomerCatalog AS DEFAULT; سپس روی ستون مورد نظر Full-Text Index ایجاد کنید و Query را با CONTAINS یا FREETEXT اجرا کنید: SELECT CustomerId, CustomerName FROM Sales.Customers WHERE CONTAINS(CustomerName, @SearchTerm); ۱۱. تراکنش‌ها را کوتاه نگه دارید در سیستم پرتراکنش، تراکنش طولانی فقط یک مشکل عملکردی نیست؛ بلکه باعث Blocking و افزایش زمان انتظار سایر درخواست‌ها می‌شود. الگوی نامناسب BEGIN TRANSACTION; SELECT * FROM Sales.Orders WHERE OrderId = @OrderId; -- پردازش طولانی در برنامه -- ارسال درخواست به سرویس خارجی -- محاسبه سنگین UPDATE Sales.Orders SET Status = 2 WHERE OrderId = @OrderId; COMMIT TRANSACTION; در این فاصله، قفل‌ها ممکن است بیشتر از زمان لازم حفظ شوند. الگوی بهتر ابتدا اطلاعات لازم را بخوانید، پردازش‌های خارج از دیتابیس را انجام دهید و فقط عملیات نهایی را در تراکنش قرار دهید: SELECT OrderId, Status, TotalAmount FROM Sales.Orders WHERE OrderId = @OrderId; سپس: SET XACT_ABORT ON; BEGIN TRY BEGIN TRANSACTION; UPDATE Sales.Orders SET Status = 2, UpdatedAt = SYSUTCDATETIME() WHERE OrderId = @OrderId AND Status = 1; IF @@ROWCOUNT = 0 THROW 50001, 'Order is not available for update.', 1; INSERT INTO Sales.OrderStatusHistory ( OrderId, OldStatus, NewStatus, CreatedAt ) VALUES ( @OrderId, 1, 2, SYSUTCDATETIME() ); COMMIT TRANSACTION; END TRY BEGIN CATCH IF XACT_STATE() &#60;&#62; 0 ROLLBACK TRANSACTION; THROW; END CATCH; نکته مهم شرط وضعیت در دستور UPDATE نقش کنترل همزمانی دارد: WHERE OrderId = @OrderId AND Status = 1 به این ترتیب، اگر درخواست دیگری قبلاً وضعیت سفارش را تغییر داده باشد، عملیات فعلی بدون بررسی اضافی شکست می‌خورد. ۱۲. Blocking و Deadlock را بررسی کنید برای مشاهده درخواست‌های در حال انتظار: SELECT r.session_id, r.status, r.command, r.wait_type, r.wait_time, r.blocking_session_id, r.cpu_time, r.logical_reads, t.text AS SqlText FROM sys.dm_exec_requests AS r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t WHERE r.session_id &#60;&#62; @@SPID ORDER BY r.wait_time DESC; برای پیدا کردن Sessionهای مسدود شده: SELECT session_id, blocking_session_id, wait_type, wait_time, wait_resource FROM sys.dm_exec_requests WHERE blocking_session_id &#60;&#62; 0; علت‌های رایج Blocking تراکنش‌های طولانی نبود ایندکس روی شرط UPDATE یا DELETE اسکن گسترده جدول اجرای گزارش سنگین روی جداول عملیاتی ترتیب متفاوت دسترسی به جداول در تراکنش‌های مختلف به روز رسانی دسته‌ای در ساعات شلوغ الگوی کاهش Deadlock در تمام بخش‌های برنامه، ترتیب دسترسی به جداول را ثابت کنید. برای مثال، اگر یک تراکنش ابتدا Customers و سپس Orders را تغییر می‌دهد، تراکنش دیگر نباید ابتدا Orders و بعد Customers را تغییر دهد. همچنین عملیات بزرگ را به بخش‌های کوچک‌تر تقسیم کنید: WHILE 1 = 1 BEGIN DELETE TOP (1000) FROM Audit.Logs WHERE CreatedAt &#60; @BeforeDate; IF @@ROWCOUNT = 0 BREAK; END; ۱۳. سطح Isolation را آگاهانه انتخاب کنید در بسیاری از سیستم‌های OLTP، خواندن‌های طولانی با نوشتن‌ها تداخل ایجاد می‌کنند. یکی از راهکارهای مهم، فعال کردن READ_COMMITTED_SNAPSHOT است: ALTER DATABASE [SalesDb] SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE; در این حالت، خواندن‌های معمولی از Version Store در tempdb استفاده می‌کنند و معمولاً کمتر منتظر قفل‌های نوشتاری می‌مانند. اما پیش از فعال سازی باید موارد زیر بررسی شود: فضای کافی برای tempdb حجم Update و Delete مدت اجرای تراکنش‌ها مصرف Version Store سازگاری برنامه با رفتار جدید خواندن برای تراکنش‌هایی که نیاز به ثبات کامل داده دارند، سطح Isolation را بدون بررسی تغییر ندهید. ۱۴. Statistics را به روز نگه دارید اگر Statistics قدیمی باشد، SQL Server ممکن است تعداد رکوردهای خروجی را اشتباه تخمین بزند و Join یا ایندکس نامناسب انتخاب کند. به روز رسانی دستی: UPDATE STATISTICS Sales.Orders WITH FULLSCAN; برای جدول‌های بزرگ، FULLSCAN ممکن است پرهزینه باشد. بنابراین آن را در ساعات مناسب و با بررسی زمان اجرا انجام دهید. مشاهده زمان آخرین به روز رسانی Statistics: SELECT OBJECT_SCHEMA_NAME(sp.object_id) AS SchemaName, OBJECT_NAME(sp.object_id) AS TableName, sp.stats_id, sp.last_updated, sp.rows, sp.rows_sampled, sp.modification_counter FROM sys.dm_db_stats_properties ( OBJECT_ID(N'Sales.Orders'), 1 ) AS sp; در پروژه‌هایی که داده به سرعت تغییر می‌کند، فقط فعال بودن Auto Update Statistics کافی نیست. آمار Query Store، زمان اجرای Query و تغییرات داده را نیز بررسی کنید. ۱۵. Query Store را فعال و بررسی کنید Query Store برای پیدا کردن Queryهایی که در طول زمان کند شده‌اند بسیار کاربردی است. فعال سازی: ALTER DATABASE [SalesDb] SET QUERY_STORE = ON; برای پیدا کردن Queryهای پرهزینه: SELECT TOP (20) qt.query_sql_text, rs.execution_count, rs.avg_duration, rs.avg_cpu_time, rs.avg_logical_io_reads, rs.last_execution_time FROM sys.query_store_query_text AS qt INNER JOIN sys.query_store_query AS q ON q.query_text_id = qt.query_text_id INNER JOIN sys.query_store_plan AS p ON p.query_id = q.query_id INNER JOIN sys.query_store_runtime_stats AS rs ON rs.plan_id = p.plan_id ORDER BY rs.avg_duration DESC; برای پیدا کردن Queryهایی که بیشترین مجموع زمان را مصرف کرده‌اند: SELECT TOP (20) qt.query_sql_text, SUM(rs.count_executions) AS TotalExecutions, SUM(rs.avg_duration * rs.count_executions) AS TotalDuration FROM sys.query_store_query_text AS qt INNER JOIN sys.query_store_query AS q ON q.query_text_id = qt.query_text_id INNER JOIN sys.query_store_plan AS p ON p.query_id = q.query_id INNER JOIN sys.query_store_runtime_stats AS rs ON rs.plan_id = p.plan_id GROUP BY qt.query_sql_text ORDER BY TotalDuration DESC; گاهی Queryای که میانگین زمان کمی دارد، به دلیل تعداد اجرای بسیار زیاد، بیشترین فشار را به SQL Server وارد می‌کند. ۱۶. برای اصلاح Query از این ترتیب استفاده کنید برای هر Query پیچیده، این مراحل را به صورت مشخص انجام دهید: مرحله اول: اجرای فعلی را ثبت کنید زمان متوسط زمان صدک ۹۵ و ۹۹ CPU Logical Read تعداد اجرا تعداد Timeout Wait Type مرحله دوم: Execution Plan را بررسی کنید به دنبال این موارد باشید: Scan روی جدول بزرگ اختلاف Estimated Rows و Actual Rows Key Lookup تکرارشونده Sort بدون ایندکس مناسب Hash Join ناشی از کمبود ایندکس یا برآورد اشتباه Implicit Conversion Spill به tempdb مرحله سوم: Query را اصلاح کنید حذف SELECT * حذف تابع از روی ستون فیلتر اصلاح Pagination حذف JOIN غیرضروری اصلاح نوع پارامترها کاهش تعداد ستون‌های خروجی مرحله چهارم: ایندکس را بررسی کنید آیا ایندکس با الگوی واقعی Query هماهنگ است؟ آیا ترتیب ستون‌ها صحیح است؟ آیا Query نیاز به INCLUDE دارد؟ آیا ایندکس مشابه از قبل وجود دارد؟ هزینه این ایندکس برای عملیات نوشتن چقدر است؟ مرحله پنجم: زیر بار واقعی آزمایش کنید Query فقط در محیط توسعه آزمایش نشود. حجم داده، همزمانی کاربران، پارامترهای مختلف و زمان‌های پرترافیک را شبیه سازی کنید. نمونه کامل بررسی یک Query Query اولیه SELECT * FROM Sales.Orders WHERE CONVERT(date, CreatedAt) = @OrderDate AND CustomerId IN ( SELECT CustomerId FROM Sales.Customers WHERE IsActive = 1 ) ORDER BY CreatedAt DESC OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY; مشکل‌های این Query: استفاده از تابع روی CreatedAt استفاده از SELECT * Pagination با OFFSET در صفحات بزرگ احتمال اسکن جدول Customers نامشخص بودن ایندکس‌های مورد نیاز نسخه اصلاح شده SELECT TOP (@PageSize) o.OrderId, o.CustomerId, o.CreatedAt, o.TotalAmount, o.Status FROM Sales.Orders AS o INNER JOIN Sales.Customers AS c ON c.CustomerId = o.CustomerId WHERE c.IsActive = 1 AND ( o.CreatedAt &#60; @LastCreatedAt OR ( o.CreatedAt = @LastCreatedAt AND o.OrderId &#60; @LastOrderId ) ) ORDER BY o.CreatedAt DESC, o.OrderId DESC; ایندکس‌های پیشنهادی: CREATE INDEX IX_Customers_IsActive_CustomerId ON Sales.Customers(IsActive, CustomerId); CREATE INDEX IX_Orders_CreatedAt_OrderId_CustomerId ON Sales.Orders(CreatedAt DESC, OrderId DESC, CustomerId) INCLUDE ( TotalAmount, Status ); این نسخه برای صفحه‌های انتهایی، خواندن ستون‌های محدود و اجرای پرتکرار، قابلیت مقیاس پذیری بیشتری دارد. چه کارهایی معمولاً نتیجه معکوس دارند؟ ایجاد ایندکس برای هر ستون تعداد زیاد ایندکس، عملیات نوشتن را کند می‌کند و فضای زیادی مصرف می‌کند. استفاده دائمی از NOLOCK SELECT * FROM Sales.Orders WITH (NOLOCK); NOLOCK ممکن است Dirty Read، رکوردهای تکراری یا داده‌های ناپایدار برگرداند. این دستور راه حل عمومی برای مشکل Blocking نیست. استفاده بی دلیل از OPTION (RECOMPILE) برای Queryهای پرتکرار، بازسازی Plan در هر اجرا می‌تواند CPU را افزایش دهد. انتقال همه Queryها به Stored Procedure Stored Procedure مفید است، اما اگر منطق Query، ایندکس یا مدل داده نادرست باشد، صرفاً قرار دادن کد در Stored Procedure مشکل را حل نمی‌کند. افزایش سخت افزار بدون اصلاح Query افزایش RAM یا CPU گاهی کمک می‌کند، اما Query دارای اسکن، Sort یا Blocking همچنان در حجم بالاتر مشکل ایجاد خواهد کرد. چک لیست نهایی بهینه سازی Query در SQL Server پیش از انتشار تغییرات، این موارد را بررسی کنید: Execution Plan واقعی مشاهده شده است. Logical Read قبل و بعد مقایسه شده است. زمان CPU و زمان سپری شده ثبت شده است. Query از SELECT * استفاده نمی‌کند. روی ستون‌های فیلتر تابع اجرا نمی‌شود. نوع پارامتر با نوع ستون یکسان است. ایندکس ترکیبی بر اساس الگوی واقعی Query طراحی شده است. Key Lookup غیرضروری حذف شده است. Pagination برای صفحات بزرگ با Keyset انجام می‌شود. تراکنش‌ها کوتاه هستند. Blocking و Deadlock بررسی شده‌اند. Statistics و Query Store در نظر گرفته شده‌اند. Query با پارامترهای کم حجم و پرحجم آزمایش شده است. تأثیر ایندکس جدید بر INSERT و UPDATE بررسی شده است. جمع بندی بهینه...</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-query-%d9%87%d8%a7%db%8c-%d9%be%db%8c%da%86%db%8c%d8%af%d9%87-sql-server-%d8%af%d8%b1-%d9%be%d8%b1%d9%88%da%98%d9%87%d9%87%d8%a7%db%8c/">بهینه سازی Query های پیچیده SQL Server در پروژه‌های با حجم تراکنش بالا</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<p dir="rtl" lang="fa">در پروژه‌های پرتراکنش، کندی SQL Server معمولاً فقط به پیچیده بودن Query مربوط نیست. ترکیبی از ایندکس نامناسب، قفل شدن رکوردها، اجرای مکرر Query، برآورد اشتباه تعداد رکوردها و طراحی نادرست تراکنش می‌تواند زمان پاسخ را از چند میلی ثانیه به چند ثانیه افزایش دهد.</p>
<p dir="rtl" lang="fa">در این آموزش، به جای توصیه‌های کلی، یک مسیر عملی برای پیدا کردن و اصلاح Queryهای کند در SQL Server ارائه می‌شود.</p>
<h2 dir="rtl" lang="fa">قبل از تغییر Query، مشکل را اندازه گیری کنید</h2>
<p dir="rtl" lang="fa">اولین اشتباه در بهینه سازی SQL Server این است که بدون مشاهده Execution Plan یا آمار اجرای Query، شروع به تغییر کد کنیم.</p>
<p dir="rtl" lang="fa">دو دستور زیر را فعال کنید:</p>
<pre><code class="hljs"><span class="hljs-keyword">SET</span> STATISTICS IO <span class="hljs-keyword">ON</span>;
<span class="hljs-keyword">SET</span> STATISTICS <span class="hljs-type">TIME</span> <span class="hljs-keyword">ON</span>;

<span class="hljs-comment">-- Query مورد نظر</span>
<span class="hljs-keyword">SELECT</span> <span class="hljs-operator">*</span>
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-number">1250</span>;

<span class="hljs-keyword">SET</span> STATISTICS IO OFF;
<span class="hljs-keyword">SET</span> STATISTICS <span class="hljs-type">TIME</span> OFF;
</code></pre>
<p dir="rtl" lang="fa">خروجی این دستورات اطلاعات مهمی در اختیار شما قرار می‌دهد:</p>
<ul dir="rtl" lang="fa">
<li>تعداد Logical Read</li>
<li>تعداد Physical Read</li>
<li>زمان CPU</li>
<li>زمان سپری شده</li>
<li>تعداد Scan و Seek</li>
<li>مقدار خواندن از حافظه یا دیسک</li>
</ul>
<h3 dir="rtl" lang="fa">تفاوت Logical Read و Physical Read</h3>
<p dir="rtl" lang="fa"><code>Logical Read</code> تعداد صفحات ۸ کیلوبایتی خوانده شده از Buffer Pool است. مقدار زیاد آن معمولاً نشانه اسکن گسترده یا ایندکس نامناسب است.</p>
<p dir="rtl" lang="fa"><code>Physical Read</code> نشان می‌دهد SQL Server مجبور شده داده را از دیسک بخواند. در سیستم‌های پرتراکنش، Physical Read بالا می‌تواند باعث رقابت شدید روی دیسک شود.</p>
<p dir="rtl" lang="fa">در SSMS، برای مشاهده Execution Plan واقعی از کلیدهای زیر استفاده کنید:</p>
<pre><code class="hljs">Ctrl + M
</code></pre>
<p dir="rtl" lang="fa">سپس Query را اجرا کنید. در Plan به این موارد توجه داشته باشید:</p>
<ul dir="rtl" lang="fa">
<li>Table Scan</li>
<li>Index Scan</li>
<li>Key Lookup</li>
<li>Sort پرهزینه</li>
<li>Hash Match</li>
<li>هشدارهای مربوط به Implicit Conversion</li>
<li>اختلاف بین Estimated Rows و Actual Rows</li>
</ul>
<p dir="rtl" lang="fa">بر اساس مستندات رسمی مایکروسافت، پایش مداوم Queryها، Execution Planها و Runtime Statistics پایه تصمیم گیری صحیح برای بهینه سازی است. <a href="https://learn.microsoft.com/en-us/sql/relational-databases/performance/monitor-and-tune-for-performance?view=sql-server-ver16" target="_blank" rel="nofollow noopener noreferrer">راهنمای مانیتورینگ و بهینه سازی SQL Server در Microsoft Learn</a></p>
<h2 dir="rtl" lang="fa">۱. Query را با فیلتر قابل استفاده برای ایندکس بنویسید</h2>
<p dir="rtl" lang="fa">SQL Server زمانی می‌تواند از ایندکس به شکل مؤثر استفاده کند که شرط <code>WHERE</code> روی خود ستون قابل جستجو باشد.</p>
<h3 dir="rtl" lang="fa">Query نامناسب</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> OrderId, TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">YEAR</span>(OrderDate) <span class="hljs-operator">=</span> <span class="hljs-number">2026</span>;
</code></pre>
<p dir="rtl" lang="fa">در این حالت، تابع <code>YEAR</code> روی ستون اجرا شده و SQL Server ممکن است مجبور شود تعداد زیادی از رکوردها را بررسی کند.</p>
<h3 dir="rtl" lang="fa">Query اصلاح شده</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> OrderId, TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> OrderDate <span class="hljs-operator">&gt;=</span> <span class="hljs-string">'20260101'</span>
  <span class="hljs-keyword">AND</span> OrderDate <span class="hljs-operator">&lt;</span>  <span class="hljs-string">'20270101'</span>;
</code></pre>
<p dir="rtl" lang="fa">این روش به SQL Server اجازه می‌دهد محدوده ایندکس را مستقیماً جستجو کند.</p>
<h3 dir="rtl" lang="fa">چند نمونه رایج دیگر</h3>
<h4 dir="rtl" lang="fa">نامناسب</h4>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">CONVERT</span>(<span class="hljs-type">date</span>, CreatedAt) <span class="hljs-operator">=</span> <span class="hljs-string">'2026-08-20'</span>
</code></pre>
<h4 dir="rtl" lang="fa">مناسب</h4>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> CreatedAt <span class="hljs-operator">&gt;=</span> <span class="hljs-string">'20260820'</span>
  <span class="hljs-keyword">AND</span> CreatedAt <span class="hljs-operator">&lt;</span>  <span class="hljs-string">'20260821'</span>
</code></pre>
<h4 dir="rtl" lang="fa">نامناسب</h4>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> ISNULL(Status, <span class="hljs-number">0</span>) <span class="hljs-operator">=</span> <span class="hljs-number">1</span>
</code></pre>
<h4 dir="rtl" lang="fa">مناسب</h4>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> Status <span class="hljs-operator">=</span> <span class="hljs-number">1</span>
</code></pre>
<p dir="rtl" lang="fa">در صورت نیاز، مقدار <code>NULL</code> را جداگانه مدیریت کنید:</p>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> Status <span class="hljs-operator">=</span> <span class="hljs-number">1</span>
   <span class="hljs-keyword">OR</span> Status <span class="hljs-keyword">IS</span> <span class="hljs-keyword">NULL</span>;
</code></pre>
<h2 dir="rtl" lang="fa">۲. برای Queryهای پرتکرار ایندکس ترکیبی بسازید</h2>
<p dir="rtl" lang="fa">فرض کنید Query اصلی سیستم سفارش‌ها به شکل زیر است:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> OrderId, CustomerId, TotalAmount, CreatedAt
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>
  <span class="hljs-keyword">AND</span> Status <span class="hljs-operator">=</span> <span class="hljs-variable">@Status</span>
  <span class="hljs-keyword">AND</span> CreatedAt <span class="hljs-operator">&gt;=</span> <span class="hljs-variable">@FromDate</span>
  <span class="hljs-keyword">AND</span> CreatedAt <span class="hljs-operator">&lt;</span> <span class="hljs-variable">@ToDate</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> CreatedAt <span class="hljs-keyword">DESC</span>;
</code></pre>
<p dir="rtl" lang="fa">یک ایندکس مناسب می‌تواند این باشد:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> INDEX IX_Orders_Customer_Status_CreatedAt
<span class="hljs-keyword">ON</span> Sales.Orders
(
    CustomerId,
    Status,
    CreatedAt <span class="hljs-keyword">DESC</span>
)
INCLUDE
(
    OrderId,
    TotalAmount
);
</code></pre>
<h3 dir="rtl" lang="fa">چرا ترتیب ستون‌ها مهم است؟</h3>
<p dir="rtl" lang="fa">در این مثال:</p>
<ul dir="rtl" lang="fa">
<li><code>CustomerId</code> و <code>Status</code> برای فیلتر برابری استفاده می‌شوند.</li>
<li><code>CreatedAt</code> برای فیلتر بازه‌ای و مرتب سازی استفاده می‌شود.</li>
<li>ستون‌های <code>OrderId</code> و <code>TotalAmount</code> در بخش <code>INCLUDE</code> قرار گرفته‌اند تا SQL Server برای تکمیل نتیجه به جدول اصلی مراجعه نکند.</li>
</ul>
<p dir="rtl" lang="fa">ستون‌هایی که در <code>WHERE</code> و <code>JOIN</code> استفاده می‌شوند، معمولاً کاندیدهای اصلی بخش کلیدی ایندکس هستند. ستون‌هایی که فقط در <code>SELECT</code> قرار دارند، اغلب برای <code>INCLUDE</code> مناسب‌ترند.</p>
<h2 dir="rtl" lang="fa">۳. مشکل Key Lookup را برطرف کنید</h2>
<p dir="rtl" lang="fa">فرض کنید این ایندکس وجود دارد:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> INDEX IX_Orders_CustomerId
<span class="hljs-keyword">ON</span> Sales.Orders(CustomerId);
</code></pre>
<p dir="rtl" lang="fa">و Query زیر اجرا می‌شود:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> OrderId, CustomerId, TotalAmount, CreatedAt, Status
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>;
</code></pre>
<p dir="rtl" lang="fa">SQL Server ابتدا رکوردها را از ایندکس پیدا می‌کند، اما برای خواندن سایر ستون‌ها به جدول اصلی برمی گردد. این عملیات در Execution Plan با عنوان <code>Key Lookup</code> نمایش داده می‌شود.</p>
<p dir="rtl" lang="fa">اگر Query پرتکرار است، ایندکس را پوششی کنید:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> INDEX IX_Orders_CustomerId_Covering
<span class="hljs-keyword">ON</span> Sales.Orders(CustomerId)
INCLUDE
(
    OrderId,
    TotalAmount,
    CreatedAt,
    Status
);
</code></pre>
<h3 dir="rtl" lang="fa">چه زمانی Covering Index نسازیم؟</h3>
<p dir="rtl" lang="fa">Covering Index همیشه بهترین راه حل نیست. ایجاد ایندکس بزرگ باعث افزایش هزینه این عملیات می‌شود:</p>
<ul dir="rtl" lang="fa">
<li><code>INSERT</code></li>
<li><code>UPDATE</code></li>
<li><code>DELETE</code></li>
<li>عملیات نگهداری ایندکس</li>
<li>مصرف فضای دیسک</li>
<li>مصرف حافظه</li>
</ul>
<p dir="rtl" lang="fa">فقط برای Queryهای پرتکرار و حساس به زمان پاسخ، از این روش استفاده کنید.</p>
<h2 dir="rtl" lang="fa">۴. از SELECT * در مسیرهای پرترافیک استفاده نکنید</h2>
<h3 dir="rtl" lang="fa">Query نامناسب</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> <span class="hljs-operator">*</span>
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>;
</code></pre>
<p dir="rtl" lang="fa">این Query به تمام ستون‌ها وابسته است. در نتیجه:</p>
<ul dir="rtl" lang="fa">
<li>حجم داده بیشتری از دیسک خوانده می‌شود.</li>
<li>امکان استفاده از Covering Index کاهش می‌یابد.</li>
<li>انتقال داده بین SQL Server و برنامه افزایش پیدا می‌کند.</li>
<li>تغییر ساختار جدول می‌تواند رفتار Query را تغییر دهد.</li>
</ul>
<h3 dir="rtl" lang="fa">Query بهتر</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    OrderId,
    CustomerId,
    Status,
    TotalAmount,
    CreatedAt
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>;
</code></pre>
<p dir="rtl" lang="fa">در APIها و صفحات لیست، فقط ستون‌هایی را دریافت کنید که واقعاً نمایش داده می‌شوند.</p>
<h2 dir="rtl" lang="fa">۵. Pagination را با Keyset انجام دهید</h2>
<p dir="rtl" lang="fa">در جدول‌های بزرگ، استفاده از <code>OFFSET</code> برای صفحات انتهایی بسیار پرهزینه است.</p>
<h3 dir="rtl" lang="fa">روش پرهزینه</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    OrderId,
    CreatedAt,
    TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> CreatedAt <span class="hljs-keyword">DESC</span>, OrderId <span class="hljs-keyword">DESC</span>
<span class="hljs-keyword">OFFSET</span> <span class="hljs-number">500000</span> <span class="hljs-keyword">ROWS</span>
<span class="hljs-keyword">FETCH</span> NEXT <span class="hljs-number">50</span> <span class="hljs-keyword">ROWS</span> <span class="hljs-keyword">ONLY</span>;
</code></pre>
<p dir="rtl" lang="fa">SQL Server برای رسیدن به صفحه مورد نظر باید تعداد زیادی رکورد را مرتب و رد کند.</p>
<h3 dir="rtl" lang="fa">روش Keyset Pagination</h3>
<p dir="rtl" lang="fa">در این روش، آخرین رکورد صفحه قبلی را به Query بعدی ارسال می‌کنیم:</p>
<pre><code class="hljs"><span class="hljs-keyword">DECLARE</span> <span class="hljs-variable">@LastCreatedAt</span> datetime2 <span class="hljs-operator">=</span> <span class="hljs-string">'2026-08-15 12:30:00'</span>;
<span class="hljs-keyword">DECLARE</span> <span class="hljs-variable">@LastOrderId</span> <span class="hljs-type">bigint</span> <span class="hljs-operator">=</span> <span class="hljs-number">987654</span>;

<span class="hljs-keyword">SELECT</span> TOP (<span class="hljs-number">50</span>)
    OrderId,
    CreatedAt,
    TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span>
    CreatedAt <span class="hljs-operator">&lt;</span> <span class="hljs-variable">@LastCreatedAt</span>
    <span class="hljs-keyword">OR</span>
    (
        CreatedAt <span class="hljs-operator">=</span> <span class="hljs-variable">@LastCreatedAt</span>
        <span class="hljs-keyword">AND</span> OrderId <span class="hljs-operator">&lt;</span> <span class="hljs-variable">@LastOrderId</span>
    )
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> CreatedAt <span class="hljs-keyword">DESC</span>, OrderId <span class="hljs-keyword">DESC</span>;
</code></pre>
<p dir="rtl" lang="fa">برای این Query ایندکس زیر مناسب است:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> INDEX IX_Orders_CreatedAt_OrderId
<span class="hljs-keyword">ON</span> Sales.Orders(CreatedAt <span class="hljs-keyword">DESC</span>, OrderId <span class="hljs-keyword">DESC</span>)
INCLUDE
(
    TotalAmount
);
</code></pre>
<p dir="rtl" lang="fa">این روش برای جدول‌های سفارش، تراکنش مالی، گزارش رخدادها و لاگ‌های حجیم عملکرد پایدارتری دارد.</p>
<h2 dir="rtl" lang="fa">۶. مراقب Parameter Sniffing باشید</h2>
<p dir="rtl" lang="fa">SQL Server معمولاً هنگام اولین اجرای Stored Procedure، مقدار پارامترها را بررسی کرده و بر اساس آن Execution Plan می‌سازد.</p>
<p dir="rtl" lang="fa">اگر توزیع داده یکنواخت نباشد، یک Plan ممکن است برای یک مقدار مناسب و برای مقدار دیگر بسیار ضعیف باشد.</p>
<p dir="rtl" lang="fa">فرض کنید یک مشتری فقط ۱۰ سفارش دارد، اما مشتری دیگری چند میلیون سفارش ثبت کرده است:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">OR</span> <span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">PROCEDURE</span> Sales.GetCustomerOrders
    <span class="hljs-variable">@CustomerId</span> <span class="hljs-type">bigint</span>
<span class="hljs-keyword">AS</span>
<span class="hljs-keyword">BEGIN</span>
    <span class="hljs-keyword">SET</span> NOCOUNT <span class="hljs-keyword">ON</span>;

    <span class="hljs-keyword">SELECT</span>
        OrderId,
        CreatedAt,
        TotalAmount,
        Status
    <span class="hljs-keyword">FROM</span> Sales.Orders
    <span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>;
<span class="hljs-keyword">END</span>;
</code></pre>
<p dir="rtl" lang="fa">ممکن است Plan ساخته شده برای مشتری کم تراکنش، هنگام اجرای Query برای مشتری بزرگ مناسب نباشد.</p>
<h3 dir="rtl" lang="fa">راه حل اول: بازکامپایل در همان اجرا</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    OrderId,
    CreatedAt,
    TotalAmount,
    Status
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>
OPTION (RECOMPILE);
</code></pre>
<p dir="rtl" lang="fa">این روش برای Queryهایی مناسب است که:</p>
<ul dir="rtl" lang="fa">
<li>تعداد اجرای آنها بسیار زیاد نیست.</li>
<li>اختلاف حجم داده بین پارامترها زیاد است.</li>
<li>زمان ساخت Plan نسبت به هزینه اجرای اشتباه کمتر است.</li>
</ul>
<h3 dir="rtl" lang="fa">راه حل دوم: استفاده از OPTIMIZE FOR UNKNOWN</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    OrderId,
    CreatedAt,
    TotalAmount,
    Status
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>
OPTION (OPTIMIZE <span class="hljs-keyword">FOR</span> <span class="hljs-literal">UNKNOWN</span>);
</code></pre>
<p dir="rtl" lang="fa">در این روش SQL Server از مقدار واقعی پارامتر برای ساخت Plan استفاده نمی‌کند و برآورد عمومی‌تری انجام می‌دهد.</p>
<h3 dir="rtl" lang="fa">راه حل سوم: متغیر محلی</h3>
<pre><code class="hljs"><span class="hljs-keyword">DECLARE</span> <span class="hljs-variable">@LocalCustomerId</span> <span class="hljs-type">bigint</span> <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>;

<span class="hljs-keyword">SELECT</span>
    OrderId,
    CreatedAt,
    TotalAmount,
    Status
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@LocalCustomerId</span>;
</code></pre>
<p dir="rtl" lang="fa">این روش گاهی مشکل را کاهش می‌دهد، اما ممکن است برآورد SQL Server را ضعیف کند. بنابراین باید با Execution Plan و آمار واقعی آزمایش شود.</p>
<h2 dir="rtl" lang="fa">۷. Implicit Conversion را حذف کنید</h2>
<p dir="rtl" lang="fa">تبدیل ضمنی نوع داده می‌تواند مانع استفاده صحیح از ایندکس شود.</p>
<p dir="rtl" lang="fa">فرض کنید نوع ستون <code>CustomerId</code> از نوع <code>bigint</code> است:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE TABLE</span> Sales.Orders
(
    OrderId <span class="hljs-type">bigint</span> <span class="hljs-keyword">NOT NULL</span>,
    CustomerId <span class="hljs-type">bigint</span> <span class="hljs-keyword">NOT NULL</span>
);
</code></pre>
<p dir="rtl" lang="fa">اما برنامه مقدار را به صورت <code>nvarchar</code> ارسال می‌کند:</p>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> N<span class="hljs-string">'1250'</span>
</code></pre>
<p dir="rtl" lang="fa">ممکن است SQL Server مجبور به تبدیل نوع داده شود. در Execution Plan، هشدار <code>CONVERT_IMPLICIT</code> را بررسی کنید.</p>
<h3 dir="rtl" lang="fa">روش صحیح</h3>
<p dir="rtl" lang="fa">نوع پارامتر در برنامه و Stored Procedure باید با نوع ستون یکسان باشد:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">OR</span> <span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">PROCEDURE</span> Sales.GetOrders
    <span class="hljs-variable">@CustomerId</span> <span class="hljs-type">bigint</span>
<span class="hljs-keyword">AS</span>
<span class="hljs-keyword">BEGIN</span>
    <span class="hljs-keyword">SET</span> NOCOUNT <span class="hljs-keyword">ON</span>;

    <span class="hljs-keyword">SELECT</span> OrderId, CreatedAt, TotalAmount
    <span class="hljs-keyword">FROM</span> Sales.Orders
    <span class="hljs-keyword">WHERE</span> CustomerId <span class="hljs-operator">=</span> <span class="hljs-variable">@CustomerId</span>;
<span class="hljs-keyword">END</span>;
</code></pre>
<p dir="rtl" lang="fa">در پروژه‌های .NET نیز نوع پارامتر را صحیح مشخص کنید:</p>
<pre><code class="hljs">command.Parameters.Add(<span class="hljs-string">"@CustomerId"</span>, SqlDbType.BigInt).Value = customerId;
</code></pre>
<h2 dir="rtl" lang="fa">۸. JOIN را با ستون‌های درست و ایندکس مناسب اجرا کنید</h2>
<p dir="rtl" lang="fa">فرض کنید Query زیر برای نمایش سفارش‌های مشتری اجرا می‌شود:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    o.OrderId,
    o.CreatedAt,
    c.CustomerName,
    o.TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders <span class="hljs-keyword">AS</span> o
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> Sales.Customers <span class="hljs-keyword">AS</span> c
    <span class="hljs-keyword">ON</span> c.CustomerId <span class="hljs-operator">=</span> o.CustomerId
<span class="hljs-keyword">WHERE</span> o.Status <span class="hljs-operator">=</span> <span class="hljs-number">1</span>
  <span class="hljs-keyword">AND</span> o.CreatedAt <span class="hljs-operator">&gt;=</span> <span class="hljs-variable">@FromDate</span>;
</code></pre>
<p dir="rtl" lang="fa">ایندکس‌های پیشنهادی:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> INDEX IX_Orders_Status_CreatedAt_CustomerId
<span class="hljs-keyword">ON</span> Sales.Orders(Status, CreatedAt, CustomerId)
INCLUDE
(
    OrderId,
    TotalAmount
);
</code></pre>
<p dir="rtl" lang="fa">و در جدول مشتری:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">UNIQUE</span> INDEX UX_Customers_CustomerId
<span class="hljs-keyword">ON</span> Sales.Customers(CustomerId)
INCLUDE
(
    CustomerName
);
</code></pre>
<h3 dir="rtl" lang="fa">از JOIN غیرضروری جلوگیری کنید</h3>
<p dir="rtl" lang="fa">اگر هیچ ستونی از جدول مشتری استفاده نمی‌شود، این JOIN را حذف کنید:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> o.OrderId, o.TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders <span class="hljs-keyword">AS</span> o
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> Sales.Customers <span class="hljs-keyword">AS</span> c
    <span class="hljs-keyword">ON</span> c.CustomerId <span class="hljs-operator">=</span> o.CustomerId
<span class="hljs-keyword">WHERE</span> o.Status <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;
</code></pre>
<p dir="rtl" lang="fa">نسخه ساده‌تر:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> OrderId, TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> Status <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;
</code></pre>
<p dir="rtl" lang="fa">هر JOIN اضافی می‌تواند هزینه CPU، حافظه و I/O را افزایش دهد.</p>
<h2 dir="rtl" lang="fa">۹. به جای IN بزرگ از روش مناسب استفاده کنید</h2>
<h3 dir="rtl" lang="fa">روش مشکل ساز</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> OrderId, TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> OrderId <span class="hljs-keyword">IN</span>
(
    <span class="hljs-number">100001</span>, <span class="hljs-number">100002</span>, <span class="hljs-number">100003</span>, <span class="hljs-number">100004</span>
);
</code></pre>
<p dir="rtl" lang="fa">برای تعداد کم شناسه مشکلی ایجاد نمی‌کند، اما در برنامه‌های پرترافیک و فهرست‌های بزرگ، بهتر است از Table-Valued Parameter استفاده شود.</p>
<h3 dir="rtl" lang="fa">تعریف نوع جدولی</h3>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> TYPE Sales.OrderIdList <span class="hljs-keyword">AS</span> <span class="hljs-keyword">TABLE</span>
(
    OrderId <span class="hljs-type">bigint</span> <span class="hljs-keyword">NOT NULL</span> <span class="hljs-keyword">PRIMARY KEY</span>
);
</code></pre>
<h3 lang="en">Stored Procedure</h3>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">OR</span> <span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">PROCEDURE</span> Sales.GetOrdersByIds
    <span class="hljs-variable">@OrderIds</span> Sales.OrderIdList READONLY
<span class="hljs-keyword">AS</span>
<span class="hljs-keyword">BEGIN</span>
    <span class="hljs-keyword">SET</span> NOCOUNT <span class="hljs-keyword">ON</span>;

    <span class="hljs-keyword">SELECT</span>
        o.OrderId,
        o.CustomerId,
        o.TotalAmount,
        o.Status
    <span class="hljs-keyword">FROM</span> Sales.Orders <span class="hljs-keyword">AS</span> o
    <span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> <span class="hljs-variable">@OrderIds</span> <span class="hljs-keyword">AS</span> ids
        <span class="hljs-keyword">ON</span> ids.OrderId <span class="hljs-operator">=</span> o.OrderId;
<span class="hljs-keyword">END</span>;
</code></pre>
<p dir="rtl" lang="fa">این روش نسبت به ساختن رشته‌های طولانی و Dynamic SQL قابل کنترل‌تر و امن‌تر است.</p>
<h2 dir="rtl" lang="fa">۱۰. LIKE را برای جستجوی متنی درست انتخاب کنید</h2>
<h3 dir="rtl" lang="fa">Query قابل استفاده از ایندکس</h3>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> CustomerName <span class="hljs-keyword">LIKE</span> <span class="hljs-variable">@Search</span> <span class="hljs-operator">+</span> N<span class="hljs-string">'%'</span>
</code></pre>
<h3 dir="rtl" lang="fa">Query پرهزینه</h3>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> CustomerName <span class="hljs-keyword">LIKE</span> N<span class="hljs-string">'%'</span> <span class="hljs-operator">+</span> <span class="hljs-variable">@Search</span> <span class="hljs-operator">+</span> N<span class="hljs-string">'%'</span>
</code></pre>
<p dir="rtl" lang="fa">در حالت دوم، SQL Server معمولاً نمی‌تواند از ایندکس معمولی برای پیدا کردن ابتدای عبارت استفاده کند.</p>
<p dir="rtl" lang="fa">برای جستجوی واقعی در متن‌های بزرگ، Full-Text Search گزینه مناسب‌تری است:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> FULLTEXT CATALOG CustomerCatalog <span class="hljs-keyword">AS</span> <span class="hljs-keyword">DEFAULT</span>;
</code></pre>
<p dir="rtl" lang="fa">سپس روی ستون مورد نظر Full-Text Index ایجاد کنید و Query را با <code>CONTAINS</code> یا <code>FREETEXT</code> اجرا کنید:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> CustomerId, CustomerName
<span class="hljs-keyword">FROM</span> Sales.Customers
<span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">CONTAINS</span>(CustomerName, <span class="hljs-variable">@SearchTerm</span>);
</code></pre>
<h2 dir="rtl" lang="fa">۱۱. تراکنش‌ها را کوتاه نگه دارید</h2>
<p dir="rtl" lang="fa">در سیستم پرتراکنش، تراکنش طولانی فقط یک مشکل عملکردی نیست؛ بلکه باعث Blocking و افزایش زمان انتظار سایر درخواست‌ها می‌شود.</p>
<h3 dir="rtl" lang="fa">الگوی نامناسب</h3>
<pre><code class="hljs"><span class="hljs-keyword">BEGIN</span> TRANSACTION;

<span class="hljs-keyword">SELECT</span> <span class="hljs-operator">*</span>
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> OrderId <span class="hljs-operator">=</span> <span class="hljs-variable">@OrderId</span>;

<span class="hljs-comment">-- پردازش طولانی در برنامه</span>
<span class="hljs-comment">-- ارسال درخواست به سرویس خارجی</span>
<span class="hljs-comment">-- محاسبه سنگین</span>

<span class="hljs-keyword">UPDATE</span> Sales.Orders
<span class="hljs-keyword">SET</span> Status <span class="hljs-operator">=</span> <span class="hljs-number">2</span>
<span class="hljs-keyword">WHERE</span> OrderId <span class="hljs-operator">=</span> <span class="hljs-variable">@OrderId</span>;

<span class="hljs-keyword">COMMIT</span> TRANSACTION;
</code></pre>
<p dir="rtl" lang="fa">در این فاصله، قفل‌ها ممکن است بیشتر از زمان لازم حفظ شوند.</p>
<h3 dir="rtl" lang="fa">الگوی بهتر</h3>
<p dir="rtl" lang="fa">ابتدا اطلاعات لازم را بخوانید، پردازش‌های خارج از دیتابیس را انجام دهید و فقط عملیات نهایی را در تراکنش قرار دهید:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    OrderId,
    Status,
    TotalAmount
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> OrderId <span class="hljs-operator">=</span> <span class="hljs-variable">@OrderId</span>;
</code></pre>
<p dir="rtl" lang="fa">سپس:</p>
<pre><code class="hljs"><span class="hljs-keyword">SET</span> XACT_ABORT <span class="hljs-keyword">ON</span>;

<span class="hljs-keyword">BEGIN</span> TRY
    <span class="hljs-keyword">BEGIN</span> TRANSACTION;

    <span class="hljs-keyword">UPDATE</span> Sales.Orders
    <span class="hljs-keyword">SET</span>
        Status <span class="hljs-operator">=</span> <span class="hljs-number">2</span>,
        UpdatedAt <span class="hljs-operator">=</span> SYSUTCDATETIME()
    <span class="hljs-keyword">WHERE</span> OrderId <span class="hljs-operator">=</span> <span class="hljs-variable">@OrderId</span>
      <span class="hljs-keyword">AND</span> Status <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;

    IF @<span class="hljs-variable">@ROWCOUNT</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>
        THROW <span class="hljs-number">50001</span>, <span class="hljs-string">'Order is not available for update.'</span>, <span class="hljs-number">1</span>;

    <span class="hljs-keyword">INSERT INTO</span> Sales.OrderStatusHistory
    (
        OrderId,
        OldStatus,
        NewStatus,
        CreatedAt
    )
    <span class="hljs-keyword">VALUES</span>
    (
        <span class="hljs-variable">@OrderId</span>,
        <span class="hljs-number">1</span>,
        <span class="hljs-number">2</span>,
        SYSUTCDATETIME()
    );

    <span class="hljs-keyword">COMMIT</span> TRANSACTION;
<span class="hljs-keyword">END</span> TRY
<span class="hljs-keyword">BEGIN</span> CATCH
    IF XACT_STATE() <span class="hljs-operator">&lt;&gt;</span> <span class="hljs-number">0</span>
        <span class="hljs-keyword">ROLLBACK</span> TRANSACTION;

    THROW;
<span class="hljs-keyword">END</span> CATCH;
</code></pre>
<h3 dir="rtl" lang="fa">نکته مهم</h3>
<p dir="rtl" lang="fa">شرط وضعیت در دستور <code>UPDATE</code> نقش کنترل همزمانی دارد:</p>
<pre><code class="hljs"><span class="hljs-keyword">WHERE</span> OrderId <span class="hljs-operator">=</span> <span class="hljs-variable">@OrderId</span>
  <span class="hljs-keyword">AND</span> Status <span class="hljs-operator">=</span> <span class="hljs-number">1</span>
</code></pre>
<p dir="rtl" lang="fa">به این ترتیب، اگر درخواست دیگری قبلاً وضعیت سفارش را تغییر داده باشد، عملیات فعلی بدون بررسی اضافی شکست می‌خورد.</p>
<h2 dir="rtl" lang="fa">۱۲. Blocking و Deadlock را بررسی کنید</h2>
<p dir="rtl" lang="fa">برای مشاهده درخواست‌های در حال انتظار:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    r.session_id,
    r.status,
    r.command,
    r.wait_type,
    r.wait_time,
    r.blocking_session_id,
    r.cpu_time,
    r.logical_reads,
    t.text <span class="hljs-keyword">AS</span> SqlText
<span class="hljs-keyword">FROM</span> sys.dm_exec_requests <span class="hljs-keyword">AS</span> r
<span class="hljs-keyword">CROSS</span> APPLY sys.dm_exec_sql_text(r.sql_handle) <span class="hljs-keyword">AS</span> t
<span class="hljs-keyword">WHERE</span> r.session_id <span class="hljs-operator">&lt;&gt;</span> @<span class="hljs-variable">@SPID</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> r.wait_time <span class="hljs-keyword">DESC</span>;
</code></pre>
<p dir="rtl" lang="fa">برای پیدا کردن Sessionهای مسدود شده:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    session_id,
    blocking_session_id,
    wait_type,
    wait_time,
    wait_resource
<span class="hljs-keyword">FROM</span> sys.dm_exec_requests
<span class="hljs-keyword">WHERE</span> blocking_session_id <span class="hljs-operator">&lt;&gt;</span> <span class="hljs-number">0</span>;
</code></pre>
<h3 dir="rtl" lang="fa">علت‌های رایج Blocking</h3>
<ul dir="rtl" lang="fa">
<li>تراکنش‌های طولانی</li>
<li>نبود ایندکس روی شرط <code>UPDATE</code> یا <code>DELETE</code></li>
<li>اسکن گسترده جدول</li>
<li>اجرای گزارش سنگین روی جداول عملیاتی</li>
<li>ترتیب متفاوت دسترسی به جداول در تراکنش‌های مختلف</li>
<li>به روز رسانی دسته‌ای در ساعات شلوغ</li>
</ul>
<h3 dir="rtl" lang="fa">الگوی کاهش Deadlock</h3>
<p dir="rtl" lang="fa">در تمام بخش‌های برنامه، ترتیب دسترسی به جداول را ثابت کنید. برای مثال، اگر یک تراکنش ابتدا <code>Customers</code> و سپس <code>Orders</code> را تغییر می‌دهد، تراکنش دیگر نباید ابتدا <code>Orders</code> و بعد <code>Customers</code> را تغییر دهد.</p>
<p dir="rtl" lang="fa">همچنین عملیات بزرگ را به بخش‌های کوچک‌تر تقسیم کنید:</p>
<pre><code class="hljs">WHILE <span class="hljs-number">1</span> <span class="hljs-operator">=</span> <span class="hljs-number">1</span>
<span class="hljs-keyword">BEGIN</span>
    <span class="hljs-keyword">DELETE</span> TOP (<span class="hljs-number">1000</span>)
    <span class="hljs-keyword">FROM</span> Audit.Logs
    <span class="hljs-keyword">WHERE</span> CreatedAt <span class="hljs-operator">&lt;</span> <span class="hljs-variable">@BeforeDate</span>;

    IF @<span class="hljs-variable">@ROWCOUNT</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>
        BREAK;
<span class="hljs-keyword">END</span>;
</code></pre>
<h2 dir="rtl" lang="fa">۱۳. سطح Isolation را آگاهانه انتخاب کنید</h2>
<p dir="rtl" lang="fa">در بسیاری از سیستم‌های OLTP، خواندن‌های طولانی با نوشتن‌ها تداخل ایجاد می‌کنند. یکی از راهکارهای مهم، فعال کردن <code>READ_COMMITTED_SNAPSHOT</code> است:</p>
<pre><code class="hljs"><span class="hljs-keyword">ALTER</span> DATABASE [SalesDb]
<span class="hljs-keyword">SET</span> READ_COMMITTED_SNAPSHOT <span class="hljs-keyword">ON</span>
<span class="hljs-keyword">WITH</span> <span class="hljs-keyword">ROLLBACK</span> IMMEDIATE;
</code></pre>
<p dir="rtl" lang="fa">در این حالت، خواندن‌های معمولی از Version Store در <code>tempdb</code> استفاده می‌کنند و معمولاً کمتر منتظر قفل‌های نوشتاری می‌مانند.</p>
<p dir="rtl" lang="fa">اما پیش از فعال سازی باید موارد زیر بررسی شود:</p>
<ul dir="rtl" lang="fa">
<li>فضای کافی برای <code>tempdb</code></li>
<li>حجم Update و Delete</li>
<li>مدت اجرای تراکنش‌ها</li>
<li>مصرف Version Store</li>
<li>سازگاری برنامه با رفتار جدید خواندن</li>
</ul>
<p dir="rtl" lang="fa">برای تراکنش‌هایی که نیاز به ثبات کامل داده دارند، سطح Isolation را بدون بررسی تغییر ندهید.</p>
<h2 dir="rtl" lang="fa">۱۴. Statistics را به روز نگه دارید</h2>
<p dir="rtl" lang="fa">اگر Statistics قدیمی باشد، SQL Server ممکن است تعداد رکوردهای خروجی را اشتباه تخمین بزند و Join یا ایندکس نامناسب انتخاب کند.</p>
<p dir="rtl" lang="fa">به روز رسانی دستی:</p>
<pre><code class="hljs"><span class="hljs-keyword">UPDATE</span> STATISTICS Sales.Orders
<span class="hljs-keyword">WITH</span> FULLSCAN;
</code></pre>
<p dir="rtl" lang="fa">برای جدول‌های بزرگ، <code>FULLSCAN</code> ممکن است پرهزینه باشد. بنابراین آن را در ساعات مناسب و با بررسی زمان اجرا انجام دهید.</p>
<p dir="rtl" lang="fa">مشاهده زمان آخرین به روز رسانی Statistics:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span>
    OBJECT_SCHEMA_NAME(sp.object_id) <span class="hljs-keyword">AS</span> SchemaName,
    OBJECT_NAME(sp.object_id) <span class="hljs-keyword">AS</span> TableName,
    sp.stats_id,
    sp.last_updated,
    sp.rows,
    sp.rows_sampled,
    sp.modification_counter
<span class="hljs-keyword">FROM</span> sys.dm_db_stats_properties
(
    OBJECT_ID(N<span class="hljs-string">'Sales.Orders'</span>),
    <span class="hljs-number">1</span>
) <span class="hljs-keyword">AS</span> sp;
</code></pre>
<p dir="rtl" lang="fa">در پروژه‌هایی که داده به سرعت تغییر می‌کند، فقط فعال بودن Auto Update Statistics کافی نیست. آمار Query Store، زمان اجرای Query و تغییرات داده را نیز بررسی کنید.</p>
<h2 dir="rtl" lang="fa">۱۵. Query Store را فعال و بررسی کنید</h2>
<p dir="rtl" lang="fa">Query Store برای پیدا کردن Queryهایی که در طول زمان کند شده‌اند بسیار کاربردی است.</p>
<p dir="rtl" lang="fa">فعال سازی:</p>
<pre><code class="hljs"><span class="hljs-keyword">ALTER</span> DATABASE [SalesDb]
<span class="hljs-keyword">SET</span> QUERY_STORE <span class="hljs-operator">=</span> <span class="hljs-keyword">ON</span>;
</code></pre>
<p dir="rtl" lang="fa">برای پیدا کردن Queryهای پرهزینه:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> TOP (<span class="hljs-number">20</span>)
    qt.query_sql_text,
    rs.execution_count,
    rs.avg_duration,
    rs.avg_cpu_time,
    rs.avg_logical_io_reads,
    rs.last_execution_time
<span class="hljs-keyword">FROM</span> sys.query_store_query_text <span class="hljs-keyword">AS</span> qt
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> sys.query_store_query <span class="hljs-keyword">AS</span> q
    <span class="hljs-keyword">ON</span> q.query_text_id <span class="hljs-operator">=</span> qt.query_text_id
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> sys.query_store_plan <span class="hljs-keyword">AS</span> p
    <span class="hljs-keyword">ON</span> p.query_id <span class="hljs-operator">=</span> q.query_id
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> sys.query_store_runtime_stats <span class="hljs-keyword">AS</span> rs
    <span class="hljs-keyword">ON</span> rs.plan_id <span class="hljs-operator">=</span> p.plan_id
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> rs.avg_duration <span class="hljs-keyword">DESC</span>;
</code></pre>
<p dir="rtl" lang="fa">برای پیدا کردن Queryهایی که بیشترین مجموع زمان را مصرف کرده‌اند:</p>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> TOP (<span class="hljs-number">20</span>)
    qt.query_sql_text,
    <span class="hljs-built_in">SUM</span>(rs.count_executions) <span class="hljs-keyword">AS</span> TotalExecutions,
    <span class="hljs-built_in">SUM</span>(rs.avg_duration <span class="hljs-operator">*</span> rs.count_executions) <span class="hljs-keyword">AS</span> TotalDuration
<span class="hljs-keyword">FROM</span> sys.query_store_query_text <span class="hljs-keyword">AS</span> qt
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> sys.query_store_query <span class="hljs-keyword">AS</span> q
    <span class="hljs-keyword">ON</span> q.query_text_id <span class="hljs-operator">=</span> qt.query_text_id
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> sys.query_store_plan <span class="hljs-keyword">AS</span> p
    <span class="hljs-keyword">ON</span> p.query_id <span class="hljs-operator">=</span> q.query_id
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> sys.query_store_runtime_stats <span class="hljs-keyword">AS</span> rs
    <span class="hljs-keyword">ON</span> rs.plan_id <span class="hljs-operator">=</span> p.plan_id
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> qt.query_sql_text
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> TotalDuration <span class="hljs-keyword">DESC</span>;
</code></pre>
<p dir="rtl" lang="fa">گاهی Queryای که میانگین زمان کمی دارد، به دلیل تعداد اجرای بسیار زیاد، بیشترین فشار را به SQL Server وارد می‌کند.</p>
<h2 dir="rtl" lang="fa">۱۶. برای اصلاح Query از این ترتیب استفاده کنید</h2>
<p dir="rtl" lang="fa">برای هر Query پیچیده، این مراحل را به صورت مشخص انجام دهید:</p>
<h3 dir="rtl" lang="fa">مرحله اول: اجرای فعلی را ثبت کنید</h3>
<ul dir="rtl" lang="fa">
<li>زمان متوسط</li>
<li>زمان صدک ۹۵ و ۹۹</li>
<li>CPU</li>
<li>Logical Read</li>
<li>تعداد اجرا</li>
<li>تعداد Timeout</li>
<li>Wait Type</li>
</ul>
<h3 dir="rtl" lang="fa">مرحله دوم: Execution Plan را بررسی کنید</h3>
<p dir="rtl" lang="fa">به دنبال این موارد باشید:</p>
<ul dir="rtl" lang="fa">
<li>Scan روی جدول بزرگ</li>
<li>اختلاف Estimated Rows و Actual Rows</li>
<li>Key Lookup تکرارشونده</li>
<li>Sort بدون ایندکس مناسب</li>
<li>Hash Join ناشی از کمبود ایندکس یا برآورد اشتباه</li>
<li>Implicit Conversion</li>
<li>Spill به <code>tempdb</code></li>
</ul>
<h3 dir="rtl" lang="fa">مرحله سوم: Query را اصلاح کنید</h3>
<ul dir="rtl" lang="fa">
<li>حذف <code>SELECT *</code></li>
<li>حذف تابع از روی ستون فیلتر</li>
<li>اصلاح Pagination</li>
<li>حذف JOIN غیرضروری</li>
<li>اصلاح نوع پارامترها</li>
<li>کاهش تعداد ستون‌های خروجی</li>
</ul>
<h3 dir="rtl" lang="fa">مرحله چهارم: ایندکس را بررسی کنید</h3>
<ul dir="rtl" lang="fa">
<li>آیا ایندکس با الگوی واقعی Query هماهنگ است؟</li>
<li>آیا ترتیب ستون‌ها صحیح است؟</li>
<li>آیا Query نیاز به <code>INCLUDE</code> دارد؟</li>
<li>آیا ایندکس مشابه از قبل وجود دارد؟</li>
<li>هزینه این ایندکس برای عملیات نوشتن چقدر است؟</li>
</ul>
<h3 dir="rtl" lang="fa">مرحله پنجم: زیر بار واقعی آزمایش کنید</h3>
<p dir="rtl" lang="fa">Query فقط در محیط توسعه آزمایش نشود. حجم داده، همزمانی کاربران، پارامترهای مختلف و زمان‌های پرترافیک را شبیه سازی کنید.</p>
<h2 dir="rtl" lang="fa">نمونه کامل بررسی یک Query</h2>
<h3 dir="rtl" lang="fa">Query اولیه</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> <span class="hljs-operator">*</span>
<span class="hljs-keyword">FROM</span> Sales.Orders
<span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">CONVERT</span>(<span class="hljs-type">date</span>, CreatedAt) <span class="hljs-operator">=</span> <span class="hljs-variable">@OrderDate</span>
  <span class="hljs-keyword">AND</span> CustomerId <span class="hljs-keyword">IN</span>
  (
      <span class="hljs-keyword">SELECT</span> CustomerId
      <span class="hljs-keyword">FROM</span> Sales.Customers
      <span class="hljs-keyword">WHERE</span> IsActive <span class="hljs-operator">=</span> <span class="hljs-number">1</span>
  )
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> CreatedAt <span class="hljs-keyword">DESC</span>
<span class="hljs-keyword">OFFSET</span> <span class="hljs-variable">@Offset</span> <span class="hljs-keyword">ROWS</span>
<span class="hljs-keyword">FETCH</span> NEXT <span class="hljs-variable">@PageSize</span> <span class="hljs-keyword">ROWS</span> <span class="hljs-keyword">ONLY</span>;
</code></pre>
<p dir="rtl" lang="fa">مشکل‌های این Query:</p>
<ul dir="rtl" lang="fa">
<li>استفاده از تابع روی <code>CreatedAt</code></li>
<li>استفاده از <code>SELECT *</code></li>
<li>Pagination با <code>OFFSET</code> در صفحات بزرگ</li>
<li>احتمال اسکن جدول Customers</li>
<li>نامشخص بودن ایندکس‌های مورد نیاز</li>
</ul>
<h3 dir="rtl" lang="fa">نسخه اصلاح شده</h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> TOP (<span class="hljs-variable">@PageSize</span>)
    o.OrderId,
    o.CustomerId,
    o.CreatedAt,
    o.TotalAmount,
    o.Status
<span class="hljs-keyword">FROM</span> Sales.Orders <span class="hljs-keyword">AS</span> o
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> Sales.Customers <span class="hljs-keyword">AS</span> c
    <span class="hljs-keyword">ON</span> c.CustomerId <span class="hljs-operator">=</span> o.CustomerId
<span class="hljs-keyword">WHERE</span> c.IsActive <span class="hljs-operator">=</span> <span class="hljs-number">1</span>
  <span class="hljs-keyword">AND</span>
  (
      o.CreatedAt <span class="hljs-operator">&lt;</span> <span class="hljs-variable">@LastCreatedAt</span>
      <span class="hljs-keyword">OR</span>
      (
          o.CreatedAt <span class="hljs-operator">=</span> <span class="hljs-variable">@LastCreatedAt</span>
          <span class="hljs-keyword">AND</span> o.OrderId <span class="hljs-operator">&lt;</span> <span class="hljs-variable">@LastOrderId</span>
      )
  )
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> o.CreatedAt <span class="hljs-keyword">DESC</span>, o.OrderId <span class="hljs-keyword">DESC</span>;
</code></pre>
<p dir="rtl" lang="fa">ایندکس‌های پیشنهادی:</p>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> INDEX IX_Customers_IsActive_CustomerId
<span class="hljs-keyword">ON</span> Sales.Customers(IsActive, CustomerId);
</code></pre>
<pre><code class="hljs"><span class="hljs-keyword">CREATE</span> INDEX IX_Orders_CreatedAt_OrderId_CustomerId
<span class="hljs-keyword">ON</span> Sales.Orders(CreatedAt <span class="hljs-keyword">DESC</span>, OrderId <span class="hljs-keyword">DESC</span>, CustomerId)
INCLUDE
(
    TotalAmount,
    Status
);
</code></pre>
<p dir="rtl" lang="fa">این نسخه برای صفحه‌های انتهایی، خواندن ستون‌های محدود و اجرای پرتکرار، قابلیت مقیاس پذیری بیشتری دارد.</p>
<h2 dir="rtl" lang="fa">چه کارهایی معمولاً نتیجه معکوس دارند؟</h2>
<h3 dir="rtl" lang="fa">ایجاد ایندکس برای هر ستون</h3>
<p dir="rtl" lang="fa">تعداد زیاد ایندکس، عملیات نوشتن را کند می‌کند و فضای زیادی مصرف می‌کند.</p>
<h3 dir="rtl" lang="fa">استفاده دائمی از <code>NOLOCK</code></h3>
<pre><code class="hljs"><span class="hljs-keyword">SELECT</span> <span class="hljs-operator">*</span>
<span class="hljs-keyword">FROM</span> Sales.Orders <span class="hljs-keyword">WITH</span> (NOLOCK);
</code></pre>
<p dir="rtl" lang="fa"><code>NOLOCK</code> ممکن است Dirty Read، رکوردهای تکراری یا داده‌های ناپایدار برگرداند. این دستور راه حل عمومی برای مشکل Blocking نیست.</p>
<h3 dir="rtl" lang="fa">استفاده بی دلیل از <code>OPTION (RECOMPILE)</code></h3>
<p dir="rtl" lang="fa">برای Queryهای پرتکرار، بازسازی Plan در هر اجرا می‌تواند CPU را افزایش دهد.</p>
<h3 dir="rtl" lang="fa">انتقال همه Queryها به Stored Procedure</h3>
<p dir="rtl" lang="fa">Stored Procedure مفید است، اما اگر منطق Query، ایندکس یا مدل داده نادرست باشد، صرفاً قرار دادن کد در Stored Procedure مشکل را حل نمی‌کند.</p>
<h3 dir="rtl" lang="fa">افزایش سخت افزار بدون اصلاح Query</h3>
<p dir="rtl" lang="fa">افزایش RAM یا CPU گاهی کمک می‌کند، اما Query دارای اسکن، Sort یا Blocking همچنان در حجم بالاتر مشکل ایجاد خواهد کرد.</p>
<h2 dir="rtl" lang="fa">چک لیست نهایی بهینه سازی Query در SQL Server</h2>
<p dir="rtl" lang="fa">پیش از انتشار تغییرات، این موارد را بررسی کنید:</p>
<ul dir="rtl" lang="fa">
<li>Execution Plan واقعی مشاهده شده است.</li>
<li>Logical Read قبل و بعد مقایسه شده است.</li>
<li>زمان CPU و زمان سپری شده ثبت شده است.</li>
<li>Query از <code>SELECT *</code> استفاده نمی‌کند.</li>
<li>روی ستون‌های فیلتر تابع اجرا نمی‌شود.</li>
<li>نوع پارامتر با نوع ستون یکسان است.</li>
<li>ایندکس ترکیبی بر اساس الگوی واقعی Query طراحی شده است.</li>
<li>Key Lookup غیرضروری حذف شده است.</li>
<li>Pagination برای صفحات بزرگ با Keyset انجام می‌شود.</li>
<li>تراکنش‌ها کوتاه هستند.</li>
<li>Blocking و Deadlock بررسی شده‌اند.</li>
<li>Statistics و Query Store در نظر گرفته شده‌اند.</li>
<li>Query با پارامترهای کم حجم و پرحجم آزمایش شده است.</li>
<li>تأثیر ایندکس جدید بر INSERT و UPDATE بررسی شده است.</li>
</ul>
<h2 dir="rtl" lang="fa">جمع بندی</h2>
<p dir="rtl" lang="fa">بهینه سازی Queryهای پیچیده SQL Server در پروژه‌های پرتراکنش، با یک تغییر ساده یا افزودن ایندکس تصادفی انجام نمی‌شود. باید ابتدا هزینه واقعی Query را اندازه گیری کرد، سپس Execution Plan، ایندکس، نوع پارامتر، مدت تراکنش و رفتار همزمانی را بررسی کرد.</p>
<p dir="rtl" lang="fa">در عمل، بیشترین نتیجه معمولاً از این اقدامات به دست می‌آید:</p>
<ol dir="rtl" lang="fa">
<li>حذف Scanهای غیرضروری</li>
<li>ایجاد ایندکس ترکیبی متناسب با Query</li>
<li>حذف Key Lookupهای پرتکرار</li>
<li>استفاده از Keyset Pagination</li>
<li>جلوگیری از Parameter Sniffing در Queryهای حساس</li>
<li>کوتاه کردن تراکنش‌ها</li>
<li>بررسی Blocking و Deadlock</li>
<li>استفاده مستمر از Query Store و آمار واقعی اجرا</li>
</ol>
<p dir="rtl" lang="fa">برای مطالعه نکات تکمیلی درباره طراحی ایندکس، مدیریت تراکنش‌ها، <code>tempdb</code> و بهینه سازی دیتابیس، مقاله <a href="https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-%d8%af%db%8c%d8%aa%d8%a7%d8%a8%db%8c%d8%b3%d8%9b-%d8%ac%d8%a7%db%8c%db%8c-%da%a9%d9%87-%db%b8%db%b0%d9%aa-%d8%b3%d8%b1%d8%b9%d8%aa-%d8%b3%d8%a7/" target="_blank" rel="nofollow noopener noreferrer">بهینه سازی دیتابیس؛ جایی که ۸۰٪ سرعت سایت شما در آن نهفته است</a> را نیز بخوانید.</p>
<p dir="rtl" lang="fa">اگر در پروژه خود با Queryهای کند، قفل شدن جداول یا افت عملکرد SQL Server روبه رو هستید، برای <a href="https://tarahanenovin.ir/site/contact" target="_blank" rel="nofollow noopener noreferrer">مشاوره و بررسی فنی پروژه با طراحان نوین تماس بگیرید</a>.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-query-%d9%87%d8%a7%db%8c-%d9%be%db%8c%da%86%db%8c%d8%af%d9%87-sql-server-%d8%af%d8%b1-%d9%be%d8%b1%d9%88%da%98%d9%87%d9%87%d8%a7%db%8c/">بهینه سازی Query های پیچیده SQL Server در پروژه‌های با حجم تراکنش بالا</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-query-%d9%87%d8%a7%db%8c-%d9%be%db%8c%da%86%db%8c%d8%af%d9%87-sql-server-%d8%af%d8%b1-%d9%be%d8%b1%d9%88%da%98%d9%87%d9%87%d8%a7%db%8c/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>بهینه سازی دیتابیس؛ جایی که ۸۰٪ سرعت سایت شما در آن نهفته است</title>
		<link>https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-%d8%af%db%8c%d8%aa%d8%a7%d8%a8%db%8c%d8%b3%d8%9b-%d8%ac%d8%a7%db%8c%db%8c-%da%a9%d9%87-%db%b8%db%b0%d9%aa-%d8%b3%d8%b1%d8%b9%d8%aa-%d8%b3%d8%a7/</link>
					<comments>https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-%d8%af%db%8c%d8%aa%d8%a7%d8%a8%db%8c%d8%b3%d8%9b-%d8%ac%d8%a7%db%8c%db%8c-%da%a9%d9%87-%db%b8%db%b0%d9%aa-%d8%b3%d8%b1%d8%b9%d8%aa-%d8%b3%d8%a7/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[افزایش سرعت سایت]]></category>
		<category><![CDATA[بهینه سازی]]></category>
		<category><![CDATA[دیتابیس]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=235</guid>

					<description><![CDATA[<p>سرعت سایت فقط «کش و CDN» نیست. در بسیاری از پروژه های واقعی، گلوگاه اصلی جایی است که همه چیز به آن ختم می شود: دیتابیس. هر صفحه، هر جستجو، هر فیلتر محصول، هر گزارش مدیریتی و حتی لاگین کاربران در نهایت به کوئری ها، ایندکس ها، قفل ها و I/O دیسک دیتابیس وابسته است. اگر دیتابیس کند باشد، بقیه بهینه سازی ها فقط مُسکن هستند. در این مقاله، به صورت جامع و عملی بررسی می کنیم چگونه دیتابیس را برای سرعت، پایداری و مقیاس پذیری بهینه کنید؛ از علائم و روش تشخیص مشکل تا تکنیک های سطح Query، Schema، Index، Cache و زیرساخت. چرا دیتابیس معمولا عامل اصلی کندی است؟ 1) بیشتر درخواست ها به دیتابیس ختم می شوند حتی اگر HTML کش شده باشد، بسیاری از بخش ها دینامیک اند: سبد خرید، موجودی، پروفایل، نتایج جستجو، پنل مدیریت، پیشنهادها و… 2) افزایش داده، خطی رشد نمی کند؛ نمایی مشکل می سازد کوئری که روی 10 هزار رکورد خوب است، روی 10 میلیون رکورد می تواند فاجعه باشد، اگر ایندکس و طراحی درست نباشد. 3) دیتابیس هم CPU دارد، هم RAM، هم Disk و هم Lock کندی ممکن است از هر کدام باشد: CPU بالا: کوئری های سنگین، Sort/Group زیاد RAM کم: کش دیتابیس کم، خواندن از دیسک Disk کند: I/O بالا، لاگ های زیاد، tempdb (در SQL Server) Lock/Blocking: تراکنش های طولانی، همزمانی بالا علائم کلاسیک مشکل دیتابیس (که باید جدی بگیرید) TTFB بالا (زمان شروع پاسخ از سرور زیاد است) افزایش ناگهانی زمان بارگذاری در ساعات شلوغ CPU یا Disk سرور دیتابیس نزدیک 100٪ تایم اوت شدن درخواست ها گزارش ها و لیست های پنل مدیریت کندتر از قبل کندی فقط در برخی صفحات (مثل جستجو/فیلتر/گزارش) روش درست شروع بهینه سازی: اول اندازه گیری، بعد تغییر اگر بدون اندازه گیری تغییر دهید، احتمال دارد مشکل را جابجا کنید یا بدتر کنید. چک لیست اندازه گیری کندترین endpointها/صفحات را پیدا کنید (از APM یا لاگ زمان پاسخ) کندترین کوئری ها را لیست کنید: میانگین زمان بیشترین زمان بیشترین تعداد اجرا برای هر کوئری، این ها را بررسی کنید: Execution Plan تعداد ردیف های واقعی vs تخمینی استفاده از Index (Seek) یا Scan میزان Sort/Hash/Spill به دیسک Bottleneck را مشخص کنید: CPU؟ I/O؟ Lock؟ Network؟ بخش ۱: بهینه سازی Query (بیشترین اثر با کمترین هزینه) 1) N+1 Query (قاتل پنهان سرعت) مثال رایج: لیست سفارش ها را می گیرید، بعد برای هر سفارش یک کوئری جدا برای آیتم ها می زنید. راه حل: Join / Include صحیح Batch query Preload کردن داده های وابسته 2) فقط ستون های لازم را SELECT کنید SELECT * در سیستم های واقعی یعنی: I/O بیشتر انتقال دیتا بیشتر کش کمتر مفید احتمال استفاده نکردن از Covering Index 3) Pagination درست بدترین حالت: OFFSET ... FETCH روی دیتای بزرگ بدون ایندکس مناسب. راه بهتر (Keyset Pagination): بر اساس کلید مرتب سازی (مثلا Id یا CreatedAt) صفحه بندی کنید. مثال منطقی: «بعد از آخرین Id قبلی» به جای OFFSET بزرگ. 4) فیلترهای قابل ایندکس بنویسید برخی الگوها باعث می شوند دیتابیس نتواند از ایندکس استفاده کند: استفاده از تابع روی ستون در WHERE (مثل WHERE YEAR(CreatedAt)=2026) تبدیل نوع داده در شرط راه حل: شرط را طوری بنویسید که ستون خام قابل مقایسه باشد (Range query). 5) جستجو با LIKE LIKE '%term%' معمولا ایندکس را بی اثر می کند. راه حل ها: Full-Text Search (در SQL Server / MySQL) موتور جدا مثل Elasticsearch برای جستجوی حرفه ای اگر فقط Prefix است: LIKE 'term%' با ایندکس مناسب 6) Aggregate های سنگین را از مسیر کاربر خارج کنید گزارش های سنگین را: Precompute کنید (جدول خلاصه / Materialized View) یا Async بسازید (job + cache) یا از replica خواندنی استفاده کنید بخش ۲: ایندکس گذاری اصولی (Index مثل میانبر است) اصول کلیدی ایندکس ایندکس روی ستون هایی که زیاد WHERE / JOIN / ORDER BY می شوند. ایندکس زیاد = سرعت خواندن بهتر، اما: سرعت نوشتن بدتر حجم بیشتر نگهداری سخت تر اشتباهات رایج ایندکس روی ستون هایی که Selectivity پایین دارند (مثل boolean) بدون ترکیب مناسب نداشتن ایندکس ترکیبی برای فیلترهای چندتایی ناهماهنگی بین ORDER BY و ترتیب ستون های ایندکس Covering Index (کاهش نیاز به Lookup) اگر کوئری همیشه 3-4 ستون را می خواند، ایندکس را طوری بسازید که همان ستون ها را پوشش دهد تا دیتابیس مجبور نشود به جدول اصلی برگردد. بخش ۳: طراحی Schema و مدل داده (ریشه ای ترین بهینه سازی) 1) نوع داده درست انتخاب کنید INT به جای BIGINT وقتی لازم نیست DATETIME2 مناسب (در SQL Server) طول varchar منطقی این ها روی I/O، کش و ایندکس مستقیم اثر دارند. 2) نرمال سازی vs دنرمال سازی برای تراکنش و صحت داده: نرمال سازی خوب است برای سرعت خواندن های پرتکرار: دنرمال سازی کنترل شده (مثلا ذخیره شمارنده ها، یا snapshot) می تواند مفید باشد 3) تاریخچه و لاگ ها را جدا کنید جدول های لاگ اگر با جداول عملیاتی قاطی شوند: ایندکس ها سنگین می شوند Backup/Restore کند می شود کوئری های روزمره کند می شوند راه حل: جدول جدا آرشیو دوره ای پارتیشن بندی (اگر امکانش باشد) بخش ۴: Cache؛ اگر درست پیاده شود، معجزه می کند چه چیزی را کش کنیم؟ داده های تقریبا ثابت: تنظیمات، دسته بندی ها نتایج محاسباتی: تعدادها، خلاصه ها نتایج جستجوهای پرتکرار (با TTL کوتاه) کجا کش کنیم؟ Application cache (in-memory) Redis / Memcached CDN برای محتوای استاتیک (کمک می کند، ولی جای دیتابیس را نمی گیرد) نکته مهم: Invalidation کش بدون سیاست invalidation یعنی «نمایش داده اشتباه». پس: TTL منطقی Cache key استاندارد پاکسازی هنگام تغییرات مهم بخش ۵: Concurrency، Lock و تراکنش ها (کندی فقط کوئری نیست) علائم Lock/Blocking کندی شدید فقط در ساعات شلوغ کوئری ها در حالت waiting راه حل های معمول: کوتاه کردن تراکنش ها جلوگیری از آپدیت های دسته ای در ساعات پیک ایندکس مناسب برای کاهش اسکن و قفل گسترده سطح ایزولیشن مناسب (بسته به دیتابیس) بخش ۶: نگهداری (Maintenance)؛ چیزی که معمولا فراموش می شود به روز بودن آمار (Statistics): برای پلن درست حیاتی است (خصوصا SQL Server) Fragmentation: ایندکس های به هم ریخته روی I/O اثر دارند Cleanup: حذف داده های قدیمی، آرشیو Backup strategy: بکاپ سنگین در ساعت پیک می تواند کندی ایجاد کند بخش ۷: زیرساخت دیتابیس (وقتی Query درست است ولی هنوز کند است) موارد مهم Disk سریع (NVMe) برای دیتابیس حیاتی است RAM کافی برای buffer pool جدا کردن دیسک دیتا و لاگ (در برخی سناریوها) تنظیم کانکشن پولینگ (Application side) Replica برای خواندن (Read scaling) Sharding فقط وقتی لازم است (پیچیده و پرهزینه) نقشه راه پیشنهادی (عملی و مرحله ای) مرحله 1: تشخیص سریع (Quick Wins) 10 کوئری کند اول را پیدا کنید N+1 را حذف کنید SELECT * را حذف کنید ایندکس های بدیهی روی WHERE/JOIN های پرتکرار بگذارید مرحله 2: اصلاح ساختاری بازطراحی جداول مشکل دار آرشیو/پارتیشن بندی داده های حجیم کش برای داده های پرتکرار مرحله 3: مقیاس و پایداری Replica خواندنی Job های async برای گزارش مانیتورینگ دائمی + بودجه نگهداری جمع بندی بهینه سازی دیتابیس معمولا بیشترین بازده را در سرعت سایت دارد، چون: مستقیم روی زمان پاسخ سرور اثر می گذارد با افزایش داده خودش را نشان می دهد با چند اصلاح درست (Query + Index + Cache) می تواند چند برابر بهبود ایجاد کند اگر احساس می کنید سایت شما با افزایش کاربران یا داده ها کند شده، یا صفحات جستجو و پنل مدیریت زمان زیادی برای لود شدن می گیرند، تیم طراحان نوین می تواند با تحلیل کوئری ها، بررسی ایندکس ها و بهینه سازی ساختار دیتابیس، سرعت سایت شما را به شکل پایدار افزایش دهد. برای مشاوره و بررسی فنی، از طریق صفحه تماس با ما در ارتباط باشید.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-%d8%af%db%8c%d8%aa%d8%a7%d8%a8%db%8c%d8%b3%d8%9b-%d8%ac%d8%a7%db%8c%db%8c-%da%a9%d9%87-%db%b8%db%b0%d9%aa-%d8%b3%d8%b1%d8%b9%d8%aa-%d8%b3%d8%a7/">بهینه سازی دیتابیس؛ جایی که ۸۰٪ سرعت سایت شما در آن نهفته است</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<p dir="rtl" lang="fa">سرعت سایت فقط «کش و CDN» نیست. در بسیاری از پروژه های واقعی، گلوگاه اصلی جایی است که همه چیز به آن ختم می شود: <strong>دیتابیس</strong>. هر صفحه، هر جستجو، هر فیلتر محصول، هر گزارش مدیریتی و حتی لاگین کاربران در نهایت به کوئری ها، ایندکس ها، قفل ها و I/O دیسک دیتابیس وابسته است. اگر دیتابیس کند باشد، بقیه بهینه سازی ها فقط مُسکن هستند.</p>
<p dir="rtl" lang="fa">در این مقاله، به صورت جامع و عملی بررسی می کنیم چگونه دیتابیس را برای سرعت، پایداری و مقیاس پذیری بهینه کنید؛ از علائم و روش تشخیص مشکل تا تکنیک های سطح Query، Schema، Index، Cache و زیرساخت.</p>
<h2 dir="rtl" lang="fa">چرا دیتابیس معمولا عامل اصلی کندی است؟</h2>
<h3 dir="rtl" lang="fa">1) بیشتر درخواست ها به دیتابیس ختم می شوند</h3>
<p dir="rtl" lang="fa">حتی اگر HTML کش شده باشد، بسیاری از بخش ها دینامیک اند: سبد خرید، موجودی، پروفایل، نتایج جستجو، پنل مدیریت، پیشنهادها و…</p>
<h3 dir="rtl" lang="fa">2) افزایش داده، خطی رشد نمی کند؛ نمایی مشکل می سازد</h3>
<p dir="rtl" lang="fa">کوئری که روی 10 هزار رکورد خوب است، روی 10 میلیون رکورد می تواند فاجعه باشد، اگر ایندکس و طراحی درست نباشد.</p>
<h3 dir="rtl" lang="fa">3) دیتابیس هم CPU دارد، هم RAM، هم Disk و هم Lock</h3>
<p dir="rtl" lang="fa">کندی ممکن است از هر کدام باشد:</p>
<ul dir="rtl" lang="fa">
<li>CPU بالا: کوئری های سنگین، Sort/Group زیاد</li>
<li>RAM کم: کش دیتابیس کم، خواندن از دیسک</li>
<li>Disk کند: I/O بالا، لاگ های زیاد، tempdb (در SQL Server)</li>
<li>Lock/Blocking: تراکنش های طولانی، همزمانی بالا</li>
</ul>
<h2 dir="rtl" lang="fa">علائم کلاسیک مشکل دیتابیس (که باید جدی بگیرید)</h2>
<ul dir="rtl" lang="fa">
<li><strong>TTFB</strong> بالا (زمان شروع پاسخ از سرور زیاد است)</li>
<li>افزایش ناگهانی زمان بارگذاری در ساعات شلوغ</li>
<li>CPU یا Disk سرور دیتابیس نزدیک 100٪</li>
<li>تایم اوت شدن درخواست ها</li>
<li>گزارش ها و لیست های پنل مدیریت کندتر از قبل</li>
<li>کندی فقط در برخی صفحات (مثل جستجو/فیلتر/گزارش)</li>
</ul>
<h2 dir="rtl" lang="fa">روش درست شروع بهینه سازی: اول اندازه گیری، بعد تغییر</h2>
<p dir="rtl" lang="fa">اگر بدون اندازه گیری تغییر دهید، احتمال دارد مشکل را جابجا کنید یا بدتر کنید.</p>
<h3 dir="rtl" lang="fa">چک لیست اندازه گیری</h3>
<ol dir="rtl" lang="fa">
<li><strong>کندترین endpointها/صفحات</strong> را پیدا کنید (از APM یا لاگ زمان پاسخ)</li>
<li><strong>کندترین کوئری ها</strong> را لیست کنید:
<ul dir="rtl" lang="fa">
<li>میانگین زمان</li>
<li>بیشترین زمان</li>
<li>بیشترین تعداد اجرا</li>
</ul>
</li>
<li>برای هر کوئری، این ها را بررسی کنید:
<ul dir="rtl" lang="fa">
<li>Execution Plan</li>
<li>تعداد ردیف های واقعی vs تخمینی</li>
<li>استفاده از Index (Seek) یا Scan</li>
<li>میزان Sort/Hash/Spill به دیسک</li>
</ul>
</li>
<li>Bottleneck را مشخص کنید: CPU؟ I/O؟ Lock؟ Network؟</li>
</ol>
<h2 dir="rtl" lang="fa">بخش ۱: بهینه سازی Query (بیشترین اثر با کمترین هزینه)</h2>
<h3 dir="rtl" lang="fa">1) N+1 Query (قاتل پنهان سرعت)</h3>
<p dir="rtl" lang="fa">مثال رایج: لیست سفارش ها را می گیرید، بعد برای هر سفارش یک کوئری جدا برای آیتم ها می زنید.</p>
<p dir="rtl" lang="fa">راه حل:</p>
<ul dir="rtl" lang="fa">
<li>Join / Include صحیح</li>
<li>Batch query</li>
<li>Preload کردن داده های وابسته</li>
</ul>
<h3 dir="rtl" lang="fa">2) فقط ستون های لازم را SELECT کنید</h3>
<p dir="rtl" lang="fa"><code>SELECT *</code> در سیستم های واقعی یعنی:</p>
<ul dir="rtl" lang="fa">
<li>I/O بیشتر</li>
<li>انتقال دیتا بیشتر</li>
<li>کش کمتر مفید</li>
<li>احتمال استفاده نکردن از Covering Index</li>
</ul>
<h3 dir="rtl" lang="fa">3) Pagination درست</h3>
<p dir="rtl" lang="fa">بدترین حالت: <code>OFFSET ... FETCH</code> روی دیتای بزرگ بدون ایندکس مناسب.</p>
<p dir="rtl" lang="fa">راه بهتر (Keyset Pagination):</p>
<ul dir="rtl" lang="fa">
<li>بر اساس کلید مرتب سازی (مثلا <code>Id</code> یا <code>CreatedAt</code>) صفحه بندی کنید.</li>
<li>مثال منطقی: «بعد از آخرین Id قبلی» به جای OFFSET بزرگ.</li>
</ul>
<h3 dir="rtl" lang="fa">4) فیلترهای قابل ایندکس بنویسید</h3>
<p dir="rtl" lang="fa">برخی الگوها باعث می شوند دیتابیس نتواند از ایندکس استفاده کند:</p>
<ul dir="rtl" lang="fa">
<li>استفاده از تابع روی ستون در WHERE (مثل <code>WHERE YEAR(CreatedAt)=2026</code>)</li>
<li>تبدیل نوع داده در شرط</li>
</ul>
<p dir="rtl" lang="fa">راه حل:</p>
<ul dir="rtl" lang="fa">
<li>شرط را طوری بنویسید که ستون خام قابل مقایسه باشد (Range query).</li>
</ul>
<h3 dir="rtl" lang="fa">5) جستجو با LIKE</h3>
<p dir="rtl" lang="fa"><code>LIKE '%term%'</code> معمولا ایندکس را بی اثر می کند. راه حل ها:</p>
<ul dir="rtl" lang="fa">
<li>Full-Text Search (در SQL Server / MySQL)</li>
<li>موتور جدا مثل Elasticsearch برای جستجوی حرفه ای</li>
<li>اگر فقط Prefix است: <code>LIKE 'term%'</code> با ایندکس مناسب</li>
</ul>
<h3 dir="rtl" lang="fa">6) Aggregate های سنگین را از مسیر کاربر خارج کنید</h3>
<p dir="rtl" lang="fa">گزارش های سنگین را:</p>
<ul dir="rtl" lang="fa">
<li>Precompute کنید (جدول خلاصه / Materialized View)</li>
<li>یا Async بسازید (job + cache)</li>
<li>یا از replica خواندنی استفاده کنید</li>
</ul>
<h2 dir="rtl" lang="fa">بخش ۲: ایندکس گذاری اصولی (Index مثل میانبر است)</h2>
<h3 dir="rtl" lang="fa">اصول کلیدی ایندکس</h3>
<ul dir="rtl" lang="fa">
<li>ایندکس روی ستون هایی که <strong>زیاد WHERE / JOIN / ORDER BY</strong> می شوند.</li>
<li>ایندکس زیاد = سرعت خواندن بهتر، اما:
<ul dir="rtl" lang="fa">
<li>سرعت نوشتن بدتر</li>
<li>حجم بیشتر</li>
<li>نگهداری سخت تر</li>
</ul>
</li>
</ul>
<h3 dir="rtl" lang="fa">اشتباهات رایج</h3>
<ul dir="rtl" lang="fa">
<li>ایندکس روی ستون هایی که Selectivity پایین دارند (مثل boolean) بدون ترکیب مناسب</li>
<li>نداشتن ایندکس ترکیبی برای فیلترهای چندتایی</li>
<li>ناهماهنگی بین ORDER BY و ترتیب ستون های ایندکس</li>
</ul>
<h3 dir="rtl" lang="fa">Covering Index (کاهش نیاز به Lookup)</h3>
<p dir="rtl" lang="fa">اگر کوئری همیشه 3-4 ستون را می خواند، ایندکس را طوری بسازید که همان ستون ها را پوشش دهد تا دیتابیس مجبور نشود به جدول اصلی برگردد.</p>
<h2 dir="rtl" lang="fa">بخش ۳: طراحی Schema و مدل داده (ریشه ای ترین بهینه سازی)</h2>
<h3 dir="rtl" lang="fa">1) نوع داده درست انتخاب کنید</h3>
<ul dir="rtl" lang="fa">
<li><code>INT</code> به جای <code>BIGINT</code> وقتی لازم نیست</li>
<li><code>DATETIME2</code> مناسب (در SQL Server)</li>
<li>طول varchar منطقی</li>
</ul>
<p dir="rtl" lang="fa">این ها روی I/O، کش و ایندکس مستقیم اثر دارند.</p>
<h3 dir="rtl" lang="fa">2) نرمال سازی vs دنرمال سازی</h3>
<ul dir="rtl" lang="fa">
<li>برای تراکنش و صحت داده: نرمال سازی خوب است</li>
<li>برای سرعت خواندن های پرتکرار: دنرمال سازی کنترل شده (مثلا ذخیره شمارنده ها، یا snapshot) می تواند مفید باشد</li>
</ul>
<h3 dir="rtl" lang="fa">3) تاریخچه و لاگ ها را جدا کنید</h3>
<p dir="rtl" lang="fa">جدول های لاگ اگر با جداول عملیاتی قاطی شوند:</p>
<ul dir="rtl" lang="fa">
<li>ایندکس ها سنگین می شوند</li>
<li>Backup/Restore کند می شود</li>
<li>کوئری های روزمره کند می شوند</li>
</ul>
<p dir="rtl" lang="fa">راه حل:</p>
<ul dir="rtl" lang="fa">
<li>جدول جدا</li>
<li>آرشیو دوره ای</li>
<li>پارتیشن بندی (اگر امکانش باشد)</li>
</ul>
<h2 dir="rtl" lang="fa">بخش ۴: Cache؛ اگر درست پیاده شود، معجزه می کند</h2>
<h3 dir="rtl" lang="fa">چه چیزی را کش کنیم؟</h3>
<ul dir="rtl" lang="fa">
<li>داده های تقریبا ثابت: تنظیمات، دسته بندی ها</li>
<li>نتایج محاسباتی: تعدادها، خلاصه ها</li>
<li>نتایج جستجوهای پرتکرار (با TTL کوتاه)</li>
</ul>
<h3 dir="rtl" lang="fa">کجا کش کنیم؟</h3>
<ul dir="rtl" lang="fa">
<li>Application cache (in-memory)</li>
<li>Redis / Memcached</li>
<li>CDN برای محتوای استاتیک (کمک می کند، ولی جای دیتابیس را نمی گیرد)</li>
</ul>
<h3 dir="rtl" lang="fa">نکته مهم: Invalidation</h3>
<p dir="rtl" lang="fa">کش بدون سیاست invalidation یعنی «نمایش داده اشتباه».</p>
<p dir="rtl" lang="fa">پس:</p>
<ul dir="rtl" lang="fa">
<li>TTL منطقی</li>
<li>Cache key استاندارد</li>
<li>پاکسازی هنگام تغییرات مهم</li>
</ul>
<h2 dir="rtl" lang="fa">بخش ۵: Concurrency، Lock و تراکنش ها (کندی فقط کوئری نیست)</h2>
<h3 dir="rtl" lang="fa">علائم Lock/Blocking</h3>
<ul dir="rtl" lang="fa">
<li>کندی شدید فقط در ساعات شلوغ</li>
<li>کوئری ها در حالت waiting</li>
</ul>
<p dir="rtl" lang="fa">راه حل های معمول:</p>
<ul dir="rtl" lang="fa">
<li>کوتاه کردن تراکنش ها</li>
<li>جلوگیری از آپدیت های دسته ای در ساعات پیک</li>
<li>ایندکس مناسب برای کاهش اسکن و قفل گسترده</li>
<li>سطح ایزولیشن مناسب (بسته به دیتابیس)</li>
</ul>
<h2 dir="rtl" lang="fa">بخش ۶: نگهداری (Maintenance)؛ چیزی که معمولا فراموش می شود</h2>
<ul dir="rtl" lang="fa">
<li><strong>به روز بودن آمار (Statistics)</strong>: برای پلن درست حیاتی است (خصوصا SQL Server)</li>
<li><strong>Fragmentation</strong>: ایندکس های به هم ریخته روی I/O اثر دارند</li>
<li><strong>Cleanup</strong>: حذف داده های قدیمی، آرشیو</li>
<li><strong>Backup strategy</strong>: بکاپ سنگین در ساعت پیک می تواند کندی ایجاد کند</li>
</ul>
<h2 dir="rtl" lang="fa">بخش ۷: زیرساخت دیتابیس (وقتی Query درست است ولی هنوز کند است)</h2>
<h3 dir="rtl" lang="fa">موارد مهم</h3>
<ul dir="rtl" lang="fa">
<li>Disk سریع (NVMe) برای دیتابیس حیاتی است</li>
<li>RAM کافی برای buffer pool</li>
<li>جدا کردن دیسک دیتا و لاگ (در برخی سناریوها)</li>
<li>تنظیم کانکشن پولینگ (Application side)</li>
<li>Replica برای خواندن (Read scaling)</li>
<li>Sharding فقط وقتی لازم است (پیچیده و پرهزینه)</li>
</ul>
<h2 dir="rtl" lang="fa">نقشه راه پیشنهادی (عملی و مرحله ای)</h2>
<h3 dir="rtl" lang="fa">مرحله 1: تشخیص سریع (Quick Wins)</h3>
<ul dir="rtl" lang="fa">
<li>10 کوئری کند اول را پیدا کنید</li>
<li>N+1 را حذف کنید</li>
<li><code>SELECT *</code> را حذف کنید</li>
<li>ایندکس های بدیهی روی WHERE/JOIN های پرتکرار بگذارید</li>
</ul>
<h3 dir="rtl" lang="fa">مرحله 2: اصلاح ساختاری</h3>
<ul dir="rtl" lang="fa">
<li>بازطراحی جداول مشکل دار</li>
<li>آرشیو/پارتیشن بندی داده های حجیم</li>
<li>کش برای داده های پرتکرار</li>
</ul>
<h3 dir="rtl" lang="fa">مرحله 3: مقیاس و پایداری</h3>
<ul dir="rtl" lang="fa">
<li>Replica خواندنی</li>
<li>Job های async برای گزارش</li>
<li>مانیتورینگ دائمی + بودجه نگهداری</li>
</ul>
<h2 dir="rtl" lang="fa">جمع بندی</h2>
<p dir="rtl" lang="fa">بهینه سازی دیتابیس معمولا بیشترین بازده را در سرعت سایت دارد، چون:</p>
<ul dir="rtl" lang="fa">
<li>مستقیم روی زمان پاسخ سرور اثر می گذارد</li>
<li>با افزایش داده خودش را نشان می دهد</li>
<li>با چند اصلاح درست (Query + Index + Cache) می تواند چند برابر بهبود ایجاد کند</li>
</ul>
<p dir="rtl" lang="fa">اگر احساس می کنید سایت شما با افزایش کاربران یا داده ها کند شده، یا صفحات جستجو و پنل مدیریت زمان زیادی برای لود شدن می گیرند، تیم طراحان نوین می تواند با تحلیل کوئری ها، بررسی ایندکس ها و بهینه سازی ساختار دیتابیس، سرعت سایت شما را به شکل پایدار افزایش دهد. برای مشاوره و بررسی فنی، از طریق صفحه <a href="https://tarahanenovin.ir/site/contact" target="_blank" rel="nofollow noopener noreferrer">تماس با ما</a> در ارتباط باشید.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-%d8%af%db%8c%d8%aa%d8%a7%d8%a8%db%8c%d8%b3%d8%9b-%d8%ac%d8%a7%db%8c%db%8c-%da%a9%d9%87-%db%b8%db%b0%d9%aa-%d8%b3%d8%b1%d8%b9%d8%aa-%d8%b3%d8%a7/">بهینه سازی دیتابیس؛ جایی که ۸۰٪ سرعت سایت شما در آن نهفته است</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d8%a8%d9%87%db%8c%d9%86%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-%d8%af%db%8c%d8%aa%d8%a7%d8%a8%db%8c%d8%b3%d8%9b-%d8%ac%d8%a7%db%8c%db%8c-%da%a9%d9%87-%db%b8%db%b0%d9%aa-%d8%b3%d8%b1%d8%b9%d8%aa-%d8%b3%d8%a7/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>تمامی چیزهایی که باید درباره Laravel 13 بدانید</title>
		<link>https://tarahanenovin.ir/blog/%d8%aa%d9%85%d8%a7%d9%85%db%8c-%da%86%db%8c%d8%b2%d9%87%d8%a7%db%8c%db%8c-%da%a9%d9%87-%d8%a8%d8%a7%db%8c%d8%af-%d8%af%d8%b1%d8%a8%d8%a7%d8%b1%d9%87-laravel-13-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/</link>
					<comments>https://tarahanenovin.ir/blog/%d8%aa%d9%85%d8%a7%d9%85%db%8c-%da%86%db%8c%d8%b2%d9%87%d8%a7%db%8c%db%8c-%da%a9%d9%87-%d8%a8%d8%a7%db%8c%d8%af-%d8%af%d8%b1%d8%a8%d8%a7%d8%b1%d9%87-laravel-13-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[طراحی وب]]></category>
		<category><![CDATA[فرانت‌اند]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[لاراول]]></category>
		<category><![CDATA[لاراول 13]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=230</guid>

					<description><![CDATA[<p>لاراول 13 نسل ۲۰۲۶ این فریم ورک است که طبق ریلیز نوت رسمی، تمرکز اصلی اش روی «AI-native workflows»، پیش فرض های امن تر، و APIهای بیانگرتر است؛ در عین حال طبق راهنمای ارتقا، برای اکثر پروژه ها یک ارتقای کم دردسر و سریع محسوب می شود. Laravel 13 دقیقا چیست و چرا مهم است؟ Laravel 13 ادامه روند انتشار سالانه لاراول است و چند پیام واضح دارد: حداقل PHP 8.3: یعنی اگر پروژه شما روی 8.2 یا پایین تر است، قبل از هر کاری باید زیرساخت اجرا را آماده کنید. AI به صورت رسمی و First-party: یعنی برای کارهای رایج هوش مصنوعی (تولید متن، تصویر، امبدینگ، agentها و…) دیگر لازم نیست همیشه از چند پکیج پراکنده استفاده کنید. امنیت با پیش فرض های سخت گیرانه تر: مخصوصا در بحث cache serialization و میان افزار جدید جلوگیری از جعل درخواست. کمترین Breaking Change: تیم لاراول عمدا تلاش کرده ارتقای 12 به 13 سریع باشد (در خود آپگرید گاید زمان تخمینی حدود ۱۰ دقیقه ذکر شده). نسخه ها، پشتیبانی و نیازمندی ها (آن چیزی که قبل از کدنویسی باید بدانید) 1) سیاست نسخه بندی و سازگاری لاراول از Semantic Versioning پیروی می کند: Major (مثل 12 → 13) می تواند Breaking Change داشته باشد. Minor/Patch نباید Breaking Change داشته باشند. نکته حرفه ای: در composer.json بهتر است constraintها را به شکل ^13.0 تنظیم کنید تا آپدیت های Minor/Patch را بدون درگیری بگیرید. 2) حداقل PHP طبق مستندات رسمی: Laravel 13.x حداقل PHP 8.3 می خواهد. این یعنی: سرور، لوکال، CI و حتی imageهای Docker باید همگی هم راستا شوند. پکیج های قدیمی که PHP 8.3 را ساپورت نمی کنند، اولین منبع دردسر شما خواهند بود (نه خود لاراول). مهم ترین قابلیت های جدید Laravel 13 (با نگاه عملی) 1) Laravel AI SDK (هسته AI به صورت رسمی) لاراول 13 یک SDK رسمی برای AI معرفی کرده که هدفش این است: شما یک API لاراولی و provider-agnostic داشته باشید. بعدا اگر provider را عوض کردید (یا چند provider داشتید)، کدتان به هم نریزد. کارهای رایج: text generation, tool-calling agents, embeddings, audio, image و یکپارچه سازی با vector store. مدل ذهنی (چطور به آن نگاه کنیم؟) AI SDK را مثل این ببینید: Service جدید در لایه infrastructure با قراردادهای مشخص و façade / entrypointهای تمیز برای use-caseهای مختلف مثال ها (از ریلیز نوت) تولید پاسخ با یک agent: use App\Ai\Agents\SalesCoach; $response = SalesCoach::make()-&#62;prompt('Analyze this sales transcript...'); return (string) $response; تولید تصویر: use Laravel\Ai\Image; $image = Image::of('A donut sitting on the kitchen counter')-&#62;generate(); $rawContent = (string) $image; تولید صوت: use Laravel\Ai\Audio; $audio = Audio::of('I love coding with Laravel.')-&#62;generate(); $rawContent = (string) $audio; تولید امبدینگ (برای semantic search / RAG): use Illuminate\Support\Str; $embeddings = Str::of('Napa Valley has great wine.')-&#62;toEmbeddings(); نکات معماری برای پروژه واقعی برای تولید امبدینگ، صف (Queue) بگذارید: هم هزینه کنترل می شود، هم UX بهتر است. نتیجه امبدینگ را در یک vector store (یا دیتابیس مناسب) ذخیره کنید و برای جستجوی معنایی استفاده کنید. خروجی AI را مثل input کاربر «غیرقابل اعتماد» فرض کنید: validate، sanitize و محدودیت دسترسی اعمال کنید. 2) JSON:API Resources (خروجی استاندارد API) لاراول 13 JSON:API resources را به صورت First-party اضافه کرده است تا: ساختار response مطابق استاندارد JSON:API باشد مدیریت relationshipها، includeها، sparse fieldsetها، links و headerهای استاندارد ساده شود. چرا این برای تیم های حرفه ای مهم است؟ چون در APIهای بزرگ: یک استاندارد خروجی، هزینه هماهنگی frontend/backend را کم می کند. و با رشد پروژه، consistency حفظ می شود. 3) PreventRequestForgery (تقویت CSRF / جعل درخواست) در لاراول 13، میان افزار حفاظت از جعل درخواست formalized و بهتر شده و با نام: PreventRequestForgery ارائه شده و origin-aware request verification را اضافه می کند در کنار سازگاری با توکن CSRF. نکته امنیتی اگر با چند subdomain، reverse proxy، یا SPA روی دامنه جدا کار می کنید: حتما رفتار originها و headerها را در staging تست کنید. چون تغییرات امنیتی معمولا روی محیط های واقعی (CDN/WAF) خودش را نشان می دهد. 4) Queue Routing (مسیر دهی صف بر اساس کلاس Job) لاراول 13 امکان route کردن jobها را به شکل مرکزی اضافه کرده: Queue::route(ProcessPodcast::class, connection: 'redis', queue: 'podcasts'); چرا این عالی است؟ در پروژه های بزرگ معمولا این درد را دارید: بعضی jobها باید سریع اجرا شوند (queue جدا) بعضی jobها heavy هستند (worker جدا) بعضی jobها IO bound هستند (connection جدا) با route مرکزی: از پخش شدن -&#62;onQueue() و -&#62;onConnection() در کل کد جلوگیری می کنید. معماری queue تمیزتر می شود. 5) گسترش PHP Attributes (اعلان محور شدن رفتارها) لاراول 13 پشتیبانی attributeها را در بخش های بیشتری گسترش داده؛ نمونه هایی که در ریلیز نوت آمده: #[Middleware] #[Authorize] و برای jobها: #[Tries], #[Backoff], #[Timeout], #[FailOnTimeout] مثال: use App\Models\Comment; use App\Models\Post; use Illuminate\Routing\Attributes\Controllers\Authorize; use Illuminate\Routing\Attributes\Controllers\Middleware; #[Middleware('auth')] class CommentController { #[Middleware('subscribed')] #[Authorize('create', [Comment::class, 'post'])] public function store(Post $post) { // ... } } نگاه مهندسی Attributes یعنی: رفتار نزدیک کد قرار می گیرد (co-located) readability بالا می رود اما باید مراقب باشید config پراکنده و غیرقابل جستجو نشود پیشنهاد تیمی: برای پروژه های بزرگ، یک convention داخلی تعیین کنید: چه چیزهایی attribute و چه چیزهایی config. 6) Cache::touch و تغییرات مهم Cache Serialization Cache::touch Laravel 13 متدی اضافه کرده که TTL یک آیتم cache را بدون re-store کردن مقدار تمدید می کند: Cache::touch(...) این در سناریوهایی مثل sliding expiration خیلی کاربردی است. سخت گیری امنیتی: serializable_classes در آپگرید گاید آمده: مقدار پیش فرض serializable_classes در config cache روی false قرار گرفته تا ریسک حملات deserialization کاهش یابد (خصوصا اگر APP_KEY لو برود). اگر شما عمدا object در cache می گذارید: باید allow-list کلاس ها را مشخص کنید. نکته: در سیستم های بزرگ بهتر است payload cache را array/JSON نگه دارید نه object؛ چون: نسخه بندی ساده تر می شود ریسک امنیتی کمتر می شود وابستگی به ساختار کلاس کاهش می یابد ارتقا به Laravel 13 از Laravel 12 طبق Upgrade Guide رسمی، زمان تخمینی ارتقا حدود ۱۰ دقیقه است (اگر پروژه خیلی خاص نباشد). اما در عمل برای تیم های حرفه ای، مسیر درست این است: گام 1: آماده سازی (قبل از composer update) PHP را روی همه محیط ها به 8.3 ارتقا دهید (لوکال، CI، سرور). یک Branch جدا برای upgrade بسازید. تست ها را سبز کنید (اگر تست ندارید، حداقل smoke test بنویسید: لاگین، CRUD اصلی، queue worker). گام 2: آپدیت وابستگی ها طبق مستندات: laravel/framework → ^13.0 laravel/boost → ^2.0 laravel/tinker → ^3.0 phpunit/phpunit → ^12.0 pestphp/pest → ^4.0 سپس: composer update و رفع تعارض پکیج ها (معمولا اصلی ترین قسمت کار همین است) گام 3: بررسی High Impact Changes Request Forgery Protection: رفتار originها و CSRF را در محیط واقعی تست کنید. Cache serialization: اگر object cache می کنید، سریع تکلیف serializable_classes را مشخص کنید. گام 4: بررسی Medium/Low Impact از مواردی که در Upgrade Guide ذکر شده: تغییر پیش فرض prefixهای cache و session cookie (اگر به fallbackهای framework متکی بودید) تغییر رفتار Container::call در پارامتر nullable با default null موارد مرتبط با MySQL در برخی queryهای DELETE با JOIN/ORDER/LIMIT (برای سیستم های قدیمی ممکن است مهم شود) ارتقا با AI (رویکرد جدید تیم لاراول) Laravel 13 پیشنهاد می دهد از Laravel Boost به عنوان MCP server استفاده کنید و با یک slash command فرایند ارتقا را هدایت کنید: دستور /upgrade-laravel-v13 نیازمند laravel/boost ^2.0 این برای تیم هایی عالی است که: کدبیس بزرگ دارند می خواهند checklist ارتقا را سریع و با کمترین خطا جلو ببرند اما باز هم باید خروجی را review کنید (AI جای review را نمی گیرد) نصب و راه اندازی Laravel 13 (برای پروژه جدید) از Installation رسمی: نیاز دارید PHP + Composer + Laravel Installer و برای assetها: Node/NPM یا Bun در تیم های حرفه ای پیشنهاد می کنم: روی لوکال از ابزارهای رسمی مثل Herd (در صورت امکان) یا Docker استفاده کنید روی CI یک matrix ساده بسازید (PHP 8.3 + DB) از همان اول queue و scheduler را جدا طراحی کنید نکات معماری و Best Practice برای Laravel 13 1) AI را Feature محور پیاده کنید، نه هیجانی به جای اینکه «AI را همه جا بریزید»، use-case تعریف کنید: جستجوی معنایی محصولات خلاصه سازی تیکت های پشتیبانی پیشنهاد پاسخ برای اپراتور دسته بندی خودکار محتوا هر use-case: ورودی مشخص خروجی مشخص logging و monitoring fallback (اگر provider قطع شد) 2) Queue-first برای کارهای AI و پردازش سنگین هر چیزی که: IO زیاد دارد هزینه دارد یا latency بالا دارد باید برود صف. بعد route کردن صف ها در Laravel 13 تمیزتر هم شده است. 3) امنیت Cache را جدی بگیرید اگر قبلا هر چیزی را object می کردید و می گذاشتید cache: الان وقت refactor است یا allow-list دقیق بنویسید 4) از استاندارد JSON:API برای تیم های چندکلاینتی استفاده کنید اگر شما: وب + اپ موبایل + پنل جدا دارید JSON:API می تواند استاندارد مشترک خروجی باشد. جمع بندی Laravel 13 یک ارتقای کم ریسک اما بسیار مهم است: حداقل PHP 8.3، SDK رسمی AI، استانداردسازی بهتر APIها با JSON:API، بهبودهای امنیتی مثل PreventRequestForgery و سخت گیری در unserialize شدن cache، و همچنین کیفیت زندگی بهتر در صف ها با Queue routing و Attributeهای بیشتر. اگر پروژه شما Laravel 12 است، بهترین مسیر این است: PHP 8.3 را آماده کنید وابستگی ها را طبق Upgrade Guide بالا ببرید موارد امنیتی cache و CSRF را در staging تست کنید سپس release کنید اگر قصد طراحی سایت یا توسعه وب اپلیکیشن با Laravel 13 را دارید و می خواهید معماری پروژه از ابتدا اصولی، امن و قابل توسعه باشد، از طریق صفحه تماس با ما با طراحان نوین در ارتباط باشید تا نیاز پروژه را بررسی و مسیر اجرای درست را پیشنهاد کنیم.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%aa%d9%85%d8%a7%d9%85%db%8c-%da%86%db%8c%d8%b2%d9%87%d8%a7%db%8c%db%8c-%da%a9%d9%87-%d8%a8%d8%a7%db%8c%d8%af-%d8%af%d8%b1%d8%a8%d8%a7%d8%b1%d9%87-laravel-13-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/">تمامی چیزهایی که باید درباره Laravel 13 بدانید</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<p dir="rtl" lang="fa"><strong>لاراول 13</strong> نسل ۲۰۲۶ این فریم ورک است که طبق ریلیز نوت رسمی، تمرکز اصلی اش روی «AI-native workflows»، پیش فرض های امن تر، و APIهای بیانگرتر است؛ در عین حال طبق راهنمای ارتقا، برای اکثر پروژه ها یک ارتقای کم دردسر و سریع محسوب می شود.</p>
<h2 dir="rtl" lang="fa">Laravel 13 دقیقا چیست و چرا مهم است؟</h2>
<p dir="rtl" lang="fa">Laravel 13 ادامه روند انتشار سالانه لاراول است و چند پیام واضح دارد:</p>
<ol dir="rtl" lang="fa">
<li><strong>حداقل PHP 8.3</strong>: یعنی اگر پروژه شما روی 8.2 یا پایین تر است، قبل از هر کاری باید زیرساخت اجرا را آماده کنید.</li>
<li><strong>AI به صورت رسمی و First-party</strong>: یعنی برای کارهای رایج هوش مصنوعی (تولید متن، تصویر، امبدینگ، agentها و…) دیگر لازم نیست همیشه از چند پکیج پراکنده استفاده کنید.</li>
<li><strong>امنیت با پیش فرض های سخت گیرانه تر</strong>: مخصوصا در بحث cache serialization و میان افزار جدید جلوگیری از جعل درخواست.</li>
<li><strong>کمترین Breaking Change</strong>: تیم لاراول عمدا تلاش کرده ارتقای 12 به 13 سریع باشد (در خود آپگرید گاید زمان تخمینی حدود ۱۰ دقیقه ذکر شده).</li>
</ol>
<h2 dir="rtl" lang="fa">نسخه ها، پشتیبانی و نیازمندی ها (آن چیزی که قبل از کدنویسی باید بدانید)</h2>
<h3 dir="rtl" lang="fa">1) سیاست نسخه بندی و سازگاری</h3>
<p dir="rtl" lang="fa">لاراول از <strong>Semantic Versioning</strong> پیروی می کند:</p>
<ul dir="rtl" lang="fa">
<li>Major (مثل 12 → 13) می تواند Breaking Change داشته باشد.</li>
<li>Minor/Patch نباید Breaking Change داشته باشند.</li>
</ul>
<p dir="rtl" lang="fa">نکته حرفه ای: در <code>composer.json</code> بهتر است constraintها را به شکل <code>^13.0</code> تنظیم کنید تا آپدیت های Minor/Patch را بدون درگیری بگیرید.</p>
<h3 dir="rtl" lang="fa">2) حداقل PHP</h3>
<p dir="rtl" lang="fa">طبق مستندات رسمی:</p>
<ul dir="rtl" lang="fa">
<li><strong>Laravel 13.x حداقل PHP 8.3 می خواهد</strong>.</li>
</ul>
<p dir="rtl" lang="fa">این یعنی:</p>
<ul dir="rtl" lang="fa">
<li>سرور، لوکال، CI و حتی imageهای Docker باید همگی هم راستا شوند.</li>
<li>پکیج های قدیمی که PHP 8.3 را ساپورت نمی کنند، اولین منبع دردسر شما خواهند بود (نه خود لاراول).</li>
</ul>
<h2 dir="rtl" lang="fa">مهم ترین قابلیت های جدید Laravel 13 (با نگاه عملی)</h2>
<h2 dir="rtl" lang="fa">1) Laravel AI SDK (هسته AI به صورت رسمی)</h2>
<p dir="rtl" lang="fa">لاراول 13 یک SDK رسمی برای AI معرفی کرده که هدفش این است:</p>
<ul dir="rtl" lang="fa">
<li>شما یک API لاراولی و provider-agnostic داشته باشید.</li>
<li>بعدا اگر provider را عوض کردید (یا چند provider داشتید)، کدتان به هم نریزد.</li>
<li>کارهای رایج: <strong>text generation</strong>, <strong>tool-calling agents</strong>, <strong>embeddings</strong>, <strong>audio</strong>, <strong>image</strong> و یکپارچه سازی با vector store.</li>
</ul>
<h3 dir="rtl" lang="fa">مدل ذهنی (چطور به آن نگاه کنیم؟)</h3>
<p dir="rtl" lang="fa">AI SDK را مثل این ببینید:</p>
<ul dir="rtl" lang="fa">
<li><code>Service</code> جدید در لایه infrastructure</li>
<li>با قراردادهای مشخص</li>
<li>و façade / entrypointهای تمیز برای use-caseهای مختلف</li>
</ul>
<h3 dir="rtl" lang="fa">مثال ها (از ریلیز نوت)</h3>
<p dir="rtl" lang="fa">تولید پاسخ با یک agent:</p>
<pre><code class="hljs"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Ai</span>\<span class="hljs-title">Agents</span>\<span class="hljs-title">SalesCoach</span>;

<span class="hljs-variable">$response</span> = <span class="hljs-title class_">SalesCoach</span>::<span class="hljs-title function_ invoke__">make</span>()-&gt;<span class="hljs-title function_ invoke__">prompt</span>(<span class="hljs-string">'Analyze this sales transcript...'</span>);

<span class="hljs-keyword">return</span> (<span class="hljs-keyword">string</span>) <span class="hljs-variable">$response</span>;
</code></pre>
<p dir="rtl" lang="fa">تولید تصویر:</p>
<pre><code class="hljs"><span class="hljs-keyword">use</span> <span class="hljs-title">Laravel</span>\<span class="hljs-title">Ai</span>\<span class="hljs-title">Image</span>;

<span class="hljs-variable">$image</span> = <span class="hljs-title class_">Image</span>::<span class="hljs-title function_ invoke__">of</span>(<span class="hljs-string">'A donut sitting on the kitchen counter'</span>)-&gt;<span class="hljs-title function_ invoke__">generate</span>();
<span class="hljs-variable">$rawContent</span> = (<span class="hljs-keyword">string</span>) <span class="hljs-variable">$image</span>;
</code></pre>
<p dir="rtl" lang="fa">تولید صوت:</p>
<pre><code class="hljs"><span class="hljs-keyword">use</span> <span class="hljs-title">Laravel</span>\<span class="hljs-title">Ai</span>\<span class="hljs-title">Audio</span>;

<span class="hljs-variable">$audio</span> = <span class="hljs-title class_">Audio</span>::<span class="hljs-title function_ invoke__">of</span>(<span class="hljs-string">'I love coding with Laravel.'</span>)-&gt;<span class="hljs-title function_ invoke__">generate</span>();
<span class="hljs-variable">$rawContent</span> = (<span class="hljs-keyword">string</span>) <span class="hljs-variable">$audio</span>;
</code></pre>
<p dir="rtl" lang="fa">تولید امبدینگ (برای semantic search / RAG):</p>
<pre><code class="hljs"><span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Str</span>;

<span class="hljs-variable">$embeddings</span> = <span class="hljs-title class_">Str</span>::<span class="hljs-title function_ invoke__">of</span>(<span class="hljs-string">'Napa Valley has great wine.'</span>)-&gt;<span class="hljs-title function_ invoke__">toEmbeddings</span>();
</code></pre>
<h3 dir="rtl" lang="fa">نکات معماری برای پروژه واقعی</h3>
<ul dir="rtl" lang="fa">
<li>برای تولید امبدینگ، <strong>صف (Queue)</strong> بگذارید: هم هزینه کنترل می شود، هم UX بهتر است.</li>
<li>نتیجه امبدینگ را در یک vector store (یا دیتابیس مناسب) ذخیره کنید و برای جستجوی معنایی استفاده کنید.</li>
<li>خروجی AI را مثل input کاربر «غیرقابل اعتماد» فرض کنید: validate، sanitize و محدودیت دسترسی اعمال کنید.</li>
</ul>
<h2 dir="rtl" lang="fa">2) JSON:API Resources (خروجی استاندارد API)</h2>
<p dir="rtl" lang="fa">لاراول 13 <strong>JSON:API resources</strong> را به صورت First-party اضافه کرده است تا:</p>
<ul dir="rtl" lang="fa">
<li>ساختار response مطابق استاندارد JSON:API باشد</li>
<li>مدیریت relationshipها، includeها، sparse fieldsetها، links و headerهای استاندارد ساده شود.</li>
</ul>
<h3 dir="rtl" lang="fa">چرا این برای تیم های حرفه ای مهم است؟</h3>
<p dir="rtl" lang="fa">چون در APIهای بزرگ:</p>
<ul dir="rtl" lang="fa">
<li>یک استاندارد خروجی، هزینه هماهنگی frontend/backend را کم می کند.</li>
<li>و با رشد پروژه، consistency حفظ می شود.</li>
</ul>
<h2 dir="rtl" lang="fa">3) PreventRequestForgery (تقویت CSRF / جعل درخواست)</h2>
<p dir="rtl" lang="fa">در لاراول 13، میان افزار حفاظت از جعل درخواست formalized و بهتر شده و با نام:</p>
<ul dir="ltr" lang="en">
<li><code>PreventRequestForgery</code></li>
</ul>
<p dir="rtl" lang="fa">ارائه شده و <strong>origin-aware request verification</strong> را اضافه می کند در کنار سازگاری با توکن CSRF.</p>
<h3 dir="rtl" lang="fa">نکته امنیتی</h3>
<p dir="rtl" lang="fa">اگر با چند subdomain، reverse proxy، یا SPA روی دامنه جدا کار می کنید:</p>
<ul dir="rtl" lang="fa">
<li>حتما رفتار originها و headerها را در staging تست کنید.</li>
<li>چون تغییرات امنیتی معمولا روی محیط های واقعی (CDN/WAF) خودش را نشان می دهد.</li>
</ul>
<h2 dir="rtl" lang="fa">4) Queue Routing (مسیر دهی صف بر اساس کلاس Job)</h2>
<p dir="rtl" lang="fa">لاراول 13 امکان route کردن jobها را به شکل مرکزی اضافه کرده:</p>
<pre><code class="hljs"><span class="hljs-title class_">Queue</span>::<span class="hljs-title function_ invoke__">route</span>(<span class="hljs-title class_">ProcessPodcast</span>::<span class="hljs-variable language_">class</span>, <span class="hljs-attr">connection</span>: <span class="hljs-string">'redis'</span>, <span class="hljs-attr">queue</span>: <span class="hljs-string">'podcasts'</span>);
</code></pre>
<h3 dir="rtl" lang="fa">چرا این عالی است؟</h3>
<p dir="rtl" lang="fa">در پروژه های بزرگ معمولا این درد را دارید:</p>
<ul dir="rtl" lang="fa">
<li>بعضی jobها باید سریع اجرا شوند (queue جدا)</li>
<li>بعضی jobها heavy هستند (worker جدا)</li>
<li>بعضی jobها IO bound هستند (connection جدا)</li>
</ul>
<p dir="rtl" lang="fa">با route مرکزی:</p>
<ul dir="rtl" lang="fa">
<li>از پخش شدن <code>-&gt;onQueue()</code> و <code>-&gt;onConnection()</code> در کل کد جلوگیری می کنید.</li>
<li>معماری queue تمیزتر می شود.</li>
</ul>
<h2 dir="rtl" lang="fa">5) گسترش PHP Attributes (اعلان محور شدن رفتارها)</h2>
<p dir="rtl" lang="fa">لاراول 13 پشتیبانی attributeها را در بخش های بیشتری گسترش داده؛ نمونه هایی که در ریلیز نوت آمده:</p>
<ul dir="ltr" lang="en">
<li><code>#[Middleware]</code></li>
<li><code>#[Authorize]</code></li>
<li>و برای jobها: <code>#[Tries]</code>, <code>#[Backoff]</code>, <code>#[Timeout]</code>, <code>#[FailOnTimeout]</code></li>
</ul>
<p dir="rtl" lang="fa">مثال:</p>
<pre><code class="hljs"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Comment</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Routing</span>\<span class="hljs-title">Attributes</span>\<span class="hljs-title">Controllers</span>\<span class="hljs-title">Authorize</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Routing</span>\<span class="hljs-title">Attributes</span>\<span class="hljs-title">Controllers</span>\<span class="hljs-title">Middleware</span>;

<span class="hljs-meta">#[Middleware</span>(<span class="hljs-string">'auth'</span>)<span class="hljs-meta">]</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CommentController</span>
</span>{
    <span class="hljs-meta">#[Middleware</span>(<span class="hljs-string">'subscribed'</span>)<span class="hljs-meta">]</span>
    <span class="hljs-meta">#[Authorize</span>(<span class="hljs-string">'create'</span>, [<span class="hljs-title class_">Comment</span>::<span class="hljs-variable language_">class</span>, <span class="hljs-string">'post'</span>])<span class="hljs-meta">]</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">store</span>(<span class="hljs-params">Post <span class="hljs-variable">$post</span></span>)
    </span>{
        <span class="hljs-comment">// ...</span>
    }
}
</code></pre>
<h3 dir="rtl" lang="fa">نگاه مهندسی</h3>
<p dir="rtl" lang="fa">Attributes یعنی:</p>
<ul dir="rtl" lang="fa">
<li>رفتار نزدیک کد قرار می گیرد (co-located)</li>
<li>readability بالا می رود</li>
<li>اما باید مراقب باشید config پراکنده و غیرقابل جستجو نشود</li>
</ul>
<p dir="rtl" lang="fa">پیشنهاد تیمی:</p>
<ul dir="rtl" lang="fa">
<li>برای پروژه های بزرگ، یک convention داخلی تعیین کنید: چه چیزهایی attribute و چه چیزهایی config.</li>
</ul>
<h2 dir="rtl" lang="fa">6) Cache::touch و تغییرات مهم Cache Serialization</h2>
<h3 lang="en">Cache::touch</h3>
<p dir="rtl" lang="fa">Laravel 13 متدی اضافه کرده که TTL یک آیتم cache را بدون re-store کردن مقدار تمدید می کند:</p>
<ul dir="ltr" lang="en">
<li><code>Cache::touch(...)</code></li>
</ul>
<p dir="rtl" lang="fa">این در سناریوهایی مثل sliding expiration خیلی کاربردی است.</p>
<h3 dir="rtl" lang="fa">سخت گیری امنیتی: <code>serializable_classes</code></h3>
<p dir="rtl" lang="fa">در آپگرید گاید آمده:</p>
<ul dir="rtl" lang="fa">
<li>مقدار پیش فرض <code>serializable_classes</code> در config cache روی <code>false</code> قرار گرفته تا <strong>ریسک حملات deserialization</strong> کاهش یابد (خصوصا اگر <code>APP_KEY</code> لو برود).</li>
</ul>
<p dir="rtl" lang="fa">اگر شما عمدا object در cache می گذارید:</p>
<ul dir="rtl" lang="fa">
<li>باید allow-list کلاس ها را مشخص کنید.</li>
</ul>
<p dir="rtl" lang="fa">نکته: در سیستم های بزرگ بهتر است <strong>payload cache را array/JSON نگه دارید</strong> نه object؛ چون:</p>
<ul dir="rtl" lang="fa">
<li>نسخه بندی ساده تر می شود</li>
<li>ریسک امنیتی کمتر می شود</li>
<li>وابستگی به ساختار کلاس کاهش می یابد</li>
</ul>
<h1 dir="rtl" lang="fa">ارتقا به Laravel 13 از Laravel 12</h1>
<p dir="rtl" lang="fa">طبق Upgrade Guide رسمی، زمان تخمینی ارتقا <strong>حدود ۱۰ دقیقه</strong> است (اگر پروژه خیلی خاص نباشد). اما در عمل برای تیم های حرفه ای، مسیر درست این است:</p>
<h2 dir="rtl" lang="fa">گام 1: آماده سازی (قبل از composer update)</h2>
<ol dir="rtl" lang="fa">
<li>PHP را روی همه محیط ها به <strong>8.3</strong> ارتقا دهید (لوکال، CI، سرور).</li>
<li>یک Branch جدا برای upgrade بسازید.</li>
<li>تست ها را سبز کنید (اگر تست ندارید، حداقل smoke test بنویسید: لاگین، CRUD اصلی، queue worker).</li>
</ol>
<h2 dir="rtl" lang="fa">گام 2: آپدیت وابستگی ها</h2>
<p dir="rtl" lang="fa">طبق مستندات:</p>
<ul dir="ltr" lang="en">
<li><code>laravel/framework</code> → <code>^13.0</code></li>
<li><code>laravel/boost</code> → <code>^2.0</code></li>
<li><code>laravel/tinker</code> → <code>^3.0</code></li>
<li><code>phpunit/phpunit</code> → <code>^12.0</code></li>
<li><code>pestphp/pest</code> → <code>^4.0</code></li>
</ul>
<p dir="rtl" lang="fa">سپس:</p>
<ul dir="rtl" lang="fa">
<li><code>composer update</code></li>
<li>و رفع تعارض پکیج ها (معمولا اصلی ترین قسمت کار همین است)</li>
</ul>
<h2 dir="rtl" lang="fa">گام 3: بررسی High Impact Changes</h2>
<ul dir="rtl" lang="fa">
<li><strong>Request Forgery Protection</strong>: رفتار originها و CSRF را در محیط واقعی تست کنید.</li>
<li><strong>Cache serialization</strong>: اگر object cache می کنید، سریع تکلیف <code>serializable_classes</code> را مشخص کنید.</li>
</ul>
<h2 dir="rtl" lang="fa">گام 4: بررسی Medium/Low Impact</h2>
<p dir="rtl" lang="fa">از مواردی که در Upgrade Guide ذکر شده:</p>
<ul dir="rtl" lang="fa">
<li>تغییر پیش فرض prefixهای cache و session cookie (اگر به fallbackهای framework متکی بودید)</li>
<li>تغییر رفتار <code>Container::call</code> در پارامتر nullable با default null</li>
<li>موارد مرتبط با MySQL در برخی queryهای DELETE با JOIN/ORDER/LIMIT (برای سیستم های قدیمی ممکن است مهم شود)</li>
</ul>
<h2 dir="rtl" lang="fa">ارتقا با AI (رویکرد جدید تیم لاراول)</h2>
<p dir="rtl" lang="fa">Laravel 13 پیشنهاد می دهد از <strong>Laravel Boost</strong> به عنوان MCP server استفاده کنید و با یک slash command فرایند ارتقا را هدایت کنید:</p>
<ul dir="rtl" lang="fa">
<li>دستور <code>/upgrade-laravel-v13</code></li>
<li>نیازمند <code>laravel/boost ^2.0</code></li>
</ul>
<p dir="rtl" lang="fa">این برای تیم هایی عالی است که:</p>
<ul dir="rtl" lang="fa">
<li>کدبیس بزرگ دارند</li>
<li>می خواهند checklist ارتقا را سریع و با کمترین خطا جلو ببرند</li>
<li>اما باز هم باید خروجی را review کنید (AI جای review را نمی گیرد)</li>
</ul>
<h1 dir="rtl" lang="fa">نصب و راه اندازی Laravel 13 (برای پروژه جدید)</h1>
<p dir="rtl" lang="fa">از Installation رسمی:</p>
<ul dir="rtl" lang="fa">
<li>نیاز دارید PHP + Composer + Laravel Installer</li>
<li>و برای assetها: Node/NPM یا Bun</li>
</ul>
<p dir="rtl" lang="fa">در تیم های حرفه ای پیشنهاد می کنم:</p>
<ul dir="rtl" lang="fa">
<li>روی لوکال از ابزارهای رسمی مثل Herd (در صورت امکان) یا Docker استفاده کنید</li>
<li>روی CI یک matrix ساده بسازید (PHP 8.3 + DB)</li>
<li>از همان اول queue و scheduler را جدا طراحی کنید</li>
</ul>
<h1 dir="rtl" lang="fa">نکات معماری و Best Practice برای Laravel 13</h1>
<h2 dir="rtl" lang="fa">1) AI را Feature محور پیاده کنید، نه هیجانی</h2>
<p dir="rtl" lang="fa">به جای اینکه «AI را همه جا بریزید»، use-case تعریف کنید:</p>
<ul dir="rtl" lang="fa">
<li>جستجوی معنایی محصولات</li>
<li>خلاصه سازی تیکت های پشتیبانی</li>
<li>پیشنهاد پاسخ برای اپراتور</li>
<li>دسته بندی خودکار محتوا</li>
</ul>
<p dir="rtl" lang="fa">هر use-case:</p>
<ul dir="rtl" lang="fa">
<li>ورودی مشخص</li>
<li>خروجی مشخص</li>
<li>logging و monitoring</li>
<li>fallback (اگر provider قطع شد)</li>
</ul>
<h2 dir="rtl" lang="fa">2) Queue-first برای کارهای AI و پردازش سنگین</h2>
<p dir="rtl" lang="fa">هر چیزی که:</p>
<ul dir="rtl" lang="fa">
<li>IO زیاد دارد</li>
<li>هزینه دارد</li>
<li>یا latency بالا دارد</li>
</ul>
<p dir="rtl" lang="fa">باید برود صف. بعد route کردن صف ها در Laravel 13 تمیزتر هم شده است.</p>
<h2 dir="rtl" lang="fa">3) امنیت Cache را جدی بگیرید</h2>
<p dir="rtl" lang="fa">اگر قبلا هر چیزی را object می کردید و می گذاشتید cache:</p>
<ul dir="rtl" lang="fa">
<li>الان وقت refactor است</li>
<li>یا allow-list دقیق بنویسید</li>
</ul>
<h2 dir="rtl" lang="fa">4) از استاندارد JSON:API برای تیم های چندکلاینتی استفاده کنید</h2>
<p dir="rtl" lang="fa">اگر شما:</p>
<ul dir="rtl" lang="fa">
<li>وب + اپ موبایل + پنل جدا دارید</li>
</ul>
<p dir="rtl" lang="fa">JSON:API می تواند استاندارد مشترک خروجی باشد.</p>
<h2 dir="rtl" lang="fa">جمع بندی</h2>
<p dir="rtl" lang="fa">Laravel 13 یک ارتقای کم ریسک اما بسیار مهم است: حداقل PHP 8.3، SDK رسمی AI، استانداردسازی بهتر APIها با JSON:API، بهبودهای امنیتی مثل PreventRequestForgery و سخت گیری در unserialize شدن cache، و همچنین کیفیت زندگی بهتر در صف ها با Queue routing و Attributeهای بیشتر.</p>
<p dir="rtl" lang="fa">اگر پروژه شما Laravel 12 است، بهترین مسیر این است:</p>
<ol dir="rtl" lang="fa">
<li>PHP 8.3 را آماده کنید</li>
<li>وابستگی ها را طبق Upgrade Guide بالا ببرید</li>
<li>موارد امنیتی cache و CSRF را در staging تست کنید</li>
<li>سپس release کنید</li>
</ol>
<p dir="rtl" lang="fa">اگر قصد <strong>طراحی سایت یا توسعه وب اپلیکیشن با Laravel 13</strong> را دارید و می خواهید معماری پروژه از ابتدا اصولی، امن و قابل توسعه باشد، از طریق صفحه <a href="https://tarahanenovin.ir/site/contact" target="_blank" rel="nofollow noopener noreferrer">تماس با ما</a> با طراحان نوین در ارتباط باشید تا نیاز پروژه را بررسی و مسیر اجرای درست را پیشنهاد کنیم.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%aa%d9%85%d8%a7%d9%85%db%8c-%da%86%db%8c%d8%b2%d9%87%d8%a7%db%8c%db%8c-%da%a9%d9%87-%d8%a8%d8%a7%db%8c%d8%af-%d8%af%d8%b1%d8%a8%d8%a7%d8%b1%d9%87-laravel-13-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/">تمامی چیزهایی که باید درباره Laravel 13 بدانید</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d8%aa%d9%85%d8%a7%d9%85%db%8c-%da%86%db%8c%d8%b2%d9%87%d8%a7%db%8c%db%8c-%da%a9%d9%87-%d8%a8%d8%a7%db%8c%d8%af-%d8%af%d8%b1%d8%a8%d8%a7%d8%b1%d9%87-laravel-13-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>قبل از ارتقا به Laravel 13 این نکات را بدانید</title>
		<link>https://tarahanenovin.ir/blog/%d9%82%d8%a8%d9%84-%d8%a7%d8%b2-%d8%a7%d8%b1%d8%aa%d9%82%d8%a7-%d8%a8%d9%87-laravel-13-%d8%a7%db%8c%d9%86-%d9%86%da%a9%d8%a7%d8%aa-%d8%b1%d8%a7-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/</link>
					<comments>https://tarahanenovin.ir/blog/%d9%82%d8%a8%d9%84-%d8%a7%d8%b2-%d8%a7%d8%b1%d8%aa%d9%82%d8%a7-%d8%a8%d9%87-laravel-13-%d8%a7%db%8c%d9%86-%d9%86%da%a9%d8%a7%d8%aa-%d8%b1%d8%a7-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[طراحی وب]]></category>
		<category><![CDATA[فرانت‌اند]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[آپدیت لاراول]]></category>
		<category><![CDATA[بروز رسانی لاراول]]></category>
		<category><![CDATA[لاراول]]></category>
		<category><![CDATA[لاراول 13]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=226</guid>

					<description><![CDATA[<p>اگر در حال برنامه ریزی برای ارتقا به Laravel 13 هستید، بهتر است قبل از هر اقدامی فقط به تغییر شماره نسخه نگاه نکنید. ارتقا فریم ورک در پروژه های واقعی، مخصوصا پروژه هایی که در حال سرویس دهی هستند، می تواند روی پکیج ها، ساختار کد، فرایند استقرار، تست ها و حتی عملکرد تیم توسعه اثر مستقیم بگذارد. به همین دلیل، قبل از ارتقا به Laravel 13 باید تصویر روشنی از وضعیت فعلی پروژه، وابستگی ها و ریسک های اجرایی داشته باشید. این مقاله با نگاه کاملا عملی نوشته شده است؛ یعنی اگر یک پروژه واقعی دارید و می خواهید تصمیم بگیرید که آیا الان زمان مناسبی برای ارتقا هست یا نه، این مطلب می تواند به شما کمک کند. چرا ارتقا به Laravel 13 فقط یک به روز رسانی ساده نیست؟ در پروژه های آزمایشی، ارتقا نسخه معمولا با چند تغییر محدود در composer.json و رفع چند خطا تمام می شود. اما در پروژه های واقعی شرایط متفاوت است. در عمل، شما فقط خود Laravel را ارتقا نمی دهید، بلکه زنجیره ای از بخش های زیر هم درگیر می شوند: نسخه PHP سرور پکیج های Composer کدهای سفارشی شده پروژه Middlewareها و Service Providerها تست های خودکار Docker یا تنظیمات محیط استقرار CI/CD صف ها، کرون جاب ها و سرویس های جانبی به همین دلیل، تصمیم برای ارتقا باید فنی، مرحله ای و همراه با ارزیابی ریسک باشد؛ نه صرفا به دلیل جدید بودن نسخه. قبل از هر چیز، مطمئن شوید Laravel 13 واقعا برای پروژه شما لازم است یکی از اشتباه های رایج این است که فقط چون نسخه جدید منتشر شده، تیم توسعه بلافاصله به فکر مهاجرت می افتد. در حالی که در بسیاری از پروژه ها، ارتقا زمانی منطقی است که حداقل یکی از شرایط زیر وجود داشته باشد: پروژه به قابلیت های جدید نسخه جدید نیاز دارد نسخه فعلی شما به پایان پشتیبانی نزدیک شده است بعضی پکیج های مهم فقط با نسخه های جدید سازگارند تیم می خواهد بدهی فنی پروژه را کاهش دهد زیرساخت و استانداردهای توسعه در حال بازبینی هستند اگر هیچ کدام از این موارد وجود ندارد و پروژه پایدار است، شاید بهتر باشد ابتدا روی تست، مستندسازی و بهینه سازی کد تمرکز کنید. در همین زمینه، اگر به موضوع زیرساخت و استقرار استاندارد علاقه دارید، مطالعه مقاله آموزش Docker از صفر تا اجرای پروژه واقعی با داکر هم می تواند برای آماده سازی محیط ارتقا مفید باشد. مهم ترین بررسی ها قبل از ارتقا به Laravel 13 1) وضعیت نسخه فعلی پروژه را دقیق ثبت کنید قبل از هر کاری، باید بدانید الان دقیقا در چه نقطه ای هستید. فقط دانستن اینکه پروژه مثلا Laravel 10 یا 11 است کافی نیست. موارد زیر را مستند کنید: نسخه دقیق Laravel نسخه PHP در لوکال، staging و production لیست تمام پکیج های Composer پکیج های اختصاصی یا fork شده ابزارهای فرانت اند مثل Vite، Node.js و NPM ساختار تست ها تنظیمات queue، cache، session و mail روش deploy فعلی این مرحله به ظاهر ساده است، اما در عمل باعث می شود بعدا با خطاهای غیرمنتظره غافلگیر نشوید. 2) Release Note و Upgrade Guide را خط به خط بخوانید بزرگ ترین اشتباه در ارتقا این است که توسعه دهنده مستقیما سراغ تغییر نسخه برود و بعد شروع به رفع خطا کند. روش حرفه ای این است که ابتدا مستندات رسمی Laravel برای نسخه جدید را کامل بررسی کنید. هنگام مطالعه Upgrade Guide به این موارد توجه ویژه داشته باشید: Breaking Changeها تغییرات مربوط به routing تغییرات Eloquent تغییرات validation تغییرات queue و jobها حذف شدن helperها یا APIهای قدیمی تغییرات مربوط به config و bootstrap این کار زمان می برد، اما هزینه اش بسیار کمتر از رفع خطا در محیط واقعی است. 3) سازگاری پکیج ها را بررسی کنید در بیشتر پروژه های واقعی، چالش اصلی خود Laravel نیست؛ پکیج ها هستند. خیلی از پروژه ها به پکیج هایی وابسته اند که ممکن است: هنوز از Laravel 13 پشتیبانی نکنند نسخه جدید داشته باشند اما نیاز به refactor ایجاد کنند رها شده باشند و نگهداری نشوند با نسخه جدید PHP دچار مشکل شوند برای هر پکیج این سوال ها را بررسی کنید: آخرین commit چه زمانی بوده است؟ آیا در Packagist یا GitHub نسخه سازگار اعلام شده؟ آیا issueهای مرتبط با Laravel 13 گزارش شده؟ آیا جایگزین مطمئن تری برای آن وجود دارد؟ اگر چند پکیج کلیدی ناسازگار باشند، ارتقا ممکن است به تعویق بیفتد یا نیاز به بازنویسی بخشی از پروژه داشته باشید. 4) ابتدا نسخه PHP را تعیین تکلیف کنید اغلب نسخه های جدید Laravel با نسخه های جدیدتر PHP بهتر کار می کنند یا حتی به آنها نیاز دارند. بنابراین قبل از ارتقا باید مشخص کنید: سرور production از چه نسخه ای استفاده می کند؟ آیا extensionهای مورد نیاز نصب هستند؟ آیا کد فعلی پروژه با نسخه جدید PHP سازگار است؟ آیا پکیج های جانبی روی این نسخه بدون مشکل اجرا می شوند؟ گاهی مسئله اصلی Laravel 13 نیست، بلکه مهاجرت واقعی از PHP قدیمی به نسخه جدید است. اگر این بخش را نادیده بگیرید، ممکن است در محیط staging همه چیز خوب باشد اما در production با خطاهای جدی روبرو شوید. قبل از ارتقا، این پیش نیازهای فنی را حتما آماده کنید 5) از پروژه بکاپ کامل بگیرید بکاپ فقط برای دیتابیس نیست. قبل از شروع، این موارد باید قابل بازگشت باشند: سورس کد دیتابیس فایل های آپلودی فایل های env و تنظیمات سرور تنظیمات supervisor، cron و nginx یا apache اگر rollback شفاف نداشته باشید، ارتقا از یک فرایند فنی به یک ریسک تجاری تبدیل می شود. 6) محیط staging واقعی بسازید ارتقا را هرگز مستقیم روی سرور اصلی انجام ندهید. محیط staging باید تا حد ممکن شبیه production باشد: نسخه PHP یکسان همان cache driver همان queue driver تنظیمات مشابه web server داده های نزدیک به واقعیت jobها و eventهای قابل تست اگر محیط staging فقط یک کپی ساده و ناقص باشد، بسیاری از خطاهای واقعی را نشان نخواهد داد. 7) تست خودکار نداشته باشید، ارتقا را شروع نکنید اگر پروژه تست ندارد، ارتقا خطرناک تر از چیزی است که به نظر می رسد. حداقل قبل از مهاجرت، این بخش ها را پوشش دهید: احراز هویت ثبت و ویرایش داده های اصلی پرداخت یا فرایندهای مالی APIهای مهم پنل مدیریت صف ها و jobهای حیاتی حتی چند تست پایه اما درست، از ده ها ساعت دیباگ بعد از deploy باارزش تر است. اشتباه های رایج در ارتقا به Laravel 13 8) ارتقا مستقیم از چند نسخه عقب تر اگر پروژه شما چند نسخه از Laravel عقب است، بهتر است ارتقا را مرحله ای انجام دهید. مثلا مهاجرت از یک نسخه خیلی قدیمی به Laravel 13 در یک مرحله، معمولا باعث انباشت خطا می شود. روش بهتر این است که: ابتدا نسخه فعلی را پایدار کنید warningها و deprecationها را برطرف کنید ارتقا را نسخه به نسخه یا در گام های منطقی جلو ببرید بعد از هر مرحله تست کامل بگیرید 9) نادیده گرفتن کدهای سفارشی و overrideها بسیاری از پروژه ها در طول زمان، کلاس های فریم ورک را extend یا override کرده اند. همین موضوع در زمان ارتقا دردسرساز می شود. بخش های زیر را با دقت بررسی کنید: Service Providerهای سفارشی Macroها Traitهای عمومی Base Controller و Base Model کلاس های helper داخلی Middlewareهای سفارشی Exception Handler ممکن است پروژه بدون خطای syntax بالا بیاید، اما در runtime رفتار نادرستی داشته باشد. 10) اعتماد کامل به composer update بعضی توسعه دهندگان تصور می کنند با اجرای composer update بخش اصلی کار انجام می شود. این فقط شروع کار است. بعد از به روز رسانی وابستگی ها باید این موارد را بررسی کنید: route cache config cache event discovery migrationها queue workerها scheduler mail و notification storage link و file system ارتقا وقتی تمام می شود که رفتار واقعی سیستم تایید شود، نه وقتی composer بدون خطا اجرا شود. چک لیست عملی قبل از ارتقا به Laravel 13 برای اینکه تصمیم گیری ساده تر شود، این چک لیست را قبل از شروع بررسی کنید: چک لیست فنی نسخه فعلی Laravel و PHP مستند شده است تمام پکیج ها و وضعیت سازگاری آنها بررسی شده است Upgrade Guide رسمی مطالعه شده است بکاپ کامل از کد و دیتابیس گرفته شده است محیط staging مشابه production آماده است تست های حیاتی پروژه نوشته یا به روز شده اند فرایند rollback مشخص و تست شده است تغییرات مورد انتظار برای تیم فنی مستند شده است چک لیست اجرایی زمان مناسب برای deploy مشخص شده است ذی نفعان پروژه از زمان ارتقا مطلع هستند plan B در صورت شکست deploy وجود دارد مانیتورینگ و لاگ ها برای بعد از انتشار آماده هستند مسئول بررسی سریع خطاهای production مشخص شده است بهترین روش اجرای ارتقا در پروژه واقعی در پروژه واقعی، این ترتیب معمولا امن تر و منطقی تر است: گام اول: ساخت branch اختصاصی برای ارتقا یک branch جداگانه برای ارتقا ایجاد کنید تا تغییرات از توسعه روزمره پروژه جدا باشد. گام دوم: به روز رسانی وابستگی ها به صورت کنترل شده نسخه Laravel و پکیج ها را مرحله ای به روز کنید و همزمان خطاها را ثبت کنید. گام سوم: رفع breaking changeها هر مورد ناسازگار را بر اساس مستندات رسمی اصلاح کنید. اینجا سرعت مهم نیست؛ دقت مهم تر است. گام چهارم: اجرای تست و تست دستی علاوه بر تست خودکار، سناریوهای واقعی کاربر را هم دستی بررسی کنید. گام پنجم: استقرار آزمایشی در staging رفتار پروژه را در محیط نزدیک به production تحلیل کنید؛ مخصوصا صف ها، فایل ها و APIها. گام ششم: deploy با قابلیت بازگشت ارتقا را در زمانی انجام دهید که اگر مشکل پیش آمد، امکان rollback سریع وجود داشته باشد. آیا الان زمان خوبی برای ارتقا به Laravel 13 است؟ پاسخ این سوال برای همه پروژه ها یکسان نیست. اگر پروژه شما: تست مناسب دارد پکیج های آن فعال و به روز هستند تیم توسعه زمان کافی برای بررسی دارد زیرساخت staging و rollback مشخصی دارد احتمالا ارتقا می تواند یک تصمیم منطقی باشد. اما اگر پروژه: مستندات ضعیف دارد پکیج های قدیمی و رها شده استفاده می کند تست ندارد مستقیم روی production تغییر می دهد بهتر است قبل از ارتقا، ابتدا بلوغ فنی پروژه را بالا ببرید. ارتقا یا بازنگری معماری؟ گاهی سوال اصلی این است در بعضی پروژه ها، مسئله فقط ارتقا نسخه نیست. گاهی ساختار پروژه آن قدر درگیر بدهی فنی شده که ارتقا به تنهایی مشکل را حل نمی کند. اگر در کنار ارتقا به فکر بازنگری معماری، بهبود فرایند توسعه یا استانداردسازی استقرار هستید، مطالعه مطالب فنی و تحلیلی بلاگ طراحان نوین مانند آموزش Vibe Coding در هوش مصنوعی؛ از ایده تا ساخت نرم افزار با زبان طبیعی هم می تواند برای نگاه سیستمی به فرایند توسعه مفید باشد. همچنین اگر پروژه شما بخشی از یک کسب و کار آنلاین بزرگ تر است، پیشنهاد می شود به ارتباط این ارتقا با عملکرد کلی سایت هم توجه کنید. برای مثال، در بسیاری از موارد تغییرات فنی در هسته پروژه باید همزمان با بررسی تجربه کاربری، سرعت و مسیر توسعه وب انجام شود. از این نظر، مقاله چطور بفهمیم کسب و کار ما به سایت جدید نیاز دارد؟ 12 نشانه مهم هم دید بهتری نسبت به تصمیم های فنی در بستر واقعی کسب و کار می دهد. جمع بندی قبل از ارتقا به Laravel 13، مهم ترین کار این نیست که سریع تر به نسخه جدید برسید؛ مهم ترین کار این است که بدون آسیب به پایداری پروژه این مسیر را طی کنید. بررسی سازگاری پکیج ها، نسخه PHP، تست ها، staging، بکاپ و سناریوی بازگشت، همگی از خود فرایند ارتقا مهم تر هستند. اگر این مسیر را مرحله ای، مستند و واقع بینانه پیش ببرید، ارتقا می تواند باعث بهبود نگهداری پروژه، افزایش امنیت و هماهنگی بهتر با ابزارهای جدید توسعه شود. اما اگر بدون آماده سازی سراغ آن بروید، حتی یک پروژه ظاهرا پایدار هم ممکن است درگیر خطاهای زمان بر و پرهزینه شود. برای اطلاعات دقیق و رسمی درباره روند مهاجرت نسخه های لاراول، حتما مستندات رسمی Laravel و بخش release notes فریم ورک Laravel را هم بررسی کنید. اگر برای بررسی فنی، بازبینی ساختار پروژه، بهینه سازی فرایند توسعه یا اجرای ارتقا در یک پروژه واقعی به همراه تیم متخصص نیاز دارید، با طراحان نوین در ارتباط باشید.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d9%82%d8%a8%d9%84-%d8%a7%d8%b2-%d8%a7%d8%b1%d8%aa%d9%82%d8%a7-%d8%a8%d9%87-laravel-13-%d8%a7%db%8c%d9%86-%d9%86%da%a9%d8%a7%d8%aa-%d8%b1%d8%a7-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/">قبل از ارتقا به Laravel 13 این نکات را بدانید</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<p dir="rtl" lang="fa">اگر در حال برنامه ریزی برای ارتقا به Laravel 13 هستید، بهتر است قبل از هر اقدامی فقط به تغییر شماره نسخه نگاه نکنید. ارتقا فریم ورک در پروژه های واقعی، مخصوصا پروژه هایی که در حال سرویس دهی هستند، می تواند روی پکیج ها، ساختار کد، فرایند استقرار، تست ها و حتی عملکرد تیم توسعه اثر مستقیم بگذارد. به همین دلیل، قبل از ارتقا به Laravel 13 باید تصویر روشنی از وضعیت فعلی پروژه، وابستگی ها و ریسک های اجرایی داشته باشید.</p>
<p dir="rtl" lang="fa">این مقاله با نگاه کاملا عملی نوشته شده است؛ یعنی اگر یک پروژه واقعی دارید و می خواهید تصمیم بگیرید که آیا الان زمان مناسبی برای ارتقا هست یا نه، این مطلب می تواند به شما کمک کند.</p>
<h2 dir="rtl" lang="fa">چرا ارتقا به Laravel 13 فقط یک به روز رسانی ساده نیست؟</h2>
<p dir="rtl" lang="fa">در پروژه های آزمایشی، ارتقا نسخه معمولا با چند تغییر محدود در <code>composer.json</code> و رفع چند خطا تمام می شود. اما در پروژه های واقعی شرایط متفاوت است. در عمل، شما فقط خود Laravel را ارتقا نمی دهید، بلکه زنجیره ای از بخش های زیر هم درگیر می شوند:</p>
<ul dir="rtl" lang="fa">
<li>نسخه PHP سرور</li>
<li>پکیج های Composer</li>
<li>کدهای سفارشی شده پروژه</li>
<li>Middlewareها و Service Providerها</li>
<li>تست های خودکار</li>
<li>Docker یا تنظیمات محیط استقرار</li>
<li>CI/CD</li>
<li>صف ها، کرون جاب ها و سرویس های جانبی</li>
</ul>
<p dir="rtl" lang="fa">به همین دلیل، تصمیم برای ارتقا باید فنی، مرحله ای و همراه با ارزیابی ریسک باشد؛ نه صرفا به دلیل جدید بودن نسخه.</p>
<h2 dir="rtl" lang="fa">قبل از هر چیز، مطمئن شوید Laravel 13 واقعا برای پروژه شما لازم است</h2>
<p dir="rtl" lang="fa">یکی از اشتباه های رایج این است که فقط چون نسخه جدید منتشر شده، تیم توسعه بلافاصله به فکر مهاجرت می افتد. در حالی که در بسیاری از پروژه ها، ارتقا زمانی منطقی است که حداقل یکی از شرایط زیر وجود داشته باشد:</p>
<ul dir="rtl" lang="fa">
<li>پروژه به قابلیت های جدید نسخه جدید نیاز دارد</li>
<li>نسخه فعلی شما به پایان پشتیبانی نزدیک شده است</li>
<li>بعضی پکیج های مهم فقط با نسخه های جدید سازگارند</li>
<li>تیم می خواهد بدهی فنی پروژه را کاهش دهد</li>
<li>زیرساخت و استانداردهای توسعه در حال بازبینی هستند</li>
</ul>
<p dir="rtl" lang="fa">اگر هیچ کدام از این موارد وجود ندارد و پروژه پایدار است، شاید بهتر باشد ابتدا روی تست، مستندسازی و بهینه سازی کد تمرکز کنید. در همین زمینه، اگر به موضوع زیرساخت و استقرار استاندارد علاقه دارید، مطالعه مقاله <a href="https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-docker-%d8%a7%d8%b2-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%a7%d8%ac%d8%b1%d8%a7%db%8c-%d9%be%d8%b1%d9%88%da%98%d9%87-%d9%88%d8%a7%d9%82%d8%b9%db%8c-%d8%a8/" target="_blank" rel="nofollow noopener noreferrer">آموزش Docker از صفر تا اجرای پروژه واقعی با داکر</a> هم می تواند برای آماده سازی محیط ارتقا مفید باشد.</p>
<h2 dir="rtl" lang="fa">مهم ترین بررسی ها قبل از ارتقا به Laravel 13</h2>
<h3 dir="rtl" lang="fa">1) وضعیت نسخه فعلی پروژه را دقیق ثبت کنید</h3>
<p dir="rtl" lang="fa">قبل از هر کاری، باید بدانید الان دقیقا در چه نقطه ای هستید. فقط دانستن اینکه پروژه مثلا Laravel 10 یا 11 است کافی نیست. موارد زیر را مستند کنید:</p>
<ul dir="rtl" lang="fa">
<li>نسخه دقیق Laravel</li>
<li>نسخه PHP در لوکال، staging و production</li>
<li>لیست تمام پکیج های Composer</li>
<li>پکیج های اختصاصی یا fork شده</li>
<li>ابزارهای فرانت اند مثل Vite، Node.js و NPM</li>
<li>ساختار تست ها</li>
<li>تنظیمات queue، cache، session و mail</li>
<li>روش deploy فعلی</li>
</ul>
<p dir="rtl" lang="fa">این مرحله به ظاهر ساده است، اما در عمل باعث می شود بعدا با خطاهای غیرمنتظره غافلگیر نشوید.</p>
<h3 dir="rtl" lang="fa">2) Release Note و Upgrade Guide را خط به خط بخوانید</h3>
<p dir="rtl" lang="fa">بزرگ ترین اشتباه در ارتقا این است که توسعه دهنده مستقیما سراغ تغییر نسخه برود و بعد شروع به رفع خطا کند. روش حرفه ای این است که ابتدا مستندات رسمی Laravel برای نسخه جدید را کامل بررسی کنید.</p>
<p dir="rtl" lang="fa">هنگام مطالعه Upgrade Guide به این موارد توجه ویژه داشته باشید:</p>
<ul dir="rtl" lang="fa">
<li>Breaking Changeها</li>
<li>تغییرات مربوط به routing</li>
<li>تغییرات Eloquent</li>
<li>تغییرات validation</li>
<li>تغییرات queue و jobها</li>
<li>حذف شدن helperها یا APIهای قدیمی</li>
<li>تغییرات مربوط به config و bootstrap</li>
</ul>
<p dir="rtl" lang="fa">این کار زمان می برد، اما هزینه اش بسیار کمتر از رفع خطا در محیط واقعی است.</p>
<h3 dir="rtl" lang="fa">3) سازگاری پکیج ها را بررسی کنید</h3>
<p dir="rtl" lang="fa">در بیشتر پروژه های واقعی، چالش اصلی خود Laravel نیست؛ پکیج ها هستند. خیلی از پروژه ها به پکیج هایی وابسته اند که ممکن است:</p>
<ul dir="rtl" lang="fa">
<li>هنوز از Laravel 13 پشتیبانی نکنند</li>
<li>نسخه جدید داشته باشند اما نیاز به refactor ایجاد کنند</li>
<li>رها شده باشند و نگهداری نشوند</li>
<li>با نسخه جدید PHP دچار مشکل شوند</li>
</ul>
<p dir="rtl" lang="fa">برای هر پکیج این سوال ها را بررسی کنید:</p>
<ul dir="rtl" lang="fa">
<li>آخرین commit چه زمانی بوده است؟</li>
<li>آیا در Packagist یا GitHub نسخه سازگار اعلام شده؟</li>
<li>آیا issueهای مرتبط با Laravel 13 گزارش شده؟</li>
<li>آیا جایگزین مطمئن تری برای آن وجود دارد؟</li>
</ul>
<p dir="rtl" lang="fa">اگر چند پکیج کلیدی ناسازگار باشند، ارتقا ممکن است به تعویق بیفتد یا نیاز به بازنویسی بخشی از پروژه داشته باشید.</p>
<h3 dir="rtl" lang="fa">4) ابتدا نسخه PHP را تعیین تکلیف کنید</h3>
<p dir="rtl" lang="fa">اغلب نسخه های جدید Laravel با نسخه های جدیدتر PHP بهتر کار می کنند یا حتی به آنها نیاز دارند. بنابراین قبل از ارتقا باید مشخص کنید:</p>
<ul dir="rtl" lang="fa">
<li>سرور production از چه نسخه ای استفاده می کند؟</li>
<li>آیا extensionهای مورد نیاز نصب هستند؟</li>
<li>آیا کد فعلی پروژه با نسخه جدید PHP سازگار است؟</li>
<li>آیا پکیج های جانبی روی این نسخه بدون مشکل اجرا می شوند؟</li>
</ul>
<p dir="rtl" lang="fa">گاهی مسئله اصلی Laravel 13 نیست، بلکه مهاجرت واقعی از PHP قدیمی به نسخه جدید است. اگر این بخش را نادیده بگیرید، ممکن است در محیط staging همه چیز خوب باشد اما در production با خطاهای جدی روبرو شوید.</p>
<h2 dir="rtl" lang="fa">قبل از ارتقا، این پیش نیازهای فنی را حتما آماده کنید</h2>
<h3 dir="rtl" lang="fa">5) از پروژه بکاپ کامل بگیرید</h3>
<p dir="rtl" lang="fa">بکاپ فقط برای دیتابیس نیست. قبل از شروع، این موارد باید قابل بازگشت باشند:</p>
<ul dir="rtl" lang="fa">
<li>سورس کد</li>
<li>دیتابیس</li>
<li>فایل های آپلودی</li>
<li>فایل های env و تنظیمات سرور</li>
<li>تنظیمات supervisor، cron و nginx یا apache</li>
</ul>
<p dir="rtl" lang="fa">اگر rollback شفاف نداشته باشید، ارتقا از یک فرایند فنی به یک ریسک تجاری تبدیل می شود.</p>
<h3 dir="rtl" lang="fa">6) محیط staging واقعی بسازید</h3>
<p dir="rtl" lang="fa">ارتقا را هرگز مستقیم روی سرور اصلی انجام ندهید. محیط staging باید تا حد ممکن شبیه production باشد:</p>
<ul dir="rtl" lang="fa">
<li>نسخه PHP یکسان</li>
<li>همان cache driver</li>
<li>همان queue driver</li>
<li>تنظیمات مشابه web server</li>
<li>داده های نزدیک به واقعیت</li>
<li>jobها و eventهای قابل تست</li>
</ul>
<p dir="rtl" lang="fa">اگر محیط staging فقط یک کپی ساده و ناقص باشد، بسیاری از خطاهای واقعی را نشان نخواهد داد.</p>
<h3 dir="rtl" lang="fa">7) تست خودکار نداشته باشید، ارتقا را شروع نکنید</h3>
<p dir="rtl" lang="fa">اگر پروژه تست ندارد، ارتقا خطرناک تر از چیزی است که به نظر می رسد. حداقل قبل از مهاجرت، این بخش ها را پوشش دهید:</p>
<ul dir="rtl" lang="fa">
<li>احراز هویت</li>
<li>ثبت و ویرایش داده های اصلی</li>
<li>پرداخت یا فرایندهای مالی</li>
<li>APIهای مهم</li>
<li>پنل مدیریت</li>
<li>صف ها و jobهای حیاتی</li>
</ul>
<p dir="rtl" lang="fa">حتی چند تست پایه اما درست، از ده ها ساعت دیباگ بعد از deploy باارزش تر است.</p>
<h2 dir="rtl" lang="fa">اشتباه های رایج در ارتقا به Laravel 13</h2>
<h3 dir="rtl" lang="fa">8) ارتقا مستقیم از چند نسخه عقب تر</h3>
<p dir="rtl" lang="fa">اگر پروژه شما چند نسخه از Laravel عقب است، بهتر است ارتقا را مرحله ای انجام دهید. مثلا مهاجرت از یک نسخه خیلی قدیمی به Laravel 13 در یک مرحله، معمولا باعث انباشت خطا می شود.</p>
<p dir="rtl" lang="fa">روش بهتر این است که:</p>
<ul dir="rtl" lang="fa">
<li>ابتدا نسخه فعلی را پایدار کنید</li>
<li>warningها و deprecationها را برطرف کنید</li>
<li>ارتقا را نسخه به نسخه یا در گام های منطقی جلو ببرید</li>
<li>بعد از هر مرحله تست کامل بگیرید</li>
</ul>
<h3 dir="rtl" lang="fa">9) نادیده گرفتن کدهای سفارشی و overrideها</h3>
<p dir="rtl" lang="fa">بسیاری از پروژه ها در طول زمان، کلاس های فریم ورک را extend یا override کرده اند. همین موضوع در زمان ارتقا دردسرساز می شود. بخش های زیر را با دقت بررسی کنید:</p>
<ul dir="rtl" lang="fa">
<li>Service Providerهای سفارشی</li>
<li>Macroها</li>
<li>Traitهای عمومی</li>
<li>Base Controller و Base Model</li>
<li>کلاس های helper داخلی</li>
<li>Middlewareهای سفارشی</li>
<li>Exception Handler</li>
</ul>
<p dir="rtl" lang="fa">ممکن است پروژه بدون خطای syntax بالا بیاید، اما در runtime رفتار نادرستی داشته باشد.</p>
<h3 dir="rtl" lang="fa">10) اعتماد کامل به composer update</h3>
<p dir="rtl" lang="fa">بعضی توسعه دهندگان تصور می کنند با اجرای <code>composer update</code> بخش اصلی کار انجام می شود. این فقط شروع کار است. بعد از به روز رسانی وابستگی ها باید این موارد را بررسی کنید:</p>
<ul dir="ltr" lang="en">
<li>route cache</li>
<li>config cache</li>
<li>event discovery</li>
<li>migrationها</li>
<li>queue workerها</li>
<li>scheduler</li>
<li>mail و notification</li>
<li>storage link و file system</li>
</ul>
<p dir="rtl" lang="fa">ارتقا وقتی تمام می شود که رفتار واقعی سیستم تایید شود، نه وقتی composer بدون خطا اجرا شود.</p>
<h2 dir="rtl" lang="fa">چک لیست عملی قبل از ارتقا به Laravel 13</h2>
<p dir="rtl" lang="fa">برای اینکه تصمیم گیری ساده تر شود، این چک لیست را قبل از شروع بررسی کنید:</p>
<h3 dir="rtl" lang="fa">چک لیست فنی</h3>
<ul dir="rtl" lang="fa">
<li>نسخه فعلی Laravel و PHP مستند شده است</li>
<li>تمام پکیج ها و وضعیت سازگاری آنها بررسی شده است</li>
<li>Upgrade Guide رسمی مطالعه شده است</li>
<li>بکاپ کامل از کد و دیتابیس گرفته شده است</li>
<li>محیط staging مشابه production آماده است</li>
<li>تست های حیاتی پروژه نوشته یا به روز شده اند</li>
<li>فرایند rollback مشخص و تست شده است</li>
<li>تغییرات مورد انتظار برای تیم فنی مستند شده است</li>
</ul>
<h3 dir="rtl" lang="fa">چک لیست اجرایی</h3>
<ul dir="rtl" lang="fa">
<li>زمان مناسب برای deploy مشخص شده است</li>
<li>ذی نفعان پروژه از زمان ارتقا مطلع هستند</li>
<li>plan B در صورت شکست deploy وجود دارد</li>
<li>مانیتورینگ و لاگ ها برای بعد از انتشار آماده هستند</li>
<li>مسئول بررسی سریع خطاهای production مشخص شده است</li>
</ul>
<h2 dir="rtl" lang="fa">بهترین روش اجرای ارتقا در پروژه واقعی</h2>
<p dir="rtl" lang="fa">در پروژه واقعی، این ترتیب معمولا امن تر و منطقی تر است:</p>
<h3 dir="rtl" lang="fa">گام اول: ساخت branch اختصاصی برای ارتقا</h3>
<p dir="rtl" lang="fa">یک branch جداگانه برای ارتقا ایجاد کنید تا تغییرات از توسعه روزمره پروژه جدا باشد.</p>
<h3 dir="rtl" lang="fa">گام دوم: به روز رسانی وابستگی ها به صورت کنترل شده</h3>
<p dir="rtl" lang="fa">نسخه Laravel و پکیج ها را مرحله ای به روز کنید و همزمان خطاها را ثبت کنید.</p>
<h3 dir="rtl" lang="fa">گام سوم: رفع breaking changeها</h3>
<p dir="rtl" lang="fa">هر مورد ناسازگار را بر اساس مستندات رسمی اصلاح کنید. اینجا سرعت مهم نیست؛ دقت مهم تر است.</p>
<h3 dir="rtl" lang="fa">گام چهارم: اجرای تست و تست دستی</h3>
<p dir="rtl" lang="fa">علاوه بر تست خودکار، سناریوهای واقعی کاربر را هم دستی بررسی کنید.</p>
<h3 dir="rtl" lang="fa">گام پنجم: استقرار آزمایشی در staging</h3>
<p dir="rtl" lang="fa">رفتار پروژه را در محیط نزدیک به production تحلیل کنید؛ مخصوصا صف ها، فایل ها و APIها.</p>
<h3 dir="rtl" lang="fa">گام ششم: deploy با قابلیت بازگشت</h3>
<p dir="rtl" lang="fa">ارتقا را در زمانی انجام دهید که اگر مشکل پیش آمد، امکان rollback سریع وجود داشته باشد.</p>
<h2 dir="rtl" lang="fa">آیا الان زمان خوبی برای ارتقا به Laravel 13 است؟</h2>
<p dir="rtl" lang="fa">پاسخ این سوال برای همه پروژه ها یکسان نیست. اگر پروژه شما:</p>
<ul dir="rtl" lang="fa">
<li>تست مناسب دارد</li>
<li>پکیج های آن فعال و به روز هستند</li>
<li>تیم توسعه زمان کافی برای بررسی دارد</li>
<li>زیرساخت staging و rollback مشخصی دارد</li>
</ul>
<p dir="rtl" lang="fa">احتمالا ارتقا می تواند یک تصمیم منطقی باشد.</p>
<p dir="rtl" lang="fa">اما اگر پروژه:</p>
<ul dir="rtl" lang="fa">
<li>مستندات ضعیف دارد</li>
<li>پکیج های قدیمی و رها شده استفاده می کند</li>
<li>تست ندارد</li>
<li>مستقیم روی production تغییر می دهد</li>
</ul>
<p dir="rtl" lang="fa">بهتر است قبل از ارتقا، ابتدا بلوغ فنی پروژه را بالا ببرید.</p>
<h2 dir="rtl" lang="fa">ارتقا یا بازنگری معماری؟ گاهی سوال اصلی این است</h2>
<p dir="rtl" lang="fa">در بعضی پروژه ها، مسئله فقط ارتقا نسخه نیست. گاهی ساختار پروژه آن قدر درگیر بدهی فنی شده که ارتقا به تنهایی مشکل را حل نمی کند. اگر در کنار ارتقا به فکر بازنگری معماری، بهبود فرایند توسعه یا استانداردسازی استقرار هستید، مطالعه مطالب فنی و تحلیلی بلاگ طراحان نوین مانند <a href="https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-vibe-coding-%d8%af%d8%b1-%d9%87%d9%88%d8%b4-%d9%85%d8%b5%d9%86%d9%88%d8%b9%db%8c%d8%9b-%d8%a7%d8%b2-%d8%a7%db%8c%d8%af%d9%87-%d8%aa%d8%a7-%d8%b3/" target="_blank" rel="nofollow noopener noreferrer">آموزش Vibe Coding در هوش مصنوعی؛ از ایده تا ساخت نرم افزار با زبان طبیعی</a> هم می تواند برای نگاه سیستمی به فرایند توسعه مفید باشد.</p>
<p dir="rtl" lang="fa">همچنین اگر پروژه شما بخشی از یک کسب و کار آنلاین بزرگ تر است، پیشنهاد می شود به ارتباط این ارتقا با عملکرد کلی سایت هم توجه کنید. برای مثال، در بسیاری از موارد تغییرات فنی در هسته پروژه باید همزمان با بررسی تجربه کاربری، سرعت و مسیر توسعه وب انجام شود. از این نظر، مقاله <a href="https://tarahanenovin.ir/blog/%da%86%d8%b7%d9%88%d8%b1-%d8%a8%d9%81%d9%87%d9%85%db%8c%d9%85-%da%a9%d8%b3%d8%a8-%d9%88-%da%a9%d8%a7%d8%b1-%d9%85%d8%a7-%d8%a8%d9%87-%d8%b3%d8%a7%db%8c%d8%aa-%d8%ac%d8%af%db%8c%d8%af-%d9%86%db%8c/" target="_blank" rel="nofollow noopener noreferrer">چطور بفهمیم کسب و کار ما به سایت جدید نیاز دارد؟ 12 نشانه مهم</a> هم دید بهتری نسبت به تصمیم های فنی در بستر واقعی کسب و کار می دهد.</p>
<h2 dir="rtl" lang="fa">جمع بندی</h2>
<p dir="rtl" lang="fa">قبل از ارتقا به Laravel 13، مهم ترین کار این نیست که سریع تر به نسخه جدید برسید؛ مهم ترین کار این است که بدون آسیب به پایداری پروژه این مسیر را طی کنید. بررسی سازگاری پکیج ها، نسخه PHP، تست ها، staging، بکاپ و سناریوی بازگشت، همگی از خود فرایند ارتقا مهم تر هستند.</p>
<p dir="rtl" lang="fa">اگر این مسیر را مرحله ای، مستند و واقع بینانه پیش ببرید، ارتقا می تواند باعث بهبود نگهداری پروژه، افزایش امنیت و هماهنگی بهتر با ابزارهای جدید توسعه شود. اما اگر بدون آماده سازی سراغ آن بروید، حتی یک پروژه ظاهرا پایدار هم ممکن است درگیر خطاهای زمان بر و پرهزینه شود.</p>
<p dir="rtl" lang="fa">برای اطلاعات دقیق و رسمی درباره روند مهاجرت نسخه های لاراول، حتما <a href="https://laravel.com/docs" target="_blank" rel="nofollow noopener noreferrer">مستندات رسمی Laravel</a> و <a href="https://laravel.com/docs/releases" target="_blank" rel="nofollow noopener noreferrer">بخش release notes فریم ورک Laravel</a> را هم بررسی کنید.</p>
<p dir="rtl" lang="fa">اگر برای بررسی فنی، بازبینی ساختار پروژه، بهینه سازی فرایند توسعه یا اجرای ارتقا در یک پروژه واقعی به همراه تیم متخصص نیاز دارید، <a href="https://tarahanenovin.ir/site/contact" target="_blank" rel="nofollow noopener noreferrer">با طراحان نوین در ارتباط باشید</a>.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d9%82%d8%a8%d9%84-%d8%a7%d8%b2-%d8%a7%d8%b1%d8%aa%d9%82%d8%a7-%d8%a8%d9%87-laravel-13-%d8%a7%db%8c%d9%86-%d9%86%da%a9%d8%a7%d8%aa-%d8%b1%d8%a7-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/">قبل از ارتقا به Laravel 13 این نکات را بدانید</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d9%82%d8%a8%d9%84-%d8%a7%d8%b2-%d8%a7%d8%b1%d8%aa%d9%82%d8%a7-%d8%a8%d9%87-laravel-13-%d8%a7%db%8c%d9%86-%d9%86%da%a9%d8%a7%d8%aa-%d8%b1%d8%a7-%d8%a8%d8%af%d8%a7%d9%86%db%8c%d8%af/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>تغییرات نسخه Yii3؛ بررسی کامل معماری، قابلیت ها و تفاوت با Yii2</title>
		<link>https://tarahanenovin.ir/blog/%d8%aa%d8%ba%db%8c%db%8c%d8%b1%d8%a7%d8%aa-%d9%86%d8%b3%d8%ae%d9%87-yii3%d8%9b-%d8%a8%d8%b1%d8%b1%d8%b3%db%8c-%da%a9%d8%a7%d9%85%d9%84-%d9%85%d8%b9%d9%85%d8%a7%d8%b1%db%8c%d8%8c-%d9%82%d8%a7%d8%a8/</link>
					<comments>https://tarahanenovin.ir/blog/%d8%aa%d8%ba%db%8c%db%8c%d8%b1%d8%a7%d8%aa-%d9%86%d8%b3%d8%ae%d9%87-yii3%d8%9b-%d8%a8%d8%b1%d8%b1%d8%b3%db%8c-%da%a9%d8%a7%d9%85%d9%84-%d9%85%d8%b9%d9%85%d8%a7%d8%b1%db%8c%d8%8c-%d9%82%d8%a7%d8%a8/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[اخبار و ترندها]]></category>
		<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[طراحی وب]]></category>
		<category><![CDATA[فرانت‌اند]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[Yii2]]></category>
		<category><![CDATA[yii3]]></category>
		<category><![CDATA[فریم ورک Yii]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=165</guid>

					<description><![CDATA[<p>تغییرات نسخه Yii3 تنها به اضافه شدن چند قابلیت جدید محدود نمی شود. این نسخه بازطراحی گسترده ای را در معماری، مدیریت وابستگی ها، ساختار بسته ها و شیوه توسعه برنامه های تحت وب ایجاد کرده است. Yii3 در ۳۱ دسامبر ۲۰۲۵ به صورت رسمی منتشر شد و اکنون نسل جدید فریم ورک Yii برای توسعه پروژه های مدرن PHP به شمار می رود. در Yii3 وابستگی شدید اجزای مختلف فریم ورک به یکدیگر کاهش یافته و توسعه دهنده می تواند متناسب با نیاز پروژه، بسته های مورد نظر خود را انتخاب کند. پشتیبانی از استانداردهای PSR، استفاده گسترده از Dependency Injection و ارائه اجزای مستقل، Yii3 را به گزینه ای انعطاف پذیر برای طراحی سایت، توسعه API و ساخت نرم افزارهای تحت وب تبدیل کرده است. Yii3 چیست؟ Yii3 نسل سوم فریم ورک متن باز Yii است که برای توسعه برنامه های تحت وب با زبان PHP طراحی شده است. تمرکز اصلی این نسخه بر معماری ماژولار، رعایت استانداردهای رایج PHP، قابلیت تست بهتر و کاهش وابستگی میان اجزای فریم ورک قرار دارد. برخلاف Yii2 که بسیاری از امکانات آن در یک هسته نسبتا یکپارچه قرار گرفته بودند، Yii3 از مجموعه ای از بسته های مستقل تشکیل شده است. هر بسته مسئولیت مشخصی دارد و می تواند در کنار سایر بسته های Yii یا حتی در پروژه های دیگر مورد استفاده قرار گیرد. توسعه Yii3 چندین سال طول کشید و اجزای مختلف آن به تدریج پایدار شدند. بر اساس اخبار رسمی فریم ورک Yii، نسخه رسمی Yii3 در پایان سال ۲۰۲۵ منتشر شد و توسعه بسته های آن در سال ۲۰۲۶ نیز ادامه پیدا کرد. مهم ترین تغییرات نسخه Yii3 تفاوت Yii3 با نسخه قبلی، بیشتر از آنکه ظاهری باشد، به ساختار داخلی و روش توسعه پروژه مربوط است. برنامه نویسانی که با Yii2 کار کرده اند، برای استفاده حرفه ای از نسل جدید باید با مفاهیمی مانند Container، استانداردهای PSR و معماری مبتنی بر بسته آشنا باشند. ۱. معماری ماژولار و مبتنی بر بسته یکی از مهم ترین تغییرات نسخه Yii3، تقسیم فریم ورک به بسته های مستقل است. در این معماری، اجزایی مانند پایگاه داده، کش، اعتبارسنجی، ثبت رویدادها، مدیریت درخواست و پاسخ و Active Record به صورت بسته های مجزا توسعه پیدا می کنند. این ساختار چند مزیت مهم دارد: فقط بسته های مورد نیاز پروژه نصب می شوند. حجم وابستگی های غیرضروری کاهش پیدا می کند. آزمایش و نگهداری هر بخش ساده تر می شود. به روز رسانی اجزا با انعطاف بیشتری انجام می گیرد. امکان استفاده از بسته های Yii در پروژه های دیگر فراهم می شود. در نتیجه، توسعه دهنده کنترل بیشتری بر ساختار برنامه دارد؛ هرچند این آزادی عمل می تواند پیکربندی اولیه پروژه را نسبت به Yii2 کمی پیچیده تر کند. ۲. استفاده گسترده از Dependency Injection Dependency Injection یا تزریق وابستگی یکی از پایه های معماری Yii3 است. در این روش، کلاس ها وابستگی های مورد نیاز خود را مستقیما ایجاد نمی کنند و این وابستگی ها از طریق یک Container در اختیار آن ها قرار می گیرد. استفاده از Dependency Injection باعث می شود: وابستگی کلاس ها شفاف تر باشد. تست واحد ساده تر انجام شود. امکان جایگزینی سرویس ها وجود داشته باشد. کدها انعطاف پذیرتر و قابل نگهداری تر شوند. ارتباط مستقیم میان بخش های برنامه کاهش پیدا کند. Yii2 نیز دارای DI Container بود، اما نقش آن در Yii3 بسیار پررنگ تر شده است. به همین دلیل، درک صحیح تزریق وابستگی برای کار با Yii3 اهمیت زیادی دارد. ۳. سازگاری بهتر با استانداردهای PSR اکوسیستم مدرن PHP بر پایه مجموعه ای از استانداردهای مشترک با نام PSR شکل گرفته است. Yii3 نسبت به Yii2 سازگاری بیشتری با این استانداردها دارد و تلاش می کند با کتابخانه ها و ابزارهای مختلف PHP ارتباط ساده تری برقرار کند. از جمله استانداردهای مهم در این زمینه می توان به رابط های استاندارد درخواست و پاسخ HTTP، Container، ثبت گزارش و Middleware اشاره کرد. رعایت استانداردهای PSR به این معنا است که توسعه دهنده کمتر به پیاده سازی اختصاصی فریم ورک وابسته می شود. همچنین استفاده از کتابخانه های خارج از اکوسیستم Yii و جایگزینی اجزای مختلف برنامه آسان تر خواهد بود. برای بررسی دقیق استانداردهای PHP می توانید به وب سایت رسمی PHP-FIG مراجعه کنید. ۴. تغییر ساختار برنامه و قالب های پروژه در Yii2 معمولا توسعه پروژه با قالب Basic یا Advanced آغاز می شد. این قالب ها ساختاری آشنا و تعداد زیادی تنظیمات از پیش آماده داشتند. در Yii3 نیز قالب های رسمی برای برنامه های وب و API ارائه شده اند، اما ساختار آن ها با معماری جدید فریم ورک هماهنگ است. در قالب های Yii3 مواردی مانند پیکربندی Container، مسیر پردازش درخواست، Middlewareها و بسته های مستقل نقش مهم تری دارند. توسعه دهنده باید شناخت روشن تری از اجزای نصب شده و ارتباط میان آن ها داشته باشد. این رویکرد ممکن است در شروع به زمان بیشتری نیاز داشته باشد، اما در پروژه های بزرگ، کنترل بهتر و ساختار منظم تری در اختیار تیم توسعه قرار می دهد. ۵. استفاده از Middleware Middleware یک لایه پردازشی است که درخواست HTTP پیش از رسیدن به منطق اصلی برنامه از آن عبور می کند. پاسخ برنامه نیز می تواند در مسیر بازگشت توسط Middleware پردازش شود. از Middleware می توان برای وظایف زیر استفاده کرد: احراز هویت و کنترل دسترسی مدیریت نشست کاربران بررسی توکن های امنیتی ثبت اطلاعات درخواست ها مدیریت خطاها فشرده سازی پاسخ اعمال محدودیت روی درخواست ها تنظیم هدرهای امنیتی ساختار Middleware محور باعث می شود هر وظیفه در یک لایه مستقل قرار گیرد و منطق اصلی برنامه با کدهای جانبی ترکیب نشود. ۶. بازطراحی مدیریت رویدادها سیستم Event در Yii3 به صورت مستقل و هماهنگ با معماری جدید ارائه شده است. رویدادها به بخش های مختلف برنامه اجازه می دهند بدون ایجاد وابستگی مستقیم با یکدیگر ارتباط برقرار کنند. برای مثال، پس از ثبت سفارش می توان یک رویداد ایجاد کرد تا سرویس ارسال ایمیل، سیستم پیامک یا بخش گزارش گیری به آن واکنش نشان دهد. در این حالت، منطق سفارش به صورت مستقیم به سرویس های دیگر وابسته نخواهد بود. این ساختار برای پروژه های سازمانی، فروشگاه های اینترنتی، سامانه های مدیریت محتوا و برنامه هایی که چندین فرآیند مرتبط دارند، کاربرد زیادی دارد. ۷. تغییر در لایه پایگاه داده بسته Yii Database در نسخه سوم بازطراحی شده و درایورهای مختلف پایگاه داده به شکل مستقل ارائه می شوند. این اکوسیستم از پایگاه های داده پرکاربردی مانند موارد زیر پشتیبانی می کند: MySQL و MariaDB PostgreSQL Microsoft SQL Server Oracle SQLite مستقل بودن درایورها کمک می کند هر پروژه فقط وابستگی مربوط به پایگاه داده خود را نصب کند. همچنین اصلاح و توسعه یک درایور، تاثیر کمتری بر سایر بخش های فریم ورک خواهد داشت. ۸. نسخه جدید Active Record Active Record یکی از محبوب ترین قابلیت های Yii2 بود و بسیاری از توسعه دهندگان برای مدیریت داده ها از آن استفاده می کردند. این قابلیت در Yii3 نیز وجود دارد، اما به صورت یک بسته مستقل و سازگار با لایه جدید پایگاه داده ارائه شده است. Yii Active Record همچنان امکان تعریف مدل ها، ارتباط میان جداول و انجام عملیات متداول پایگاه داده را فراهم می کند. با این حال، نباید انتظار داشت تمام کدهای Active Record نوشته شده برای Yii2 بدون تغییر در Yii3 اجرا شوند. نسخه پایدار Yii Active Record در دسامبر ۲۰۲۵ منتشر شد و نسخه های جدیدتر آن نیز در سال ۲۰۲۶ در دسترس قرار گرفتند. آخرین وضعیت هر بسته را می توان در صفحه رسمی بسته های YiiSoft در Packagist بررسی کرد. ۹. بهبود قابلیت تست کاهش وابستگی مستقیم کلاس ها، استفاده از Interfaceها و تزریق وابستگی باعث شده است اجزای Yii3 راحت تر آزمایش شوند. توسعه دهنده می تواند سرویس های واقعی را با نمونه های آزمایشی جایگزین کند و هر بخش را به صورت مستقل مورد بررسی قرار دهد. این موضوع برای پروژه هایی که به پایداری طولانی مدت نیاز دارند اهمیت زیادی دارد. تست خودکار می تواند احتمال بروز خطا بعد از توسعه قابلیت های جدید یا به روز رسانی بسته ها را کاهش دهد. ۱۰. مدیریت بهتر تنظیمات پیکربندی در Yii3 بر پایه ترکیب فایل های تنظیمات و تعریف دقیق وابستگی ها انجام می شود. این ساختار امکان تفکیک تنظیمات محیط توسعه، آزمایش و تولید را فراهم می کند. مدیریت تنظیمات در نسل جدید، انعطاف پذیرتر است؛ اما توسعه دهنده باید نحوه ترکیب فایل ها و اولویت هر تنظیم را به خوبی بشناسد. پیکربندی اشتباه Container یا تعریف چندباره یک سرویس می تواند رفتار برنامه را تغییر دهد. جدول مقایسه Yii3 و Yii2 ویژگی Yii2 Yii3 معماری نسبتا یکپارچه ماژولار و مبتنی بر بسته Dependency Injection پشتیبانی داخلی بخش اساسی معماری استانداردهای PSR پشتیبانی محدودتر سازگاری گسترده تر پردازش درخواست مبتنی بر ساختار داخلی فریم ورک مبتنی بر Middleware و استانداردهای HTTP نصب اجزا بسیاری از امکانات همراه هسته نصب بسته های مورد نیاز Active Record بخشی از فریم ورک بسته مستقل قابلیت تست مناسب انعطاف پذیرتر به دلیل کاهش وابستگی منحنی یادگیری ساده تر برای کاربران Yii نیازمند شناخت DI، PSR و Middleware مهاجرت از نسخه قبل قابل انجام با تغییرات محدودتر نیازمند بازنگری جدی در معماری کاربرد پیشنهادی نگهداری پروژه های موجود پروژه های جدید و آینده محور آیا Yii3 نسخه ارتقا یافته مستقیم Yii2 است؟ Yii3 را نباید فقط یک ارتقای معمولی برای Yii2 در نظر گرفت. تغییر معماری در این نسخه به اندازه ای گسترده است که مهاجرت پروژه های موجود معمولا با اجرای یک دستور Composer یا تغییر شماره نسخه امکان پذیر نیست. بخش هایی مانند مدل های دامنه، منطق تجاری و بعضی سرویس های مستقل ممکن است با تغییرات محدود قابل استفاده باشند. با این حال، قسمت هایی که مستقیما به ساختار Yii2 وابسته هستند احتمالا باید بازنویسی یا اصلاح شوند. موارد زیر معمولا در فرآیند مهاجرت به بررسی دقیق نیاز دارند: فایل های تنظیمات کنترلرها و مسیرها فیلترها و رفتارها مدل های Active Record افزونه های اختصاصی Yii2 مدیریت درخواست و پاسخ احراز هویت و سطح دسترسی قالب ها و Widgetها دستورات کنسول کش و مدیریت Session بنابراین، تصمیم برای مهاجرت باید بر اساس ارزش تجاری، هزینه فنی و طول عمر مورد انتظار پروژه گرفته شود. آیا پشتیبانی از Yii2 متوقف شده است؟ انتشار Yii3 به معنای توقف فوری Yii2 نیست. Yii2 همچنان در وضعیت نگهداری فعال قرار دارد و نسخه های اصلاحی هسته و برخی افزونه های رسمی آن منتشر می شوند. برای نمونه، نسخه 2.0.55 این فریم ورک در ماه مه ۲۰۲۶ انتشار یافت. صفحه Yii2 در Packagist آخرین نسخه، نیازمندی های PHP و آمار نصب این فریم ورک را نمایش می دهد. مستندات کامل Yii2 نیز همچنان از طریق راهنمای رسمی Yii2 در دسترس است. در نتیجه، اگر یک سامانه پایدار با Yii2 دارید، مهاجرت فوری تنها به دلیل انتشار Yii3 ضروری نیست. ابتدا باید وضعیت امنیت، هزینه نگهداری، وابستگی ها و برنامه توسعه آینده پروژه بررسی شود. مزایای Yii3 برای پروژه های جدید تغییرات نسخه Yii3 مزایای مهمی برای توسعه پروژه های جدید ایجاد کرده اند. مهم ترین مزایای این فریم ورک عبارتند از: معماری منعطف و قابل توسعه امکان انتخاب بسته های مورد نیاز سازگاری بهتر با اکوسیستم PHP جداسازی مسئولیت بخش های مختلف قابلیت تست بهتر مدیریت شفاف وابستگی ها مناسب بودن برای توسعه API امکان جایگزینی ساده تر سرویس ها کاهش وابستگی مستقیم به هسته فریم ورک توسعه مستقل اجزای مختلف این مزایا در پروژه های بزرگ، سامانه های سازمانی و نرم افزارهایی که قرار است چندین سال توسعه پیدا کنند، ارزش بیشتری دارند. چالش ها و محدودیت های Yii3 با وجود تغییرات مثبت، انتخاب Yii3 برای هر پروژه ای بهترین تصمیم نیست. معماری جدید علاوه بر مزایا، چالش هایی نیز به همراه دارد. منحنی یادگیری بیشتر توسعه دهنده باید علاوه بر مفاهیم اصلی Yii، با Dependency Injection، Container، Middleware، استانداردهای PSR و ساختار بسته ها آشنا باشد. افرادی که تنها تجربه کار با Yii2 را دارند، برای تسلط بر Yii3 به آموزش و تمرین نیاز خواهند داشت. پیکربندی اولیه پیچیده تر Yii2 تجربه شروع سریع و امکانات آماده زیادی در اختیار توسعه دهنده قرار می دهد. Yii3 کنترل بیشتری ارائه می کند، اما در مقابل ممکن است نصب، انتخاب بسته ها و تنظیم اولیه آن زمان بیشتری ببرد. تفاوت در میزان بلوغ مستندات مستندات Yii2 طی سال های طولانی تکمیل شده اند و پاسخ بسیاری از سوالات در راهنماها و انجمن های مختلف وجود دارد. در Yii3 ممکن است برای شناخت بعضی قابلیت ها لازم باشد مستندات یا فایل README هر بسته به صورت جداگانه مطالعه شود. ناسازگاری برخی افزونه های قدیمی افزونه هایی که برای Yii2 نوشته شده اند لزوما در Yii3 قابل استفاده نیستند. پیش از انتخاب این نسخه باید بسته های مورد نیاز پروژه، وضعیت نگهداری آن ها و امکان پیاده سازی جایگزین بررسی شود. مهاجرت از Yii2 به Yii3 چگونه انجام می شود؟ برای مهاجرت یک پروژه واقعی، ابتدا باید ارزیابی فنی انجام شود. مهاجرت مستقیم و یکباره برای سامانه های بزرگ می تواند هزینه و ریسک زیادی داشته باشد. مرحله اول: شناسایی وابستگی ها همه بسته ها، افزونه ها، Widgetها، رفتارها و کتابخانه های خارجی پروژه باید فهرست شوند. سپس مشخص شود که آیا نسخه سازگار با Yii3 یا جایگزین مناسبی برای آن ها وجود دارد. مرحله دوم: جداسازی منطق تجاری منطق تجاری نباید به کنترلر، Active Record یا اجزای اختصاصی فریم ورک وابسته باشد. انتقال این منطق به سرویس های مستقل می تواند فرآیند مهاجرت را ساده تر کند. مرحله سوم: ایجاد تست های خودکار پیش از بازنویسی بخش های اصلی، باید رفتارهای مهم پروژه با تست پوشش داده شوند. تست ها کمک می کنند نتیجه نسخه جدید با سامانه فعلی مقایسه شود. مرحله چهارم: ساخت نمونه اولیه بهتر است ابتدا یک بخش محدود از پروژه در Yii3 پیاده سازی شود. این نمونه می تواند شامل یک ماژول داخلی، چند Endpoint یا فرآیندی باشد که وابستگی کمتری به بخش های قدیمی دارد. مرحله پنجم: مهاجرت تدریجی در پروژه های بزرگ می توان بخش های مختلف را به صورت مرحله ای منتقل کرد. مهاجرت تدریجی امکان بررسی عملکرد، امنیت و پایداری هر مرحله را فراهم می کند و خطر توقف کامل سامانه را کاهش می دهد. Yii3 برای چه پروژه هایی مناسب است؟ Yii3 می تواند برای پروژه های زیر انتخاب مناسبی باشد: سامانه های تحت وب سفارشی پنل های مدیریت سازمانی APIهای وب و موبایل فروشگاه های اینترنتی اختصاصی نرم افزارهای مدیریت ارتباط با مشتری سامانه های رزرو و نوبت دهی پلتفرم های چندکاربره پروژه های نیازمند توسعه بلندمدت نرم افزارهای دارای منطق تجاری پیچیده با این حال، انتخاب فریم ورک باید پس از تحلیل نیازها انجام شود. اندازه تیم، تجربه برنامه نویسان، بودجه، زمان تحویل، نیازهای امنیتی و زیرساخت اجرایی همگی در این تصمیم موثر هستند. آیا استفاده از Yii3 برای طراحی سایت منطقی است؟ برای طراحی سایت های ساده و محتوایی، استفاده از یک سیستم مدیریت محتوا ممکن است سریع تر و اقتصادی تر باشد. اما زمانی که پروژه به فرآیندهای اختصاصی، پنل مدیریتی سفارشی، اتصال به نرم افزارهای دیگر یا APIهای ویژه نیاز دارد، استفاده از یک فریم ورک مانند Yii3 می تواند منطقی باشد. معماری ماژولار Yii3 به تیم توسعه اجازه می دهد سامانه را بر اساس نیاز واقعی کسب و کار طراحی کند. البته این رویکرد به تحلیل دقیق، طراحی معماری و نگهداری حرفه ای نیاز دارد. تیم طراحان نوین با توجه به حوزه فعالیت خود در طراحی سایت، توسعه نرم افزار و بهینه سازی وب سایت می تواند نیازهای فنی پروژه را بررسی کند. برای طراحی سایت اختصاصی یا ارزیابی امکان توسعه پروژه با Yii3، از طریق صفحه تماس با طراحان نوین با ما در ارتباط باشید. نکات مهم پیش از انتخاب Yii3 پیش از شروع پروژه با Yii3، پاسخ این پرسش ها را مشخص کنید: آیا تیم توسعه با PHP مدرن و Composer آشنایی کافی دارد؟ آیا بسته های مورد نیاز پروژه در Yii3 موجود و پایدار هستند؟ آیا پروژه به معماری سفارشی و توسعه بلندمدت نیاز دارد؟ آیا زمان کافی برای پیکربندی و طراحی اولیه وجود دارد؟ آیا زیرساخت میزبانی با نیازمندی های پروژه سازگار است؟ آیا برای بخش های مهم تست خودکار نوشته خواهد شد؟ آیا هزینه نگهداری پروژه در برنامه مالی کسب و کار پیش بینی شده است؟ پاسخ دقیق به این سوالات کمک می کند تصمیم بر اساس نیازهای واقعی پروژه گرفته شود، نه صرفا جدید بودن یک فناوری. جمع بندی تغییرات نسخه Yii3 نشان می دهد که این فریم ورک مسیر متفاوتی نسبت به Yii2 در پیش گرفته است. معماری مبتنی بر بسته، استفاده جدی از Dependency Injection، سازگاری با استانداردهای PSR، پردازش Middleware محور و جداسازی اجزای پایگاه داده از مهم ترین تغییرات این نسخه هستند. Yii3 برای پروژه های جدیدی که به معماری منعطف، تست پذیری و توسعه بلندمدت نیاز دارند، گزینه ای قابل بررسی است. در مقابل، پروژه های پایدار Yii2 لزوما به مهاجرت فوری نیاز ندارند و بهتر است تصمیم مهاجرت پس از ارزیابی هزینه، ریسک و مزیت های فنی گرفته شود. انتخاب میان Yii2، Yii3 یا یک فریم ورک دیگر باید با توجه به نیازهای کسب و کار، مهارت تیم توسعه و آینده محصول انجام شود. معماری مناسب زمانی ارزشمند است که علاوه بر کیفیت فنی، هزینه نگهداری را کنترل کند و امکان توسعه پایدار محصول را فراهم سازد.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%aa%d8%ba%db%8c%db%8c%d8%b1%d8%a7%d8%aa-%d9%86%d8%b3%d8%ae%d9%87-yii3%d8%9b-%d8%a8%d8%b1%d8%b1%d8%b3%db%8c-%da%a9%d8%a7%d9%85%d9%84-%d9%85%d8%b9%d9%85%d8%a7%d8%b1%db%8c%d8%8c-%d9%82%d8%a7%d8%a8/">تغییرات نسخه Yii3؛ بررسی کامل معماری، قابلیت ها و تفاوت با Yii2</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<p dir="rtl" lang="fa">تغییرات نسخه Yii3 تنها به اضافه شدن چند قابلیت جدید محدود نمی شود. این نسخه بازطراحی گسترده ای را در معماری، مدیریت وابستگی ها، ساختار بسته ها و شیوه توسعه برنامه های تحت وب ایجاد کرده است. Yii3 در ۳۱ دسامبر ۲۰۲۵ به صورت رسمی منتشر شد و اکنون نسل جدید فریم ورک Yii برای توسعه پروژه های مدرن PHP به شمار می رود.</p>
<p dir="rtl" lang="fa">در Yii3 وابستگی شدید اجزای مختلف فریم ورک به یکدیگر کاهش یافته و توسعه دهنده می تواند متناسب با نیاز پروژه، بسته های مورد نظر خود را انتخاب کند. پشتیبانی از استانداردهای PSR، استفاده گسترده از Dependency Injection و ارائه اجزای مستقل، Yii3 را به گزینه ای انعطاف پذیر برای طراحی سایت، توسعه API و ساخت نرم افزارهای تحت وب تبدیل کرده است.</p>
<h2 dir="rtl" lang="fa">Yii3 چیست؟</h2>
<p dir="rtl" lang="fa">Yii3 نسل سوم فریم ورک متن باز Yii است که برای توسعه برنامه های تحت وب با زبان PHP طراحی شده است. تمرکز اصلی این نسخه بر معماری ماژولار، رعایت استانداردهای رایج PHP، قابلیت تست بهتر و کاهش وابستگی میان اجزای فریم ورک قرار دارد.</p>
<p dir="rtl" lang="fa">برخلاف Yii2 که بسیاری از امکانات آن در یک هسته نسبتا یکپارچه قرار گرفته بودند، Yii3 از مجموعه ای از بسته های مستقل تشکیل شده است. هر بسته مسئولیت مشخصی دارد و می تواند در کنار سایر بسته های Yii یا حتی در پروژه های دیگر مورد استفاده قرار گیرد.</p>
<p dir="rtl" lang="fa">توسعه Yii3 چندین سال طول کشید و اجزای مختلف آن به تدریج پایدار شدند. بر اساس <a href="https://www.yiiframework.com/news?year=2025&amp;tag=yii3" target="_blank" rel="nofollow noopener noreferrer">اخبار رسمی فریم ورک Yii</a>، نسخه رسمی Yii3 در پایان سال ۲۰۲۵ منتشر شد و توسعه بسته های آن در سال ۲۰۲۶ نیز ادامه پیدا کرد.</p>
<h2 dir="rtl" lang="fa">مهم ترین تغییرات نسخه Yii3</h2>
<p dir="rtl" lang="fa">تفاوت Yii3 با نسخه قبلی، بیشتر از آنکه ظاهری باشد، به ساختار داخلی و روش توسعه پروژه مربوط است. برنامه نویسانی که با Yii2 کار کرده اند، برای استفاده حرفه ای از نسل جدید باید با مفاهیمی مانند Container، استانداردهای PSR و معماری مبتنی بر بسته آشنا باشند.</p>
<h3 dir="rtl" lang="fa">۱. معماری ماژولار و مبتنی بر بسته</h3>
<p dir="rtl" lang="fa">یکی از مهم ترین تغییرات نسخه Yii3، تقسیم فریم ورک به بسته های مستقل است. در این معماری، اجزایی مانند پایگاه داده، کش، اعتبارسنجی، ثبت رویدادها، مدیریت درخواست و پاسخ و Active Record به صورت بسته های مجزا توسعه پیدا می کنند.</p>
<p dir="rtl" lang="fa">این ساختار چند مزیت مهم دارد:</p>
<ul dir="rtl" lang="fa">
<li>فقط بسته های مورد نیاز پروژه نصب می شوند.</li>
<li>حجم وابستگی های غیرضروری کاهش پیدا می کند.</li>
<li>آزمایش و نگهداری هر بخش ساده تر می شود.</li>
<li>به روز رسانی اجزا با انعطاف بیشتری انجام می گیرد.</li>
<li>امکان استفاده از بسته های Yii در پروژه های دیگر فراهم می شود.</li>
</ul>
<p dir="rtl" lang="fa">در نتیجه، توسعه دهنده کنترل بیشتری بر ساختار برنامه دارد؛ هرچند این آزادی عمل می تواند پیکربندی اولیه پروژه را نسبت به Yii2 کمی پیچیده تر کند.</p>
<h3 dir="rtl" lang="fa">۲. استفاده گسترده از Dependency Injection</h3>
<p dir="rtl" lang="fa">Dependency Injection یا تزریق وابستگی یکی از پایه های معماری Yii3 است. در این روش، کلاس ها وابستگی های مورد نیاز خود را مستقیما ایجاد نمی کنند و این وابستگی ها از طریق یک Container در اختیار آن ها قرار می گیرد.</p>
<p dir="rtl" lang="fa">استفاده از Dependency Injection باعث می شود:</p>
<ul dir="rtl" lang="fa">
<li>وابستگی کلاس ها شفاف تر باشد.</li>
<li>تست واحد ساده تر انجام شود.</li>
<li>امکان جایگزینی سرویس ها وجود داشته باشد.</li>
<li>کدها انعطاف پذیرتر و قابل نگهداری تر شوند.</li>
<li>ارتباط مستقیم میان بخش های برنامه کاهش پیدا کند.</li>
</ul>
<p dir="rtl" lang="fa">Yii2 نیز دارای DI Container بود، اما نقش آن در Yii3 بسیار پررنگ تر شده است. به همین دلیل، درک صحیح تزریق وابستگی برای کار با Yii3 اهمیت زیادی دارد.</p>
<h3 dir="rtl" lang="fa">۳. سازگاری بهتر با استانداردهای PSR</h3>
<p dir="rtl" lang="fa">اکوسیستم مدرن PHP بر پایه مجموعه ای از استانداردهای مشترک با نام PSR شکل گرفته است. Yii3 نسبت به Yii2 سازگاری بیشتری با این استانداردها دارد و تلاش می کند با کتابخانه ها و ابزارهای مختلف PHP ارتباط ساده تری برقرار کند.</p>
<p dir="rtl" lang="fa">از جمله استانداردهای مهم در این زمینه می توان به رابط های استاندارد درخواست و پاسخ HTTP، Container، ثبت گزارش و Middleware اشاره کرد.</p>
<p dir="rtl" lang="fa">رعایت استانداردهای PSR به این معنا است که توسعه دهنده کمتر به پیاده سازی اختصاصی فریم ورک وابسته می شود. همچنین استفاده از کتابخانه های خارج از اکوسیستم Yii و جایگزینی اجزای مختلف برنامه آسان تر خواهد بود.</p>
<p dir="rtl" lang="fa">برای بررسی دقیق استانداردهای PHP می توانید به <a href="https://www.php-fig.org/psr/" target="_blank" rel="nofollow noopener noreferrer">وب سایت رسمی PHP-FIG</a> مراجعه کنید.</p>
<h3 dir="rtl" lang="fa">۴. تغییر ساختار برنامه و قالب های پروژه</h3>
<p dir="rtl" lang="fa">در Yii2 معمولا توسعه پروژه با قالب Basic یا Advanced آغاز می شد. این قالب ها ساختاری آشنا و تعداد زیادی تنظیمات از پیش آماده داشتند. در Yii3 نیز قالب های رسمی برای برنامه های وب و API ارائه شده اند، اما ساختار آن ها با معماری جدید فریم ورک هماهنگ است.</p>
<p dir="rtl" lang="fa">در قالب های Yii3 مواردی مانند پیکربندی Container، مسیر پردازش درخواست، Middlewareها و بسته های مستقل نقش مهم تری دارند. توسعه دهنده باید شناخت روشن تری از اجزای نصب شده و ارتباط میان آن ها داشته باشد.</p>
<p dir="rtl" lang="fa">این رویکرد ممکن است در شروع به زمان بیشتری نیاز داشته باشد، اما در پروژه های بزرگ، کنترل بهتر و ساختار منظم تری در اختیار تیم توسعه قرار می دهد.</p>
<h3 dir="rtl" lang="fa">۵. استفاده از Middleware</h3>
<p dir="rtl" lang="fa">Middleware یک لایه پردازشی است که درخواست HTTP پیش از رسیدن به منطق اصلی برنامه از آن عبور می کند. پاسخ برنامه نیز می تواند در مسیر بازگشت توسط Middleware پردازش شود.</p>
<p dir="rtl" lang="fa">از Middleware می توان برای وظایف زیر استفاده کرد:</p>
<ul dir="rtl" lang="fa">
<li>احراز هویت و کنترل دسترسی</li>
<li>مدیریت نشست کاربران</li>
<li>بررسی توکن های امنیتی</li>
<li>ثبت اطلاعات درخواست ها</li>
<li>مدیریت خطاها</li>
<li>فشرده سازی پاسخ</li>
<li>اعمال محدودیت روی درخواست ها</li>
<li>تنظیم هدرهای امنیتی</li>
</ul>
<p dir="rtl" lang="fa">ساختار Middleware محور باعث می شود هر وظیفه در یک لایه مستقل قرار گیرد و منطق اصلی برنامه با کدهای جانبی ترکیب نشود.</p>
<h3 dir="rtl" lang="fa">۶. بازطراحی مدیریت رویدادها</h3>
<p dir="rtl" lang="fa">سیستم Event در Yii3 به صورت مستقل و هماهنگ با معماری جدید ارائه شده است. رویدادها به بخش های مختلف برنامه اجازه می دهند بدون ایجاد وابستگی مستقیم با یکدیگر ارتباط برقرار کنند.</p>
<p dir="rtl" lang="fa">برای مثال، پس از ثبت سفارش می توان یک رویداد ایجاد کرد تا سرویس ارسال ایمیل، سیستم پیامک یا بخش گزارش گیری به آن واکنش نشان دهد. در این حالت، منطق سفارش به صورت مستقیم به سرویس های دیگر وابسته نخواهد بود.</p>
<p dir="rtl" lang="fa">این ساختار برای پروژه های سازمانی، فروشگاه های اینترنتی، سامانه های مدیریت محتوا و برنامه هایی که چندین فرآیند مرتبط دارند، کاربرد زیادی دارد.</p>
<h3 dir="rtl" lang="fa">۷. تغییر در لایه پایگاه داده</h3>
<p dir="rtl" lang="fa">بسته Yii Database در نسخه سوم بازطراحی شده و درایورهای مختلف پایگاه داده به شکل مستقل ارائه می شوند. این اکوسیستم از پایگاه های داده پرکاربردی مانند موارد زیر پشتیبانی می کند:</p>
<ul lang="en">
<li>MySQL و MariaDB</li>
<li>PostgreSQL</li>
<li>Microsoft SQL Server</li>
<li>Oracle</li>
<li>SQLite</li>
</ul>
<p dir="rtl" lang="fa">مستقل بودن درایورها کمک می کند هر پروژه فقط وابستگی مربوط به پایگاه داده خود را نصب کند. همچنین اصلاح و توسعه یک درایور، تاثیر کمتری بر سایر بخش های فریم ورک خواهد داشت.</p>
<h3 dir="rtl" lang="fa">۸. نسخه جدید Active Record</h3>
<p dir="rtl" lang="fa">Active Record یکی از محبوب ترین قابلیت های Yii2 بود و بسیاری از توسعه دهندگان برای مدیریت داده ها از آن استفاده می کردند. این قابلیت در Yii3 نیز وجود دارد، اما به صورت یک بسته مستقل و سازگار با لایه جدید پایگاه داده ارائه شده است.</p>
<p dir="rtl" lang="fa">Yii Active Record همچنان امکان تعریف مدل ها، ارتباط میان جداول و انجام عملیات متداول پایگاه داده را فراهم می کند. با این حال، نباید انتظار داشت تمام کدهای Active Record نوشته شده برای Yii2 بدون تغییر در Yii3 اجرا شوند.</p>
<p dir="rtl" lang="fa">نسخه پایدار Yii Active Record در دسامبر ۲۰۲۵ منتشر شد و نسخه های جدیدتر آن نیز در سال ۲۰۲۶ در دسترس قرار گرفتند. آخرین وضعیت هر بسته را می توان در <a href="https://packagist.org/packages/yiisoft/" target="_blank" rel="nofollow noopener noreferrer">صفحه رسمی بسته های YiiSoft در Packagist</a> بررسی کرد.</p>
<h3 dir="rtl" lang="fa">۹. بهبود قابلیت تست</h3>
<p dir="rtl" lang="fa">کاهش وابستگی مستقیم کلاس ها، استفاده از Interfaceها و تزریق وابستگی باعث شده است اجزای Yii3 راحت تر آزمایش شوند. توسعه دهنده می تواند سرویس های واقعی را با نمونه های آزمایشی جایگزین کند و هر بخش را به صورت مستقل مورد بررسی قرار دهد.</p>
<p dir="rtl" lang="fa">این موضوع برای پروژه هایی که به پایداری طولانی مدت نیاز دارند اهمیت زیادی دارد. تست خودکار می تواند احتمال بروز خطا بعد از توسعه قابلیت های جدید یا به روز رسانی بسته ها را کاهش دهد.</p>
<h3 dir="rtl" lang="fa">۱۰. مدیریت بهتر تنظیمات</h3>
<p dir="rtl" lang="fa">پیکربندی در Yii3 بر پایه ترکیب فایل های تنظیمات و تعریف دقیق وابستگی ها انجام می شود. این ساختار امکان تفکیک تنظیمات محیط توسعه، آزمایش و تولید را فراهم می کند.</p>
<p dir="rtl" lang="fa">مدیریت تنظیمات در نسل جدید، انعطاف پذیرتر است؛ اما توسعه دهنده باید نحوه ترکیب فایل ها و اولویت هر تنظیم را به خوبی بشناسد. پیکربندی اشتباه Container یا تعریف چندباره یک سرویس می تواند رفتار برنامه را تغییر دهد.</p>
<h2 dir="rtl" lang="fa">جدول مقایسه Yii3 و Yii2</h2>
<div class="table-container">
<div class="table-scroll">
<table dir="rtl" lang="fa">
<thead>
<tr>
<th>ویژگی</th>
<th>Yii2</th>
<th>Yii3</th>
</tr>
</thead>
<tbody>
<tr>
<td dir="rtl" lang="fa">معماری</td>
<td dir="rtl" lang="fa">نسبتا یکپارچه</td>
<td dir="rtl" lang="fa">ماژولار و مبتنی بر بسته</td>
</tr>
<tr>
<td lang="en">Dependency Injection</td>
<td dir="rtl" lang="fa">پشتیبانی داخلی</td>
<td dir="rtl" lang="fa">بخش اساسی معماری</td>
</tr>
<tr>
<td dir="rtl" lang="fa">استانداردهای PSR</td>
<td dir="rtl" lang="fa">پشتیبانی محدودتر</td>
<td dir="rtl" lang="fa">سازگاری گسترده تر</td>
</tr>
<tr>
<td dir="rtl" lang="fa">پردازش درخواست</td>
<td dir="rtl" lang="fa">مبتنی بر ساختار داخلی فریم ورک</td>
<td dir="rtl" lang="fa">مبتنی بر Middleware و استانداردهای HTTP</td>
</tr>
<tr>
<td dir="rtl" lang="fa">نصب اجزا</td>
<td dir="rtl" lang="fa">بسیاری از امکانات همراه هسته</td>
<td dir="rtl" lang="fa">نصب بسته های مورد نیاز</td>
</tr>
<tr>
<td lang="en">Active Record</td>
<td dir="rtl" lang="fa">بخشی از فریم ورک</td>
<td dir="rtl" lang="fa">بسته مستقل</td>
</tr>
<tr>
<td dir="rtl" lang="fa">قابلیت تست</td>
<td dir="rtl" lang="fa">مناسب</td>
<td dir="rtl" lang="fa">انعطاف پذیرتر به دلیل کاهش وابستگی</td>
</tr>
<tr>
<td dir="rtl" lang="fa">منحنی یادگیری</td>
<td dir="rtl" lang="fa">ساده تر برای کاربران Yii</td>
<td dir="rtl" lang="fa">نیازمند شناخت DI، PSR و Middleware</td>
</tr>
<tr>
<td dir="rtl" lang="fa">مهاجرت از نسخه قبل</td>
<td dir="rtl" lang="fa">قابل انجام با تغییرات محدودتر</td>
<td dir="rtl" lang="fa">نیازمند بازنگری جدی در معماری</td>
</tr>
<tr>
<td dir="rtl" lang="fa">کاربرد پیشنهادی</td>
<td dir="rtl" lang="fa">نگهداری پروژه های موجود</td>
<td dir="rtl" lang="fa">پروژه های جدید و آینده محور</td>
</tr>
</tbody>
</table>
</div>
</div>
<h2 dir="rtl" lang="fa">آیا Yii3 نسخه ارتقا یافته مستقیم Yii2 است؟</h2>
<p dir="rtl" lang="fa">Yii3 را نباید فقط یک ارتقای معمولی برای Yii2 در نظر گرفت. تغییر معماری در این نسخه به اندازه ای گسترده است که مهاجرت پروژه های موجود معمولا با اجرای یک دستور Composer یا تغییر شماره نسخه امکان پذیر نیست.</p>
<p dir="rtl" lang="fa">بخش هایی مانند مدل های دامنه، منطق تجاری و بعضی سرویس های مستقل ممکن است با تغییرات محدود قابل استفاده باشند. با این حال، قسمت هایی که مستقیما به ساختار Yii2 وابسته هستند احتمالا باید بازنویسی یا اصلاح شوند.</p>
<p dir="rtl" lang="fa">موارد زیر معمولا در فرآیند مهاجرت به بررسی دقیق نیاز دارند:</p>
<ul dir="rtl" lang="fa">
<li>فایل های تنظیمات</li>
<li>کنترلرها و مسیرها</li>
<li>فیلترها و رفتارها</li>
<li>مدل های Active Record</li>
<li>افزونه های اختصاصی Yii2</li>
<li>مدیریت درخواست و پاسخ</li>
<li>احراز هویت و سطح دسترسی</li>
<li>قالب ها و Widgetها</li>
<li>دستورات کنسول</li>
<li>کش و مدیریت Session</li>
</ul>
<p dir="rtl" lang="fa">بنابراین، تصمیم برای مهاجرت باید بر اساس ارزش تجاری، هزینه فنی و طول عمر مورد انتظار پروژه گرفته شود.</p>
<h2 dir="rtl" lang="fa">آیا پشتیبانی از Yii2 متوقف شده است؟</h2>
<p dir="rtl" lang="fa">انتشار Yii3 به معنای توقف فوری Yii2 نیست. Yii2 همچنان در وضعیت نگهداری فعال قرار دارد و نسخه های اصلاحی هسته و برخی افزونه های رسمی آن منتشر می شوند. برای نمونه، نسخه 2.0.55 این فریم ورک در ماه مه ۲۰۲۶ انتشار یافت.</p>
<p dir="rtl" lang="fa">صفحه <a href="https://packagist.org/packages/yiisoft/yii2" target="_blank" rel="nofollow noopener noreferrer">Yii2 در Packagist</a> آخرین نسخه، نیازمندی های PHP و آمار نصب این فریم ورک را نمایش می دهد. مستندات کامل Yii2 نیز همچنان از طریق <a href="https://www.yiiframework.com/doc/guide/2.0" target="_blank" rel="nofollow noopener noreferrer">راهنمای رسمی Yii2</a> در دسترس است.</p>
<p dir="rtl" lang="fa">در نتیجه، اگر یک سامانه پایدار با Yii2 دارید، مهاجرت فوری تنها به دلیل انتشار Yii3 ضروری نیست. ابتدا باید وضعیت امنیت، هزینه نگهداری، وابستگی ها و برنامه توسعه آینده پروژه بررسی شود.</p>
<h2 dir="rtl" lang="fa">مزایای Yii3 برای پروژه های جدید</h2>
<p dir="rtl" lang="fa">تغییرات نسخه Yii3 مزایای مهمی برای توسعه پروژه های جدید ایجاد کرده اند. مهم ترین مزایای این فریم ورک عبارتند از:</p>
<ul dir="rtl" lang="fa">
<li>معماری منعطف و قابل توسعه</li>
<li>امکان انتخاب بسته های مورد نیاز</li>
<li>سازگاری بهتر با اکوسیستم PHP</li>
<li>جداسازی مسئولیت بخش های مختلف</li>
<li>قابلیت تست بهتر</li>
<li>مدیریت شفاف وابستگی ها</li>
<li>مناسب بودن برای توسعه API</li>
<li>امکان جایگزینی ساده تر سرویس ها</li>
<li>کاهش وابستگی مستقیم به هسته فریم ورک</li>
<li>توسعه مستقل اجزای مختلف</li>
</ul>
<p dir="rtl" lang="fa">این مزایا در پروژه های بزرگ، سامانه های سازمانی و نرم افزارهایی که قرار است چندین سال توسعه پیدا کنند، ارزش بیشتری دارند.</p>
<h2 dir="rtl" lang="fa">چالش ها و محدودیت های Yii3</h2>
<p dir="rtl" lang="fa">با وجود تغییرات مثبت، انتخاب Yii3 برای هر پروژه ای بهترین تصمیم نیست. معماری جدید علاوه بر مزایا، چالش هایی نیز به همراه دارد.</p>
<h3 dir="rtl" lang="fa">منحنی یادگیری بیشتر</h3>
<p dir="rtl" lang="fa">توسعه دهنده باید علاوه بر مفاهیم اصلی Yii، با Dependency Injection، Container، Middleware، استانداردهای PSR و ساختار بسته ها آشنا باشد. افرادی که تنها تجربه کار با Yii2 را دارند، برای تسلط بر Yii3 به آموزش و تمرین نیاز خواهند داشت.</p>
<h3 dir="rtl" lang="fa">پیکربندی اولیه پیچیده تر</h3>
<p dir="rtl" lang="fa">Yii2 تجربه شروع سریع و امکانات آماده زیادی در اختیار توسعه دهنده قرار می دهد. Yii3 کنترل بیشتری ارائه می کند، اما در مقابل ممکن است نصب، انتخاب بسته ها و تنظیم اولیه آن زمان بیشتری ببرد.</p>
<h3 dir="rtl" lang="fa">تفاوت در میزان بلوغ مستندات</h3>
<p dir="rtl" lang="fa">مستندات Yii2 طی سال های طولانی تکمیل شده اند و پاسخ بسیاری از سوالات در راهنماها و انجمن های مختلف وجود دارد. در Yii3 ممکن است برای شناخت بعضی قابلیت ها لازم باشد مستندات یا فایل README هر بسته به صورت جداگانه مطالعه شود.</p>
<h3 dir="rtl" lang="fa">ناسازگاری برخی افزونه های قدیمی</h3>
<p dir="rtl" lang="fa">افزونه هایی که برای Yii2 نوشته شده اند لزوما در Yii3 قابل استفاده نیستند. پیش از انتخاب این نسخه باید بسته های مورد نیاز پروژه، وضعیت نگهداری آن ها و امکان پیاده سازی جایگزین بررسی شود.</p>
<h2 dir="rtl" lang="fa">مهاجرت از Yii2 به Yii3 چگونه انجام می شود؟</h2>
<p dir="rtl" lang="fa">برای مهاجرت یک پروژه واقعی، ابتدا باید ارزیابی فنی انجام شود. مهاجرت مستقیم و یکباره برای سامانه های بزرگ می تواند هزینه و ریسک زیادی داشته باشد.</p>
<h3 dir="rtl" lang="fa">مرحله اول: شناسایی وابستگی ها</h3>
<p dir="rtl" lang="fa">همه بسته ها، افزونه ها، Widgetها، رفتارها و کتابخانه های خارجی پروژه باید فهرست شوند. سپس مشخص شود که آیا نسخه سازگار با Yii3 یا جایگزین مناسبی برای آن ها وجود دارد.</p>
<h3 dir="rtl" lang="fa">مرحله دوم: جداسازی منطق تجاری</h3>
<p dir="rtl" lang="fa">منطق تجاری نباید به کنترلر، Active Record یا اجزای اختصاصی فریم ورک وابسته باشد. انتقال این منطق به سرویس های مستقل می تواند فرآیند مهاجرت را ساده تر کند.</p>
<h3 dir="rtl" lang="fa">مرحله سوم: ایجاد تست های خودکار</h3>
<p dir="rtl" lang="fa">پیش از بازنویسی بخش های اصلی، باید رفتارهای مهم پروژه با تست پوشش داده شوند. تست ها کمک می کنند نتیجه نسخه جدید با سامانه فعلی مقایسه شود.</p>
<h3 dir="rtl" lang="fa">مرحله چهارم: ساخت نمونه اولیه</h3>
<p dir="rtl" lang="fa">بهتر است ابتدا یک بخش محدود از پروژه در Yii3 پیاده سازی شود. این نمونه می تواند شامل یک ماژول داخلی، چند Endpoint یا فرآیندی باشد که وابستگی کمتری به بخش های قدیمی دارد.</p>
<h3 dir="rtl" lang="fa">مرحله پنجم: مهاجرت تدریجی</h3>
<p dir="rtl" lang="fa">در پروژه های بزرگ می توان بخش های مختلف را به صورت مرحله ای منتقل کرد. مهاجرت تدریجی امکان بررسی عملکرد، امنیت و پایداری هر مرحله را فراهم می کند و خطر توقف کامل سامانه را کاهش می دهد.</p>
<h2 dir="rtl" lang="fa">Yii3 برای چه پروژه هایی مناسب است؟</h2>
<p dir="rtl" lang="fa">Yii3 می تواند برای پروژه های زیر انتخاب مناسبی باشد:</p>
<ul dir="rtl" lang="fa">
<li>سامانه های تحت وب سفارشی</li>
<li>پنل های مدیریت سازمانی</li>
<li>APIهای وب و موبایل</li>
<li>فروشگاه های اینترنتی اختصاصی</li>
<li>نرم افزارهای مدیریت ارتباط با مشتری</li>
<li>سامانه های رزرو و نوبت دهی</li>
<li>پلتفرم های چندکاربره</li>
<li>پروژه های نیازمند توسعه بلندمدت</li>
<li>نرم افزارهای دارای منطق تجاری پیچیده</li>
</ul>
<p dir="rtl" lang="fa">با این حال، انتخاب فریم ورک باید پس از تحلیل نیازها انجام شود. اندازه تیم، تجربه برنامه نویسان، بودجه، زمان تحویل، نیازهای امنیتی و زیرساخت اجرایی همگی در این تصمیم موثر هستند.</p>
<h2 dir="rtl" lang="fa">آیا استفاده از Yii3 برای طراحی سایت منطقی است؟</h2>
<p dir="rtl" lang="fa">برای طراحی سایت های ساده و محتوایی، استفاده از یک سیستم مدیریت محتوا ممکن است سریع تر و اقتصادی تر باشد. اما زمانی که پروژه به فرآیندهای اختصاصی، پنل مدیریتی سفارشی، اتصال به نرم افزارهای دیگر یا APIهای ویژه نیاز دارد، استفاده از یک فریم ورک مانند Yii3 می تواند منطقی باشد.</p>
<p dir="rtl" lang="fa">معماری ماژولار Yii3 به تیم توسعه اجازه می دهد سامانه را بر اساس نیاز واقعی کسب و کار طراحی کند. البته این رویکرد به تحلیل دقیق، طراحی معماری و نگهداری حرفه ای نیاز دارد.</p>
<p dir="rtl" lang="fa">تیم طراحان نوین با توجه به حوزه فعالیت خود در طراحی سایت، توسعه نرم افزار و بهینه سازی وب سایت می تواند نیازهای فنی پروژه را بررسی کند. برای طراحی سایت اختصاصی یا ارزیابی امکان توسعه پروژه با Yii3، از طریق صفحه <a href="https://tarahanenovin.ir/site/contact" target="_blank" rel="nofollow noopener noreferrer">تماس با طراحان نوین</a> با ما در ارتباط باشید.</p>
<h2 dir="rtl" lang="fa">نکات مهم پیش از انتخاب Yii3</h2>
<p dir="rtl" lang="fa">پیش از شروع پروژه با Yii3، پاسخ این پرسش ها را مشخص کنید:</p>
<ul dir="rtl" lang="fa">
<li>آیا تیم توسعه با PHP مدرن و Composer آشنایی کافی دارد؟</li>
<li>آیا بسته های مورد نیاز پروژه در Yii3 موجود و پایدار هستند؟</li>
<li>آیا پروژه به معماری سفارشی و توسعه بلندمدت نیاز دارد؟</li>
<li>آیا زمان کافی برای پیکربندی و طراحی اولیه وجود دارد؟</li>
<li>آیا زیرساخت میزبانی با نیازمندی های پروژه سازگار است؟</li>
<li>آیا برای بخش های مهم تست خودکار نوشته خواهد شد؟</li>
<li>آیا هزینه نگهداری پروژه در برنامه مالی کسب و کار پیش بینی شده است؟</li>
</ul>
<p dir="rtl" lang="fa">پاسخ دقیق به این سوالات کمک می کند تصمیم بر اساس نیازهای واقعی پروژه گرفته شود، نه صرفا جدید بودن یک فناوری.</p>
<h2 dir="rtl" lang="fa">جمع بندی</h2>
<p dir="rtl" lang="fa">تغییرات نسخه Yii3 نشان می دهد که این فریم ورک مسیر متفاوتی نسبت به Yii2 در پیش گرفته است. معماری مبتنی بر بسته، استفاده جدی از Dependency Injection، سازگاری با استانداردهای PSR، پردازش Middleware محور و جداسازی اجزای پایگاه داده از مهم ترین تغییرات این نسخه هستند.</p>
<p dir="rtl" lang="fa">Yii3 برای پروژه های جدیدی که به معماری منعطف، تست پذیری و توسعه بلندمدت نیاز دارند، گزینه ای قابل بررسی است. در مقابل، پروژه های پایدار Yii2 لزوما به مهاجرت فوری نیاز ندارند و بهتر است تصمیم مهاجرت پس از ارزیابی هزینه، ریسک و مزیت های فنی گرفته شود.</p>
<p dir="rtl" lang="fa">انتخاب میان Yii2، Yii3 یا یک فریم ورک دیگر باید با توجه به نیازهای کسب و کار، مهارت تیم توسعه و آینده محصول انجام شود. معماری مناسب زمانی ارزشمند است که علاوه بر کیفیت فنی، هزینه نگهداری را کنترل کند و امکان توسعه پایدار محصول را فراهم سازد.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%aa%d8%ba%db%8c%db%8c%d8%b1%d8%a7%d8%aa-%d9%86%d8%b3%d8%ae%d9%87-yii3%d8%9b-%d8%a8%d8%b1%d8%b1%d8%b3%db%8c-%da%a9%d8%a7%d9%85%d9%84-%d9%85%d8%b9%d9%85%d8%a7%d8%b1%db%8c%d8%8c-%d9%82%d8%a7%d8%a8/">تغییرات نسخه Yii3؛ بررسی کامل معماری، قابلیت ها و تفاوت با Yii2</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d8%aa%d8%ba%db%8c%db%8c%d8%b1%d8%a7%d8%aa-%d9%86%d8%b3%d8%ae%d9%87-yii3%d8%9b-%d8%a8%d8%b1%d8%b1%d8%b3%db%8c-%da%a9%d8%a7%d9%85%d9%84-%d9%85%d8%b9%d9%85%d8%a7%d8%b1%db%8c%d8%8c-%d9%82%d8%a7%d8%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>مقایسه 5 تا از بهترین فریم ورک های PHP؛ کدام گزینه برای پروژه شما مناسب است؟</title>
		<link>https://tarahanenovin.ir/blog/%d9%85%d9%82%d8%a7%db%8c%d8%b3%d9%87-5-%d8%aa%d8%a7-%d8%a7%d8%b2-%d8%a8%d9%87%d8%aa%d8%b1%db%8c%d9%86-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%d9%87%d8%a7%db%8c-php%d8%9b-%da%a9%d8%af%d8%a7%d9%85/</link>
					<comments>https://tarahanenovin.ir/blog/%d9%85%d9%82%d8%a7%db%8c%d8%b3%d9%87-5-%d8%aa%d8%a7-%d8%a7%d8%b2-%d8%a8%d9%87%d8%aa%d8%b1%db%8c%d9%86-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%d9%87%d8%a7%db%8c-php%d8%9b-%da%a9%d8%af%d8%a7%d9%85/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[طراحی وب]]></category>
		<category><![CDATA[فرانت‌اند]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[Yii2]]></category>
		<category><![CDATA[لاراول]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=159</guid>

					<description><![CDATA[<p>انتخاب از میان بهترین فریم ورک های PHP فقط یک تصمیم فنی نیست؛ زیرا این انتخاب می تواند بر هزینه توسعه، امنیت، سرعت اجرای پروژه، نگهداری کد و امکان گسترش محصول تاثیر مستقیم بگذارد. Laravel، Symfony، CodeIgniter، Yii و CakePHP از شناخته شده ترین گزینه های موجود هستند، اما هر کدام برای نوع خاصی از پروژه مناسب ترند. در این مقاله، این 5 فریم ورک PHP را از نظر معماری، عملکرد، امنیت، امکانات، مستندات، سرعت توسعه و کاربردهای تجاری مقایسه می کنیم. همچنین با استفاده از جدول ها و نمودارهای امتیازی، انتخاب مناسب برای فروشگاه اینترنتی، سامانه سازمانی، استارتاپ و وب سایت اختصاصی را ساده تر خواهیم کرد. اطلاعات نسخه ها و وضعیت انتشار این مقاله بر اساس منابع رسمی در زمان نگارش بررسی شده است. از آنجا که فریم ورک ها به صورت مداوم به روز می شوند، برای مشاهده آخرین نسخه باید صفحه رسمی هر پروژه را بررسی کنید. فریم ورک PHP چیست؟ فریم ورک PHP مجموعه ای از کتابخانه ها، ابزارها، قواعد معماری و قابلیت های آماده است که فرآیند توسعه برنامه های تحت وب را سریع تر و منظم تر می کند. بدون استفاده از فریم ورک، توسعه دهنده باید قابلیت هایی مانند مسیریابی، اعتبارسنجی اطلاعات، اتصال به پایگاه داده، مدیریت نشست، احراز هویت و کنترل امنیت را از ابتدا پیاده سازی کند. یک فریم ورک مناسب بخش قابل توجهی از این زیرساخت را در اختیار تیم توسعه قرار می دهد. مهم ترین مزایای استفاده از فریم ورک PHP عبارت اند از: کاهش زمان توسعه پروژه ایجاد ساختار منظم و قابل نگهداری استفاده از قابلیت های امنیتی استاندارد تسهیل همکاری میان اعضای تیم کاهش کدهای تکراری امکان توسعه و گسترش ساده تر پروژه دسترسی به کتابخانه ها و بسته های آماده ساده تر شدن آزمایش و رفع خطا با این حال، استفاده از فریم ورک به تنهایی کیفیت یک پروژه را تضمین نمی کند. معماری صحیح، تجربه تیم توسعه، کیفیت پایگاه داده، تنظیمات سرور و رعایت اصول امنیتی همچنان اهمیت زیادی دارند. بهترین فریم ورک های PHP کدام اند؟ در این مقایسه، 5 فریم ورک مطرح PHP بررسی شده اند: Laravel Symfony CodeIgniter Yii CakePHP این فریم ورک ها از نظر فلسفه طراحی و جامعه هدف با یکدیگر تفاوت دارند. برای مثال، Laravel بیشتر بر تجربه توسعه دهنده و سرعت ساخت محصول تمرکز دارد، در حالی که Symfony برای سامانه های بزرگ و معماری های سازمانی انتخاب بسیار قدرتمندی است. CodeIgniter ساختاری سبک و ساده ارائه می دهد، Yii به عملکرد مناسب و ابزارهای تولید کد شناخته می شود و CakePHP نیز توسعه سریع بر پایه قراردادهای مشخص را دنبال می کند. جدول مقایسه سریع بهترین فریم ورک های PHP فریم ورک یادگیری سرعت توسعه عملکرد در پروژه سبک امکانات داخلی مناسب پروژه سازمانی جامعه و اکوسیستم Laravel آسان تا متوسط بسیار بالا خوب بسیار کامل خوب بسیار گسترده Symfony متوسط تا دشوار متوسط متوسط بسیار کامل بسیار عالی بسیار گسترده CodeIgniter آسان بالا بسیار خوب متوسط متوسط مناسب Yii متوسط بالا بسیار خوب کامل خوب مناسب CakePHP متوسط بالا خوب کامل خوب مناسب این جدول یک ارزیابی کلی است. عملکرد واقعی هر فریم ورک به معماری پروژه، نسخه PHP، تنظیمات سرور، سیستم کش، پایگاه داده و کیفیت کد وابسته خواهد بود. نمودار مقایسه کلی فریم ورک های PHP امتیازهای زیر از 10 محاسبه شده اند و ارزیابی تحلیلی مقاله محسوب می شوند. این امتیازها آمار رسمی پروژه ها نیستند، بلکه بر اساس امکانات، مستندات، سهولت توسعه، انعطاف پذیری و کاربرد در پروژه های واقعی ارائه شده اند. Laravel 9.2 █████████░ Symfony 8.9 █████████░ CodeIgniter 7.8 ████████░░ Yii 8.0 ████████░░ CakePHP 7.7 ████████░░ Laravel در امتیاز کلی به دلیل اکوسیستم گسترده، منابع آموزشی فراوان و سرعت بالای توسعه در جایگاه اول قرار می گیرد. Symfony در پروژه های سازمانی و معماری های پیچیده عملکرد درخشانی دارد، اما یادگیری آن معمولا زمان بیشتری نیاز دارد. 1. Laravel؛ بهترین انتخاب عمومی برای توسعه وب Laravel یکی از محبوب ترین و کامل ترین فریم ورک های PHP است. ساختار منظم، مستندات مناسب، ابزارهای توسعه متنوع و جامعه بزرگ باعث شده اند Laravel در بسیاری از پروژه های جدید PHP به گزینه اول تیم های توسعه تبدیل شود. این فریم ورک از معماری MVC استفاده می کند و قابلیت هایی مانند مسیریابی، احراز هویت، صف پردازش، ارسال اعلان، مدیریت کش، زمان بندی وظایف و کار با پایگاه داده را در اختیار توسعه دهنده قرار می دهد. مهم ترین امکانات Laravel ORM قدرتمند Eloquent موتور قالب Blade سیستم مسیریابی ساده و انعطاف پذیر ابزار خط فرمان Artisan پشتیبانی از Queue و پردازش پس زمینه سیستم Migration برای مدیریت ساختار پایگاه داده قابلیت ساخت API و احراز هویت کاربران پشتیبانی مناسب از تست نویسی اکوسیستم گسترده برای توسعه و استقرار ابزارها و محصولات جانبی مانند Horizon، Sanctum، Passport، Scout و Octane نیز برای حل نیازهای متداول پروژه های حرفه ای در دسترس هستند. مزایای Laravel Laravel سرعت ساخت نمونه اولیه و محصول نهایی را افزایش می دهد. ساختار کدنویسی خوانا و وجود بسته های متعدد باعث می شود تیم توسعه برای قابلیت های رایج مجبور به پیاده سازی همه چیز از ابتدا نباشد. این فریم ورک برای استارتاپ ها، فروشگاه های اینترنتی، پنل های مدیریتی، سامانه های رزرو، پلتفرم های خدماتی و API اپلیکیشن های موبایل گزینه مناسبی است. معایب Laravel مصرف منابع آن از فریم ورک های بسیار سبک بیشتر است. قابلیت های متعدد می توانند برای یک پروژه ساده اضافی باشند. استفاده نادرست از Eloquent ممکن است تعداد Queryها را افزایش دهد. بهینه سازی پروژه های پرترافیک به تجربه فنی نیاز دارد. نسخه های اصلی دارای چرخه پشتیبانی مشخص هستند و باید ارتقاها برنامه ریزی شوند. اطلاعات آخرین نسخه، تغییرات و نیازمندی های فنی Laravel را می توان در مستندات رسمی Laravel بررسی کرد. Laravel برای چه پروژه هایی مناسب است؟ Laravel انتخاب مناسبی برای پروژه هایی است که باید در زمان منطقی توسعه پیدا کنند و در آینده نیز قابل گسترش باشند. این فریم ورک برای بیشتر پروژه های تجاری کوچک تا بزرگ پاسخ مناسبی ارائه می دهد. 2. Symfony؛ گزینه قدرتمند برای سامانه های سازمانی Symfony هم یک فریم ورک کامل PHP و هم مجموعه ای از کامپوننت های مستقل و قابل استفاده مجدد است. بسیاری از پروژه ها و ابزارهای PHP، از جمله بخش هایی از Laravel، از کامپوننت های Symfony استفاده می کنند. Symfony انعطاف پذیری بالایی دارد و به تیم توسعه اجازه می دهد معماری پروژه را با کنترل بیشتری طراحی کند. این ویژگی آن را برای سامانه های سازمانی، محصولات دارای منطق پیچیده و پروژه های بلند مدت مناسب می کند. مهم ترین امکانات Symfony مجموعه گسترده ای از کامپوننت های مستقل سیستم Dependency Injection حرفه ای پشتیبانی مناسب از معماری ماژولار ابزارهای امنیتی قابل تنظیم سیستم کش و مدیریت رویدادها یکپارچگی مناسب با Doctrine ORM ابزارهای تست و اشکال زدایی پشتیبانی از Console Commands نسخه های LTS با پشتیبانی بلند مدت براساس صفحه رسمی انتشارهای Symfony، این فریم ورک نسخه های استاندارد و LTS دارد. نسخه های LTS برای سازمان هایی اهمیت دارند که به ثبات، دریافت اصلاحات امنیتی و برنامه ارتقای قابل پیش بینی نیاز دارند. مزایای Symfony Symfony آزادی عمل زیادی در طراحی معماری پروژه ایجاد می کند. کامپوننت های آن را می توان به صورت مستقل نیز در پروژه های مختلف به کار برد. استانداردهای کدنویسی دقیق، قابلیت تست مناسب و ساختار ماژولار باعث می شوند Symfony برای تیم های بزرگ و پروژه هایی با عمر طولانی مناسب باشد. معایب Symfony منحنی یادگیری آن از Laravel و CodeIgniter بیشتر است. راه اندازی اولیه بعضی پروژه ها زمان بیشتری نیاز دارد. توسعه دهنده باید با مفاهیم معماری نرم افزار آشنایی مناسبی داشته باشد. ممکن است برای وب سایت های بسیار ساده بیش از حد پیچیده باشد. Symfony برای چه پروژه هایی مناسب است؟ Symfony برای سامانه های مالی، نرم افزارهای سازمانی، پلتفرم های چند بخشی، سیستم های دارای قوانین تجاری پیچیده و پروژه هایی که نگهداری بلند مدت در آنها اهمیت دارد، گزینه ای قدرتمند است. 3. CodeIgniter؛ فریم ورک سبک و سریع PHP CodeIgniter یک فریم ورک سبک PHP است که به دلیل راه اندازی ساده، حجم کم و انعطاف پذیری مناسب شناخته می شود. توسعه دهنده می تواند بدون درگیر شدن با تنظیمات پیچیده، پروژه را در مدت کوتاهی آغاز کند. CodeIgniter محدودیت های معماری کمتری نسبت به بعضی فریم ورک های بزرگ دارد. این ویژگی برای توسعه دهندگان باتجربه مفید است، اما در تیم های بزرگ باید قواعد کدنویسی مشخصی تعریف شود تا ساختار پروژه نامنظم نشود. مهم ترین امکانات CodeIgniter ساختار سبک و راه اندازی سریع سیستم مسیریابی Query Builder برای کار با پایگاه داده اعتبارسنجی فرم ها مدیریت نشست و کش ابزارهای امنیتی پایه پشتیبانی از دستورات خط فرمان ساختار مناسب برای توسعه API مستندات قابل فهم برای بررسی آخرین قابلیت ها و الزامات اجرا می توان به مستندات رسمی CodeIgniter 4 مراجعه کرد. مزایای CodeIgniter یادگیری نسبتا آسان عملکرد مناسب در پروژه های سبک تنظیمات اولیه محدود آزادی عمل بیشتر در طراحی ساختار مناسب برای سرورهایی با منابع محدود امکان انتقال ساده تر پروژه های PHP قدیمی معایب CodeIgniter اکوسیستم آن به گستردگی Laravel نیست. برای پروژه های بزرگ به تعریف معماری دقیق نیاز دارد. بعضی ابزارهای پیشرفته باید به صورت جداگانه اضافه شوند. آزادی عمل زیاد ممکن است در تیم های کم تجربه به کد نامنظم منجر شود. CodeIgniter برای چه پروژه هایی مناسب است؟ این فریم ورک برای وب سایت های شرکتی، پنل های سبک، APIهای ساده، پروژه های کوچک و نرم افزارهایی که مصرف منابع در آنها مهم است، انتخاب مناسبی محسوب می شود. 4. Yii؛ عملکرد مناسب همراه با ابزارهای توسعه سریع Yii یک فریم ورک متن باز PHP است که بر عملکرد، توسعه سریع و استفاده مجدد از کد تمرکز دارد. ابزار Gii در Yii می تواند مدل ها، کنترلرها، فرم ها و بخش هایی از عملیات CRUD را تولید کند. این قابلیت برای پروژه هایی که دارای فرم ها، جداول و عملیات مدیریتی متعدد هستند، زمان توسعه را کاهش می دهد. مهم ترین امکانات Yii ابزار تولید کد Gii پشتیبانی از Active Record سیستم کش چند لایه اعتبارسنجی ورودی ها کنترل دسترسی مبتنی بر نقش پشتیبانی از REST API سیستم Widget ابزارهای امنیتی داخلی امکان توسعه ماژولار مزایای Yii عملکرد مناسب در بسیاری از پروژه ها تولید سریع بخش های تکراری امکانات کامل برای مدیریت پایگاه داده سیستم کش قابل تنظیم مناسب برای پنل های مدیریتی و سامانه های داده محور معایب Yii منابع آموزشی فارسی و انگلیسی آن از Laravel کمتر است. بازار کار آن در بسیاری از مناطق محدودتر است. برخی الگوها و تنظیمات آن به یادگیری اولیه نیاز دارند. انتخاب میان نسل ها و نسخه های مختلف Yii باید با دقت انجام شود. Yii برای چه پروژه هایی مناسب است؟ Yii برای سامانه های مدیریتی، داشبوردهای آماری، پرتال ها، نرم افزارهای دارای عملیات CRUD گسترده و پروژه هایی که سرعت توسعه بخش مدیریت اهمیت دارد، مناسب است. آخرین مستندات و وضعیت نسخه های این فریم ورک در وب سایت رسمی Yii منتشر می شود. 5. CakePHP؛ توسعه سریع بر اساس قراردادها CakePHP یکی از فریم ورک های قدیمی و شناخته شده PHP است. فلسفه اصلی آن Convention over Configuration است؛ یعنی توسعه دهنده با رعایت قراردادهای تعیین شده می تواند بدون انجام تنظیمات فراوان، بخش های مختلف پروژه را ایجاد کند. CakePHP ابزارهای مناسبی برای مدل سازی داده، اعتبارسنجی، احراز هویت، مسیریابی و ساخت سریع عملیات مدیریتی دارد. مهم ترین امکانات CakePHP ORM داخلی ابزار Bake برای تولید کد سیستم اعتبارسنجی قابلیت های احراز هویت و مجوزدهی سیستم مسیریابی پشتیبانی از Migration ابزارهای تست ساختار مبتنی بر MVC قراردادهای مشخص برای توسعه منظم مزایای CakePHP توسعه سریع قابلیت های متداول ساختار منظم و قابل پیش بینی کاهش تنظیمات تکراری مستندات مناسب ابزارهای کاربردی برای تولید کد معایب CakePHP جامعه کاربری آن از Laravel کوچک تر است. قراردادهای فریم ورک می توانند آزادی توسعه دهنده را محدود کنند. تعداد فرصت های شغلی و منابع آموزشی آن در برخی بازارها کمتر است. مهاجرت پروژه هایی که قراردادهای فریم ورک را رعایت نکرده اند، دشوار می شود. CakePHP برای چه پروژه هایی مناسب است؟ CakePHP برای نرم افزارهای تجاری، پنل های مدیریتی، سامانه های مبتنی بر فرم و پروژه هایی که از الگوهای استاندارد پیروی می کنند، انتخاب قابل قبولی است. جزئیات نسخه های پایدار و نیازمندی های اجرا در مستندات رسمی CakePHP در دسترس قرار دارد. مقایسه امکانات فنی 5 فریم ورک PHP قابلیت Laravel Symfony CodeIgniter Yii CakePHP معماری MVC دارد دارد دارد دارد دارد ORM داخلی یا پیشنهادی Eloquent Doctrine Model و Query Builder Active Record CakePHP ORM ابزار خط فرمان Artisan Console Spark Yii Console Cake تولید خودکار کد متوسط قابل توسعه محدود بسیار خوب بسیار خوب پشتیبانی از Queue بسیار خوب بسیار خوب نیازمند تنظیم بیشتر خوب قابل توسعه ساخت REST API بسیار خوب بسیار خوب خوب بسیار خوب خوب احراز هویت کامل بسیار انعطاف پذیر پایه تا متوسط کامل کامل تست نویسی بسیار خوب بسیار خوب خوب خوب خوب نسخه LTS براساس چرخه انتشار دارد وابسته به نسخه وابسته به شاخه وابسته به نسخه مناسب معماری پیچیده خوب بسیار عالی متوسط خوب خوب نمودار سرعت یادگیری و توسعه امتیاز بیشتر به معنای شروع ساده تر و رسیدن سریع تر به خروجی اولیه است. Laravel 9/10 █████████░ CodeIgniter 9/10 █████████░ CakePHP 8/10 ████████░░ Yii 7/10 ███████░░░ Symfony 6/10 ██████░░░░ Laravel به دلیل مستندات منظم، آموزش های متعدد و ابزارهای آماده، مسیر شروع مناسبی دارد. CodeIgniter نیز به دلیل ساختار سبک و تنظیمات محدود، برای توسعه دهندگان تازه وارد قابل فهم است. امتیاز پایین تر Symfony به معنای ضعف این فریم ورک نیست. Symfony مفاهیم و قابلیت های پیشرفته تری دارد و برای استفاده صحیح از آنها باید زمان بیشتری صرف یادگیری شود. نمودار تناسب با پروژه های سازمانی Symfony 10/10 ██████████ Laravel 9/10 █████████░ Yii 8/10 ████████░░ CakePHP 7/10 ███████░░░ CodeIgniter 6/10 ██████░░░░ Symfony به دلیل معماری ماژولار، کامپوننت های مستقل، نسخه های LTS و کنترل دقیق بر سرویس ها، در پروژه های سازمانی امتیاز بالایی دریافت می کند. Laravel نیز می تواند در پروژه های بزرگ استفاده شود، اما معماری نرم افزار باید از ابتدا برای رشد محصول طراحی شده باشد. انتخاب Laravel به تنهایی مانع ایجاد مشکلات مقیاس پذیری یا نگهداری نخواهد شد. نمودار امکانات آماده و اکوسیستم Laravel 10/10 ██████████ Symfony 10/10 ██████████ Yii 8/10 ████████░░ CakePHP 8/10 ████████░░ CodeIgniter 7/10 ███████░░░ Laravel یک اکوسیستم یکپارچه برای صف، کش، جستجو، احراز هویت و مانیتورینگ دارد. Symfony نیز مجموعه بسیار بزرگی از کامپوننت های استاندارد ارائه می دهد که در بسیاری از پروژه های PHP استفاده می شوند. آمار رسمی را از کجا بررسی کنیم؟ برای ارزیابی محبوبیت فریم ورک ها باید از منابع قابل استناد استفاده کرد. تعداد ستاره های GitHub و دانلودهای Packagist به صورت مداوم تغییر می کنند؛ بنابراین ثبت یک عدد ثابت بدون تاریخ، ممکن است خیلی زود اعتبار خود را از دست بدهد. آمار زنده هر پروژه را می توان از منابع زیر مشاهده کرد: فریم ورک مخزن رسمی بسته رسمی Laravel GitHub Laravel Packagist Laravel Symfony GitHub Symfony Packagist Symfony CodeIgniter GitHub CodeIgniter Packagist CodeIgniter Yii GitHub Yii Packagist Yii CakePHP GitHub CakePHP Packagist CakePHP تعداد دانلود بسته لزوما برابر با تعداد پروژه های فعال نیست. نصب های خودکار در سرورهای CI، به روز رسانی وابستگی ها، محیط های آزمایشی و نصب چندباره یک بسته نیز در این آمار تاثیر دارند. ستاره GitHub نیز بیشتر نشان دهنده توجه جامعه است و نمی توان آن را معیار قطعی کیفیت یا سهم بازار دانست. مقایسه عملکرد و سرعت فریم ورک های PHP نمی توان یک فریم ورک را در تمام شرایط سریع ترین گزینه معرفی کرد. نتیجه بنچمارک ها به عوامل متعددی وابسته است: نسخه PHP فعال بودن OPcache نوع وب سرور تنظیمات پایگاه داده تعداد Middlewareها ساختار Queryها نحوه استفاده از ORM تنظیمات Cache حالت Development یا Production سخت افزار و سیستم عامل CodeIgniter به دلیل هسته سبک معمولا سربار اولیه کمتری دارد. با این حال، در یک پروژه واقعی ممکن است Laravel یا Symfony با معماری درست، کش مناسب و پردازش پس زمینه عملکرد بهتری از یک پروژه CodeIgniter با کد ضعیف داشته باشند. برای سایت های پرترافیک، انتخاب فریم ورک باید در کنار طراحی زیرساخت، CDN، کش سمت سرور، بهینه سازی پایگاه داده، Queue و مانیتورینگ انجام شود. مطالب آموزشی و تحلیلی مرتبط با توسعه نرم افزار را نیز می توانید در وبلاگ طراحان نوین مطالعه کنید. مقایسه امنیت فریم ورک های PHP هر 5 فریم ورک امکاناتی برای کاهش آسیب پذیری های متداول وب دارند، اما امنیت نهایی به نحوه پیاده سازی بستگی دارد. قابلیت های امنیتی مهم در یک فریم ورک شامل موارد زیر هستند: محافظت در برابر CSRF جلوگیری از SQL Injection پاک سازی و اعتبارسنجی ورودی مدیریت امن نشست هش کردن رمز عبور کنترل دسترسی کاربران مدیریت Cookie جلوگیری از XSS مدیریت صحیح خطاها دریافت به روز رسانی های امنیتی Laravel و Symfony ابزارهای امنیتی گسترده و قابل تنظیمی دارند. Yii و CakePHP نیز امکانات مناسبی برای اعتبارسنجی و کنترل دسترسی ارائه می دهند. CodeIgniter قابلیت های امنیتی لازم را فراهم می کند، اما در پروژه های پیچیده ممکن است به طراحی و بسته های تکمیلی بیشتری نیاز باشد. صرف نظر از فریم ورک انتخاب شده، استفاده از نسخه های پشتیبانی شده PHP و به روز نگه داشتن Composer Packages ضروری است. پایگاه داده، سرور، سیستم عامل و کتابخانه های جانبی نیز باید به صورت منظم به روز شوند. Laravel بهتر است یا Symfony؟ برای بسیاری از پروژه ها، پاسخ این پرسش به ساختار تیم و نوع محصول وابسته است. Laravel زمانی انتخاب مناسب تری است که: سرعت توسعه اهمیت زیادی دارد. تیم به ابزارهای آماده نیاز دارد. پروژه یک محصول استارتاپی یا تجاری است. دسترسی به نیروی متخصص و منابع آموزشی مهم است. قرار است API، پنل مدیریت یا فروشگاه اختصاصی ساخته شود. Symfony زمانی انتخاب مناسب تری است که: پروژه دارای منطق تجاری بسیار پیچیده است. معماری ماژولار و کنترل دقیق اهمیت دارد. محصول باید برای مدت طولانی نگهداری شود. تیم توسعه تجربه کافی در معماری نرم افزار دارد. نسخه LTS و برنامه پشتیبانی بلند مدت اهمیت زیادی دارد. Laravel بخشی از زیرساخت خود را با استفاده از کامپوننت های Symfony ایجاد کرده است. بنابراین این دو فریم ورک فقط رقیب نیستند و در سطح اکوسیستم PHP ارتباط نزدیکی با یکدیگر دارند. Laravel بهتر است یا CodeIgniter؟ Laravel امکانات داخلی و اکوسیستم گسترده تری دارد، اما CodeIgniter سبک تر است و تنظیمات اولیه کمتری نیاز دارد. برای یک سامانه...</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d9%85%d9%82%d8%a7%db%8c%d8%b3%d9%87-5-%d8%aa%d8%a7-%d8%a7%d8%b2-%d8%a8%d9%87%d8%aa%d8%b1%db%8c%d9%86-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%d9%87%d8%a7%db%8c-php%d8%9b-%da%a9%d8%af%d8%a7%d9%85/">مقایسه 5 تا از بهترین فریم ورک های PHP؛ کدام گزینه برای پروژه شما مناسب است؟</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<div data-v-3d7837ba="">
<div class="markdown-container" dir="ltr" data-v-1a76c2f2="" data-v-3d7837ba="" data-block-id="9fd023b1-31c3-491e-b261-8bbf2b1d9872">
<p dir="rtl" lang="fa">انتخاب از میان <strong>بهترین فریم ورک های PHP</strong> فقط یک تصمیم فنی نیست؛ زیرا این انتخاب می تواند بر هزینه توسعه، امنیت، سرعت اجرای پروژه، نگهداری کد و امکان گسترش محصول تاثیر مستقیم بگذارد. Laravel، Symfony، CodeIgniter، Yii و CakePHP از شناخته شده ترین گزینه های موجود هستند، اما هر کدام برای نوع خاصی از پروژه مناسب ترند.</p>
<p dir="rtl" lang="fa">در این مقاله، این 5 فریم ورک PHP را از نظر معماری، عملکرد، امنیت، امکانات، مستندات، سرعت توسعه و کاربردهای تجاری مقایسه می کنیم. همچنین با استفاده از جدول ها و نمودارهای امتیازی، انتخاب مناسب برای فروشگاه اینترنتی، سامانه سازمانی، استارتاپ و وب سایت اختصاصی را ساده تر خواهیم کرد.</p>
<blockquote>
<p dir="rtl" lang="fa">اطلاعات نسخه ها و وضعیت انتشار این مقاله بر اساس منابع رسمی در زمان نگارش بررسی شده است. از آنجا که فریم ورک ها به صورت مداوم به روز می شوند، برای مشاهده آخرین نسخه باید صفحه رسمی هر پروژه را بررسی کنید.</p>
</blockquote>
<h2 dir="rtl" lang="fa">فریم ورک PHP چیست؟</h2>
<p dir="rtl" lang="fa">فریم ورک PHP مجموعه ای از کتابخانه ها، ابزارها، قواعد معماری و قابلیت های آماده است که فرآیند توسعه برنامه های تحت وب را سریع تر و منظم تر می کند.</p>
<p dir="rtl" lang="fa">بدون استفاده از فریم ورک، توسعه دهنده باید قابلیت هایی مانند مسیریابی، اعتبارسنجی اطلاعات، اتصال به پایگاه داده، مدیریت نشست، احراز هویت و کنترل امنیت را از ابتدا پیاده سازی کند. یک فریم ورک مناسب بخش قابل توجهی از این زیرساخت را در اختیار تیم توسعه قرار می دهد.</p>
<p dir="rtl" lang="fa">مهم ترین مزایای استفاده از فریم ورک PHP عبارت اند از:</p>
<ul dir="rtl" lang="fa">
<li>کاهش زمان توسعه پروژه</li>
<li>ایجاد ساختار منظم و قابل نگهداری</li>
<li>استفاده از قابلیت های امنیتی استاندارد</li>
<li>تسهیل همکاری میان اعضای تیم</li>
<li>کاهش کدهای تکراری</li>
<li>امکان توسعه و گسترش ساده تر پروژه</li>
<li>دسترسی به کتابخانه ها و بسته های آماده</li>
<li>ساده تر شدن آزمایش و رفع خطا</li>
</ul>
<p dir="rtl" lang="fa">با این حال، استفاده از فریم ورک به تنهایی کیفیت یک پروژه را تضمین نمی کند. معماری صحیح، تجربه تیم توسعه، کیفیت پایگاه داده، تنظیمات سرور و رعایت اصول امنیتی همچنان اهمیت زیادی دارند.</p>
<h2 dir="rtl" lang="fa">بهترین فریم ورک های PHP کدام اند؟</h2>
<p dir="rtl" lang="fa">در این مقایسه، 5 فریم ورک مطرح PHP بررسی شده اند:</p>
<ol lang="en">
<li>Laravel</li>
<li>Symfony</li>
<li>CodeIgniter</li>
<li>Yii</li>
<li>CakePHP</li>
</ol>
<p dir="rtl" lang="fa">این فریم ورک ها از نظر فلسفه طراحی و جامعه هدف با یکدیگر تفاوت دارند. برای مثال، Laravel بیشتر بر تجربه توسعه دهنده و سرعت ساخت محصول تمرکز دارد، در حالی که Symfony برای سامانه های بزرگ و معماری های سازمانی انتخاب بسیار قدرتمندی است.</p>
<p dir="rtl" lang="fa">CodeIgniter ساختاری سبک و ساده ارائه می دهد، Yii به عملکرد مناسب و ابزارهای تولید کد شناخته می شود و CakePHP نیز توسعه سریع بر پایه قراردادهای مشخص را دنبال می کند.</p>
<h2 dir="rtl" lang="fa">جدول مقایسه سریع بهترین فریم ورک های PHP</h2>
<div class="table-container">
<div class="table-scroll">
<table dir="rtl" lang="fa">
<thead>
<tr>
<th>فریم ورک</th>
<th>یادگیری</th>
<th>سرعت توسعه</th>
<th>عملکرد در پروژه سبک</th>
<th>امکانات داخلی</th>
<th>مناسب پروژه سازمانی</th>
<th>جامعه و اکوسیستم</th>
</tr>
</thead>
<tbody>
<tr>
<td lang="en">Laravel</td>
<td dir="rtl" lang="fa">آسان تا متوسط</td>
<td dir="rtl" lang="fa">بسیار بالا</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">بسیار کامل</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">بسیار گسترده</td>
</tr>
<tr>
<td lang="en">Symfony</td>
<td dir="rtl" lang="fa">متوسط تا دشوار</td>
<td dir="rtl" lang="fa">متوسط</td>
<td dir="rtl" lang="fa">متوسط</td>
<td dir="rtl" lang="fa">بسیار کامل</td>
<td dir="rtl" lang="fa">بسیار عالی</td>
<td dir="rtl" lang="fa">بسیار گسترده</td>
</tr>
<tr>
<td lang="en">CodeIgniter</td>
<td dir="rtl" lang="fa">آسان</td>
<td dir="rtl" lang="fa">بالا</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">متوسط</td>
<td dir="rtl" lang="fa">متوسط</td>
<td dir="rtl" lang="fa">مناسب</td>
</tr>
<tr>
<td lang="en">Yii</td>
<td dir="rtl" lang="fa">متوسط</td>
<td dir="rtl" lang="fa">بالا</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">کامل</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">مناسب</td>
</tr>
<tr>
<td lang="en">CakePHP</td>
<td dir="rtl" lang="fa">متوسط</td>
<td dir="rtl" lang="fa">بالا</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">کامل</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">مناسب</td>
</tr>
</tbody>
</table>
</div>
</div>
<p dir="rtl" lang="fa">این جدول یک ارزیابی کلی است. عملکرد واقعی هر فریم ورک به معماری پروژه، نسخه PHP، تنظیمات سرور، سیستم کش، پایگاه داده و کیفیت کد وابسته خواهد بود.</p>
<h2 dir="rtl" lang="fa">نمودار مقایسه کلی فریم ورک های PHP</h2>
<p dir="rtl" lang="fa">امتیازهای زیر از 10 محاسبه شده اند و ارزیابی تحلیلی مقاله محسوب می شوند. این امتیازها آمار رسمی پروژه ها نیستند، بلکه بر اساس امکانات، مستندات، سهولت توسعه، انعطاف پذیری و کاربرد در پروژه های واقعی ارائه شده اند.</p>
</div>
</div>
<div data-v-3d7837ba="">
<div class="q-card q-card--dark q-dark q-card--flat no-shadow canvas-block q-pa-md" data-v-6d507704="">
<div class="q-card__section q-card__section--vert content-wrapper" data-v-6d507704="">
<div class="canvas-content" dir="ltr" data-v-6d507704="">
<pre><code class="language-text">Laravel      9.2  █████████░
Symfony      8.9  █████████░
CodeIgniter  7.8  ████████░░
Yii          8.0  ████████░░
CakePHP      7.7  ████████░░
</code></pre>
</div>
</div>
</div>
</div>
<div data-v-3d7837ba="">
<div class="markdown-container" dir="ltr" data-v-1a76c2f2="" data-v-3d7837ba="" data-block-id="02dea45d-ddea-4655-b85f-f6c60ad8613e">
<div data-v-1a76c2f2="">
<p dir="rtl" lang="fa">Laravel در امتیاز کلی به دلیل اکوسیستم گسترده، منابع آموزشی فراوان و سرعت بالای توسعه در جایگاه اول قرار می گیرد. Symfony در پروژه های سازمانی و معماری های پیچیده عملکرد درخشانی دارد، اما یادگیری آن معمولا زمان بیشتری نیاز دارد.</p>
<h2 dir="rtl" lang="fa">1. Laravel؛ بهترین انتخاب عمومی برای توسعه وب</h2>
<p dir="rtl" lang="fa"><a href="https://laravel.com/" target="_blank" rel="nofollow noopener noreferrer">Laravel</a> یکی از محبوب ترین و کامل ترین فریم ورک های PHP است. ساختار منظم، مستندات مناسب، ابزارهای توسعه متنوع و جامعه بزرگ باعث شده اند Laravel در بسیاری از پروژه های جدید PHP به گزینه اول تیم های توسعه تبدیل شود.</p>
<p dir="rtl" lang="fa">این فریم ورک از معماری MVC استفاده می کند و قابلیت هایی مانند مسیریابی، احراز هویت، صف پردازش، ارسال اعلان، مدیریت کش، زمان بندی وظایف و کار با پایگاه داده را در اختیار توسعه دهنده قرار می دهد.</p>
<h3 dir="rtl" lang="fa">مهم ترین امکانات Laravel</h3>
<ul dir="rtl" lang="fa">
<li>ORM قدرتمند Eloquent</li>
<li>موتور قالب Blade</li>
<li>سیستم مسیریابی ساده و انعطاف پذیر</li>
<li>ابزار خط فرمان Artisan</li>
<li>پشتیبانی از Queue و پردازش پس زمینه</li>
<li>سیستم Migration برای مدیریت ساختار پایگاه داده</li>
<li>قابلیت ساخت API و احراز هویت کاربران</li>
<li>پشتیبانی مناسب از تست نویسی</li>
<li>اکوسیستم گسترده برای توسعه و استقرار</li>
</ul>
<p dir="rtl" lang="fa">ابزارها و محصولات جانبی مانند Horizon، Sanctum، Passport، Scout و Octane نیز برای حل نیازهای متداول پروژه های حرفه ای در دسترس هستند.</p>
<h3 dir="rtl" lang="fa">مزایای Laravel</h3>
<p dir="rtl" lang="fa">Laravel سرعت ساخت نمونه اولیه و محصول نهایی را افزایش می دهد. ساختار کدنویسی خوانا و وجود بسته های متعدد باعث می شود تیم توسعه برای قابلیت های رایج مجبور به پیاده سازی همه چیز از ابتدا نباشد.</p>
<p dir="rtl" lang="fa">این فریم ورک برای استارتاپ ها، فروشگاه های اینترنتی، پنل های مدیریتی، سامانه های رزرو، پلتفرم های خدماتی و API اپلیکیشن های موبایل گزینه مناسبی است.</p>
<h3 dir="rtl" lang="fa">معایب Laravel</h3>
<ul dir="rtl" lang="fa">
<li>مصرف منابع آن از فریم ورک های بسیار سبک بیشتر است.</li>
<li>قابلیت های متعدد می توانند برای یک پروژه ساده اضافی باشند.</li>
<li>استفاده نادرست از Eloquent ممکن است تعداد Queryها را افزایش دهد.</li>
<li>بهینه سازی پروژه های پرترافیک به تجربه فنی نیاز دارد.</li>
<li>نسخه های اصلی دارای چرخه پشتیبانی مشخص هستند و باید ارتقاها برنامه ریزی شوند.</li>
</ul>
<p dir="rtl" lang="fa">اطلاعات آخرین نسخه، تغییرات و نیازمندی های فنی Laravel را می توان در <a href="https://laravel.com/docs" target="_blank" rel="nofollow noopener noreferrer">مستندات رسمی Laravel</a> بررسی کرد.</p>
<h3 dir="rtl" lang="fa">Laravel برای چه پروژه هایی مناسب است؟</h3>
<p dir="rtl" lang="fa">Laravel انتخاب مناسبی برای پروژه هایی است که باید در زمان منطقی توسعه پیدا کنند و در آینده نیز قابل گسترش باشند. این فریم ورک برای بیشتر پروژه های تجاری کوچک تا بزرگ پاسخ مناسبی ارائه می دهد.</p>
<h2 dir="rtl" lang="fa">2. Symfony؛ گزینه قدرتمند برای سامانه های سازمانی</h2>
<p dir="rtl" lang="fa"><a href="https://symfony.com/" target="_blank" rel="nofollow noopener noreferrer">Symfony</a> هم یک فریم ورک کامل PHP و هم مجموعه ای از کامپوننت های مستقل و قابل استفاده مجدد است. بسیاری از پروژه ها و ابزارهای PHP، از جمله بخش هایی از Laravel، از کامپوننت های Symfony استفاده می کنند.</p>
<p dir="rtl" lang="fa">Symfony انعطاف پذیری بالایی دارد و به تیم توسعه اجازه می دهد معماری پروژه را با کنترل بیشتری طراحی کند. این ویژگی آن را برای سامانه های سازمانی، محصولات دارای منطق پیچیده و پروژه های بلند مدت مناسب می کند.</p>
<h3 dir="rtl" lang="fa">مهم ترین امکانات Symfony</h3>
<ul dir="rtl" lang="fa">
<li>مجموعه گسترده ای از کامپوننت های مستقل</li>
<li>سیستم Dependency Injection حرفه ای</li>
<li>پشتیبانی مناسب از معماری ماژولار</li>
<li>ابزارهای امنیتی قابل تنظیم</li>
<li>سیستم کش و مدیریت رویدادها</li>
<li>یکپارچگی مناسب با Doctrine ORM</li>
<li>ابزارهای تست و اشکال زدایی</li>
<li>پشتیبانی از Console Commands</li>
<li>نسخه های LTS با پشتیبانی بلند مدت</li>
</ul>
<p dir="rtl" lang="fa">براساس <a href="https://symfony.com/releases" target="_blank" rel="nofollow noopener noreferrer">صفحه رسمی انتشارهای Symfony</a>، این فریم ورک نسخه های استاندارد و LTS دارد. نسخه های LTS برای سازمان هایی اهمیت دارند که به ثبات، دریافت اصلاحات امنیتی و برنامه ارتقای قابل پیش بینی نیاز دارند.</p>
<h3 dir="rtl" lang="fa">مزایای Symfony</h3>
<p dir="rtl" lang="fa">Symfony آزادی عمل زیادی در طراحی معماری پروژه ایجاد می کند. کامپوننت های آن را می توان به صورت مستقل نیز در پروژه های مختلف به کار برد.</p>
<p dir="rtl" lang="fa">استانداردهای کدنویسی دقیق، قابلیت تست مناسب و ساختار ماژولار باعث می شوند Symfony برای تیم های بزرگ و پروژه هایی با عمر طولانی مناسب باشد.</p>
<h3 dir="rtl" lang="fa">معایب Symfony</h3>
<ul dir="rtl" lang="fa">
<li>منحنی یادگیری آن از Laravel و CodeIgniter بیشتر است.</li>
<li>راه اندازی اولیه بعضی پروژه ها زمان بیشتری نیاز دارد.</li>
<li>توسعه دهنده باید با مفاهیم معماری نرم افزار آشنایی مناسبی داشته باشد.</li>
<li>ممکن است برای وب سایت های بسیار ساده بیش از حد پیچیده باشد.</li>
</ul>
<h3 dir="rtl" lang="fa">Symfony برای چه پروژه هایی مناسب است؟</h3>
<p dir="rtl" lang="fa">Symfony برای سامانه های مالی، نرم افزارهای سازمانی، پلتفرم های چند بخشی، سیستم های دارای قوانین تجاری پیچیده و پروژه هایی که نگهداری بلند مدت در آنها اهمیت دارد، گزینه ای قدرتمند است.</p>
<h2 dir="rtl" lang="fa">3. CodeIgniter؛ فریم ورک سبک و سریع PHP</h2>
<p dir="rtl" lang="fa"><a href="https://codeigniter.com/" target="_blank" rel="nofollow noopener noreferrer">CodeIgniter</a> یک فریم ورک سبک PHP است که به دلیل راه اندازی ساده، حجم کم و انعطاف پذیری مناسب شناخته می شود. توسعه دهنده می تواند بدون درگیر شدن با تنظیمات پیچیده، پروژه را در مدت کوتاهی آغاز کند.</p>
<p dir="rtl" lang="fa">CodeIgniter محدودیت های معماری کمتری نسبت به بعضی فریم ورک های بزرگ دارد. این ویژگی برای توسعه دهندگان باتجربه مفید است، اما در تیم های بزرگ باید قواعد کدنویسی مشخصی تعریف شود تا ساختار پروژه نامنظم نشود.</p>
<h3 dir="rtl" lang="fa">مهم ترین امکانات CodeIgniter</h3>
<ul dir="rtl" lang="fa">
<li>ساختار سبک و راه اندازی سریع</li>
<li>سیستم مسیریابی</li>
<li>Query Builder برای کار با پایگاه داده</li>
<li>اعتبارسنجی فرم ها</li>
<li>مدیریت نشست و کش</li>
<li>ابزارهای امنیتی پایه</li>
<li>پشتیبانی از دستورات خط فرمان</li>
<li>ساختار مناسب برای توسعه API</li>
<li>مستندات قابل فهم</li>
</ul>
<p dir="rtl" lang="fa">برای بررسی آخرین قابلیت ها و الزامات اجرا می توان به <a href="https://codeigniter4.github.io/userguide/" target="_blank" rel="nofollow noopener noreferrer">مستندات رسمی CodeIgniter 4</a> مراجعه کرد.</p>
<h3 dir="rtl" lang="fa">مزایای CodeIgniter</h3>
<ul dir="rtl" lang="fa">
<li>یادگیری نسبتا آسان</li>
<li>عملکرد مناسب در پروژه های سبک</li>
<li>تنظیمات اولیه محدود</li>
<li>آزادی عمل بیشتر در طراحی ساختار</li>
<li>مناسب برای سرورهایی با منابع محدود</li>
<li>امکان انتقال ساده تر پروژه های PHP قدیمی</li>
</ul>
<h3 dir="rtl" lang="fa">معایب CodeIgniter</h3>
<ul dir="rtl" lang="fa">
<li>اکوسیستم آن به گستردگی Laravel نیست.</li>
<li>برای پروژه های بزرگ به تعریف معماری دقیق نیاز دارد.</li>
<li>بعضی ابزارهای پیشرفته باید به صورت جداگانه اضافه شوند.</li>
<li>آزادی عمل زیاد ممکن است در تیم های کم تجربه به کد نامنظم منجر شود.</li>
</ul>
<h3 dir="rtl" lang="fa">CodeIgniter برای چه پروژه هایی مناسب است؟</h3>
<p dir="rtl" lang="fa">این فریم ورک برای وب سایت های شرکتی، پنل های سبک، APIهای ساده، پروژه های کوچک و نرم افزارهایی که مصرف منابع در آنها مهم است، انتخاب مناسبی محسوب می شود.</p>
<h2 dir="rtl" lang="fa">4. Yii؛ عملکرد مناسب همراه با ابزارهای توسعه سریع</h2>
<p dir="rtl" lang="fa"><a href="https://www.yiiframework.com/" target="_blank" rel="nofollow noopener noreferrer">Yii</a> یک فریم ورک متن باز PHP است که بر عملکرد، توسعه سریع و استفاده مجدد از کد تمرکز دارد. ابزار Gii در Yii می تواند مدل ها، کنترلرها، فرم ها و بخش هایی از عملیات CRUD را تولید کند.</p>
<p dir="rtl" lang="fa">این قابلیت برای پروژه هایی که دارای فرم ها، جداول و عملیات مدیریتی متعدد هستند، زمان توسعه را کاهش می دهد.</p>
<h3 dir="rtl" lang="fa">مهم ترین امکانات Yii</h3>
<ul dir="rtl" lang="fa">
<li>ابزار تولید کد Gii</li>
<li>پشتیبانی از Active Record</li>
<li>سیستم کش چند لایه</li>
<li>اعتبارسنجی ورودی ها</li>
<li>کنترل دسترسی مبتنی بر نقش</li>
<li>پشتیبانی از REST API</li>
<li>سیستم Widget</li>
<li>ابزارهای امنیتی داخلی</li>
<li>امکان توسعه ماژولار</li>
</ul>
<h3 dir="rtl" lang="fa">مزایای Yii</h3>
<ul dir="rtl" lang="fa">
<li>عملکرد مناسب در بسیاری از پروژه ها</li>
<li>تولید سریع بخش های تکراری</li>
<li>امکانات کامل برای مدیریت پایگاه داده</li>
<li>سیستم کش قابل تنظیم</li>
<li>مناسب برای پنل های مدیریتی و سامانه های داده محور</li>
</ul>
<h3 dir="rtl" lang="fa">معایب Yii</h3>
<ul dir="rtl" lang="fa">
<li>منابع آموزشی فارسی و انگلیسی آن از Laravel کمتر است.</li>
<li>بازار کار آن در بسیاری از مناطق محدودتر است.</li>
<li>برخی الگوها و تنظیمات آن به یادگیری اولیه نیاز دارند.</li>
<li>انتخاب میان نسل ها و نسخه های مختلف Yii باید با دقت انجام شود.</li>
</ul>
<h3 dir="rtl" lang="fa">Yii برای چه پروژه هایی مناسب است؟</h3>
<p dir="rtl" lang="fa">Yii برای سامانه های مدیریتی، داشبوردهای آماری، پرتال ها، نرم افزارهای دارای عملیات CRUD گسترده و پروژه هایی که سرعت توسعه بخش مدیریت اهمیت دارد، مناسب است.</p>
<p dir="rtl" lang="fa">آخرین مستندات و وضعیت نسخه های این فریم ورک در <a href="https://www.yiiframework.com/doc/guide" target="_blank" rel="nofollow noopener noreferrer">وب سایت رسمی Yii</a> منتشر می شود.</p>
<h2 dir="rtl" lang="fa">5. CakePHP؛ توسعه سریع بر اساس قراردادها</h2>
<p dir="rtl" lang="fa"><a href="https://cakephp.org/" target="_blank" rel="nofollow noopener noreferrer">CakePHP</a> یکی از فریم ورک های قدیمی و شناخته شده PHP است. فلسفه اصلی آن Convention over Configuration است؛ یعنی توسعه دهنده با رعایت قراردادهای تعیین شده می تواند بدون انجام تنظیمات فراوان، بخش های مختلف پروژه را ایجاد کند.</p>
<p dir="rtl" lang="fa">CakePHP ابزارهای مناسبی برای مدل سازی داده، اعتبارسنجی، احراز هویت، مسیریابی و ساخت سریع عملیات مدیریتی دارد.</p>
<h3 dir="rtl" lang="fa">مهم ترین امکانات CakePHP</h3>
<ul dir="rtl" lang="fa">
<li>ORM داخلی</li>
<li>ابزار Bake برای تولید کد</li>
<li>سیستم اعتبارسنجی</li>
<li>قابلیت های احراز هویت و مجوزدهی</li>
<li>سیستم مسیریابی</li>
<li>پشتیبانی از Migration</li>
<li>ابزارهای تست</li>
<li>ساختار مبتنی بر MVC</li>
<li>قراردادهای مشخص برای توسعه منظم</li>
</ul>
<h3 dir="rtl" lang="fa">مزایای CakePHP</h3>
<ul dir="rtl" lang="fa">
<li>توسعه سریع قابلیت های متداول</li>
<li>ساختار منظم و قابل پیش بینی</li>
<li>کاهش تنظیمات تکراری</li>
<li>مستندات مناسب</li>
<li>ابزارهای کاربردی برای تولید کد</li>
</ul>
<h3 dir="rtl" lang="fa">معایب CakePHP</h3>
<ul dir="rtl" lang="fa">
<li>جامعه کاربری آن از Laravel کوچک تر است.</li>
<li>قراردادهای فریم ورک می توانند آزادی توسعه دهنده را محدود کنند.</li>
<li>تعداد فرصت های شغلی و منابع آموزشی آن در برخی بازارها کمتر است.</li>
<li>مهاجرت پروژه هایی که قراردادهای فریم ورک را رعایت نکرده اند، دشوار می شود.</li>
</ul>
<h3 dir="rtl" lang="fa">CakePHP برای چه پروژه هایی مناسب است؟</h3>
<p dir="rtl" lang="fa">CakePHP برای نرم افزارهای تجاری، پنل های مدیریتی، سامانه های مبتنی بر فرم و پروژه هایی که از الگوهای استاندارد پیروی می کنند، انتخاب قابل قبولی است.</p>
<p dir="rtl" lang="fa">جزئیات نسخه های پایدار و نیازمندی های اجرا در <a href="https://book.cakephp.org/" target="_blank" rel="nofollow noopener noreferrer">مستندات رسمی CakePHP</a> در دسترس قرار دارد.</p>
<h2 dir="rtl" lang="fa">مقایسه امکانات فنی 5 فریم ورک PHP</h2>
<div class="table-container">
<div class="table-scroll">
<table dir="rtl" lang="fa">
<thead>
<tr>
<th>قابلیت</th>
<th>Laravel</th>
<th>Symfony</th>
<th>CodeIgniter</th>
<th>Yii</th>
<th>CakePHP</th>
</tr>
</thead>
<tbody>
<tr>
<td dir="rtl" lang="fa">معماری MVC</td>
<td dir="rtl" lang="fa">دارد</td>
<td dir="rtl" lang="fa">دارد</td>
<td dir="rtl" lang="fa">دارد</td>
<td dir="rtl" lang="fa">دارد</td>
<td dir="rtl" lang="fa">دارد</td>
</tr>
<tr>
<td dir="rtl" lang="fa">ORM داخلی یا پیشنهادی</td>
<td lang="en">Eloquent</td>
<td lang="en">Doctrine</td>
<td lang="en">Model و Query Builder</td>
<td lang="en">Active Record</td>
<td lang="en">CakePHP ORM</td>
</tr>
<tr>
<td dir="rtl" lang="fa">ابزار خط فرمان</td>
<td lang="en">Artisan</td>
<td lang="en">Console</td>
<td lang="en">Spark</td>
<td lang="en">Yii Console</td>
<td lang="en">Cake</td>
</tr>
<tr>
<td dir="rtl" lang="fa">تولید خودکار کد</td>
<td dir="rtl" lang="fa">متوسط</td>
<td dir="rtl" lang="fa">قابل توسعه</td>
<td dir="rtl" lang="fa">محدود</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
</tr>
<tr>
<td dir="rtl" lang="fa">پشتیبانی از Queue</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">نیازمند تنظیم بیشتر</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">قابل توسعه</td>
</tr>
<tr>
<td dir="rtl" lang="fa">ساخت REST API</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">خوب</td>
</tr>
<tr>
<td dir="rtl" lang="fa">احراز هویت</td>
<td dir="rtl" lang="fa">کامل</td>
<td dir="rtl" lang="fa">بسیار انعطاف پذیر</td>
<td dir="rtl" lang="fa">پایه تا متوسط</td>
<td dir="rtl" lang="fa">کامل</td>
<td dir="rtl" lang="fa">کامل</td>
</tr>
<tr>
<td dir="rtl" lang="fa">تست نویسی</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">بسیار خوب</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">خوب</td>
</tr>
<tr>
<td dir="rtl" lang="fa">نسخه LTS</td>
<td dir="rtl" lang="fa">براساس چرخه انتشار</td>
<td dir="rtl" lang="fa">دارد</td>
<td dir="rtl" lang="fa">وابسته به نسخه</td>
<td dir="rtl" lang="fa">وابسته به شاخه</td>
<td dir="rtl" lang="fa">وابسته به نسخه</td>
</tr>
<tr>
<td dir="rtl" lang="fa">مناسب معماری پیچیده</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">بسیار عالی</td>
<td dir="rtl" lang="fa">متوسط</td>
<td dir="rtl" lang="fa">خوب</td>
<td dir="rtl" lang="fa">خوب</td>
</tr>
</tbody>
</table>
</div>
</div>
<h2 dir="rtl" lang="fa">نمودار سرعت یادگیری و توسعه</h2>
<p dir="rtl" lang="fa">امتیاز بیشتر به معنای شروع ساده تر و رسیدن سریع تر به خروجی اولیه است.</p>
<pre><code class="hljs">Laravel      9/10  █████████░
CodeIgniter  9/10  █████████░
CakePHP      8/10  ████████░░
Yii          7/10  ███████░░░
Symfony      6/10  ██████░░░░
</code></pre>
<p dir="rtl" lang="fa">Laravel به دلیل مستندات منظم، آموزش های متعدد و ابزارهای آماده، مسیر شروع مناسبی دارد. CodeIgniter نیز به دلیل ساختار سبک و تنظیمات محدود، برای توسعه دهندگان تازه وارد قابل فهم است.</p>
<p dir="rtl" lang="fa">امتیاز پایین تر Symfony به معنای ضعف این فریم ورک نیست. Symfony مفاهیم و قابلیت های پیشرفته تری دارد و برای استفاده صحیح از آنها باید زمان بیشتری صرف یادگیری شود.</p>
<h2 dir="rtl" lang="fa">نمودار تناسب با پروژه های سازمانی</h2>
<pre><code class="hljs">Symfony      10/10 ██████████
Laravel       9/10 █████████░
Yii           8/10 ████████░░
CakePHP       7/10 ███████░░░
CodeIgniter   6/10 ██████░░░░
</code></pre>
<p dir="rtl" lang="fa">Symfony به دلیل معماری ماژولار، کامپوننت های مستقل، نسخه های LTS و کنترل دقیق بر سرویس ها، در پروژه های سازمانی امتیاز بالایی دریافت می کند.</p>
<p dir="rtl" lang="fa">Laravel نیز می تواند در پروژه های بزرگ استفاده شود، اما معماری نرم افزار باید از ابتدا برای رشد محصول طراحی شده باشد. انتخاب Laravel به تنهایی مانع ایجاد مشکلات مقیاس پذیری یا نگهداری نخواهد شد.</p>
<h2 dir="rtl" lang="fa">نمودار امکانات آماده و اکوسیستم</h2>
<pre><code class="hljs">Laravel      10/10 ██████████
Symfony      10/10 ██████████
Yii           8/10 ████████░░
CakePHP       8/10 ████████░░
CodeIgniter   7/10 ███████░░░
</code></pre>
<p dir="rtl" lang="fa">Laravel یک اکوسیستم یکپارچه برای صف، کش، جستجو، احراز هویت و مانیتورینگ دارد. Symfony نیز مجموعه بسیار بزرگی از کامپوننت های استاندارد ارائه می دهد که در بسیاری از پروژه های PHP استفاده می شوند.</p>
<h2 dir="rtl" lang="fa">آمار رسمی را از کجا بررسی کنیم؟</h2>
<p dir="rtl" lang="fa">برای ارزیابی محبوبیت فریم ورک ها باید از منابع قابل استناد استفاده کرد. تعداد ستاره های GitHub و دانلودهای Packagist به صورت مداوم تغییر می کنند؛ بنابراین ثبت یک عدد ثابت بدون تاریخ، ممکن است خیلی زود اعتبار خود را از دست بدهد.</p>
<p dir="rtl" lang="fa">آمار زنده هر پروژه را می توان از منابع زیر مشاهده کرد:</p>
<div class="table-container">
<div class="table-scroll">
<table dir="rtl" lang="fa">
<thead>
<tr>
<th>فریم ورک</th>
<th>مخزن رسمی</th>
<th>بسته رسمی</th>
</tr>
</thead>
<tbody>
<tr>
<td lang="en">Laravel</td>
<td lang="en"><a href="https://github.com/laravel/framework" target="_blank" rel="nofollow noopener noreferrer">GitHub Laravel</a></td>
<td lang="en"><a href="https://packagist.org/packages/laravel/framework" target="_blank" rel="nofollow noopener noreferrer">Packagist Laravel</a></td>
</tr>
<tr>
<td lang="en">Symfony</td>
<td lang="en"><a href="https://github.com/symfony/symfony" target="_blank" rel="nofollow noopener noreferrer">GitHub Symfony</a></td>
<td lang="en"><a href="https://packagist.org/packages/symfony/symfony" target="_blank" rel="nofollow noopener noreferrer">Packagist Symfony</a></td>
</tr>
<tr>
<td lang="en">CodeIgniter</td>
<td lang="en"><a href="https://github.com/codeigniter4/CodeIgniter4" target="_blank" rel="nofollow noopener noreferrer">GitHub CodeIgniter</a></td>
<td lang="en"><a href="https://packagist.org/packages/codeigniter4/framework" target="_blank" rel="nofollow noopener noreferrer">Packagist CodeIgniter</a></td>
</tr>
<tr>
<td lang="en">Yii</td>
<td lang="en"><a href="https://github.com/yiisoft/yii2" target="_blank" rel="nofollow noopener noreferrer">GitHub Yii</a></td>
<td lang="en"><a href="https://packagist.org/packages/yiisoft/yii2" target="_blank" rel="nofollow noopener noreferrer">Packagist Yii</a></td>
</tr>
<tr>
<td lang="en">CakePHP</td>
<td lang="en"><a href="https://github.com/cakephp/cakephp" target="_blank" rel="nofollow noopener noreferrer">GitHub CakePHP</a></td>
<td lang="en"><a href="https://packagist.org/packages/cakephp/cakephp" target="_blank" rel="nofollow noopener noreferrer">Packagist CakePHP</a></td>
</tr>
</tbody>
</table>
</div>
</div>
<p dir="rtl" lang="fa">تعداد دانلود بسته لزوما برابر با تعداد پروژه های فعال نیست. نصب های خودکار در سرورهای CI، به روز رسانی وابستگی ها، محیط های آزمایشی و نصب چندباره یک بسته نیز در این آمار تاثیر دارند. ستاره GitHub نیز بیشتر نشان دهنده توجه جامعه است و نمی توان آن را معیار قطعی کیفیت یا سهم بازار دانست.</p>
<h2 dir="rtl" lang="fa">مقایسه عملکرد و سرعت فریم ورک های PHP</h2>
<p dir="rtl" lang="fa">نمی توان یک فریم ورک را در تمام شرایط سریع ترین گزینه معرفی کرد. نتیجه بنچمارک ها به عوامل متعددی وابسته است:</p>
<ul dir="rtl" lang="fa">
<li>نسخه PHP</li>
<li>فعال بودن OPcache</li>
<li>نوع وب سرور</li>
<li>تنظیمات پایگاه داده</li>
<li>تعداد Middlewareها</li>
<li>ساختار Queryها</li>
<li>نحوه استفاده از ORM</li>
<li>تنظیمات Cache</li>
<li>حالت Development یا Production</li>
<li>سخت افزار و سیستم عامل</li>
</ul>
<p dir="rtl" lang="fa">CodeIgniter به دلیل هسته سبک معمولا سربار اولیه کمتری دارد. با این حال، در یک پروژه واقعی ممکن است Laravel یا Symfony با معماری درست، کش مناسب و پردازش پس زمینه عملکرد بهتری از یک پروژه CodeIgniter با کد ضعیف داشته باشند.</p>
<p dir="rtl" lang="fa">برای سایت های پرترافیک، انتخاب فریم ورک باید در کنار طراحی زیرساخت، CDN، کش سمت سرور، بهینه سازی پایگاه داده، Queue و مانیتورینگ انجام شود. مطالب آموزشی و تحلیلی مرتبط با توسعه نرم افزار را نیز می توانید در <a href="https://tarahanenovin.ir/blog" target="_blank" rel="nofollow noopener noreferrer">وبلاگ طراحان نوین</a> مطالعه کنید.</p>
<h2 dir="rtl" lang="fa">مقایسه امنیت فریم ورک های PHP</h2>
<p dir="rtl" lang="fa">هر 5 فریم ورک امکاناتی برای کاهش آسیب پذیری های متداول وب دارند، اما امنیت نهایی به نحوه پیاده سازی بستگی دارد.</p>
<p dir="rtl" lang="fa">قابلیت های امنیتی مهم در یک فریم ورک شامل موارد زیر هستند:</p>
<ul dir="rtl" lang="fa">
<li>محافظت در برابر CSRF</li>
<li>جلوگیری از SQL Injection</li>
<li>پاک سازی و اعتبارسنجی ورودی</li>
<li>مدیریت امن نشست</li>
<li>هش کردن رمز عبور</li>
<li>کنترل دسترسی کاربران</li>
<li>مدیریت Cookie</li>
<li>جلوگیری از XSS</li>
<li>مدیریت صحیح خطاها</li>
<li>دریافت به روز رسانی های امنیتی</li>
</ul>
<p dir="rtl" lang="fa">Laravel و Symfony ابزارهای امنیتی گسترده و قابل تنظیمی دارند. Yii و CakePHP نیز امکانات مناسبی برای اعتبارسنجی و کنترل دسترسی ارائه می دهند. CodeIgniter قابلیت های امنیتی لازم را فراهم می کند، اما در پروژه های پیچیده ممکن است به طراحی و بسته های تکمیلی بیشتری نیاز باشد.</p>
<p dir="rtl" lang="fa">صرف نظر از فریم ورک انتخاب شده، استفاده از نسخه های پشتیبانی شده PHP و به روز نگه داشتن Composer Packages ضروری است. پایگاه داده، سرور، سیستم عامل و کتابخانه های جانبی نیز باید به صورت منظم به روز شوند.</p>
<h2 dir="rtl" lang="fa">Laravel بهتر است یا Symfony؟</h2>
<p dir="rtl" lang="fa">برای بسیاری از پروژه ها، پاسخ این پرسش به ساختار تیم و نوع محصول وابسته است.</p>
<p dir="rtl" lang="fa">Laravel زمانی انتخاب مناسب تری است که:</p>
<ul dir="rtl" lang="fa">
<li>سرعت توسعه اهمیت زیادی دارد.</li>
<li>تیم به ابزارهای آماده نیاز دارد.</li>
<li>پروژه یک محصول استارتاپی یا تجاری است.</li>
<li>دسترسی به نیروی متخصص و منابع آموزشی مهم است.</li>
<li>قرار است API، پنل مدیریت یا فروشگاه اختصاصی ساخته شود.</li>
</ul>
<p dir="rtl" lang="fa">Symfony زمانی انتخاب مناسب تری است که:</p>
<ul dir="rtl" lang="fa">
<li>پروژه دارای منطق تجاری بسیار پیچیده است.</li>
<li>معماری ماژولار و کنترل دقیق اهمیت دارد.</li>
<li>محصول باید برای مدت طولانی نگهداری شود.</li>
<li>تیم توسعه تجربه کافی در معماری نرم افزار دارد.</li>
<li>نسخه LTS و برنامه پشتیبانی بلند مدت اهمیت زیادی دارد.</li>
</ul>
<p dir="rtl" lang="fa">Laravel بخشی از زیرساخت خود را با استفاده از کامپوننت های Symfony ایجاد کرده است. بنابراین این دو فریم ورک فقط رقیب نیستند و در سطح اکوسیستم PHP ارتباط نزدیکی با یکدیگر دارند.</p>
<h2 dir="rtl" lang="fa">Laravel بهتر است یا CodeIgniter؟</h2>
<p dir="rtl" lang="fa">Laravel امکانات داخلی و اکوسیستم گسترده تری دارد، اما CodeIgniter سبک تر است و تنظیمات اولیه کمتری نیاز دارد.</p>
<p dir="rtl" lang="fa">برای یک سامانه فروشگاهی، پلتفرم خدماتی یا محصول قابل گسترش، Laravel معمولا انتخاب کامل تری است. برای یک وب سایت سبک، API ساده یا پروژه ای با منابع محدود، CodeIgniter می تواند گزینه منطقی تری باشد.</p>
<p dir="rtl" lang="fa">تیم توسعه باید هزینه نگهداری آینده را نیز در نظر بگیرد. انتخاب فریم ورک سبک در شروع پروژه همیشه به معنای هزینه کمتر در مراحل بعدی نیست.</p>
<h2 dir="rtl" lang="fa">بهترین فریم ورک PHP برای فروشگاه اینترنتی</h2>
<p dir="rtl" lang="fa">برای ساخت فروشگاه اینترنتی اختصاصی، Laravel در بیشتر موارد انتخاب مناسبی است. سیستم احراز هویت، Queue، اعلان ها، مدیریت فایل، کش و بسته های متعدد آن می توانند فرآیند توسعه فروشگاه را سریع تر کنند.</p>
<p dir="rtl" lang="fa">در فروشگاه های بسیار بزرگ یا سامانه های تجارت الکترونیک دارای چند سرویس، Symfony نیز گزینه قدرتمندی است. البته موفقیت فروشگاه فقط به فریم ورک وابسته نیست. معماری پرداخت، مدیریت موجودی، امنیت حساب کاربران، سرعت صفحات، سئو فنی و زیرساخت سرور نیز اهمیت زیادی دارند.</p>
<h2 dir="rtl" lang="fa">بهترین فریم ورک PHP برای ساخت API</h2>
<p dir="rtl" lang="fa">Laravel و Symfony هر دو برای ساخت APIهای حرفه ای مناسب هستند.</p>
<p dir="rtl" lang="fa">Laravel برای توسعه سریع API، احراز هویت و اتصال به اپلیکیشن اندروید یا iOS ابزارهای مناسبی دارد. Symfony نیز برای APIهای پیچیده، معماری سرویس گرا و پروژه هایی که کنترل دقیق روی اجزا نیاز دارند، انتخاب قدرتمندی است.</p>
<p dir="rtl" lang="fa">Yii برای APIهای داده محور و CodeIgniter برای APIهای سبک نیز گزینه های قابل استفاده ای هستند.</p>
<h2 dir="rtl" lang="fa">بهترین فریم ورک PHP برای استارتاپ</h2>
<p dir="rtl" lang="fa">استارتاپ ها معمولا به عرضه سریع نسخه اولیه، امکان تغییر محصول و دسترسی آسان به توسعه دهنده نیاز دارند. Laravel در این شرایط تعادل مناسبی میان سرعت توسعه، امکانات و توسعه پذیری ایجاد می کند.</p>
<p dir="rtl" lang="fa">با این حال، اگر محصول دارای منطق سازمانی پیچیده باشد یا از ابتدا برای یک ساختار بسیار بزرگ طراحی شود، Symfony نیز باید بررسی شود. برای نمونه اولیه بسیار کوچک، CodeIgniter می تواند هزینه و پیچیدگی اولیه را کاهش دهد.</p>
<h2 dir="rtl" lang="fa">کدام فریم ورک PHP را انتخاب کنیم؟</h2>
<p dir="rtl" lang="fa">انتخاب نهایی باید براساس نیاز پروژه انجام شود:</p>
<div class="table-container">
<div class="table-scroll">
<table dir="rtl" lang="fa">
<thead>
<tr>
<th>نوع پروژه</th>
<th>پیشنهاد اصلی</th>
<th>گزینه جایگزین</th>
</tr>
</thead>
<tbody>
<tr>
<td dir="rtl" lang="fa">استارتاپ و MVP</td>
<td lang="en">Laravel</td>
<td lang="en">CodeIgniter</td>
</tr>
<tr>
<td dir="rtl" lang="fa">فروشگاه اینترنتی اختصاصی</td>
<td lang="en">Laravel</td>
<td lang="en">Symfony</td>
</tr>
<tr>
<td dir="rtl" lang="fa">سامانه سازمانی بزرگ</td>
<td lang="en">Symfony</td>
<td lang="en">Laravel</td>
</tr>
<tr>
<td dir="rtl" lang="fa">API اپلیکیشن موبایل</td>
<td lang="en">Laravel</td>
<td lang="en">Symfony</td>
</tr>
<tr>
<td dir="rtl" lang="fa">سایت یا پنل سبک</td>
<td lang="en">CodeIgniter</td>
<td lang="en">Laravel</td>
</tr>
<tr>
<td dir="rtl" lang="fa">داشبورد داده محور</td>
<td lang="en">Yii</td>
<td lang="en">Laravel</td>
</tr>
<tr>
<td dir="rtl" lang="fa">نرم افزار مبتنی بر CRUD</td>
<td lang="en">CakePHP یا Yii</td>
<td lang="en">Laravel</td>
</tr>
<tr>
<td dir="rtl" lang="fa">پروژه بلند مدت با معماری پیچیده</td>
<td lang="en">Symfony</td>
<td lang="en">Laravel</td>
</tr>
</tbody>
</table>
</div>
</div>
<p dir="rtl" lang="fa">پیش از انتخاب بهتر است این پرسش ها پاسخ داده شوند:</p>
<ol dir="rtl" lang="fa">
<li>پروژه در سه سال آینده تا چه اندازه رشد می کند؟</li>
<li>تیم توسعه با کدام فریم ورک تجربه بیشتری دارد؟</li>
<li>آیا دسترسی به نیروی متخصص در آینده آسان است؟</li>
<li>پروژه به چه سطحی از امنیت و مقیاس پذیری نیاز دارد؟</li>
<li>چه مدت برای عرضه نسخه اولیه فرصت وجود دارد؟</li>
<li>آیا پروژه به Queue، WebSocket، جستجو یا پردازش سنگین نیاز دارد؟</li>
<li>هزینه نگهداری و ارتقای نسخه ها چقدر است؟</li>
</ol>
<h2 dir="rtl" lang="fa">جمع بندی مقایسه بهترین فریم ورک های PHP</h2>
<p dir="rtl" lang="fa">در مقایسه <strong>بهترین فریم ورک های PHP</strong> نمی توان یک گزینه را برای تمام پروژه ها برنده قطعی دانست. Laravel بهترین انتخاب عمومی برای بسیاری از محصولات تحت وب، فروشگاه های اختصاصی، APIها و استارتاپ ها است. Symfony در سامانه های سازمانی و پروژه های دارای معماری پیچیده برتری دارد.</p>
<p dir="rtl" lang="fa">CodeIgniter برای پروژه های سبک و توسعه سریع، Yii برای سامانه های داده محور و CakePHP برای توسعه مبتنی بر قراردادها گزینه های مناسبی هستند.</p>
<p dir="rtl" lang="fa">انتخاب صحیح زمانی انجام می شود که نیازهای فنی، بودجه، تجربه تیم، زمان توسعه و برنامه رشد کسب و کار در کنار یکدیگر بررسی شوند. محبوب ترین فریم ورک همیشه بهترین فریم ورک برای پروژه شما نیست.</p>
<p dir="rtl" lang="fa">اگر برای انتخاب فناوری، طراحی معماری یا توسعه یک وب سایت اختصاصی به مشاوره نیاز دارید، برای <strong>طراحی سایت و برنامه نویسی تحت وب توسط طراحان نوین</strong> از طریق <a href="https://tarahanenovin.ir/site/contact" target="_blank" rel="nofollow noopener noreferrer">صفحه تماس با ما</a> با تیم طراحان نوین در ارتباط باشید.</p>
</div>
</div>
</div>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d9%85%d9%82%d8%a7%db%8c%d8%b3%d9%87-5-%d8%aa%d8%a7-%d8%a7%d8%b2-%d8%a8%d9%87%d8%aa%d8%b1%db%8c%d9%86-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%d9%87%d8%a7%db%8c-php%d8%9b-%da%a9%d8%af%d8%a7%d9%85/">مقایسه 5 تا از بهترین فریم ورک های PHP؛ کدام گزینه برای پروژه شما مناسب است؟</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d9%85%d9%82%d8%a7%db%8c%d8%b3%d9%87-5-%d8%aa%d8%a7-%d8%a7%d8%b2-%d8%a8%d9%87%d8%aa%d8%b1%db%8c%d9%86-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%d9%87%d8%a7%db%8c-php%d8%9b-%da%a9%d8%af%d8%a7%d9%85/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>آموزش Docker از صفر تا اجرای پروژه واقعی با داکر</title>
		<link>https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-docker-%d8%a7%d8%b2-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%a7%d8%ac%d8%b1%d8%a7%db%8c-%d9%be%d8%b1%d9%88%da%98%d9%87-%d9%88%d8%a7%d9%82%d8%b9%db%8c-%d8%a8/</link>
					<comments>https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-docker-%d8%a7%d8%b2-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%a7%d8%ac%d8%b1%d8%a7%db%8c-%d9%be%d8%b1%d9%88%da%98%d9%87-%d9%88%d8%a7%d9%82%d8%b9%db%8c-%d8%a8/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[طراحی وب]]></category>
		<category><![CDATA[فرانت‌اند]]></category>
		<category><![CDATA[معرفی ابزار]]></category>
		<category><![CDATA[موبایل]]></category>
		<category><![CDATA[ویندوز]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[آموزش]]></category>
		<category><![CDATA[آموزش Docker]]></category>
		<category><![CDATA[آموزش داکر]]></category>
		<category><![CDATA[داکر]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=112</guid>

					<description><![CDATA[<p>آموزش داکر یکی از بهترین نقاط شروع برای توسعه دهندگانی است که می خواهند پروژه های خود را در محیطی استاندارد، قابل انتقال و مستقل اجرا کنند. Docker کمک می کند نرم افزار، کتابخانه ها و تنظیمات مورد نیاز آن را داخل یک بسته مشخص قرار دهید و همان بسته را روی سیستم شخصی، سرور یا زیرساخت ابری اجرا کنید. در این آموزش، ابتدا با مفاهیم اصلی Docker آشنا می شویم و سپس نصب داکر، ساخت Image، اجرای Container، مدیریت داده ها و استفاده از Docker Compose را به صورت مرحله به مرحله بررسی می کنیم. داکر چیست؟ داکر یک پلتفرم متن باز برای ساخت، بسته بندی، توزیع و اجرای نرم افزار در محیط هایی به نام Container است. هر Container شامل برنامه و وابستگی های مورد نیاز آن می شود و می تواند بدون وابستگی مستقیم به تنظیمات سیستم میزبان اجرا شود. برای مثال، فرض کنید یک برنامه تحت وب با Python، Node.js یا PHP توسعه داده اید. اجرای این برنامه ممکن است به نسخه مشخصی از زبان برنامه نویسی، پایگاه داده، وب سرور و چند کتابخانه نیاز داشته باشد. با Docker می توانید تمام این موارد را در قالب یک Image تعریف کنید تا اعضای تیم و سرور اصلی دقیقا از همان محیط استفاده کنند. برای مطالعه تعاریف و راهنماهای رسمی می توانید به مستندات Docker مراجعه کنید. چرا باید Docker را یاد بگیریم؟ مشکل معروف «روی سیستم من اجرا می شود» معمولا زمانی به وجود می آید که محیط توسعه با محیط آزمایش یا سرور اصلی تفاوت دارد. ممکن است نسخه زبان برنامه نویسی، کتابخانه ها، متغیرهای محیطی یا تنظیمات سیستم عامل یکسان نباشند. داکر این تفاوت ها را تا حد زیادی کاهش می دهد. مهم ترین مزایای استفاده از Docker عبارت هستند از: ایجاد محیط توسعه یکسان برای تمام اعضای تیم انتقال آسان نرم افزار میان سیستم شخصی، سرور و فضای ابری کاهش مشکلات مربوط به نسخه کتابخانه ها و وابستگی ها راه اندازی سریع محیط توسعه و آزمایش جداسازی سرویس های مختلف از یکدیگر استفاده بهتر از منابع در مقایسه با بسیاری از ماشین های مجازی ساده تر شدن فرآیند استقرار و انتشار نرم افزار امکان بازگشت سریع به نسخه قبلی برنامه یادگیری داکر برای توسعه دهندگان وب، برنامه نویسان بک اند، کارشناسان DevOps، مدیران سرور و تیم های توسعه نرم افزار کاربردی است. تفاوت Docker و ماشین مجازی چیست؟ ماشین مجازی یا Virtual Machine معمولا یک سیستم عامل کامل را همراه با برنامه ها اجرا می کند. هر ماشین مجازی به حافظه، پردازنده و فضای ذخیره سازی جداگانه نیاز دارد و راه اندازی آن ممکن است زمان بیشتری ببرد. Container برخلاف ماشین مجازی، معمولا از هسته سیستم عامل میزبان استفاده می کند. به همین دلیل سبک تر است، سریع تر اجرا می شود و منابع کمتری مصرف می کند. تفاوت های مهم این دو فناوری را می توان به شکل زیر خلاصه کرد: ویژگی Docker Container ماشین مجازی زمان راه اندازی معمولا چند ثانیه معمولا بیشتر مصرف منابع کمتر بیشتر سیستم عامل کامل ندارد دارد قابلیت انتقال بسیار مناسب مناسب جداسازی در سطح فرآیند در سطح سیستم عامل کاربرد رایج توسعه، آزمایش و استقرار سرویس اجرای سیستم عامل مستقل داکر همیشه جایگزین ماشین مجازی نیست. انتخاب میان این دو به سطح جداسازی، امنیت، نوع نرم افزار و معماری زیرساخت بستگی دارد. مفاهیم اصلی در آموزش داکر قبل از اجرای دستورات Docker باید با چند مفهوم پایه آشنا شوید. Docker Image چیست؟ Image یک الگوی فقط خواندنی است که فایل های برنامه، وابستگی ها، تنظیمات و دستور اجرای نرم افزار را در خود نگه می دارد. می توانید Image را مانند نقشه ساخت یک محیط اجرایی در نظر بگیرید. برای مثال، Image رسمی Nginx شامل فایل ها و تنظیمات لازم برای اجرای وب سرور Nginx است. Docker Container چیست؟ Container نمونه در حال اجرا یا متوقف شده یک Image است. از یک Image می توان چند Container مستقل ایجاد کرد. برای نمونه، امکان دارد سه Container از Image یک برنامه بسازید و هر کدام را روی پورت متفاوتی اجرا کنید. Dockerfile چیست؟ Dockerfile یک فایل متنی شامل دستوراتی است که Docker برای ساخت Image اجرا می کند. در این فایل می توانید Image پایه، مسیر کاری، فایل های پروژه، وابستگی ها و فرمان اجرای برنامه را مشخص کنید. Docker Registry چیست؟ Registry محلی برای ذخیره و توزیع Imageها است. Docker Hub یکی از شناخته شده ترین Registryهای عمومی محسوب می شود. سازمان ها نیز می توانند Registry خصوصی خود را راه اندازی کنند. Docker Volume چیست؟ اطلاعات داخل لایه قابل نوشتن Container با حذف Container از دسترس خارج می شوند. Volume برای نگهداری پایدار داده ها استفاده می شود و چرخه عمر آن از Container مستقل است. Volume به ویژه برای پایگاه داده، فایل های بارگذاری شده توسط کاربران و اطلاعاتی که نباید با حذف Container از بین بروند اهمیت دارد. Docker Network چیست؟ Network امکان ارتباط میان Containerها و همچنین ارتباط Container با شبکه بیرونی را فراهم می کند. در پروژه های چند سرویسه، برنامه می تواند از طریق نام سرویس به پایگاه داده یا سرویس های دیگر متصل شود. آموزش نصب Docker روش نصب Docker به سیستم عامل شما بستگی دارد. نصب Docker در ویندوز برای استفاده از Docker در ویندوز معمولا Docker Desktop نصب می شود. در نسخه های جدید ویندوز، استفاده از WSL 2 می تواند تجربه مناسب تری برای اجرای Containerهای لینوکسی فراهم کند. مراحل کلی عبارت هستند از: فعال کردن قابلیت مجازی سازی در BIOS یا UEFI نصب و فعال سازی WSL 2 در صورت نیاز دریافت Docker Desktop از وب سایت رسمی نصب و اجرای برنامه بررسی فعال بودن Docker Engine نصب Docker در macOS کاربران macOS نیز می توانند Docker Desktop را متناسب با پردازنده Intel یا Apple Silicon دریافت و نصب کنند. پس از نصب، Docker Engine از طریق محیط Docker Desktop مدیریت می شود. نصب Docker در لینوکس در توزیع های لینوکسی می توان Docker Engine را از مخزن رسمی Docker نصب کرد. دستورهای نصب براساس توزیع و نسخه سیستم عامل متفاوت هستند. بهتر است به جای استفاده از بسته های قدیمی، مراحل موجود در راهنمای رسمی نصب Docker Engine را دنبال کنید. بعد از نصب، برای بررسی نسخه Docker دستور زیر را اجرا کنید: docker --version سپس برای آزمایش عملکرد Docker از دستور زیر استفاده کنید: docker run hello-world Docker در صورت نبودن Image روی سیستم، آن را دریافت می کند و یک Container آزمایشی می سازد. نمایش پیام موفقیت نشان می دهد نصب اولیه به درستی انجام شده است. اولین Container را اجرا کنید برای اجرای وب سرور Nginx می توانید دستور زیر را وارد کنید: docker run -d --name my-nginx -p 8080:80 nginx اجزای این دستور عبارت هستند از: docker run: ساخت و اجرای Container جدید -d: اجرای Container در پس زمینه --name my-nginx: تعیین نام برای Container -p 8080:80: اتصال پورت 8080 سیستم میزبان به پورت 80 Container nginx: نام Image مورد استفاده پس از اجرا، آدرس زیر را در مرورگر باز کنید: http://localhost:8080 اگر صفحه پیش فرض Nginx نمایش داده شود، اولین Container شما با موفقیت اجرا شده است. دستورات مهم Docker برای شروع در ادامه تعدادی از پرکاربردترین دستورات Docker را بررسی می کنیم. نمایش Containerهای در حال اجرا docker ps برای نمایش تمام Containerها، از جمله موارد متوقف شده، از گزینه -a استفاده کنید: docker ps -a نمایش Imageهای موجود docker images متوقف کردن Container docker stop my-nginx اجرای مجدد Container docker start my-nginx حذف Container docker rm my-nginx Container باید پیش از حذف متوقف شود. برای توقف و حذف اجباری می توان از دستور زیر استفاده کرد: docker rm -f my-nginx حذف Image docker rmi nginx مشاهده گزارش اجرای Container docker logs my-nginx برای دنبال کردن گزارش ها به صورت زنده از گزینه -f استفاده کنید: docker logs -f my-nginx اجرای دستور داخل Container docker exec -it my-nginx sh این دستور یک پوسته تعاملی داخل Container باز می کند. البته نوع پوسته موجود به Image مورد استفاده بستگی دارد. آموزش ساخت Dockerfile برای درک بهتر فرآیند ساخت Image، یک برنامه ساده Node.js را در نظر بگیرید. ساختار پروژه می تواند به صورت زیر باشد: docker-demo/ ├── Dockerfile ├── package.json └── server.js محتوای فایل server.js: const http = require("http"); const server = http.createServer((request, response) =&#62; { response.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" }); response.end("Hello from Docker"); }); server.listen(3000, "0.0.0.0", () =&#62; { console.log("Server is running on port 3000"); }); محتوای فایل package.json: { "name": "docker-demo", "version": "1.0.0", "scripts": { "start": "node server.js" } } اکنون یک فایل بدون پسوند با نام Dockerfile ایجاد کنید: FROM node:22-alpine WORKDIR /app COPY package*.json ./ COPY . . EXPOSE 3000 CMD ["npm", "start"] هر دستور وظیفه مشخصی دارد: FROM: تعیین Image پایه WORKDIR: مشخص کردن مسیر کاری داخل Image COPY: کپی کردن فایل ها به Image EXPOSE: مستند کردن پورت مورد استفاده برنامه CMD: تعیین فرمان پیش فرض هنگام اجرای Container ساخت Image اختصاصی در مسیر پروژه دستور زیر را اجرا کنید: docker build -t docker-demo:1.0 . گزینه -t نام و برچسب Image را تعیین می کند. نقطه انتهای دستور نیز نشان می دهد که Docker باید فایل های مورد نیاز را از مسیر فعلی دریافت کند. بعد از پایان ساخت، Image را اجرا کنید: docker run -d --name docker-demo-app -p 3000:3000 docker-demo:1.0 اکنون برنامه از آدرس زیر در دسترس است: http://localhost:3000 استفاده از فایل .dockerignore هنگام ساخت Image لازم نیست تمام فایل های پروژه به Docker ارسال شوند. فایل هایی مانند پوشه وابستگی ها، اطلاعات Git، گزارش ها و فایل های موقت می توانند فرآیند ساخت را کند کنند یا حجم Image را افزایش دهند. برای پروژه Node.js یک فایل .dockerignore با محتوای زیر بسازید: node_modules npm-debug.log .git .gitignore .env فایل های حساس مانند .env نباید بدون دلیل داخل Image کپی شوند. اطلاعات محرمانه باید از روش های امن مدیریت متغیرهای محیطی و Secretها در اختیار برنامه قرار بگیرند. مدیریت داده ها با Docker Volume اگر یک Container پایگاه داده را حذف کنید، نباید اطلاعات اصلی برنامه نیز حذف شوند. Volume راهکار پیشنهادی Docker برای نگهداری پایدار داده ها است. برای ساخت Volume از دستور زیر استفاده کنید: docker volume create app-data فهرست Volumeها را مشاهده کنید: docker volume ls سپس Volume را هنگام اجرای Container متصل کنید: docker run -d \ --name my-nginx \ -p 8080:80 \ -v app-data:/usr/share/nginx/html \ nginx برای مشاهده اطلاعات کامل Volume نیز می توانید دستور زیر را اجرا کنید: docker volume inspect app-data جزئیات بیشتر درباره روش های ذخیره سازی در مستندات رسمی Docker Volume در دسترس است. تفاوت Volume و Bind Mount در Bind Mount یک مسیر مشخص از سیستم میزبان مستقیما به Container متصل می شود. این روش در محیط توسعه مفید است؛ زیرا تغییر فایل های پروژه بلافاصله داخل Container دیده می شود. نمونه اتصال پوشه فعلی به Nginx: docker run -d \ --name local-web \ -p 8080:80 \ -v "$(pwd)":/usr/share/nginx/html:ro \ nginx در این مثال، گزینه ro دسترسی Container را به حالت فقط خواندنی محدود می کند. به طور کلی: Volume توسط Docker مدیریت می شود و برای داده های پایدار انتخاب مناسبی است. Bind Mount به مسیر مشخصی از سیستم میزبان وابسته است و بیشتر در محیط توسعه کاربرد دارد. شبکه در Docker چگونه کار می کند؟ برای ایجاد یک شبکه اختصاصی دستور زیر را اجرا کنید: docker network create app-network سپس می توانید Containerها را روی همان شبکه اجرا کنید: docker run -d \ --name database \ --network app-network \ -e POSTGRES_PASSWORD=change-this-password \ postgres Container دیگری که عضو app-network باشد، می تواند با استفاده از نام database به این سرویس متصل شود. این قابلیت نیاز به استفاده از آدرس IP ثابت برای ارتباط داخلی سرویس ها را کاهش می دهد. در پروژه های واقعی نباید رمز عبور پایگاه داده را مستقیما در تاریخچه دستورات، فایل Dockerfile یا مخزن Git ثبت کنید. Docker Compose چیست؟ بسیاری از پروژه ها فقط از یک Container تشکیل نمی شوند. یک سامانه تحت وب ممکن است شامل برنامه اصلی، پایگاه داده، Redis، وب سرور و سرویس های جانبی باشد. Docker Compose امکان تعریف و مدیریت چند سرویس را در یک فایل YAML فراهم می کند. به جای اجرای چند دستور طولانی، تمام سرویس ها، شبکه ها و Volumeها را در فایل compose.yaml مشخص می کنید. برای اطلاعات تکمیلی می توانید مستندات Docker Compose را مطالعه کنید. آموزش Docker Compose با یک مثال کاربردی در مثال زیر یک برنامه Node.js در کنار پایگاه داده PostgreSQL اجرا می شود: services: app: build: . container_name: demo-app ports: - "3000:3000" environment: DATABASE_HOST: db DATABASE_PORT: 5432 DATABASE_NAME: appdb DATABASE_USER: appuser DATABASE_PASSWORD: ${DATABASE_PASSWORD} depends_on: db: condition: service_healthy db: image: postgres:17-alpine container_name: demo-db environment: POSTGRES_DB: appdb POSTGRES_USER: appuser POSTGRES_PASSWORD: ${DATABASE_PASSWORD} volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"] interval: 5s timeout: 5s retries: 10 volumes: postgres-data: رمز عبور را در فایل .env قرار دهید: DATABASE_PASSWORD=replace-with-a-strong-password فایل .env را به .gitignore اضافه کنید تا اطلاعات حساس وارد مخزن Git نشوند. برای ساخت و اجرای سرویس ها از دستور زیر استفاده کنید: docker compose up -d --build برای مشاهده وضعیت سرویس ها: docker compose ps برای مشاهده گزارش ها: docker compose logs -f برای توقف و حذف Containerها و شبکه ایجاد شده: docker compose down دستور بالا Volume را حذف نمی کند. اگر قصد حذف Volume و داده های آن را دارید، می توانید از دستور زیر استفاده کنید: docker compose down -v این دستور اطلاعات ذخیره شده در Volumeهای پروژه را پاک می کند؛ بنابراین باید با دقت اجرا شود. یک نمونه کامل تر نیز در راهنمای شروع سریع Docker Compose ارائه شده است. بهترین روش ها برای نوشتن Dockerfile یک Dockerfile نامناسب ممکن است Image بسیار حجیم، ناامن یا کند تولید کند. رعایت نکات زیر کیفیت خروجی را بهتر می کند. از Image پایه مناسب استفاده کنید Imageهای سبک مانند نسخه های Alpine یا Slim در بعضی پروژه ها حجم نهایی را کاهش می دهند. با این حال، کوچک ترین Image همیشه بهترین انتخاب نیست. سازگاری کتابخانه ها، ابزارهای عیب یابی و نیازهای امنیتی را نیز بررسی کنید. ترتیب دستورها را بهینه کنید Docker برای افزایش سرعت ساخت از کش لایه ها استفاده می کند. فایل هایی که کمتر تغییر می کنند باید قبل از کدهای اصلی کپی شوند. برای نمونه، بهتر است ابتدا فایل وابستگی ها کپی و نصب شود و سپس کد برنامه داخل Image قرار بگیرد. در این حالت، تغییر یک فایل کد باعث نصب دوباره تمام وابستگی ها نمی شود. نسخه Imageها را مشخص کنید استفاده بدون بررسی از برچسب latest می تواند نتیجه ساخت را در زمان های مختلف تغییر دهد. بهتر است نسخه مشخص و متناسب با پروژه را انتخاب کنید: FROM node:22-alpine برنامه را با کاربر root اجرا نکنید در محیط عملیاتی بهتر است یک کاربر با دسترسی محدود بسازید و برنامه را با همان کاربر اجرا کنید. این کار بخشی از ریسک های امنیتی را کاهش می دهد. اطلاعات حساس را وارد Image نکنید رمز عبور، کلید API، گواهی خصوصی و فایل های تنظیمات حساس نباید داخل Dockerfile یا لایه های Image قرار بگیرند. حذف یک Secret در دستور بعدی نیز لزوما آن را از لایه قبلی پاک نمی کند. از Multi-stage Build استفاده کنید Multi-stage Build اجازه می دهد ابزارهای ساخت را از Image نهایی جدا کنید. این روش به ویژه برای پروژه های Go، Java، .NET و برنامه های فرانت اند مفید است. نمونه ساده برای یک پروژه فرانت اند: FROM node:22-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 در مرحله اول پروژه ساخته می شود و در مرحله دوم فقط فایل های خروجی وارد Image نهایی می شوند. خطاهای رایج هنگام کار با Docker Container بلافاصله متوقف می شود Container تا زمانی فعال می ماند که فرآیند اصلی آن در حال اجرا باشد. برای بررسی علت توقف از دستور زیر استفاده کنید: docker logs container-name همچنین مقدار CMD یا ENTRYPOINT را در Dockerfile بررسی کنید. پورت برنامه در دسترس نیست موارد زیر را کنترل کنید: اتصال پورت با گزینه -p انجام شده باشد. برنامه داخل Container روی 0.0.0.0 گوش دهد، نه فقط localhost. پورت مورد نظر توسط برنامه دیگری اشغال نشده باشد. دیوار آتش یا تنظیمات شبکه مانع اتصال نباشد. تغییرات کد در Container دیده نمی شود اگر Image را از روی کد ساخته اید، بعد از تغییر کد باید Image دوباره ساخته شود: docker compose up -d --build در محیط توسعه می توانید از Bind Mount یا قابلیت های مخصوص توسعه Compose استفاده کنید. نام سرویس پایگاه داده اشتباه است در Docker Compose، برنامه معمولا باید با نام سرویس به پایگاه داده متصل شود. اگر نام سرویس db است، مقدار میزبان پایگاه داده نیز باید db باشد، نه localhost. فضای ذخیره سازی Docker پر شده است Imageها، Containerهای متوقف شده و کش ساخت می توانند فضای زیادی مصرف کنند. ابتدا میزان مصرف را بررسی کنید: docker system df برای پاک سازی منابع بدون استفاده می توان از دستورهای docker container prune، docker image prune و docker builder prune استفاده کرد. پیش از پاک سازی، مطمئن شوید داده یا منبع مورد نیاز پروژه حذف نمی شود. کاربرد Docker در پروژه های طراحی سایت و نرم افزار داکر فقط یک ابزار مخصوص مدیران سرور نیست. تیم های طراحی سایت و توسعه نرم افزار می توانند از آن در مراحل مختلف پروژه استفاده کنند. برخی از کاربردهای مهم عبارت هستند از: ساخت محیط توسعه یکسان برای اعضای تیم اجرای نسخه مشخص PHP، Node.js، Python یا .NET راه اندازی سریع MySQL، PostgreSQL، Redis و Elasticsearch آزمایش پروژه در نسخه های مختلف پایگاه داده اجرای تست های خودکار در فرآیند CI/CD آماده سازی نسخه آزمایشی برای کارفرما استقرار کنترل شده برنامه روی سرور جداسازی پروژه های مختلف روی یک سیستم توسعه ساده کردن فرآیند ورود اعضای جدید به تیم برای مثال، یک تیم طراحی سایت می تواند WordPress، MySQL و ابزار مدیریت پایگاه داده را در یک فایل Compose تعریف کند. در نتیجه، راه اندازی محیط پروژه برای عضو جدید تیم به جای چند ساعت تنظیم دستی، با چند دستور مشخص انجام می شود. آیا Docker برای محیط عملیاتی مناسب است؟ Docker می تواند در محیط عملیاتی استفاده شود، اما نصب داکر به تنهایی یک زیرساخت پایدار و امن ایجاد نمی کند. برای استفاده حرفه ای باید موضوعات زیر نیز بررسی شوند: امنیت Imageها و بررسی آسیب پذیری ها مدیریت Secretها و اطلاعات حساس ثبت و نگهداری گزارش ها تهیه نسخه پشتیبان از داده ها مانیتورینگ مصرف منابع و سلامت سرویس ها محدود کردن...</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-docker-%d8%a7%d8%b2-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%a7%d8%ac%d8%b1%d8%a7%db%8c-%d9%be%d8%b1%d9%88%da%98%d9%87-%d9%88%d8%a7%d9%82%d8%b9%db%8c-%d8%a8/">آموزش Docker از صفر تا اجرای پروژه واقعی با داکر</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<p dir="rtl" lang="fa">آموزش داکر یکی از بهترین نقاط شروع برای توسعه دهندگانی است که می خواهند پروژه های خود را در محیطی استاندارد، قابل انتقال و مستقل اجرا کنند. Docker کمک می کند نرم افزار، کتابخانه ها و تنظیمات مورد نیاز آن را داخل یک بسته مشخص قرار دهید و همان بسته را روی سیستم شخصی، سرور یا زیرساخت ابری اجرا کنید.</p>
<p dir="rtl" lang="fa">در این آموزش، ابتدا با مفاهیم اصلی Docker آشنا می شویم و سپس نصب داکر، ساخت Image، اجرای Container، مدیریت داده ها و استفاده از Docker Compose را به صورت مرحله به مرحله بررسی می کنیم.</p>
<h2 dir="rtl" lang="fa">داکر چیست؟</h2>
<p dir="rtl" lang="fa">داکر یک پلتفرم متن باز برای ساخت، بسته بندی، توزیع و اجرای نرم افزار در محیط هایی به نام Container است. هر Container شامل برنامه و وابستگی های مورد نیاز آن می شود و می تواند بدون وابستگی مستقیم به تنظیمات سیستم میزبان اجرا شود.</p>
<p dir="rtl" lang="fa">برای مثال، فرض کنید یک برنامه تحت وب با Python، Node.js یا PHP توسعه داده اید. اجرای این برنامه ممکن است به نسخه مشخصی از زبان برنامه نویسی، پایگاه داده، وب سرور و چند کتابخانه نیاز داشته باشد. با Docker می توانید تمام این موارد را در قالب یک Image تعریف کنید تا اعضای تیم و سرور اصلی دقیقا از همان محیط استفاده کنند.</p>
<p dir="rtl" lang="fa">برای مطالعه تعاریف و راهنماهای رسمی می توانید به <a href="https://docs.docker.com/" target="_blank" rel="nofollow noopener noreferrer">مستندات Docker</a> مراجعه کنید.</p>
<h2 dir="rtl" lang="fa">چرا باید Docker را یاد بگیریم؟</h2>
<p dir="rtl" lang="fa">مشکل معروف «روی سیستم من اجرا می شود» معمولا زمانی به وجود می آید که محیط توسعه با محیط آزمایش یا سرور اصلی تفاوت دارد. ممکن است نسخه زبان برنامه نویسی، کتابخانه ها، متغیرهای محیطی یا تنظیمات سیستم عامل یکسان نباشند.</p>
<p dir="rtl" lang="fa">داکر این تفاوت ها را تا حد زیادی کاهش می دهد. مهم ترین مزایای استفاده از Docker عبارت هستند از:</p>
<ul dir="rtl" lang="fa">
<li>ایجاد محیط توسعه یکسان برای تمام اعضای تیم</li>
<li>انتقال آسان نرم افزار میان سیستم شخصی، سرور و فضای ابری</li>
<li>کاهش مشکلات مربوط به نسخه کتابخانه ها و وابستگی ها</li>
<li>راه اندازی سریع محیط توسعه و آزمایش</li>
<li>جداسازی سرویس های مختلف از یکدیگر</li>
<li>استفاده بهتر از منابع در مقایسه با بسیاری از ماشین های مجازی</li>
<li>ساده تر شدن فرآیند استقرار و انتشار نرم افزار</li>
<li>امکان بازگشت سریع به نسخه قبلی برنامه</li>
</ul>
<p dir="rtl" lang="fa">یادگیری داکر برای توسعه دهندگان وب، برنامه نویسان بک اند، کارشناسان DevOps، مدیران سرور و تیم های توسعه نرم افزار کاربردی است.</p>
<h2 dir="rtl" lang="fa">تفاوت Docker و ماشین مجازی چیست؟</h2>
<p dir="rtl" lang="fa">ماشین مجازی یا Virtual Machine معمولا یک سیستم عامل کامل را همراه با برنامه ها اجرا می کند. هر ماشین مجازی به حافظه، پردازنده و فضای ذخیره سازی جداگانه نیاز دارد و راه اندازی آن ممکن است زمان بیشتری ببرد.</p>
<p dir="rtl" lang="fa">Container برخلاف ماشین مجازی، معمولا از هسته سیستم عامل میزبان استفاده می کند. به همین دلیل سبک تر است، سریع تر اجرا می شود و منابع کمتری مصرف می کند.</p>
<p dir="rtl" lang="fa">تفاوت های مهم این دو فناوری را می توان به شکل زیر خلاصه کرد:</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>ویژگی</th>
<th>Docker Container</th>
<th>ماشین مجازی</th>
</tr>
</thead>
<tbody>
<tr>
<td dir="rtl" lang="fa">زمان راه اندازی</td>
<td dir="rtl" lang="fa">معمولا چند ثانیه</td>
<td dir="rtl" lang="fa">معمولا بیشتر</td>
</tr>
<tr>
<td dir="rtl" lang="fa">مصرف منابع</td>
<td dir="rtl" lang="fa">کمتر</td>
<td dir="rtl" lang="fa">بیشتر</td>
</tr>
<tr>
<td dir="rtl" lang="fa">سیستم عامل کامل</td>
<td dir="rtl" lang="fa">ندارد</td>
<td dir="rtl" lang="fa">دارد</td>
</tr>
<tr>
<td dir="rtl" lang="fa">قابلیت انتقال</td>
<td dir="rtl" lang="fa">بسیار مناسب</td>
<td dir="rtl" lang="fa">مناسب</td>
</tr>
<tr>
<td dir="rtl" lang="fa">جداسازی</td>
<td dir="rtl" lang="fa">در سطح فرآیند</td>
<td dir="rtl" lang="fa">در سطح سیستم عامل</td>
</tr>
<tr>
<td dir="rtl" lang="fa">کاربرد رایج</td>
<td dir="rtl" lang="fa">توسعه، آزمایش و استقرار سرویس</td>
<td dir="rtl" lang="fa">اجرای سیستم عامل مستقل</td>
</tr>
</tbody>
</table>
</div>
<p dir="rtl" lang="fa">داکر همیشه جایگزین ماشین مجازی نیست. انتخاب میان این دو به سطح جداسازی، امنیت، نوع نرم افزار و معماری زیرساخت بستگی دارد.</p>
<h2 dir="rtl" lang="fa">مفاهیم اصلی در آموزش داکر</h2>
<p dir="rtl" lang="fa">قبل از اجرای دستورات Docker باید با چند مفهوم پایه آشنا شوید.</p>
<h3 dir="rtl" lang="fa">Docker Image چیست؟</h3>
<p dir="rtl" lang="fa">Image یک الگوی فقط خواندنی است که فایل های برنامه، وابستگی ها، تنظیمات و دستور اجرای نرم افزار را در خود نگه می دارد. می توانید Image را مانند نقشه ساخت یک محیط اجرایی در نظر بگیرید.</p>
<p dir="rtl" lang="fa">برای مثال، Image رسمی Nginx شامل فایل ها و تنظیمات لازم برای اجرای وب سرور Nginx است.</p>
<h3 dir="rtl" lang="fa">Docker Container چیست؟</h3>
<p dir="rtl" lang="fa">Container نمونه در حال اجرا یا متوقف شده یک Image است. از یک Image می توان چند Container مستقل ایجاد کرد.</p>
<p dir="rtl" lang="fa">برای نمونه، امکان دارد سه Container از Image یک برنامه بسازید و هر کدام را روی پورت متفاوتی اجرا کنید.</p>
<h3 dir="rtl" lang="fa">Dockerfile چیست؟</h3>
<p dir="rtl" lang="fa">Dockerfile یک فایل متنی شامل دستوراتی است که Docker برای ساخت Image اجرا می کند. در این فایل می توانید Image پایه، مسیر کاری، فایل های پروژه، وابستگی ها و فرمان اجرای برنامه را مشخص کنید.</p>
<h3 dir="rtl" lang="fa">Docker Registry چیست؟</h3>
<p dir="rtl" lang="fa">Registry محلی برای ذخیره و توزیع Imageها است. Docker Hub یکی از شناخته شده ترین Registryهای عمومی محسوب می شود. سازمان ها نیز می توانند Registry خصوصی خود را راه اندازی کنند.</p>
<h3 dir="rtl" lang="fa">Docker Volume چیست؟</h3>
<p dir="rtl" lang="fa">اطلاعات داخل لایه قابل نوشتن Container با حذف Container از دسترس خارج می شوند. Volume برای نگهداری پایدار داده ها استفاده می شود و چرخه عمر آن از Container مستقل است.</p>
<p dir="rtl" lang="fa">Volume به ویژه برای پایگاه داده، فایل های بارگذاری شده توسط کاربران و اطلاعاتی که نباید با حذف Container از بین بروند اهمیت دارد.</p>
<h3 dir="rtl" lang="fa">Docker Network چیست؟</h3>
<p dir="rtl" lang="fa">Network امکان ارتباط میان Containerها و همچنین ارتباط Container با شبکه بیرونی را فراهم می کند. در پروژه های چند سرویسه، برنامه می تواند از طریق نام سرویس به پایگاه داده یا سرویس های دیگر متصل شود.</p>
<h2 dir="rtl" lang="fa">آموزش نصب Docker</h2>
<p dir="rtl" lang="fa">روش نصب Docker به سیستم عامل شما بستگی دارد.</p>
<h3 dir="rtl" lang="fa">نصب Docker در ویندوز</h3>
<p dir="rtl" lang="fa">برای استفاده از Docker در ویندوز معمولا Docker Desktop نصب می شود. در نسخه های جدید ویندوز، استفاده از WSL 2 می تواند تجربه مناسب تری برای اجرای Containerهای لینوکسی فراهم کند.</p>
<p dir="rtl" lang="fa">مراحل کلی عبارت هستند از:</p>
<ol dir="rtl" lang="fa">
<li>فعال کردن قابلیت مجازی سازی در BIOS یا UEFI</li>
<li>نصب و فعال سازی WSL 2 در صورت نیاز</li>
<li>دریافت Docker Desktop از وب سایت رسمی</li>
<li>نصب و اجرای برنامه</li>
<li>بررسی فعال بودن Docker Engine</li>
</ol>
<h3 dir="rtl" lang="fa">نصب Docker در macOS</h3>
<p dir="rtl" lang="fa">کاربران macOS نیز می توانند Docker Desktop را متناسب با پردازنده Intel یا Apple Silicon دریافت و نصب کنند. پس از نصب، Docker Engine از طریق محیط Docker Desktop مدیریت می شود.</p>
<h3 dir="rtl" lang="fa">نصب Docker در لینوکس</h3>
<p dir="rtl" lang="fa">در توزیع های لینوکسی می توان Docker Engine را از مخزن رسمی Docker نصب کرد. دستورهای نصب براساس توزیع و نسخه سیستم عامل متفاوت هستند. بهتر است به جای استفاده از بسته های قدیمی، مراحل موجود در <a href="https://docs.docker.com/engine/install/" target="_blank" rel="nofollow noopener noreferrer">راهنمای رسمی نصب Docker Engine</a> را دنبال کنید.</p>
<p dir="rtl" lang="fa">بعد از نصب، برای بررسی نسخه Docker دستور زیر را اجرا کنید:</p>
<pre><code class="hljs">docker --version
</code></pre>
<p dir="rtl" lang="fa">سپس برای آزمایش عملکرد Docker از دستور زیر استفاده کنید:</p>
<pre><code class="hljs">docker run hello-world
</code></pre>
<p dir="rtl" lang="fa">Docker در صورت نبودن Image روی سیستم، آن را دریافت می کند و یک Container آزمایشی می سازد. نمایش پیام موفقیت نشان می دهد نصب اولیه به درستی انجام شده است.</p>
<h2 dir="rtl" lang="fa">اولین Container را اجرا کنید</h2>
<p dir="rtl" lang="fa">برای اجرای وب سرور Nginx می توانید دستور زیر را وارد کنید:</p>
<pre><code class="hljs">docker run -d --name my-nginx -p 8080:80 nginx
</code></pre>
<p dir="rtl" lang="fa">اجزای این دستور عبارت هستند از:</p>
<ul dir="rtl" lang="fa">
<li><code>docker run</code>: ساخت و اجرای Container جدید</li>
<li><code>-d</code>: اجرای Container در پس زمینه</li>
<li><code>--name my-nginx</code>: تعیین نام برای Container</li>
<li><code>-p 8080:80</code>: اتصال پورت 8080 سیستم میزبان به پورت 80 Container</li>
<li><code>nginx</code>: نام Image مورد استفاده</li>
</ul>
<p dir="rtl" lang="fa">پس از اجرا، آدرس زیر را در مرورگر باز کنید:</p>
<pre><code class="hljs">http://localhost:8080
</code></pre>
<p dir="rtl" lang="fa">اگر صفحه پیش فرض Nginx نمایش داده شود، اولین Container شما با موفقیت اجرا شده است.</p>
<h2 dir="rtl" lang="fa">دستورات مهم Docker برای شروع</h2>
<p dir="rtl" lang="fa">در ادامه تعدادی از پرکاربردترین دستورات Docker را بررسی می کنیم.</p>
<h3 dir="rtl" lang="fa">نمایش Containerهای در حال اجرا</h3>
<pre><code class="hljs">docker ps
</code></pre>
<p dir="rtl" lang="fa">برای نمایش تمام Containerها، از جمله موارد متوقف شده، از گزینه <code>-a</code> استفاده کنید:</p>
<pre><code class="hljs">docker ps -a
</code></pre>
<h3 dir="rtl" lang="fa">نمایش Imageهای موجود</h3>
<pre><code class="hljs">docker images
</code></pre>
<h3 dir="rtl" lang="fa">متوقف کردن Container</h3>
<pre><code class="hljs">docker stop my-nginx
</code></pre>
<h3 dir="rtl" lang="fa">اجرای مجدد Container</h3>
<pre><code class="hljs">docker start my-nginx
</code></pre>
<h3 dir="rtl" lang="fa">حذف Container</h3>
<pre><code class="hljs">docker <span class="hljs-built_in">rm</span> my-nginx
</code></pre>
<p dir="rtl" lang="fa">Container باید پیش از حذف متوقف شود. برای توقف و حذف اجباری می توان از دستور زیر استفاده کرد:</p>
<pre><code class="hljs">docker <span class="hljs-built_in">rm</span> -f my-nginx
</code></pre>
<h3 dir="rtl" lang="fa">حذف Image</h3>
<pre><code class="hljs">docker rmi nginx
</code></pre>
<h3 dir="rtl" lang="fa">مشاهده گزارش اجرای Container</h3>
<pre><code class="hljs">docker logs my-nginx
</code></pre>
<p dir="rtl" lang="fa">برای دنبال کردن گزارش ها به صورت زنده از گزینه <code>-f</code> استفاده کنید:</p>
<pre><code class="hljs">docker logs -f my-nginx
</code></pre>
<h3 dir="rtl" lang="fa">اجرای دستور داخل Container</h3>
<pre><code class="hljs">docker <span class="hljs-built_in">exec</span> -it my-nginx sh
</code></pre>
<p dir="rtl" lang="fa">این دستور یک پوسته تعاملی داخل Container باز می کند. البته نوع پوسته موجود به Image مورد استفاده بستگی دارد.</p>
<h2 dir="rtl" lang="fa">آموزش ساخت Dockerfile</h2>
<p dir="rtl" lang="fa">برای درک بهتر فرآیند ساخت Image، یک برنامه ساده Node.js را در نظر بگیرید. ساختار پروژه می تواند به صورت زیر باشد:</p>
<pre><code class="hljs">docker-demo/
├── Dockerfile
├── package.json
└── server.js
</code></pre>
<p dir="rtl" lang="fa">محتوای فایل <code>server.js</code>:</p>
<pre><code class="hljs"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">"http"</span>);

<span class="hljs-keyword">const</span> server = http.<span class="hljs-title function_">createServer</span>(<span class="hljs-function">(<span class="hljs-params">request, response</span>) =&gt;</span> {
  response.<span class="hljs-title function_">writeHead</span>(<span class="hljs-number">200</span>, { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"text/plain; charset=utf-8"</span> });
  response.<span class="hljs-title function_">end</span>(<span class="hljs-string">"Hello from Docker"</span>);
});

server.<span class="hljs-title function_">listen</span>(<span class="hljs-number">3000</span>, <span class="hljs-string">"0.0.0.0"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"Server is running on port 3000"</span>);
});
</code></pre>
<p dir="rtl" lang="fa">محتوای فایل <code>package.json</code>:</p>
<pre><code class="hljs"><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">"name"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"docker-demo"</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">"version"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1.0.0"</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">"scripts"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">"start"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"node server.js"</span>
  <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre>
<p dir="rtl" lang="fa">اکنون یک فایل بدون پسوند با نام <code>Dockerfile</code> ایجاد کنید:</p>
<pre><code class="hljs"><span class="hljs-keyword">FROM</span> node:<span class="hljs-number">22</span>-alpine

<span class="hljs-keyword">WORKDIR</span><span class="language-bash"> /app</span>

<span class="hljs-keyword">COPY</span><span class="language-bash"> package*.json ./</span>

<span class="hljs-keyword">COPY</span><span class="language-bash"> . .</span>

<span class="hljs-keyword">EXPOSE</span> <span class="hljs-number">3000</span>

<span class="hljs-keyword">CMD</span><span class="language-bash"> [<span class="hljs-string">"npm"</span>, <span class="hljs-string">"start"</span>]</span>
</code></pre>
<p dir="rtl" lang="fa">هر دستور وظیفه مشخصی دارد:</p>
<ul dir="rtl" lang="fa">
<li><code>FROM</code>: تعیین Image پایه</li>
<li><code>WORKDIR</code>: مشخص کردن مسیر کاری داخل Image</li>
<li><code>COPY</code>: کپی کردن فایل ها به Image</li>
<li><code>EXPOSE</code>: مستند کردن پورت مورد استفاده برنامه</li>
<li><code>CMD</code>: تعیین فرمان پیش فرض هنگام اجرای Container</li>
</ul>
<h2 dir="rtl" lang="fa">ساخت Image اختصاصی</h2>
<p dir="rtl" lang="fa">در مسیر پروژه دستور زیر را اجرا کنید:</p>
<pre><code class="hljs">docker build -t docker-demo:1.0 .
</code></pre>
<p dir="rtl" lang="fa">گزینه <code>-t</code> نام و برچسب Image را تعیین می کند. نقطه انتهای دستور نیز نشان می دهد که Docker باید فایل های مورد نیاز را از مسیر فعلی دریافت کند.</p>
<p dir="rtl" lang="fa">بعد از پایان ساخت، Image را اجرا کنید:</p>
<pre><code class="hljs">docker run -d --name docker-demo-app -p 3000:3000 docker-demo:1.0
</code></pre>
<p dir="rtl" lang="fa">اکنون برنامه از آدرس زیر در دسترس است:</p>
<pre><code class="hljs">http://localhost:3000
</code></pre>
<h2 dir="rtl" lang="fa">استفاده از فایل .dockerignore</h2>
<p dir="rtl" lang="fa">هنگام ساخت Image لازم نیست تمام فایل های پروژه به Docker ارسال شوند. فایل هایی مانند پوشه وابستگی ها، اطلاعات Git، گزارش ها و فایل های موقت می توانند فرآیند ساخت را کند کنند یا حجم Image را افزایش دهند.</p>
<p dir="rtl" lang="fa">برای پروژه Node.js یک فایل <code>.dockerignore</code> با محتوای زیر بسازید:</p>
<pre><code class="hljs">node_modules
npm-debug.log
.git
.gitignore
.env
</code></pre>
<p dir="rtl" lang="fa">فایل های حساس مانند <code>.env</code> نباید بدون دلیل داخل Image کپی شوند. اطلاعات محرمانه باید از روش های امن مدیریت متغیرهای محیطی و Secretها در اختیار برنامه قرار بگیرند.</p>
<h2 dir="rtl" lang="fa">مدیریت داده ها با Docker Volume</h2>
<p dir="rtl" lang="fa">اگر یک Container پایگاه داده را حذف کنید، نباید اطلاعات اصلی برنامه نیز حذف شوند. Volume راهکار پیشنهادی Docker برای نگهداری پایدار داده ها است.</p>
<p dir="rtl" lang="fa">برای ساخت Volume از دستور زیر استفاده کنید:</p>
<pre><code class="hljs">docker volume create app-data
</code></pre>
<p dir="rtl" lang="fa">فهرست Volumeها را مشاهده کنید:</p>
<pre><code class="hljs">docker volume <span class="hljs-built_in">ls</span>
</code></pre>
<p dir="rtl" lang="fa">سپس Volume را هنگام اجرای Container متصل کنید:</p>
<pre><code class="hljs">docker run -d \
  --name my-nginx \
  -p 8080:80 \
  -v app-data:/usr/share/nginx/html \
  nginx
</code></pre>
<p dir="rtl" lang="fa">برای مشاهده اطلاعات کامل Volume نیز می توانید دستور زیر را اجرا کنید:</p>
<pre><code class="hljs">docker volume inspect app-data
</code></pre>
<p dir="rtl" lang="fa">جزئیات بیشتر درباره روش های ذخیره سازی در <a href="https://docs.docker.com/engine/storage/volumes/" target="_blank" rel="nofollow noopener noreferrer">مستندات رسمی Docker Volume</a> در دسترس است.</p>
<h2 dir="rtl" lang="fa">تفاوت Volume و Bind Mount</h2>
<p dir="rtl" lang="fa">در Bind Mount یک مسیر مشخص از سیستم میزبان مستقیما به Container متصل می شود. این روش در محیط توسعه مفید است؛ زیرا تغییر فایل های پروژه بلافاصله داخل Container دیده می شود.</p>
<p dir="rtl" lang="fa">نمونه اتصال پوشه فعلی به Nginx:</p>
<pre><code class="hljs">docker run -d \
  --name local-web \
  -p 8080:80 \
  -v <span class="hljs-string">"<span class="hljs-subst">$(pwd)</span>"</span>:/usr/share/nginx/html:ro \
  nginx
</code></pre>
<p dir="rtl" lang="fa">در این مثال، گزینه <code>ro</code> دسترسی Container را به حالت فقط خواندنی محدود می کند.</p>
<p dir="rtl" lang="fa">به طور کلی:</p>
<ul dir="rtl" lang="fa">
<li>Volume توسط Docker مدیریت می شود و برای داده های پایدار انتخاب مناسبی است.</li>
<li>Bind Mount به مسیر مشخصی از سیستم میزبان وابسته است و بیشتر در محیط توسعه کاربرد دارد.</li>
</ul>
<h2 dir="rtl" lang="fa">شبکه در Docker چگونه کار می کند؟</h2>
<p dir="rtl" lang="fa">برای ایجاد یک شبکه اختصاصی دستور زیر را اجرا کنید:</p>
<pre><code class="hljs">docker network create app-network
</code></pre>
<p dir="rtl" lang="fa">سپس می توانید Containerها را روی همان شبکه اجرا کنید:</p>
<pre><code class="hljs">docker run -d \
  --name database \
  --network app-network \
  -e POSTGRES_PASSWORD=change-this-password \
  postgres
</code></pre>
<p dir="rtl" lang="fa">Container دیگری که عضو <code>app-network</code> باشد، می تواند با استفاده از نام <code>database</code> به این سرویس متصل شود. این قابلیت نیاز به استفاده از آدرس IP ثابت برای ارتباط داخلی سرویس ها را کاهش می دهد.</p>
<p dir="rtl" lang="fa">در پروژه های واقعی نباید رمز عبور پایگاه داده را مستقیما در تاریخچه دستورات، فایل Dockerfile یا مخزن Git ثبت کنید.</p>
<h2 dir="rtl" lang="fa">Docker Compose چیست؟</h2>
<p dir="rtl" lang="fa">بسیاری از پروژه ها فقط از یک Container تشکیل نمی شوند. یک سامانه تحت وب ممکن است شامل برنامه اصلی، پایگاه داده، Redis، وب سرور و سرویس های جانبی باشد.</p>
<p dir="rtl" lang="fa">Docker Compose امکان تعریف و مدیریت چند سرویس را در یک فایل YAML فراهم می کند. به جای اجرای چند دستور طولانی، تمام سرویس ها، شبکه ها و Volumeها را در فایل <code>compose.yaml</code> مشخص می کنید.</p>
<p dir="rtl" lang="fa">برای اطلاعات تکمیلی می توانید <a href="https://docs.docker.com/compose/" target="_blank" rel="nofollow noopener noreferrer">مستندات Docker Compose</a> را مطالعه کنید.</p>
<h2 dir="rtl" lang="fa">آموزش Docker Compose با یک مثال کاربردی</h2>
<p dir="rtl" lang="fa">در مثال زیر یک برنامه Node.js در کنار پایگاه داده PostgreSQL اجرا می شود:</p>
<pre><code class="hljs"><span class="hljs-attr">services:</span>
  <span class="hljs-attr">app:</span>
    <span class="hljs-attr">build:</span> <span class="hljs-string">.</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">demo-app</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"3000:3000"</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">DATABASE_HOST:</span> <span class="hljs-string">db</span>
      <span class="hljs-attr">DATABASE_PORT:</span> <span class="hljs-number">5432</span>
      <span class="hljs-attr">DATABASE_NAME:</span> <span class="hljs-string">appdb</span>
      <span class="hljs-attr">DATABASE_USER:</span> <span class="hljs-string">appuser</span>
      <span class="hljs-attr">DATABASE_PASSWORD:</span> <span class="hljs-string">${DATABASE_PASSWORD}</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-attr">db:</span>
        <span class="hljs-attr">condition:</span> <span class="hljs-string">service_healthy</span>

  <span class="hljs-attr">db:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">postgres:17-alpine</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">demo-db</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">POSTGRES_DB:</span> <span class="hljs-string">appdb</span>
      <span class="hljs-attr">POSTGRES_USER:</span> <span class="hljs-string">appuser</span>
      <span class="hljs-attr">POSTGRES_PASSWORD:</span> <span class="hljs-string">${DATABASE_PASSWORD}</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">postgres-data:/var/lib/postgresql/data</span>
    <span class="hljs-attr">healthcheck:</span>
      <span class="hljs-attr">test:</span> [<span class="hljs-string">"CMD-SHELL"</span>, <span class="hljs-string">"pg_isready -U appuser -d appdb"</span>]
      <span class="hljs-attr">interval:</span> <span class="hljs-string">5s</span>
      <span class="hljs-attr">timeout:</span> <span class="hljs-string">5s</span>
      <span class="hljs-attr">retries:</span> <span class="hljs-number">10</span>

<span class="hljs-attr">volumes:</span>
  <span class="hljs-attr">postgres-data:</span>
</code></pre>
<p dir="rtl" lang="fa">رمز عبور را در فایل <code>.env</code> قرار دهید:</p>
<pre><code class="hljs">DATABASE_PASSWORD=replace-with-a-strong-password
</code></pre>
<p dir="rtl" lang="fa">فایل <code>.env</code> را به <code>.gitignore</code> اضافه کنید تا اطلاعات حساس وارد مخزن Git نشوند.</p>
<p dir="rtl" lang="fa">برای ساخت و اجرای سرویس ها از دستور زیر استفاده کنید:</p>
<pre><code class="hljs">docker compose up -d --build
</code></pre>
<p dir="rtl" lang="fa">برای مشاهده وضعیت سرویس ها:</p>
<pre><code class="hljs">docker compose ps
</code></pre>
<p dir="rtl" lang="fa">برای مشاهده گزارش ها:</p>
<pre><code class="hljs">docker compose logs -f
</code></pre>
<p dir="rtl" lang="fa">برای توقف و حذف Containerها و شبکه ایجاد شده:</p>
<pre><code class="hljs">docker compose down
</code></pre>
<p dir="rtl" lang="fa">دستور بالا Volume را حذف نمی کند. اگر قصد حذف Volume و داده های آن را دارید، می توانید از دستور زیر استفاده کنید:</p>
<pre><code class="hljs">docker compose down -v
</code></pre>
<p dir="rtl" lang="fa">این دستور اطلاعات ذخیره شده در Volumeهای پروژه را پاک می کند؛ بنابراین باید با دقت اجرا شود.</p>
<p dir="rtl" lang="fa">یک نمونه کامل تر نیز در <a href="https://docs.docker.com/compose/gettingstarted/" target="_blank" rel="nofollow noopener noreferrer">راهنمای شروع سریع Docker Compose</a> ارائه شده است.</p>
<h2 dir="rtl" lang="fa">بهترین روش ها برای نوشتن Dockerfile</h2>
<p dir="rtl" lang="fa">یک Dockerfile نامناسب ممکن است Image بسیار حجیم، ناامن یا کند تولید کند. رعایت نکات زیر کیفیت خروجی را بهتر می کند.</p>
<h3 dir="rtl" lang="fa">از Image پایه مناسب استفاده کنید</h3>
<p dir="rtl" lang="fa">Imageهای سبک مانند نسخه های Alpine یا Slim در بعضی پروژه ها حجم نهایی را کاهش می دهند. با این حال، کوچک ترین Image همیشه بهترین انتخاب نیست. سازگاری کتابخانه ها، ابزارهای عیب یابی و نیازهای امنیتی را نیز بررسی کنید.</p>
<h3 dir="rtl" lang="fa">ترتیب دستورها را بهینه کنید</h3>
<p dir="rtl" lang="fa">Docker برای افزایش سرعت ساخت از کش لایه ها استفاده می کند. فایل هایی که کمتر تغییر می کنند باید قبل از کدهای اصلی کپی شوند.</p>
<p dir="rtl" lang="fa">برای نمونه، بهتر است ابتدا فایل وابستگی ها کپی و نصب شود و سپس کد برنامه داخل Image قرار بگیرد. در این حالت، تغییر یک فایل کد باعث نصب دوباره تمام وابستگی ها نمی شود.</p>
<h3 dir="rtl" lang="fa">نسخه Imageها را مشخص کنید</h3>
<p dir="rtl" lang="fa">استفاده بدون بررسی از برچسب <code>latest</code> می تواند نتیجه ساخت را در زمان های مختلف تغییر دهد. بهتر است نسخه مشخص و متناسب با پروژه را انتخاب کنید:</p>
<pre><code class="hljs"><span class="hljs-keyword">FROM</span> node:<span class="hljs-number">22</span>-alpine
</code></pre>
<h3 dir="rtl" lang="fa">برنامه را با کاربر root اجرا نکنید</h3>
<p dir="rtl" lang="fa">در محیط عملیاتی بهتر است یک کاربر با دسترسی محدود بسازید و برنامه را با همان کاربر اجرا کنید. این کار بخشی از ریسک های امنیتی را کاهش می دهد.</p>
<h3 dir="rtl" lang="fa">اطلاعات حساس را وارد Image نکنید</h3>
<p dir="rtl" lang="fa">رمز عبور، کلید API، گواهی خصوصی و فایل های تنظیمات حساس نباید داخل Dockerfile یا لایه های Image قرار بگیرند. حذف یک Secret در دستور بعدی نیز لزوما آن را از لایه قبلی پاک نمی کند.</p>
<h3 dir="rtl" lang="fa">از Multi-stage Build استفاده کنید</h3>
<p dir="rtl" lang="fa">Multi-stage Build اجازه می دهد ابزارهای ساخت را از Image نهایی جدا کنید. این روش به ویژه برای پروژه های Go، Java، .NET و برنامه های فرانت اند مفید است.</p>
<p dir="rtl" lang="fa">نمونه ساده برای یک پروژه فرانت اند:</p>
<pre><code class="hljs"><span class="hljs-keyword">FROM</span> node:<span class="hljs-number">22</span>-alpine AS builder

<span class="hljs-keyword">WORKDIR</span><span class="language-bash"> /app</span>
<span class="hljs-keyword">COPY</span><span class="language-bash"> package*.json ./</span>
<span class="hljs-keyword">RUN</span><span class="language-bash"> npm ci</span>
<span class="hljs-keyword">COPY</span><span class="language-bash"> . .</span>
<span class="hljs-keyword">RUN</span><span class="language-bash"> npm run build</span>

<span class="hljs-keyword">FROM</span> nginx:alpine
<span class="hljs-keyword">COPY</span><span class="language-bash"> --from=builder /app/dist /usr/share/nginx/html</span>
<span class="hljs-keyword">EXPOSE</span> <span class="hljs-number">80</span>
</code></pre>
<p dir="rtl" lang="fa">در مرحله اول پروژه ساخته می شود و در مرحله دوم فقط فایل های خروجی وارد Image نهایی می شوند.</p>
<h2 dir="rtl" lang="fa">خطاهای رایج هنگام کار با Docker</h2>
<h3 dir="rtl" lang="fa">Container بلافاصله متوقف می شود</h3>
<p dir="rtl" lang="fa">Container تا زمانی فعال می ماند که فرآیند اصلی آن در حال اجرا باشد. برای بررسی علت توقف از دستور زیر استفاده کنید:</p>
<pre><code class="hljs">docker logs container-name
</code></pre>
<p dir="rtl" lang="fa">همچنین مقدار <code>CMD</code> یا <code>ENTRYPOINT</code> را در Dockerfile بررسی کنید.</p>
<h3 dir="rtl" lang="fa">پورت برنامه در دسترس نیست</h3>
<p dir="rtl" lang="fa">موارد زیر را کنترل کنید:</p>
<ul dir="rtl" lang="fa">
<li>اتصال پورت با گزینه <code>-p</code> انجام شده باشد.</li>
<li>برنامه داخل Container روی <code>0.0.0.0</code> گوش دهد، نه فقط <code>localhost</code>.</li>
<li>پورت مورد نظر توسط برنامه دیگری اشغال نشده باشد.</li>
<li>دیوار آتش یا تنظیمات شبکه مانع اتصال نباشد.</li>
</ul>
<h3 dir="rtl" lang="fa">تغییرات کد در Container دیده نمی شود</h3>
<p dir="rtl" lang="fa">اگر Image را از روی کد ساخته اید، بعد از تغییر کد باید Image دوباره ساخته شود:</p>
<pre><code class="hljs">docker compose up -d --build
</code></pre>
<p dir="rtl" lang="fa">در محیط توسعه می توانید از Bind Mount یا قابلیت های مخصوص توسعه Compose استفاده کنید.</p>
<h3 dir="rtl" lang="fa">نام سرویس پایگاه داده اشتباه است</h3>
<p dir="rtl" lang="fa">در Docker Compose، برنامه معمولا باید با نام سرویس به پایگاه داده متصل شود. اگر نام سرویس <code>db</code> است، مقدار میزبان پایگاه داده نیز باید <code>db</code> باشد، نه <code>localhost</code>.</p>
<h3 dir="rtl" lang="fa">فضای ذخیره سازی Docker پر شده است</h3>
<p dir="rtl" lang="fa">Imageها، Containerهای متوقف شده و کش ساخت می توانند فضای زیادی مصرف کنند. ابتدا میزان مصرف را بررسی کنید:</p>
<pre><code class="hljs">docker system <span class="hljs-built_in">df</span>
</code></pre>
<p dir="rtl" lang="fa">برای پاک سازی منابع بدون استفاده می توان از دستورهای <code>docker container prune</code>، <code>docker image prune</code> و <code>docker builder prune</code> استفاده کرد. پیش از پاک سازی، مطمئن شوید داده یا منبع مورد نیاز پروژه حذف نمی شود.</p>
<h2 dir="rtl" lang="fa">کاربرد Docker در پروژه های طراحی سایت و نرم افزار</h2>
<p dir="rtl" lang="fa">داکر فقط یک ابزار مخصوص مدیران سرور نیست. تیم های طراحی سایت و توسعه نرم افزار می توانند از آن در مراحل مختلف پروژه استفاده کنند.</p>
<p dir="rtl" lang="fa">برخی از کاربردهای مهم عبارت هستند از:</p>
<ul dir="rtl" lang="fa">
<li>ساخت محیط توسعه یکسان برای اعضای تیم</li>
<li>اجرای نسخه مشخص PHP، Node.js، Python یا .NET</li>
<li>راه اندازی سریع MySQL، PostgreSQL، Redis و Elasticsearch</li>
<li>آزمایش پروژه در نسخه های مختلف پایگاه داده</li>
<li>اجرای تست های خودکار در فرآیند CI/CD</li>
<li>آماده سازی نسخه آزمایشی برای کارفرما</li>
<li>استقرار کنترل شده برنامه روی سرور</li>
<li>جداسازی پروژه های مختلف روی یک سیستم توسعه</li>
<li>ساده کردن فرآیند ورود اعضای جدید به تیم</li>
</ul>
<p dir="rtl" lang="fa">برای مثال، یک تیم طراحی سایت می تواند WordPress، MySQL و ابزار مدیریت پایگاه داده را در یک فایل Compose تعریف کند. در نتیجه، راه اندازی محیط پروژه برای عضو جدید تیم به جای چند ساعت تنظیم دستی، با چند دستور مشخص انجام می شود.</p>
<h2 dir="rtl" lang="fa">آیا Docker برای محیط عملیاتی مناسب است؟</h2>
<p dir="rtl" lang="fa">Docker می تواند در محیط عملیاتی استفاده شود، اما نصب داکر به تنهایی یک زیرساخت پایدار و امن ایجاد نمی کند. برای استفاده حرفه ای باید موضوعات زیر نیز بررسی شوند:</p>
<ul dir="rtl" lang="fa">
<li>امنیت Imageها و بررسی آسیب پذیری ها</li>
<li>مدیریت Secretها و اطلاعات حساس</li>
<li>ثبت و نگهداری گزارش ها</li>
<li>تهیه نسخه پشتیبان از داده ها</li>
<li>مانیتورینگ مصرف منابع و سلامت سرویس ها</li>
<li>محدود کردن دسترسی Containerها</li>
<li>مدیریت شبکه و گواهی SSL</li>
<li>تعیین سیاست راه اندازی مجدد</li>
<li>انتشار نسخه های مشخص و امکان بازگشت</li>
<li>به روز رسانی منظم Imageهای پایه</li>
</ul>
<p dir="rtl" lang="fa">در پروژه های بزرگ، ابزارهایی مانند Kubernetes برای مدیریت تعداد زیادی Container استفاده می شوند. با این حال، Docker Compose برای بسیاری از محیط های توسعه، آزمایش و پروژه های کوچک یا متوسط گزینه ساده و کاربردی است.</p>
<h2 dir="rtl" lang="fa">مسیر پیشنهادی یادگیری داکر</h2>
<p dir="rtl" lang="fa">برای یادگیری موثر Docker بهتر است فقط دستورات را حفظ نکنید. یک پروژه واقعی انتخاب کنید و مراحل زیر را انجام دهید:</p>
<ol dir="rtl" lang="fa">
<li>نصب Docker و اجرای <code>hello-world</code></li>
<li>اجرای یک Container آماده مانند Nginx</li>
<li>یادگیری مدیریت Image و Container</li>
<li>ساخت Dockerfile برای یک برنامه ساده</li>
<li>اتصال Volume و Bind Mount</li>
<li>ایجاد شبکه اختصاصی میان دو Container</li>
<li>اجرای برنامه و پایگاه داده با Docker Compose</li>
<li>مدیریت متغیرهای محیطی و اطلاعات حساس</li>
<li>بهینه کردن حجم و امنیت Image</li>
<li>استفاده از Docker در فرآیند آزمایش و استقرار</li>
</ol>
<p dir="rtl" lang="fa">پس از تسلط بر این موارد، می توانید مفاهیمی مانند Registry خصوصی، Multi-stage Build، Health Check، Docker Buildx، CI/CD و ابزارهای مدیریت Container را دنبال کنید.</p>
<h2 dir="rtl" lang="fa">جمع بندی آموزش داکر</h2>
<p dir="rtl" lang="fa">در این آموزش داکر با مفاهیم Image، Container، Dockerfile، Volume، Network و Docker Compose آشنا شدیم. همچنین نحوه نصب Docker، اجرای اولین Container، ساخت Image اختصاصی و راه اندازی چند سرویس را بررسی کردیم.</p>
<p dir="rtl" lang="fa">Docker زمانی بیشترین ارزش را ایجاد می کند که تنظیمات پروژه به شکل شفاف، قابل تکرار و تحت کنترل نسخه باشند. استفاده اصولی از این ابزار می تواند همکاری تیمی را ساده تر کند، خطاهای ناشی از تفاوت محیط ها را کاهش دهد و فرآیند توسعه و استقرار نرم افزار را منظم تر سازد.</p>
<p dir="rtl" lang="fa">اگر برای طراحی سایت، توسعه نرم افزار یا آماده سازی زیرساخت فنی پروژه خود به مشاوره و اجرای تخصصی نیاز دارید، از طریق صفحه <a href="https://tarahanenovin.ir/site/contact" target="_blank" rel="nofollow noopener noreferrer">تماس با طراحان نوین</a> با کارشناسان مجموعه در ارتباط باشید.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-docker-%d8%a7%d8%b2-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%a7%d8%ac%d8%b1%d8%a7%db%8c-%d9%be%d8%b1%d9%88%da%98%d9%87-%d9%88%d8%a7%d9%82%d8%b9%db%8c-%d8%a8/">آموزش Docker از صفر تا اجرای پروژه واقعی با داکر</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-docker-%d8%a7%d8%b2-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%a7%d8%ac%d8%b1%d8%a7%db%8c-%d9%be%d8%b1%d9%88%da%98%d9%87-%d9%88%d8%a7%d9%82%d8%b9%db%8c-%d8%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>آموزش صفر تا صد مدیریت پروژه در گیت هاب؛ راهنمای کاربردی برای تیم ها و کسب و کارها</title>
		<link>https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%b5%d8%af-%d9%85%d8%af%db%8c%d8%b1%db%8c%d8%aa-%d9%be%d8%b1%d9%88%da%98%d9%87-%d8%af%d8%b1-%da%af%db%8c%d8%aa-%d9%87%d8%a7%d8%a8/</link>
					<comments>https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%b5%d8%af-%d9%85%d8%af%db%8c%d8%b1%db%8c%d8%aa-%d9%be%d8%b1%d9%88%da%98%d9%87-%d8%af%d8%b1-%da%af%db%8c%d8%aa-%d9%87%d8%a7%d8%a8/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[طراحی وب]]></category>
		<category><![CDATA[فرانت‌اند]]></category>
		<category><![CDATA[معرفی ابزار]]></category>
		<category><![CDATA[موبایل]]></category>
		<category><![CDATA[ویندوز]]></category>
		<category><![CDATA[Github]]></category>
		<category><![CDATA[آموزش گیت]]></category>
		<category><![CDATA[گیت هاب]]></category>
		<category><![CDATA[مدیریت پروژه]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=109</guid>

					<description><![CDATA[<p>مدیریت پروژه در گیت هاب فقط مخصوص برنامه نویس ها نیست. اگر یک تیم طراحی سایت، تولید نرم افزار، طراحی رابط کاربری، سئو یا حتی تولید محتوا دارید، GitHub می تواند به شما کمک کند وظایف را منظم تر مدیریت کنید، تغییرات را دقیق تر پیگیری کنید و همکاری بین اعضای تیم را شفاف تر انجام دهید. در این مقاله از طراحان نوین، به صورت کامل و کاربردی با مدیریت پروژه در گیت هاب آشنا می شوید؛ از ساخت مخزن و تعریف Issue گرفته تا استفاده از GitHub Projects، Pull Request، Branch، Milestone و اتوماسیون های کاربردی. گیت هاب چیست و چرا برای مدیریت پروژه مهم است؟ گیت هاب یک پلتفرم تحت وب برای میزبانی کد، مدیریت نسخه ها و همکاری تیمی روی پروژه های نرم افزاری است. این سرویس بر پایه Git کار می کند و به تیم ها اجازه می دهد تغییرات پروژه را مرحله به مرحله ثبت، بررسی و مدیریت کنند. اما کاربرد GitHub فقط به ذخیره کد محدود نمی شود. امروزه بسیاری از تیم های حرفه ای از گیت هاب برای موارد زیر استفاده می کنند: مدیریت وظایف پروژه ثبت باگ ها و درخواست های جدید بررسی تغییرات قبل از انتشار مستند سازی پروژه برنامه ریزی اسپرینت ها همکاری بین برنامه نویسان، طراحان و مدیران پروژه کنترل کیفیت کد و فرآیند توسعه برای آشنایی رسمی با امکانات این پلتفرم، می توانید به مستندات گیت هاب در آدرس زیر مراجعه کنید: GitHub Docs مدیریت پروژه در گیت هاب برای چه کسانی مناسب است؟ مدیریت پروژه در گیت هاب برای تیم هایی مناسب است که نیاز به نظم، شفافیت و کنترل دقیق روی روند انجام کارها دارند. این ابزار برای گروه های زیر بسیار کاربردی است: تیم های برنامه نویسی تیم های توسعه وب، اپلیکیشن موبایل، نرم افزار دسکتاپ و سرویس های آنلاین می توانند از گیت هاب برای کنترل نسخه، بررسی کد، مدیریت تسک ها و انتشار نسخه های جدید استفاده کنند. شرکت های طراحی سایت در پروژه های طراحی سایت، معمولا چند نفر روی بخش های مختلف پروژه کار می کنند؛ از طراحی رابط کاربری تا پیاده سازی فرانت اند، بک اند، سئو و تست. گیت هاب کمک می کند همه این فعالیت ها در یک ساختار مشخص مدیریت شوند. استارتاپ ها استارتاپ ها معمولا با منابع محدود و سرعت بالا کار می کنند. گیت هاب باعث می شود ایده ها، باگ ها، نسخه ها و وظایف تیمی به شکل دقیق ثبت و قابل پیگیری باشند. مدیران پروژه دیجیتال حتی اگر برنامه نویس نباشید، می توانید از امکاناتی مثل GitHub Projects، Issues و Milestones برای پیگیری وظایف تیم و زمان بندی پروژه استفاده کنید. مفاهیم پایه در مدیریت پروژه با گیت هاب قبل از شروع کار، بهتر است چند مفهوم اصلی گیت هاب را بشناسید. این مفاهیم پایه مدیریت پروژه در گیت هاب هستند. Repository یا مخزن مخزن یا Repository محل نگهداری فایل های پروژه است. تمام کدها، مستندات، تصاویر، تنظیمات و تغییرات پروژه داخل مخزن قرار می گیرند. هر پروژه معمولا یک Repository اختصاصی دارد. برای مثال: پروژه طراحی سایت فروشگاهی پروژه اپلیکیشن اندروید پروژه پنل مدیریتی پروژه قالب وردپرس پروژه API بک اند Branch یا شاخه Branch به شما اجازه می دهد بدون دست زدن به نسخه اصلی پروژه، تغییرات جدید را در یک مسیر جداگانه انجام دهید. برای مثال، می توانید برای طراحی صفحه تماس با ما یک شاخه جدید بسازید: feature/contact-page بعد از کامل شدن و بررسی تغییرات، این شاخه می تواند با شاخه اصلی ادغام شود. Commit یا ثبت تغییرات Commit یعنی ثبت یک تغییر مشخص در تاریخچه پروژه. هر Commit بهتر است پیام واضحی داشته باشد تا بعدا مشخص شود چه تغییری، توسط چه کسی و با چه هدفی انجام شده است. نمونه پیام Commit مناسب: Add contact form validation نمونه پیام نامناسب: Update files پیام های دقیق، مدیریت پروژه را بسیار آسان تر می کنند. Pull Request یا درخواست ادغام Pull Request زمانی ایجاد می شود که یک عضو تیم تغییراتی را در یک شاخه انجام داده و می خواهد آن را وارد شاخه اصلی کند. در این مرحله، سایر اعضای تیم می توانند تغییرات را بررسی کنند، نظر بدهند، اصلاح بخواهند یا آن را تایید کنند. Issue یا وظیفه و مشکل Issue یکی از مهم ترین ابزارهای مدیریت پروژه در گیت هاب است. با Issue می توانید موارد زیر را ثبت کنید: باگ ها درخواست قابلیت جدید وظایف تیم سوالات فنی پیشنهادهای بهبود کارهای مربوط به تست و کیفیت شروع مدیریت پروژه در گیت هاب برای مدیریت پروژه در گیت هاب، بهتر است یک ساختار مشخص داشته باشید. در ادامه، مراحل اصلی را بررسی می کنیم. مرحله اول: ساخت Repository برای پروژه ابتدا وارد حساب GitHub خود شوید و یک Repository جدید بسازید. برای این کار: روی گزینه New Repository کلیک کنید. نام پروژه را وارد کنید. توضیح کوتاهی برای پروژه بنویسید. نوع مخزن را Public یا Private انتخاب کنید. فایل README را فعال کنید. در صورت نیاز، فایل .gitignore مناسب زبان پروژه را انتخاب کنید. اگر پروژه شما تجاری یا مربوط به مشتری است، بهتر است مخزن را Private بسازید. نکات مهم در نام گذاری Repository نام مخزن باید کوتاه، واضح و قابل فهم باشد. برای مثال: company-website crm-panel online-shop-api mobile-app wordpress-theme از نام های نامفهوم، فارسی یا خیلی طولانی برای مخزن استفاده نکنید. مرحله دوم: ساختاردهی فایل های پروژه یکی از اصول مهم مدیریت پروژه در گیت هاب، داشتن ساختار فایل منظم است. این موضوع مخصوصا در پروژه های تیمی اهمیت زیادی دارد. برای مثال، ساختار یک پروژه وب می تواند به شکل زیر باشد: project-name/ │ ├── docs/ ├── src/ ├── public/ ├── tests/ ├── assets/ ├── README.md ├── .gitignore └── package.json چرا ساختار فایل مهم است؟ ساختار مناسب باعث می شود: اعضای تیم سریع تر پروژه را درک کنند. توسعه پروژه راحت تر شود. خطاهای انسانی کاهش پیدا کند. مستند سازی بهتر انجام شود. ورود نیروهای جدید به پروژه آسان تر شود. مرحله سوم: نوشتن فایل README حرفه ای فایل README اولین چیزی است که اعضای تیم یا کاربران پروژه مشاهده می کنند. بنابراین باید واضح، کامل و کاربردی باشد. یک README مناسب بهتر است شامل موارد زیر باشد: معرفی پروژه هدف پروژه تکنولوژی های استفاده شده روش نصب و اجرا ساختار پوشه ها دستورات مهم روش مشارکت در پروژه اطلاعات تماس یا پشتیبانی نمونه ساختار ساده README: # Project Name ## Introduction Short description of the project. ## Technologies - PHP - Yii2 - MySQL - Bootstrap ## Installation 1. Clone the repository 2. Install dependencies 3. Configure database 4. Run the project ## Contribution Please create a new branch and submit a pull request. برای یادگیری بیشتر درباره README می توانید راهنمای رسمی گیت هاب را بررسی کنید: About README files مرحله چهارم: تعریف Issue برای وظایف پروژه Issue قلب مدیریت پروژه در گیت هاب است. هر کار، مشکل یا قابلیت جدید بهتر است به صورت یک Issue ثبت شود. نمونه Issue برای باگ Title: مشکل در ارسال فرم تماس با ما Description: در صفحه تماس با ما، بعد از وارد کردن اطلاعات و کلیک روی دکمه ارسال، پیام موفقیت نمایش داده نمی شود. Steps to reproduce: 1. ورود به صفحه تماس با ما 2. تکمیل فرم 3. کلیک روی دکمه ارسال Expected result: نمایش پیام موفقیت Actual result: هیچ پیامی نمایش داده نمی شود نمونه Issue برای قابلیت جدید Title: افزودن فیلتر قیمت به صفحه محصولات Description: در صفحه محصولات، کاربر باید بتواند محصولات را بر اساس بازه قیمت فیلتر کند. Acceptance Criteria: - فیلتر حداقل قیمت وجود داشته باشد. - فیلتر حداکثر قیمت وجود داشته باشد. - بعد از اعمال فیلتر، فقط محصولات مرتبط نمایش داده شوند. نکته مهم در نوشتن Issue هر Issue باید فقط یک موضوع مشخص داشته باشد. اگر چند کار مختلف را داخل یک Issue بنویسید، پیگیری آن سخت می شود. مرحله پنجم: استفاده از Label برای دسته بندی کارها Label ها برچسب هایی هستند که به Issue ها و Pull Request ها اضافه می شوند تا دسته بندی و اولویت بندی ساده تر شود. Label های پیشنهادی برای پروژه های نرم افزاری bug برای خطاها feature برای قابلیت جدید enhancement برای بهبود documentation برای مستندات design برای طراحی frontend برای فرانت اند backend برای بک اند urgent برای موارد فوری question برای سوالات استفاده درست از Label باعث می شود مدیر پروژه سریع تر وضعیت کلی پروژه را بررسی کند. مرحله ششم: تعریف Milestone برای نسخه ها و فازها Milestone برای گروه بندی Issue ها بر اساس نسخه، فاز یا بازه زمانی استفاده می شود. برای مثال: Version 1.0 Version 1.1 MVP Sprint 01 Redesign Phase SEO Improvements اگر برای یک پروژه طراحی سایت، فازهای مختلف داشته باشید، می توانید هر فاز را به عنوان یک Milestone تعریف کنید: فاز طراحی رابط کاربری فاز پیاده سازی فرانت اند فاز توسعه بک اند فاز تست و رفع باگ فاز تحویل نهایی مزیت استفاده از Milestone Milestone کمک می کند بدانید: چه کارهایی برای یک نسخه باقی مانده است. چند درصد پروژه انجام شده است. کدام بخش ها تاخیر دارند. وضعیت کلی هر فاز چگونه است. مرحله هفتم: استفاده از GitHub Projects GitHub Projects یکی از قدرتمندترین ابزارهای مدیریت پروژه در گیت هاب است. این بخش به شما اجازه می دهد وظایف را در قالب بردهای کاری مدیریت کنید. در ساده ترین حالت، می توانید یک برد Kanban بسازید و ستون های زیر را داشته باشید: Backlog To Do In Progress Review Done معنی هر ستون در برد پروژه Backlog لیست ایده ها، پیشنهادها و کارهایی که هنوز وارد برنامه اجرایی نشده اند. To Do کارهایی که باید انجام شوند و در برنامه فعلی قرار دارند. In Progress کارهایی که در حال انجام هستند. Review کارهایی که انجام شده اند اما نیاز به بررسی، تست یا تایید دارند. Done کارهایی که کامل شده اند و نیاز به اقدام بیشتری ندارند. برای مطالعه بیشتر درباره GitHub Projects می توانید از مستندات رسمی استفاده کنید: GitHub Projects Documentation مرحله هشتم: طراحی جریان کاری استاندارد در گیت هاب برای اینکه مدیریت پروژه در گیت هاب به شکل حرفه ای انجام شود، باید یک جریان کاری مشخص داشته باشید. یک جریان کاری مناسب می تواند به شکل زیر باشد: ایجاد Issue برای هر کار اختصاص دادن Issue به مسئول مربوطه ساخت Branch برای انجام کار انجام تغییرات و ثبت Commit های منظم ایجاد Pull Request بررسی کد توسط اعضای تیم انجام اصلاحات در صورت نیاز تایید و ادغام با شاخه اصلی بستن Issue انتقال کارت به ستون Done این ساختار باعث می شود هیچ کاری بدون ثبت، بررسی و تایید وارد پروژه نشود. مرحله نهم: نام گذاری استاندارد Branch ها نام گذاری درست Branch ها باعث نظم بیشتر پروژه می شود. بهتر است قبل از شروع پروژه، یک قانون مشخص برای تیم تعریف کنید. نمونه الگوی نام گذاری Branch feature/login-page bugfix/contact-form-error hotfix/payment-gateway refactor/user-service docs/api-documentation انواع رایج Branch feature برای قابلیت جدید bugfix برای رفع باگ hotfix برای اصلاح فوری refactor برای بازنویسی کد docs برای مستندات test برای تست ها این روش در پروژه های بزرگ، مخصوصا پروژه های طراحی سایت، اپلیکیشن و نرم افزارهای سازمانی بسیار کاربردی است. مرحله دهم: مدیریت Pull Request ها Pull Request یکی از نقاط کلیدی کنترل کیفیت پروژه است. هیچ تغییری نباید بدون بررسی وارد شاخه اصلی شود. یک Pull Request خوب باید چه ویژگی هایی داشته باشد؟ عنوان واضح داشته باشد. توضیح دهد چه تغییری انجام شده است. به Issue مرتبط وصل شده باشد. اسکرین شات یا توضیح تست داشته باشد. تغییرات آن محدود و قابل بررسی باشد. فقط روی یک موضوع مشخص تمرکز کند. نمونه متن Pull Request Title: Add login page validation Description: This pull request adds client-side validation to the login page. Related issue: Closes #24 Changes: - Added validation for email field - Added validation for password field - Added error messages Test: - Tested with empty fields - Tested with invalid email - Tested with valid data نکته حرفه ای Pull Request های بزرگ معمولا سخت بررسی می شوند و احتمال خطا در آن ها بیشتر است. بهتر است تغییرات را به بخش های کوچک تر تقسیم کنید. مرحله یازدهم: استفاده از GitHub Actions برای اتوماسیون GitHub Actions ابزاری برای خودکار سازی فرآیندهای پروژه است. با این قابلیت می توانید کارهایی مثل تست، بررسی کد، ساخت پروژه و انتشار را به صورت خودکار انجام دهید. کاربردهای GitHub Actions اجرای تست ها بعد از هر Pull Request بررسی کیفیت کد ساخت نسخه نهایی پروژه انتشار خودکار روی سرور ارسال اعلان به تیم اجرای اسکریپت های زمان بندی شده برای اطلاعات بیشتر می توانید راهنمای رسمی آن را ببینید: GitHub Actions Documentation نمونه کاربرد ساده فرض کنید در یک پروژه طراحی سایت، هر بار که یک Pull Request ایجاد می شود، تست های پروژه به صورت خودکار اجرا شوند. اگر تست ها موفق باشند، تیم می تواند با اطمینان بیشتری تغییرات را تایید کند. مرحله دوازدهم: مدیریت دسترسی اعضای تیم در پروژه های واقعی، همه اعضای تیم نباید دسترسی یکسان داشته باشند. گیت هاب امکان مدیریت سطح دسترسی را فراهم می کند. سطوح دسترسی رایج Read: فقط مشاهده پروژه Triage: مدیریت Issue ها بدون تغییر کد Write: امکان تغییر کد و ایجاد Branch Maintain: مدیریت بخش های اصلی پروژه Admin: دسترسی کامل به تنظیمات پروژه چرا مدیریت دسترسی مهم است؟ مدیریت دسترسی باعث افزایش امنیت پروژه می شود. در پروژه های مشتریان، اطلاعات حساس، کدهای اختصاصی و تنظیمات سرور باید فقط در اختیار افراد مجاز باشد. مرحله سیزدهم: مستند سازی فرآیندها یکی از اشتباهات رایج در مدیریت پروژه های نرم افزاری، بی توجهی به مستند سازی است. حتی اگر بهترین کد را بنویسید، بدون مستندات مناسب، نگهداری پروژه سخت می شود. چه چیزهایی باید مستند شوند؟ روش نصب پروژه تنظیمات محیط توسعه استانداردهای کد نویسی روش ایجاد Branch روش ثبت Pull Request فرآیند انتشار نسخه راهنمای استفاده از API ساختار دیتابیس نکات امنیتی می توانید این مستندات را در پوشه docs قرار دهید یا از بخش Wiki گیت هاب استفاده کنید. مرحله چهاردهم: استفاده از Wiki در گیت هاب GitHub Wiki برای نگهداری مستندات طولانی و آموزشی پروژه مناسب است. برای مثال، می توانید صفحات زیر را در Wiki ایجاد کنید: راهنمای نصب پروژه معرفی ساختار پروژه راهنمای توسعه برای برنامه نویسان جدید مستندات API قوانین همکاری تیمی راهنمای استقرار روی سرور Wiki مخصوصا در پروژه های طولانی مدت و تیمی بسیار مفید است. مرحله پانزدهم: مدیریت نسخه ها با Release و Tag وقتی یک نسخه مشخص از پروژه آماده انتشار است، بهتر است از Tag و Release استفاده کنید. Tag چیست؟ Tag یک نشان مشخص روی یک نقطه از تاریخچه پروژه است. معمولا برای نسخه گذاری استفاده می شود. نمونه: v1.0.0 v1.1.0 v2.0.0 Release چیست؟ Release نسخه منتشر شده پروژه است که می تواند شامل توضیحات، فایل های خروجی و لیست تغییرات باشد. نمونه نسخه گذاری استاندارد v1.0.0 در این روش: عدد اول برای تغییرات بزرگ عدد دوم برای قابلیت های جدید عدد سوم برای رفع باگ ها استفاده می شود. مرحله شانزدهم: مدیریت باگ ها در گیت هاب یکی از مهم ترین کاربردهای گیت هاب، مدیریت باگ ها است. برای اینکه باگ ها درست پیگیری شوند، باید ساختار مشخصی برای ثبت آن ها داشته باشید. قالب پیشنهادی گزارش باگ Title: توضیح کوتاه مشکل Environment: مرورگر، سیستم عامل، نسخه نرم افزار Steps to reproduce: مراحل ایجاد مشکل Expected result: نتیجه مورد انتظار Actual result: نتیجه واقعی Screenshot: تصویر یا ویدیو در صورت نیاز این قالب کمک می کند برنامه نویس سریع تر مشکل را پیدا و رفع کند. مرحله هفدهم: مدیریت کارهای طراحی سایت در گیت هاب در پروژه های طراحی سایت، گیت هاب می تواند برای هماهنگی بین طراح، برنامه نویس، کارشناس سئو و مدیر پروژه استفاده شود. نمونه Issue های مربوط به طراحی سایت طراحی صفحه اصلی پیاده سازی منوی واکنش گرا اتصال فرم تماس با ما افزودن اسکیما به صفحات بهینه سازی سرعت بارگذاری رفع خطای نمایش در موبایل تنظیم متا تگ های صفحات تست فرم ثبت نام اتصال درگاه پرداخت نمونه Label های مناسب طراحی سایت ui-design frontend backend seo performance responsive content security این دسته بندی کمک می کند هر عضو تیم دقیقا بداند مسئول چه بخشی است. مرحله هجدهم: مدیریت پروژه های سئو با گیت هاب اگرچه گیت هاب بیشتر به عنوان ابزار برنامه نویسی شناخته می شود، اما برای مدیریت پروژه های سئو هم می تواند مفید باشد. کاربرد گیت هاب در پروژه سئو ثبت مشکلات فنی سایت پیگیری بهینه سازی سرعت مدیریت تغییرات متا تگ ها ثبت خطاهای سرچ کنسول برنامه ریزی تولید محتوا پیگیری بهینه سازی ساختار لینک داخلی بررسی مشکلات Core Web Vitals ثبت تغییرات فایل robots.txt و sitemap.xml برای مطالعه بیشتر درباره اصول فنی سئو می توانید از راهنمای گوگل استفاده کنید: Google Search Central مرحله نوزدهم: نکات امنیتی در مدیریت پروژه با گیت هاب امنیت در گیت هاب بسیار مهم است؛ مخصوصا اگر پروژه تجاری یا اطلاعات مشتریان در آن وجود داشته باشد. نکات مهم امنیتی هیچ وقت رمز عبور را داخل کد قرار ندهید. فایل های تنظیمات حساس را در .gitignore قرار دهید. از Secret های GitHub Actions استفاده کنید. دسترسی اعضای تیم را محدود و کنترل شده تعریف کنید. مخازن خصوصی را برای پروژه های مشتریان انتخاب کنید. Pull Request ها را قبل از ادغام بررسی کنید. از احراز هویت دو مرحله ای استفاده کنید. فایل هایی که معمولا نباید Commit شوند .env config.local.php database-password.txt private-key.pem node_modules/ vendor/ برای مدیریت بهتر فایل های نادیده گرفته شده می توانید از مستندات رسمی Git استفاده کنید: Git Ignore Documentation مرحله بیستم: اشتباهات رایج در مدیریت پروژه در گیت هاب برای اینکه مدیریت پروژه در گیت هاب موفق باشد، باید از چند اشتباه رایج دوری کنید. 1. ثبت نکردن وظایف به صورت Issue اگر کارها فقط در پیام رسان یا جلسه شفاهی مطرح شوند، احتمال فراموشی و بی نظمی بالا می رود. هر کار مهم باید در قالب Issue ثبت شود. 2. پیام Commit نامفهوم پیام هایی مثل fix یا update در آینده هیچ کمکی به تیم نمی کنند. پیام Commit باید توضیح دهد دقیقا چه چیزی تغییر کرده است. 3. ادغام مستقیم در شاخه اصلی کار کردن مستقیم روی شاخه اصلی می تواند خطرناک باشد. بهتر است برای هر تغییر، یک Branch جداگانه ساخته شود. 4. Pull Request های بسیار بزرگ Pull Request بزرگ بررسی را سخت می کند و احتمال خطا را افزایش می دهد. تغییرات را کوچک و هدفمند نگه دارید. 5. نداشتن مستندات بدون مستندات، پروژه به مرور برای اعضای جدید و حتی اعضای فعلی نامفهوم می شود. 6. مدیریت نکردن دسترسی ها دادن دسترسی...</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%b5%d8%af-%d9%85%d8%af%db%8c%d8%b1%db%8c%d8%aa-%d9%be%d8%b1%d9%88%da%98%d9%87-%d8%af%d8%b1-%da%af%db%8c%d8%aa-%d9%87%d8%a7%d8%a8/">آموزش صفر تا صد مدیریت پروژه در گیت هاب؛ راهنمای کاربردی برای تیم ها و کسب و کارها</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<p dir="rtl" lang="fa">مدیریت پروژه در گیت هاب فقط مخصوص برنامه نویس ها نیست. اگر یک تیم طراحی سایت، تولید نرم افزار، طراحی رابط کاربری، سئو یا حتی تولید محتوا دارید، GitHub می تواند به شما کمک کند وظایف را منظم تر مدیریت کنید، تغییرات را دقیق تر پیگیری کنید و همکاری بین اعضای تیم را شفاف تر انجام دهید.</p>
<p dir="rtl" lang="fa">در این مقاله از طراحان نوین، به صورت کامل و کاربردی با مدیریت پروژه در گیت هاب آشنا می شوید؛ از ساخت مخزن و تعریف Issue گرفته تا استفاده از GitHub Projects، Pull Request، Branch، Milestone و اتوماسیون های کاربردی.</p>
<hr />
<h2 dir="rtl" lang="fa">گیت هاب چیست و چرا برای مدیریت پروژه مهم است؟</h2>
<p dir="rtl" lang="fa">گیت هاب یک پلتفرم تحت وب برای میزبانی کد، مدیریت نسخه ها و همکاری تیمی روی پروژه های نرم افزاری است. این سرویس بر پایه Git کار می کند و به تیم ها اجازه می دهد تغییرات پروژه را مرحله به مرحله ثبت، بررسی و مدیریت کنند.</p>
<p dir="rtl" lang="fa">اما کاربرد GitHub فقط به ذخیره کد محدود نمی شود. امروزه بسیاری از تیم های حرفه ای از گیت هاب برای موارد زیر استفاده می کنند:</p>
<ul dir="rtl" lang="fa">
<li>مدیریت وظایف پروژه</li>
<li>ثبت باگ ها و درخواست های جدید</li>
<li>بررسی تغییرات قبل از انتشار</li>
<li>مستند سازی پروژه</li>
<li>برنامه ریزی اسپرینت ها</li>
<li>همکاری بین برنامه نویسان، طراحان و مدیران پروژه</li>
<li>کنترل کیفیت کد و فرآیند توسعه</li>
</ul>
<p dir="rtl" lang="fa">برای آشنایی رسمی با امکانات این پلتفرم، می توانید به مستندات گیت هاب در آدرس زیر مراجعه کنید:</p>
<p lang="en"><a href="https://docs.github.com" target="_blank" rel="nofollow noopener noreferrer">GitHub Docs</a></p>
<hr />
<h2 dir="rtl" lang="fa">مدیریت پروژه در گیت هاب برای چه کسانی مناسب است؟</h2>
<p dir="rtl" lang="fa">مدیریت پروژه در گیت هاب برای تیم هایی مناسب است که نیاز به نظم، شفافیت و کنترل دقیق روی روند انجام کارها دارند. این ابزار برای گروه های زیر بسیار کاربردی است:</p>
<h3 dir="rtl" lang="fa">تیم های برنامه نویسی</h3>
<p dir="rtl" lang="fa">تیم های توسعه وب، اپلیکیشن موبایل، نرم افزار دسکتاپ و سرویس های آنلاین می توانند از گیت هاب برای کنترل نسخه، بررسی کد، مدیریت تسک ها و انتشار نسخه های جدید استفاده کنند.</p>
<h3 dir="rtl" lang="fa">شرکت های طراحی سایت</h3>
<p dir="rtl" lang="fa">در پروژه های طراحی سایت، معمولا چند نفر روی بخش های مختلف پروژه کار می کنند؛ از طراحی رابط کاربری تا پیاده سازی فرانت اند، بک اند، سئو و تست. گیت هاب کمک می کند همه این فعالیت ها در یک ساختار مشخص مدیریت شوند.</p>
<h3 dir="rtl" lang="fa">استارتاپ ها</h3>
<p dir="rtl" lang="fa">استارتاپ ها معمولا با منابع محدود و سرعت بالا کار می کنند. گیت هاب باعث می شود ایده ها، باگ ها، نسخه ها و وظایف تیمی به شکل دقیق ثبت و قابل پیگیری باشند.</p>
<h3 dir="rtl" lang="fa">مدیران پروژه دیجیتال</h3>
<p dir="rtl" lang="fa">حتی اگر برنامه نویس نباشید، می توانید از امکاناتی مثل GitHub Projects، Issues و Milestones برای پیگیری وظایف تیم و زمان بندی پروژه استفاده کنید.</p>
<hr />
<h2 dir="rtl" lang="fa">مفاهیم پایه در مدیریت پروژه با گیت هاب</h2>
<p dir="rtl" lang="fa">قبل از شروع کار، بهتر است چند مفهوم اصلی گیت هاب را بشناسید. این مفاهیم پایه مدیریت پروژه در گیت هاب هستند.</p>
<h3 dir="rtl" lang="fa">Repository یا مخزن</h3>
<p dir="rtl" lang="fa">مخزن یا Repository محل نگهداری فایل های پروژه است. تمام کدها، مستندات، تصاویر، تنظیمات و تغییرات پروژه داخل مخزن قرار می گیرند.</p>
<p dir="rtl" lang="fa">هر پروژه معمولا یک Repository اختصاصی دارد. برای مثال:</p>
<ul dir="rtl" lang="fa">
<li>پروژه طراحی سایت فروشگاهی</li>
<li>پروژه اپلیکیشن اندروید</li>
<li>پروژه پنل مدیریتی</li>
<li>پروژه قالب وردپرس</li>
<li>پروژه API بک اند</li>
</ul>
<h3 dir="rtl" lang="fa">Branch یا شاخه</h3>
<p dir="rtl" lang="fa">Branch به شما اجازه می دهد بدون دست زدن به نسخه اصلی پروژه، تغییرات جدید را در یک مسیر جداگانه انجام دهید.</p>
<p dir="rtl" lang="fa">برای مثال، می توانید برای طراحی صفحه تماس با ما یک شاخه جدید بسازید:</p>
<pre><code class="hljs">feature/contact-page
</code></pre>
<p dir="rtl" lang="fa">بعد از کامل شدن و بررسی تغییرات، این شاخه می تواند با شاخه اصلی ادغام شود.</p>
<h3 dir="rtl" lang="fa">Commit یا ثبت تغییرات</h3>
<p dir="rtl" lang="fa">Commit یعنی ثبت یک تغییر مشخص در تاریخچه پروژه. هر Commit بهتر است پیام واضحی داشته باشد تا بعدا مشخص شود چه تغییری، توسط چه کسی و با چه هدفی انجام شده است.</p>
<p dir="rtl" lang="fa">نمونه پیام Commit مناسب:</p>
<pre><code class="hljs">Add contact form validation
</code></pre>
<p dir="rtl" lang="fa">نمونه پیام نامناسب:</p>
<pre><code class="hljs">Update files
</code></pre>
<p dir="rtl" lang="fa">پیام های دقیق، مدیریت پروژه را بسیار آسان تر می کنند.</p>
<h3 dir="rtl" lang="fa">Pull Request یا درخواست ادغام</h3>
<p dir="rtl" lang="fa">Pull Request زمانی ایجاد می شود که یک عضو تیم تغییراتی را در یک شاخه انجام داده و می خواهد آن را وارد شاخه اصلی کند.</p>
<p dir="rtl" lang="fa">در این مرحله، سایر اعضای تیم می توانند تغییرات را بررسی کنند، نظر بدهند، اصلاح بخواهند یا آن را تایید کنند.</p>
<h3 dir="rtl" lang="fa">Issue یا وظیفه و مشکل</h3>
<p dir="rtl" lang="fa">Issue یکی از مهم ترین ابزارهای مدیریت پروژه در گیت هاب است. با Issue می توانید موارد زیر را ثبت کنید:</p>
<ul dir="rtl" lang="fa">
<li>باگ ها</li>
<li>درخواست قابلیت جدید</li>
<li>وظایف تیم</li>
<li>سوالات فنی</li>
<li>پیشنهادهای بهبود</li>
<li>کارهای مربوط به تست و کیفیت</li>
</ul>
<hr />
<h2 dir="rtl" lang="fa">شروع مدیریت پروژه در گیت هاب</h2>
<p dir="rtl" lang="fa">برای مدیریت پروژه در گیت هاب، بهتر است یک ساختار مشخص داشته باشید. در ادامه، مراحل اصلی را بررسی می کنیم.</p>
<h2 dir="rtl" lang="fa">مرحله اول: ساخت Repository برای پروژه</h2>
<p dir="rtl" lang="fa">ابتدا وارد حساب GitHub خود شوید و یک Repository جدید بسازید. برای این کار:</p>
<ol dir="rtl" lang="fa">
<li>روی گزینه New Repository کلیک کنید.</li>
<li>نام پروژه را وارد کنید.</li>
<li>توضیح کوتاهی برای پروژه بنویسید.</li>
<li>نوع مخزن را Public یا Private انتخاب کنید.</li>
<li>فایل README را فعال کنید.</li>
<li>در صورت نیاز، فایل .gitignore مناسب زبان پروژه را انتخاب کنید.</li>
</ol>
<p dir="rtl" lang="fa">اگر پروژه شما تجاری یا مربوط به مشتری است، بهتر است مخزن را Private بسازید.</p>
<h3 dir="rtl" lang="fa">نکات مهم در نام گذاری Repository</h3>
<p dir="rtl" lang="fa">نام مخزن باید کوتاه، واضح و قابل فهم باشد. برای مثال:</p>
<pre><code class="hljs">company-website
crm-panel
online-shop-api
mobile-app
wordpress-theme
</code></pre>
<p dir="rtl" lang="fa">از نام های نامفهوم، فارسی یا خیلی طولانی برای مخزن استفاده نکنید.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله دوم: ساختاردهی فایل های پروژه</h2>
<p dir="rtl" lang="fa">یکی از اصول مهم مدیریت پروژه در گیت هاب، داشتن ساختار فایل منظم است. این موضوع مخصوصا در پروژه های تیمی اهمیت زیادی دارد.</p>
<p dir="rtl" lang="fa">برای مثال، ساختار یک پروژه وب می تواند به شکل زیر باشد:</p>
<pre><code class="hljs">project-name/
│
├── docs/
├── src/
├── public/
├── tests/
├── assets/
├── README.md
├── .gitignore
└── package.json
</code></pre>
<h3 dir="rtl" lang="fa">چرا ساختار فایل مهم است؟</h3>
<p dir="rtl" lang="fa">ساختار مناسب باعث می شود:</p>
<ul dir="rtl" lang="fa">
<li>اعضای تیم سریع تر پروژه را درک کنند.</li>
<li>توسعه پروژه راحت تر شود.</li>
<li>خطاهای انسانی کاهش پیدا کند.</li>
<li>مستند سازی بهتر انجام شود.</li>
<li>ورود نیروهای جدید به پروژه آسان تر شود.</li>
</ul>
<hr />
<h2 dir="rtl" lang="fa">مرحله سوم: نوشتن فایل README حرفه ای</h2>
<p dir="rtl" lang="fa">فایل README اولین چیزی است که اعضای تیم یا کاربران پروژه مشاهده می کنند. بنابراین باید واضح، کامل و کاربردی باشد.</p>
<p dir="rtl" lang="fa">یک README مناسب بهتر است شامل موارد زیر باشد:</p>
<ul dir="rtl" lang="fa">
<li>معرفی پروژه</li>
<li>هدف پروژه</li>
<li>تکنولوژی های استفاده شده</li>
<li>روش نصب و اجرا</li>
<li>ساختار پوشه ها</li>
<li>دستورات مهم</li>
<li>روش مشارکت در پروژه</li>
<li>اطلاعات تماس یا پشتیبانی</li>
</ul>
<p dir="rtl" lang="fa">نمونه ساختار ساده README:</p>
<pre><code class="hljs"><span class="hljs-section"># Project Name</span>

<span class="hljs-section">## Introduction</span>
Short description of the project.

<span class="hljs-section">## Technologies</span>
<span class="hljs-bullet">-</span> PHP
<span class="hljs-bullet">-</span> Yii2
<span class="hljs-bullet">-</span> MySQL
<span class="hljs-bullet">-</span> Bootstrap

<span class="hljs-section">## Installation</span>
<span class="hljs-bullet">1.</span> Clone the repository
<span class="hljs-bullet">2.</span> Install dependencies
<span class="hljs-bullet">3.</span> Configure database
<span class="hljs-bullet">4.</span> Run the project

<span class="hljs-section">## Contribution</span>
Please create a new branch and submit a pull request.
</code></pre>
<p dir="rtl" lang="fa">برای یادگیری بیشتر درباره README می توانید راهنمای رسمی گیت هاب را بررسی کنید:</p>
<p lang="en"><a href="https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes" target="_blank" rel="nofollow noopener noreferrer">About README files</a></p>
<hr />
<h2 dir="rtl" lang="fa">مرحله چهارم: تعریف Issue برای وظایف پروژه</h2>
<p dir="rtl" lang="fa">Issue قلب مدیریت پروژه در گیت هاب است. هر کار، مشکل یا قابلیت جدید بهتر است به صورت یک Issue ثبت شود.</p>
<h3 dir="rtl" lang="fa">نمونه Issue برای باگ</h3>
<pre><code class="hljs">Title: مشکل در ارسال فرم تماس با ما

Description:
در صفحه تماس با ما، بعد از وارد کردن اطلاعات و کلیک روی دکمه ارسال، پیام موفقیت نمایش داده نمی شود.

Steps to reproduce:
1. ورود به صفحه تماس با ما
2. تکمیل فرم
3. کلیک روی دکمه ارسال

Expected result:
نمایش پیام موفقیت

Actual result:
هیچ پیامی نمایش داده نمی شود
</code></pre>
<h3 dir="rtl" lang="fa">نمونه Issue برای قابلیت جدید</h3>
<pre><code class="hljs">Title: افزودن فیلتر قیمت به صفحه محصولات

Description:
در صفحه محصولات، کاربر باید بتواند محصولات را بر اساس بازه قیمت فیلتر کند.

Acceptance Criteria:
- فیلتر حداقل قیمت وجود داشته باشد.
- فیلتر حداکثر قیمت وجود داشته باشد.
- بعد از اعمال فیلتر، فقط محصولات مرتبط نمایش داده شوند.
</code></pre>
<h3 dir="rtl" lang="fa">نکته مهم در نوشتن Issue</h3>
<p dir="rtl" lang="fa">هر Issue باید فقط یک موضوع مشخص داشته باشد. اگر چند کار مختلف را داخل یک Issue بنویسید، پیگیری آن سخت می شود.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله پنجم: استفاده از Label برای دسته بندی کارها</h2>
<p dir="rtl" lang="fa">Label ها برچسب هایی هستند که به Issue ها و Pull Request ها اضافه می شوند تا دسته بندی و اولویت بندی ساده تر شود.</p>
<h3 dir="rtl" lang="fa">Label های پیشنهادی برای پروژه های نرم افزاری</h3>
<ul dir="rtl" lang="fa">
<li><code>bug</code> برای خطاها</li>
<li><code>feature</code> برای قابلیت جدید</li>
<li><code>enhancement</code> برای بهبود</li>
<li><code>documentation</code> برای مستندات</li>
<li><code>design</code> برای طراحی</li>
<li><code>frontend</code> برای فرانت اند</li>
<li><code>backend</code> برای بک اند</li>
<li><code>urgent</code> برای موارد فوری</li>
<li><code>question</code> برای سوالات</li>
</ul>
<p dir="rtl" lang="fa">استفاده درست از Label باعث می شود مدیر پروژه سریع تر وضعیت کلی پروژه را بررسی کند.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله ششم: تعریف Milestone برای نسخه ها و فازها</h2>
<p dir="rtl" lang="fa">Milestone برای گروه بندی Issue ها بر اساس نسخه، فاز یا بازه زمانی استفاده می شود.</p>
<p dir="rtl" lang="fa">برای مثال:</p>
<pre><code class="hljs">Version 1.0
Version 1.1
MVP
Sprint 01
Redesign Phase
SEO Improvements
</code></pre>
<p dir="rtl" lang="fa">اگر برای یک پروژه طراحی سایت، فازهای مختلف داشته باشید، می توانید هر فاز را به عنوان یک Milestone تعریف کنید:</p>
<ul dir="rtl" lang="fa">
<li>فاز طراحی رابط کاربری</li>
<li>فاز پیاده سازی فرانت اند</li>
<li>فاز توسعه بک اند</li>
<li>فاز تست و رفع باگ</li>
<li>فاز تحویل نهایی</li>
</ul>
<h3 dir="rtl" lang="fa">مزیت استفاده از Milestone</h3>
<p dir="rtl" lang="fa">Milestone کمک می کند بدانید:</p>
<ul dir="rtl" lang="fa">
<li>چه کارهایی برای یک نسخه باقی مانده است.</li>
<li>چند درصد پروژه انجام شده است.</li>
<li>کدام بخش ها تاخیر دارند.</li>
<li>وضعیت کلی هر فاز چگونه است.</li>
</ul>
<hr />
<h2 dir="rtl" lang="fa">مرحله هفتم: استفاده از GitHub Projects</h2>
<p dir="rtl" lang="fa">GitHub Projects یکی از قدرتمندترین ابزارهای مدیریت پروژه در گیت هاب است. این بخش به شما اجازه می دهد وظایف را در قالب بردهای کاری مدیریت کنید.</p>
<p dir="rtl" lang="fa">در ساده ترین حالت، می توانید یک برد Kanban بسازید و ستون های زیر را داشته باشید:</p>
<pre><code class="hljs">Backlog
To Do
In Progress
Review
Done
</code></pre>
<h3 dir="rtl" lang="fa">معنی هر ستون در برد پروژه</h3>
<h4 lang="en">Backlog</h4>
<p dir="rtl" lang="fa">لیست ایده ها، پیشنهادها و کارهایی که هنوز وارد برنامه اجرایی نشده اند.</p>
<h4 lang="en">To Do</h4>
<p dir="rtl" lang="fa">کارهایی که باید انجام شوند و در برنامه فعلی قرار دارند.</p>
<h4 lang="en">In Progress</h4>
<p dir="rtl" lang="fa">کارهایی که در حال انجام هستند.</p>
<h4 lang="en">Review</h4>
<p dir="rtl" lang="fa">کارهایی که انجام شده اند اما نیاز به بررسی، تست یا تایید دارند.</p>
<h4 lang="en">Done</h4>
<p dir="rtl" lang="fa">کارهایی که کامل شده اند و نیاز به اقدام بیشتری ندارند.</p>
<p dir="rtl" lang="fa">برای مطالعه بیشتر درباره GitHub Projects می توانید از مستندات رسمی استفاده کنید:</p>
<p lang="en"><a href="https://docs.github.com/en/issues/planning-and-tracking-with-projects" target="_blank" rel="nofollow noopener noreferrer">GitHub Projects Documentation</a></p>
<hr />
<h2 dir="rtl" lang="fa">مرحله هشتم: طراحی جریان کاری استاندارد در گیت هاب</h2>
<p dir="rtl" lang="fa">برای اینکه مدیریت پروژه در گیت هاب به شکل حرفه ای انجام شود، باید یک جریان کاری مشخص داشته باشید.</p>
<p dir="rtl" lang="fa">یک جریان کاری مناسب می تواند به شکل زیر باشد:</p>
<ol dir="rtl" lang="fa">
<li>ایجاد Issue برای هر کار</li>
<li>اختصاص دادن Issue به مسئول مربوطه</li>
<li>ساخت Branch برای انجام کار</li>
<li>انجام تغییرات و ثبت Commit های منظم</li>
<li>ایجاد Pull Request</li>
<li>بررسی کد توسط اعضای تیم</li>
<li>انجام اصلاحات در صورت نیاز</li>
<li>تایید و ادغام با شاخه اصلی</li>
<li>بستن Issue</li>
<li>انتقال کارت به ستون Done</li>
</ol>
<p dir="rtl" lang="fa">این ساختار باعث می شود هیچ کاری بدون ثبت، بررسی و تایید وارد پروژه نشود.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله نهم: نام گذاری استاندارد Branch ها</h2>
<p dir="rtl" lang="fa">نام گذاری درست Branch ها باعث نظم بیشتر پروژه می شود. بهتر است قبل از شروع پروژه، یک قانون مشخص برای تیم تعریف کنید.</p>
<h3 dir="rtl" lang="fa">نمونه الگوی نام گذاری Branch</h3>
<pre><code class="hljs">feature/login-page
bugfix/contact-form-error
hotfix/payment-gateway
refactor/user-service
docs/api-documentation
</code></pre>
<h3 dir="rtl" lang="fa">انواع رایج Branch</h3>
<ul dir="rtl" lang="fa">
<li><code>feature</code> برای قابلیت جدید</li>
<li><code>bugfix</code> برای رفع باگ</li>
<li><code>hotfix</code> برای اصلاح فوری</li>
<li><code>refactor</code> برای بازنویسی کد</li>
<li><code>docs</code> برای مستندات</li>
<li><code>test</code> برای تست ها</li>
</ul>
<p dir="rtl" lang="fa">این روش در پروژه های بزرگ، مخصوصا پروژه های طراحی سایت، اپلیکیشن و نرم افزارهای سازمانی بسیار کاربردی است.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله دهم: مدیریت Pull Request ها</h2>
<p dir="rtl" lang="fa">Pull Request یکی از نقاط کلیدی کنترل کیفیت پروژه است. هیچ تغییری نباید بدون بررسی وارد شاخه اصلی شود.</p>
<h3 dir="rtl" lang="fa">یک Pull Request خوب باید چه ویژگی هایی داشته باشد؟</h3>
<ul dir="rtl" lang="fa">
<li>عنوان واضح داشته باشد.</li>
<li>توضیح دهد چه تغییری انجام شده است.</li>
<li>به Issue مرتبط وصل شده باشد.</li>
<li>اسکرین شات یا توضیح تست داشته باشد.</li>
<li>تغییرات آن محدود و قابل بررسی باشد.</li>
<li>فقط روی یک موضوع مشخص تمرکز کند.</li>
</ul>
<h3 dir="rtl" lang="fa">نمونه متن Pull Request</h3>
<pre><code class="hljs">Title: Add login page validation

Description:
This pull request adds client-side validation to the login page.

Related issue:
Closes #24

Changes:
- Added validation for email field
- Added validation for password field
- Added error messages

Test:
- Tested with empty fields
- Tested with invalid email
- Tested with valid data
</code></pre>
<h3 dir="rtl" lang="fa">نکته حرفه ای</h3>
<p dir="rtl" lang="fa">Pull Request های بزرگ معمولا سخت بررسی می شوند و احتمال خطا در آن ها بیشتر است. بهتر است تغییرات را به بخش های کوچک تر تقسیم کنید.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله یازدهم: استفاده از GitHub Actions برای اتوماسیون</h2>
<p dir="rtl" lang="fa">GitHub Actions ابزاری برای خودکار سازی فرآیندهای پروژه است. با این قابلیت می توانید کارهایی مثل تست، بررسی کد، ساخت پروژه و انتشار را به صورت خودکار انجام دهید.</p>
<h3 dir="rtl" lang="fa">کاربردهای GitHub Actions</h3>
<ul dir="rtl" lang="fa">
<li>اجرای تست ها بعد از هر Pull Request</li>
<li>بررسی کیفیت کد</li>
<li>ساخت نسخه نهایی پروژه</li>
<li>انتشار خودکار روی سرور</li>
<li>ارسال اعلان به تیم</li>
<li>اجرای اسکریپت های زمان بندی شده</li>
</ul>
<p dir="rtl" lang="fa">برای اطلاعات بیشتر می توانید راهنمای رسمی آن را ببینید:</p>
<p lang="en"><a href="https://docs.github.com/en/actions" target="_blank" rel="nofollow noopener noreferrer">GitHub Actions Documentation</a></p>
<h3 dir="rtl" lang="fa">نمونه کاربرد ساده</h3>
<p dir="rtl" lang="fa">فرض کنید در یک پروژه طراحی سایت، هر بار که یک Pull Request ایجاد می شود، تست های پروژه به صورت خودکار اجرا شوند. اگر تست ها موفق باشند، تیم می تواند با اطمینان بیشتری تغییرات را تایید کند.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله دوازدهم: مدیریت دسترسی اعضای تیم</h2>
<p dir="rtl" lang="fa">در پروژه های واقعی، همه اعضای تیم نباید دسترسی یکسان داشته باشند. گیت هاب امکان مدیریت سطح دسترسی را فراهم می کند.</p>
<h3 dir="rtl" lang="fa">سطوح دسترسی رایج</h3>
<ul dir="rtl" lang="fa">
<li>Read: فقط مشاهده پروژه</li>
<li>Triage: مدیریت Issue ها بدون تغییر کد</li>
<li>Write: امکان تغییر کد و ایجاد Branch</li>
<li>Maintain: مدیریت بخش های اصلی پروژه</li>
<li>Admin: دسترسی کامل به تنظیمات پروژه</li>
</ul>
<h3 dir="rtl" lang="fa">چرا مدیریت دسترسی مهم است؟</h3>
<p dir="rtl" lang="fa">مدیریت دسترسی باعث افزایش امنیت پروژه می شود. در پروژه های مشتریان، اطلاعات حساس، کدهای اختصاصی و تنظیمات سرور باید فقط در اختیار افراد مجاز باشد.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله سیزدهم: مستند سازی فرآیندها</h2>
<p dir="rtl" lang="fa">یکی از اشتباهات رایج در مدیریت پروژه های نرم افزاری، بی توجهی به مستند سازی است. حتی اگر بهترین کد را بنویسید، بدون مستندات مناسب، نگهداری پروژه سخت می شود.</p>
<h3 dir="rtl" lang="fa">چه چیزهایی باید مستند شوند؟</h3>
<ul dir="rtl" lang="fa">
<li>روش نصب پروژه</li>
<li>تنظیمات محیط توسعه</li>
<li>استانداردهای کد نویسی</li>
<li>روش ایجاد Branch</li>
<li>روش ثبت Pull Request</li>
<li>فرآیند انتشار نسخه</li>
<li>راهنمای استفاده از API</li>
<li>ساختار دیتابیس</li>
<li>نکات امنیتی</li>
</ul>
<p dir="rtl" lang="fa">می توانید این مستندات را در پوشه <code>docs</code> قرار دهید یا از بخش Wiki گیت هاب استفاده کنید.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله چهاردهم: استفاده از Wiki در گیت هاب</h2>
<p dir="rtl" lang="fa">GitHub Wiki برای نگهداری مستندات طولانی و آموزشی پروژه مناسب است. برای مثال، می توانید صفحات زیر را در Wiki ایجاد کنید:</p>
<ul dir="rtl" lang="fa">
<li>راهنمای نصب پروژه</li>
<li>معرفی ساختار پروژه</li>
<li>راهنمای توسعه برای برنامه نویسان جدید</li>
<li>مستندات API</li>
<li>قوانین همکاری تیمی</li>
<li>راهنمای استقرار روی سرور</li>
</ul>
<p dir="rtl" lang="fa">Wiki مخصوصا در پروژه های طولانی مدت و تیمی بسیار مفید است.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله پانزدهم: مدیریت نسخه ها با Release و Tag</h2>
<p dir="rtl" lang="fa">وقتی یک نسخه مشخص از پروژه آماده انتشار است، بهتر است از Tag و Release استفاده کنید.</p>
<h3 dir="rtl" lang="fa">Tag چیست؟</h3>
<p dir="rtl" lang="fa">Tag یک نشان مشخص روی یک نقطه از تاریخچه پروژه است. معمولا برای نسخه گذاری استفاده می شود.</p>
<p dir="rtl" lang="fa">نمونه:</p>
<pre><code class="hljs">v1.0.0
v1.1.0
v2.0.0
</code></pre>
<h3 dir="rtl" lang="fa">Release چیست؟</h3>
<p dir="rtl" lang="fa">Release نسخه منتشر شده پروژه است که می تواند شامل توضیحات، فایل های خروجی و لیست تغییرات باشد.</p>
<h3 dir="rtl" lang="fa">نمونه نسخه گذاری استاندارد</h3>
<pre><code class="hljs">v1.0.0
</code></pre>
<p dir="rtl" lang="fa">در این روش:</p>
<ul dir="rtl" lang="fa">
<li>عدد اول برای تغییرات بزرگ</li>
<li>عدد دوم برای قابلیت های جدید</li>
<li>عدد سوم برای رفع باگ ها</li>
</ul>
<p dir="rtl" lang="fa">استفاده می شود.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله شانزدهم: مدیریت باگ ها در گیت هاب</h2>
<p dir="rtl" lang="fa">یکی از مهم ترین کاربردهای گیت هاب، مدیریت باگ ها است. برای اینکه باگ ها درست پیگیری شوند، باید ساختار مشخصی برای ثبت آن ها داشته باشید.</p>
<h3 dir="rtl" lang="fa">قالب پیشنهادی گزارش باگ</h3>
<pre><code class="hljs">Title:
توضیح کوتاه مشکل

Environment:
مرورگر، سیستم عامل، نسخه نرم افزار

Steps to reproduce:
مراحل ایجاد مشکل

Expected result:
نتیجه مورد انتظار

Actual result:
نتیجه واقعی

Screenshot:
تصویر یا ویدیو در صورت نیاز
</code></pre>
<p dir="rtl" lang="fa">این قالب کمک می کند برنامه نویس سریع تر مشکل را پیدا و رفع کند.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله هفدهم: مدیریت کارهای طراحی سایت در گیت هاب</h2>
<p dir="rtl" lang="fa">در پروژه های طراحی سایت، گیت هاب می تواند برای هماهنگی بین طراح، برنامه نویس، کارشناس سئو و مدیر پروژه استفاده شود.</p>
<h3 dir="rtl" lang="fa">نمونه Issue های مربوط به طراحی سایت</h3>
<ul dir="rtl" lang="fa">
<li>طراحی صفحه اصلی</li>
<li>پیاده سازی منوی واکنش گرا</li>
<li>اتصال فرم تماس با ما</li>
<li>افزودن اسکیما به صفحات</li>
<li>بهینه سازی سرعت بارگذاری</li>
<li>رفع خطای نمایش در موبایل</li>
<li>تنظیم متا تگ های صفحات</li>
<li>تست فرم ثبت نام</li>
<li>اتصال درگاه پرداخت</li>
</ul>
<h3 dir="rtl" lang="fa">نمونه Label های مناسب طراحی سایت</h3>
<ul lang="en">
<li><code>ui-design</code></li>
<li><code>frontend</code></li>
<li><code>backend</code></li>
<li><code>seo</code></li>
<li><code>performance</code></li>
<li><code>responsive</code></li>
<li><code>content</code></li>
<li><code>security</code></li>
</ul>
<p dir="rtl" lang="fa">این دسته بندی کمک می کند هر عضو تیم دقیقا بداند مسئول چه بخشی است.</p>
<hr />
<h2 dir="rtl" lang="fa">مرحله هجدهم: مدیریت پروژه های سئو با گیت هاب</h2>
<p dir="rtl" lang="fa">اگرچه گیت هاب بیشتر به عنوان ابزار برنامه نویسی شناخته می شود، اما برای مدیریت پروژه های سئو هم می تواند مفید باشد.</p>
<h3 dir="rtl" lang="fa">کاربرد گیت هاب در پروژه سئو</h3>
<ul dir="rtl" lang="fa">
<li>ثبت مشکلات فنی سایت</li>
<li>پیگیری بهینه سازی سرعت</li>
<li>مدیریت تغییرات متا تگ ها</li>
<li>ثبت خطاهای سرچ کنسول</li>
<li>برنامه ریزی تولید محتوا</li>
<li>پیگیری بهینه سازی ساختار لینک داخلی</li>
<li>بررسی مشکلات Core Web Vitals</li>
<li>ثبت تغییرات فایل robots.txt و sitemap.xml</li>
</ul>
<p dir="rtl" lang="fa">برای مطالعه بیشتر درباره اصول فنی سئو می توانید از راهنمای گوگل استفاده کنید:</p>
<p lang="en"><a href="https://developers.google.com/search/docs" target="_blank" rel="nofollow noopener noreferrer">Google Search Central</a></p>
<hr />
<h2 dir="rtl" lang="fa">مرحله نوزدهم: نکات امنیتی در مدیریت پروژه با گیت هاب</h2>
<p dir="rtl" lang="fa">امنیت در گیت هاب بسیار مهم است؛ مخصوصا اگر پروژه تجاری یا اطلاعات مشتریان در آن وجود داشته باشد.</p>
<h3 dir="rtl" lang="fa">نکات مهم امنیتی</h3>
<ul dir="rtl" lang="fa">
<li>هیچ وقت رمز عبور را داخل کد قرار ندهید.</li>
<li>فایل های تنظیمات حساس را در <code>.gitignore</code> قرار دهید.</li>
<li>از Secret های GitHub Actions استفاده کنید.</li>
<li>دسترسی اعضای تیم را محدود و کنترل شده تعریف کنید.</li>
<li>مخازن خصوصی را برای پروژه های مشتریان انتخاب کنید.</li>
<li>Pull Request ها را قبل از ادغام بررسی کنید.</li>
<li>از احراز هویت دو مرحله ای استفاده کنید.</li>
</ul>
<h3 dir="rtl" lang="fa">فایل هایی که معمولا نباید Commit شوند</h3>
<pre><code class="hljs">.env
config.local.php
database-password.txt
private-key.pem
node_modules/
vendor/
</code></pre>
<p dir="rtl" lang="fa">برای مدیریت بهتر فایل های نادیده گرفته شده می توانید از مستندات رسمی Git استفاده کنید:</p>
<p lang="en"><a href="https://git-scm.com/docs/gitignore" target="_blank" rel="nofollow noopener noreferrer">Git Ignore Documentation</a></p>
<hr />
<h2 dir="rtl" lang="fa">مرحله بیستم: اشتباهات رایج در مدیریت پروژه در گیت هاب</h2>
<p dir="rtl" lang="fa">برای اینکه مدیریت پروژه در گیت هاب موفق باشد، باید از چند اشتباه رایج دوری کنید.</p>
<h3 dir="rtl" lang="fa">1. ثبت نکردن وظایف به صورت Issue</h3>
<p dir="rtl" lang="fa">اگر کارها فقط در پیام رسان یا جلسه شفاهی مطرح شوند، احتمال فراموشی و بی نظمی بالا می رود. هر کار مهم باید در قالب Issue ثبت شود.</p>
<h3 dir="rtl" lang="fa">2. پیام Commit نامفهوم</h3>
<p dir="rtl" lang="fa">پیام هایی مثل <code>fix</code> یا <code>update</code> در آینده هیچ کمکی به تیم نمی کنند. پیام Commit باید توضیح دهد دقیقا چه چیزی تغییر کرده است.</p>
<h3 dir="rtl" lang="fa">3. ادغام مستقیم در شاخه اصلی</h3>
<p dir="rtl" lang="fa">کار کردن مستقیم روی شاخه اصلی می تواند خطرناک باشد. بهتر است برای هر تغییر، یک Branch جداگانه ساخته شود.</p>
<h3 dir="rtl" lang="fa">4. Pull Request های بسیار بزرگ</h3>
<p dir="rtl" lang="fa">Pull Request بزرگ بررسی را سخت می کند و احتمال خطا را افزایش می دهد. تغییرات را کوچک و هدفمند نگه دارید.</p>
<h3 dir="rtl" lang="fa">5. نداشتن مستندات</h3>
<p dir="rtl" lang="fa">بدون مستندات، پروژه به مرور برای اعضای جدید و حتی اعضای فعلی نامفهوم می شود.</p>
<h3 dir="rtl" lang="fa">6. مدیریت نکردن دسترسی ها</h3>
<p dir="rtl" lang="fa">دادن دسترسی کامل به همه اعضا می تواند امنیت پروژه را به خطر بیندازد. دسترسی ها باید بر اساس نقش افراد تعریف شوند.</p>
<hr />
<h2 dir="rtl" lang="fa">بهترین ساختار پیشنهادی برای مدیریت پروژه در گیت هاب</h2>
<p dir="rtl" lang="fa">اگر بخواهیم یک ساختار استاندارد برای پروژه های حرفه ای پیشنهاد کنیم، می تواند به شکل زیر باشد:</p>
<h3 dir="rtl" lang="fa">ساختار مخزن</h3>
<pre><code class="hljs">project/
├── docs/
├── src/
├── tests/
├── assets/
├── README.md
├── CONTRIBUTING.md
├── CHANGELOG.md
└── .gitignore
</code></pre>
<h3 dir="rtl" lang="fa">ساختار برد پروژه</h3>
<pre><code class="hljs">Backlog
To Do
In Progress
Code Review
Testing
Done
</code></pre>
<h3 dir="rtl" lang="fa">ساختار Label ها</h3>
<pre><code class="hljs">bug
feature
enhancement
frontend
backend
design
seo
urgent
documentation
</code></pre>
<h3 dir="rtl" lang="fa">ساختار Branch ها</h3>
<pre><code class="hljs">feature/
bugfix/
hotfix/
refactor/
docs/
</code></pre>
<p dir="rtl" lang="fa">این ساختار برای بسیاری از پروژه های طراحی سایت، اپلیکیشن، پنل مدیریتی و نرم افزارهای اختصاصی قابل استفاده است.</p>
<hr />
<h2 dir="rtl" lang="fa">نمونه سناریو واقعی مدیریت پروژه طراحی سایت با گیت هاب</h2>
<p dir="rtl" lang="fa">فرض کنید یک شرکت قصد دارد سایت شرکتی خود را طراحی کند. تیم پروژه شامل مدیر پروژه، طراح رابط کاربری، برنامه نویس فرانت اند، برنامه نویس بک اند و کارشناس سئو است.</p>
<h3 dir="rtl" lang="fa">فاز اول: برنامه ریزی</h3>
<p dir="rtl" lang="fa">مدیر پروژه یک Repository خصوصی ایجاد می کند و در GitHub Projects ستون های کاری را می سازد.</p>
<h3 dir="rtl" lang="fa">فاز دوم: تعریف وظایف</h3>
<p dir="rtl" lang="fa">برای هر بخش سایت یک Issue ثبت می شود:</p>
<ul dir="rtl" lang="fa">
<li>طراحی صفحه اصلی</li>
<li>طراحی صفحه درباره ما</li>
<li>طراحی صفحه تماس با ما</li>
<li>پیاده سازی فرم تماس</li>
<li>ساخت پنل مدیریت محتوا</li>
<li>بهینه سازی سرعت سایت</li>
<li>تنظیم متا تگ ها</li>
<li>تست نمایش موبایل</li>
</ul>
<h3 dir="rtl" lang="fa">فاز سوم: انجام کارها</h3>
<p dir="rtl" lang="fa">هر عضو تیم برای وظیفه خود یک Branch ایجاد می کند و بعد از انجام کار، Pull Request ثبت می کند.</p>
<h3 dir="rtl" lang="fa">فاز چهارم: بررسی و تایید</h3>
<p dir="rtl" lang="fa">مدیر فنی Pull Request ها را بررسی می کند. اگر تغییرات درست باشد، آن ها را تایید و با شاخه اصلی ادغام می کند.</p>
<h3 dir="rtl" lang="fa">فاز پنجم: تست و انتشار</h3>
<p dir="rtl" lang="fa">بعد از تکمیل کارها، نسخه نهایی تست می شود و با استفاده از Release، نسخه رسمی پروژه ثبت می شود.</p>
<p dir="rtl" lang="fa">این فرآیند باعث می شود پروژه با نظم، شفافیت و کیفیت بالاتری پیش برود.</p>
<hr />
<h2 dir="rtl" lang="fa">مزایای مدیریت پروژه در گیت هاب برای کسب و کارها</h2>
<p dir="rtl" lang="fa">استفاده از گیت هاب فقط یک انتخاب فنی نیست؛ بلکه برای مدیریت بهتر کسب و کارهای دیجیتال هم اهمیت دارد.</p>
<h3 dir="rtl" lang="fa">شفافیت در روند انجام پروژه</h3>
<p dir="rtl" lang="fa">کارفرما و اعضای تیم می توانند ببینند چه کارهایی انجام شده، چه کارهایی باقی مانده و هر وظیفه در چه مرحله ای قرار دارد.</p>
<h3 dir="rtl" lang="fa">کاهش خطا و دوباره کاری</h3>
<p dir="rtl" lang="fa">با وجود Pull Request، Review و تاریخچه تغییرات، احتمال خطاهای ناخواسته کمتر می شود.</p>
<h3 dir="rtl" lang="fa">افزایش کیفیت خروجی</h3>
<p dir="rtl" lang="fa">وقتی هر تغییر بررسی و مستند شود، کیفیت نهایی پروژه بالاتر می رود.</p>
<h3 dir="rtl" lang="fa">مدیریت بهتر زمان</h3>
<p dir="rtl" lang="fa">Issue ها، Milestone ها و Project Board ها کمک می کنند زمان بندی پروژه دقیق تر انجام شود.</p>
<h3 dir="rtl" lang="fa">حفظ تاریخچه کامل پروژه</h3>
<p dir="rtl" lang="fa">تمام تغییرات پروژه در گیت هاب ثبت می شود و در صورت نیاز می توان به نسخه های قبلی برگشت.</p>
<hr />
<h2 dir="rtl" lang="fa">آیا گیت هاب جایگزین ابزارهای مدیریت پروژه مثل Trello یا Jira است؟</h2>
<p dir="rtl" lang="fa">پاسخ به نیاز تیم بستگی دارد. گیت هاب می تواند برای بسیاری از تیم های فنی جایگزین مناسبی باشد، زیرا ابزارهای مدیریت وظیفه، برد پروژه، Issue، Pull Request و اتوماسیون را در یک محیط یکپارچه ارائه می دهد.</p>
<p dir="rtl" lang="fa">اما در تیم های غیر فنی یا سازمان های بزرگ، ممکن است ابزارهایی مثل Jira، Trello، Asana یا ClickUp هم در کنار GitHub استفاده شوند.</p>
<h3 dir="rtl" lang="fa">چه زمانی GitHub کافی است؟</h3>
<p dir="rtl" lang="fa">اگر پروژه شما فنی است و بیشتر اعضای تیم با کد، طراحی سایت، اپلیکیشن یا توسعه نرم افزار درگیر هستند، GitHub معمولا گزینه بسیار مناسبی است.</p>
<h3 dir="rtl" lang="fa">چه زمانی ابزار مکمل لازم است؟</h3>
<p dir="rtl" lang="fa">اگر تیم شما شامل بخش های فروش، مالی، منابع انسانی، بازاریابی و پشتیبانی است، شاید نیاز به ابزارهای مدیریت پروژه عمومی تر هم داشته باشید.</p>
<hr />
<h2 dir="rtl" lang="fa">چک لیست مدیریت پروژه در گیت هاب</h2>
<p dir="rtl" lang="fa">برای شروع حرفه ای، این چک لیست را دنبال کنید:</p>
<ul dir="rtl" lang="fa">
<li>ساخت Repository خصوصی یا عمومی</li>
<li>نوشتن README کامل</li>
<li>تعریف ساختار پوشه ها</li>
<li>ساخت GitHub Project</li>
<li>ایجاد ستون های کاری</li>
<li>تعریف Label های استاندارد</li>
<li>ایجاد Milestone برای فازها</li>
<li>ثبت Issue برای همه وظایف</li>
<li>استفاده از Branch برای هر تغییر</li>
<li>ثبت Commit های دقیق</li>
<li>ایجاد Pull Request برای بررسی تغییرات</li>
<li>فعال سازی Review قبل از Merge</li>
<li>مستند سازی فرآیندها</li>
<li>مدیریت دسترسی اعضای تیم</li>
<li>استفاده از GitHub Actions در صورت نیاز</li>
<li>ثبت Release برای نسخه های نهایی</li>
</ul>
<hr />
<h2 dir="rtl" lang="fa">جمع بندی</h2>
<p dir="rtl" lang="fa">مدیریت پروژه در گیت هاب یکی از بهترین روش ها برای افزایش نظم، شفافیت و کیفیت در پروژه های دیجیتال است. با استفاده از امکاناتی مثل Repository، Issue، Branch، Pull Request، Milestone، GitHub Projects و GitHub Actions می توانید فرآیند توسعه نرم افزار، طراحی سایت، اپلیکیشن و حتی پروژه های سئو را دقیق تر مدیریت کنید.</p>
<p dir="rtl" lang="fa">اگر تیم شما روی پروژه های فنی کار می کند، یادگیری مدیریت پروژه در گیت هاب یک مهارت ضروری است. این ابزار کمک می کند همه اعضای تیم بدانند چه کاری باید انجام دهند، تغییرات چگونه بررسی می شود و پروژه در چه مرحله ای قرار دارد.</p>
<p dir="rtl" lang="fa">برای طراحی سایت، توسعه نرم افزار، برنامه نویسی اپلیکیشن و اجرای پروژه های دیجیتال با ساختار حرفه ای و مدیریت دقیق، می توانید با تیم طراحان نوین در ارتباط باشید. جهت مشاوره و ثبت درخواست پروژه، از صفحه <a href="https://tarahanenovin.ir/site/contact" target="_blank" rel="nofollow noopener noreferrer">تماس با ما</a> اقدام کنید.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%b5%d8%af-%d9%85%d8%af%db%8c%d8%b1%db%8c%d8%aa-%d9%be%d8%b1%d9%88%da%98%d9%87-%d8%af%d8%b1-%da%af%db%8c%d8%aa-%d9%87%d8%a7%d8%a8/">آموزش صفر تا صد مدیریت پروژه در گیت هاب؛ راهنمای کاربردی برای تیم ها و کسب و کارها</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-%d8%b5%d9%81%d8%b1-%d8%aa%d8%a7-%d8%b5%d8%af-%d9%85%d8%af%db%8c%d8%b1%db%8c%d8%aa-%d9%be%d8%b1%d9%88%da%98%d9%87-%d8%af%d8%b1-%da%af%db%8c%d8%aa-%d9%87%d8%a7%d8%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>راهنمای جامع انتخاب فریم ورک: چرا و چگونه Yii2 را بررسی می‌کنیم؟</title>
		<link>https://tarahanenovin.ir/blog/%d8%b1%d8%a7%d9%87%d9%86%d9%85%d8%a7%db%8c-%d8%ac%d8%a7%d9%85%d8%b9-%d8%a7%d9%86%d8%aa%d8%ae%d8%a7%d8%a8-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%da%86%d8%b1%d8%a7-%d9%88-%da%86%da%af%d9%88%d9%86/</link>
					<comments>https://tarahanenovin.ir/blog/%d8%b1%d8%a7%d9%87%d9%86%d9%85%d8%a7%db%8c-%d8%ac%d8%a7%d9%85%d8%b9-%d8%a7%d9%86%d8%aa%d8%ae%d8%a7%d8%a8-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%da%86%d8%b1%d8%a7-%d9%88-%da%86%da%af%d9%88%d9%86/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[طراحی وب]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[Yii2]]></category>
		<category><![CDATA[فریم ورک]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=85</guid>

					<description><![CDATA[<p>انتخاب یک فریم ورک مناسب برای توسعه نرم افزارهای تحت وب، فراتر از مقایسه ساده ویژگی‌های بازاریابی آن‌ها است. به عنوان یک توسعه دهنده با تجربه که به دنبال زیرساختی پایدار، سریع و قابل اعتماد برای پروژه‌های تجاری است، معیارهای متعددی مانند معماری کدنویسی، امنیت پیش فرض، مدیریت داده‌ها، عملکرد در مقیاس بالا و هزینه نگهداری اهمیت پیدا می‌کنند. فریم ورک Yii2 (مخفف Yes It Is) یکی از فریم ورک‌های مطرح زبان برنامه نویسی PHP است که با معماری مبتنی بر کامپوننت و تمرکز بر کارایی بالا شناخته می‌شود. در این تحلیل، ساختار داخلی، قابلیت‌های عملیاتی و نقاط قوت و ضعف این فریم ورک را به صورت ریز به ریز بررسی می‌کنیم تا مشخص شود در چه سناریوهایی بهترین انتخاب خواهد بود. معماری و ساختار داخلی Yii2 فریم ورک Yii2 بر پایه الگوی معماری MVC (Model-View-Controller) بنا شده است، اما پیاده سازی آن به گونه‌ای است که وابستگی بسیار کمی میان اجزا ایجاد می‌کند. ۱. مدیریت کامپوننت‌ها و لود تنبل (Lazy Loading): یکی از دلایل سرعت بالای این فریم ورک، استفاده از سیستم مدیریت کامپوننت است. در Yii2 تا زمانی که به یک کامپوننت (مانند سیستم ارسال ایمیل یا اتصال به دیتابیس) نیاز نباشد، شیء آن در حافظه ساخته نمی‌شود. این رویکرد مصرف حافظه RAM را در هر درخواست به حداقل می‌رساند. ۲. سرویس دهنده مکان یاب (Service Locator) و تزریق وابستگی (Dependency Injection): فریم ورک Yii2 از یک کانتینر DI قدرتمند بهره می‌برد که اجازه می‌دهد وابستگی کلاس‌ها را به صورت پویا مدیریت کنید. این ویژگی قابلیت تست پذیری کدها را به شدت افزایش می‌دهد. ۳. ابزار تولید کد Gii: یکی از ابزارهای منحصر به فرد این فریم ورک، ابزار بصری Gii است. Gii به توسعه دهنده اجازه می‌دهد کدهای پایه مربوط به مدل‌ها، کنترلرها، فرم‌ها و ماژول‌های CRUD (ایجاد، خواندن، بروز رسانی و حذف) را بر اساس ساختار جداول دیتابیس در چند ثانیه تولید کند. این ابزار سرعت توسعه اولیه پروژه را به شکل چشمگیری افزایش می‌دهد. کار با داده‌ها و سیستم Active Record در Yii2 مدیریت پایگاه داده در پروژه های بزرگ، گلوگاه اصلی کارایی است. Yii2 با ارائه یک لایه انتزاعی قوی روی دیتابیس، تعادل مناسبی بین راحتی کدنویسی و سرعت اجرا ایجاد کرده است. نگاشت شیء-رابطه‌ای (ORM) اختصاصی: سیستم Active Record در Yii2 بسیار سر راست و کارآمد است. هر جدول دیتابیس به یک کلاس مدل متصل می‌شود. پیاده سازی روابط پیچیده مانند یک‌به‌چند یا چند‌به‌چند به سادگی و با تعریف متدهایی نظیر hasMany و hasOne انجام می‌شود. بهینه سازی کوئری‌ها با Lazy Loading و Eager Loading: به طور پیش فرض، روابط به صورت تنبل بارگذاری می‌شوند. اما برای جلوگیری از مشکل معروف N+1 در واکشی داده‌ها، با استفاده از متد with می‌توان داده‌های مرتبط را به صورت Eager Loading و تنها با یک یا دو کوئری بهینه از دیتابیس دریافت کرد. سیستم مهاجرت دیتابیس (Migrations): مدیریت ساختار دیتابیس در تیم‌های توسعه اهمیت زیادی دارد. سیستم کامندلاین Yii2 امکان ساخت، اجرا و بازگردانی دیتابیس میگریشن‌ها را به راحتی فراهم می‌کند تا تغییرات دیتابیس همگام با کدهای برنامه پیش برود. امنیت پیش فرض و مدیریت دسترسی‌ها (RBAC) امنیت نرم افزار نباید به عنوان یک بخش الحاقی در انتهای پروژه در نظر گرفته شود. فریم ورک Yii2 امنیت را در تار و پود خود جای داده است: جلوگیری از حملات رایج: سیستم اعتبارسنجی فرم‌ها به صورت خودکار توکن‌های CSRF تولید و بررسی می‌کند. همچنین، استفاده از معماری Active Record و PDO مانع از بروز حملات SQL Injection می‌شود. خروجی‌های سمت ویو نیز به طور پیش فرض انکود می‌شوند تا جلوی حملات XSS گرفته شود. کنترل دسترسی نقش‌محور (RBAC): مدیریت سطوح دسترسی کاربران در سیستم‌های سازمانی بسیار پیچیده است. Yii2 دارای یک کامپوننت داخلی و به شدت منعطف برای RBAC است که اجازه می‌دهد نقش‌ها (Roles)، قوانین (Rules) و مجوزها (Permissions) را تعریف کنید. این داده‌ها را می‌توان در فایل‌های متنی یا جداول پایگاه داده ذخیره و مدیریت کرد. کارایی، کشینگ و مدیریت صف (Queue) برای پروژه‌هایی که با ترافیک بالا مواجه هستند، کارایی پردازش اهمیت حیاتی دارد. ۱. مکانیزم‌های چندلایه کشینگ: Yii2 از انواع روش‌های کش شامل Data Caching، Fragment Caching (کش کردن بخش خاصی از قالب)، Page Caching (کش کامل صفحه) و HTTP Caching پشتیبانی می‌کند. سازگاری کامل با سیستم‌های ذخیره سازی پرسرعت مانند Redis و Memcached به صورت پیش فرض در تنظیمات فریم ورک تعبیه شده است. ۲. مدیریت کارهای پس زمینه با Yii2 Queue: برای جلوگیری از مسدود شدن درخواست‌های کاربر، کارهایی مانند ارسال ایمیل‌های انبوه، پردازش تصاویر یا تولید خروجی‌های سنگین باید به صف منتقل شوند. افزونه رسمی yiisoft/yii2-queue از درایورهای مختلفی مانند دیتابیس، Redis، RabbitMQ و Beanstalkd پشتیبانی می‌کند تا کارها به صورت غیرهمزمان در پس زمینه پردازش شوند. توسعه API و تست پذیری امروزه بسیاری از پروژه‌ها به صورت جداگانه در سمت فرانت اند و بک اند توسعه می‌یابند. فریم ورک Yii2 ابزارهای قدرتمندی برای ساخت RESTful API ارائه می‌دهد: پشتیبانی بومی از فرمت‌های خروجی: تنظیم پاسخ‌ها به صورت JSON یا XML تنها با چند خط تنظیمات ساده در کنترلر امکان پذیر است. مدیریت نرخ درخواست (Rate Limiting): برای جلوگیری از سوء استفاده از APIها، ویژگی Rate Limiting به راحتی با پیاده سازی اینترفیس RateLimitInterface روی مدل کاربر فعال می‌شود. تست نویسی: فریم ورک Yii2 به طور کامل با فریم ورک تست نویسی Codeception ادغام شده است. این موضوع به شما اجازه می‌دهد تا تست‌های واحد (Unit)، تست‌های عملکردی (Functional) و تست‌های پذیرش (Acceptance) را به راحتی بازنویسی و اجرا کنید. مقایسه کاربردی: Yii2 در برابر Laravel و Symfony برای انتخاب نهایی، مقایسه این فریم ورک با سایر رقبای بزرگ PHP به درک بهتر جایگاه آن کمک می‌کند: معیار بررسی فریم ورک Yii2 فریم ورک Laravel فریم ورک Symfony عملکرد و سرعت (Throughput) بسیار بالا به دلیل ساختار سبک و Lazy Loading متوسط (نیازمند بهینه سازی‌های متعدد) بالا و پایدار در پروژه‌های بزرگ سرعت توسعه اولیه بسیار سریع به لطف ابزار تولید کد Gii سریع به دلیل ابزارهای آماده و اکوسیستم وسیع متوسط به دلیل نیاز به پیکربندی‌های زیاد سیستم مدیریت دسترسی دارای RBAC داخلی بسیار قدرتمند و منعطف نیازمند پکیج‌های جانبی (مانند Spatie) دارای سیستم امنیتی پیچیده و بسیار قوی جامعه کاربری و اکوسیستم متوسط (بیشتر در فاز نگهداری و اصلاحات) بسیار بزرگ و دارای پکیج‌های مدرن فراوان بسیار بزرگ و تامین کننده کامپوننت‌های پایه از نظر چرخه پشتیبانی، هسته Yii2 در حال حاضر در فاز اصلاح باگ‌های امنیتی و حفظ سازگاری با نسخه‌های جدید PHP (مانند PHP 8.x) است و تمرکز تیم توسعه روی نسخه جدید یعنی Yii3 قرار دارد. در حالی که لاراول هر ساله نسخه‌های بزرگ جدیدی با ویژگی‌های نوین منتشر می‌کند. با این حال، پایداری کدهای نوشته شده با Yii2 و عدم نیاز به تغییرات مداوم به دلیل ارتقای نسخه‌ها، یک مزیت بزرگ برای پروژه‌های طولانی مدت تجاری محسوب می‌شود. برای بررسی ابزارها و پکیج‌های رسمی توسعه یافته، می‌توانید به مخزن پکیج‌های PHP در سایت Packagist مراجعه کنید. نتیجه گیری و سناریوهای مناسب برای انتخاب Yii2 فریم ورک Yii2 یک ابزار مهندسی شده، با ساختاری منظم و کارایی فوق العاده است. اگر پروژه شما ویژگی‌های زیر را دارد، Yii2 یک انتخاب کاملا منطقی و اقتصادی خواهد بود: پروژه‌هایی با ساختار داده‌ای پیچیده و جداول دیتابیس متعدد که نیاز به تولید سریع کدهای CRUD دارند. سیستم‌های مدیریتی، پنل‌های سازمانی و اتوماسیون‌های اداری که امنیت بالا و مدیریت دسترسی‌های پیچیده (RBAC) از اولویت‌های اصلی آن‌ها است. پروژه‌هایی که روی سرورهای اشتراکی یا با منابع محدود میزبانی می‌شوند و کارایی بالا همراه با مصرف کم حافظه در آن‌ها اهمیت دارد. در مقابل، اگر پروژه شما نیازمند استفاده مداوم از آخرین تکنولوژی‌ها و ابزارهای فرانت اند روز دنیا است و یا جامعه کاربری بسیار بزرگ برای حل چالش‌های روزمره اولویت اول شماست، ممکن است گزینه‌های دیگر انتخاب‌های مناسب تری باشند. با این حال، پایداری بی نظیر و سرعت اجرای فریم ورک Yii2 همچنان آن را به یکی از قابل اعتماد ترین ابزارهای توسعه وب تبدیل کرده است.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%b1%d8%a7%d9%87%d9%86%d9%85%d8%a7%db%8c-%d8%ac%d8%a7%d9%85%d8%b9-%d8%a7%d9%86%d8%aa%d8%ae%d8%a7%d8%a8-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%da%86%d8%b1%d8%a7-%d9%88-%da%86%da%af%d9%88%d9%86/">راهنمای جامع انتخاب فریم ورک: چرا و چگونه Yii2 را بررسی می‌کنیم؟</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<p dir="rtl" lang="fa">انتخاب یک فریم ورک مناسب برای توسعه نرم افزارهای تحت وب، فراتر از مقایسه ساده ویژگی‌های بازاریابی آن‌ها است. به عنوان یک توسعه دهنده با تجربه که به دنبال زیرساختی پایدار، سریع و قابل اعتماد برای پروژه‌های تجاری است، معیارهای متعددی مانند معماری کدنویسی، امنیت پیش فرض، مدیریت داده‌ها، عملکرد در مقیاس بالا و هزینه نگهداری اهمیت پیدا می‌کنند. فریم ورک Yii2 (مخفف Yes It Is) یکی از فریم ورک‌های مطرح زبان برنامه نویسی PHP است که با معماری مبتنی بر کامپوننت و تمرکز بر کارایی بالا شناخته می‌شود. در این تحلیل، ساختار داخلی، قابلیت‌های عملیاتی و نقاط قوت و ضعف این فریم ورک را به صورت ریز به ریز بررسی می‌کنیم تا مشخص شود در چه سناریوهایی بهترین انتخاب خواهد بود.</p>
<h3 dir="rtl" lang="fa">معماری و ساختار داخلی Yii2</h3>
<p dir="rtl" lang="fa">فریم ورک Yii2 بر پایه الگوی معماری MVC (Model-View-Controller) بنا شده است، اما پیاده سازی آن به گونه‌ای است که وابستگی بسیار کمی میان اجزا ایجاد می‌کند.</p>
<p dir="rtl" lang="fa">۱. <strong>مدیریت کامپوننت‌ها و لود تنبل (Lazy Loading):</strong> یکی از دلایل سرعت بالای این فریم ورک، استفاده از سیستم مدیریت کامپوننت است. در Yii2 تا زمانی که به یک کامپوننت (مانند سیستم ارسال ایمیل یا اتصال به دیتابیس) نیاز نباشد، شیء آن در حافظه ساخته نمی‌شود. این رویکرد مصرف حافظه RAM را در هر درخواست به حداقل می‌رساند.</p>
<p dir="rtl" lang="fa">۲. <strong>سرویس دهنده مکان یاب (Service Locator) و تزریق وابستگی (Dependency Injection):</strong> فریم ورک Yii2 از یک کانتینر DI قدرتمند بهره می‌برد که اجازه می‌دهد وابستگی کلاس‌ها را به صورت پویا مدیریت کنید. این ویژگی قابلیت تست پذیری کدها را به شدت افزایش می‌دهد.</p>
<p dir="rtl" lang="fa">۳. <strong>ابزار تولید کد Gii:</strong> یکی از ابزارهای منحصر به فرد این فریم ورک، ابزار بصری Gii است. Gii به توسعه دهنده اجازه می‌دهد کدهای پایه مربوط به مدل‌ها، کنترلرها، فرم‌ها و ماژول‌های CRUD (ایجاد، خواندن، بروز رسانی و حذف) را بر اساس ساختار جداول دیتابیس در چند ثانیه تولید کند. این ابزار سرعت توسعه اولیه پروژه را به شکل چشمگیری افزایش می‌دهد.</p>
<h3 dir="rtl" lang="fa">کار با داده‌ها و سیستم Active Record در Yii2</h3>
<p dir="rtl" lang="fa">مدیریت پایگاه داده در پروژه های بزرگ، گلوگاه اصلی کارایی است. Yii2 با ارائه یک لایه انتزاعی قوی روی دیتابیس، تعادل مناسبی بین راحتی کدنویسی و سرعت اجرا ایجاد کرده است.</p>
<ul dir="rtl" lang="fa">
<li><strong>نگاشت شیء-رابطه‌ای (ORM) اختصاصی:</strong> سیستم Active Record در Yii2 بسیار سر راست و کارآمد است. هر جدول دیتابیس به یک کلاس مدل متصل می‌شود. پیاده سازی روابط پیچیده مانند یک‌به‌چند یا چند‌به‌چند به سادگی و با تعریف متدهایی نظیر <code>hasMany</code> و <code>hasOne</code> انجام می‌شود.</li>
<li><strong>بهینه سازی کوئری‌ها با Lazy Loading و Eager Loading:</strong> به طور پیش فرض، روابط به صورت تنبل بارگذاری می‌شوند. اما برای جلوگیری از مشکل معروف N+1 در واکشی داده‌ها، با استفاده از متد <code>with</code> می‌توان داده‌های مرتبط را به صورت Eager Loading و تنها با یک یا دو کوئری بهینه از دیتابیس دریافت کرد.</li>
<li><strong>سیستم مهاجرت دیتابیس (Migrations):</strong> مدیریت ساختار دیتابیس در تیم‌های توسعه اهمیت زیادی دارد. سیستم کامندلاین Yii2 امکان ساخت، اجرا و بازگردانی دیتابیس میگریشن‌ها را به راحتی فراهم می‌کند تا تغییرات دیتابیس همگام با کدهای برنامه پیش برود.</li>
</ul>
<h3 dir="rtl" lang="fa">امنیت پیش فرض و مدیریت دسترسی‌ها (RBAC)</h3>
<p dir="rtl" lang="fa">امنیت نرم افزار نباید به عنوان یک بخش الحاقی در انتهای پروژه در نظر گرفته شود. فریم ورک Yii2 امنیت را در تار و پود خود جای داده است:</p>
<ul dir="rtl" lang="fa">
<li><strong>جلوگیری از حملات رایج:</strong> سیستم اعتبارسنجی فرم‌ها به صورت خودکار توکن‌های CSRF تولید و بررسی می‌کند. همچنین، استفاده از معماری Active Record و PDO مانع از بروز حملات SQL Injection می‌شود. خروجی‌های سمت ویو نیز به طور پیش فرض انکود می‌شوند تا جلوی حملات XSS گرفته شود.</li>
<li><strong>کنترل دسترسی نقش‌محور (RBAC):</strong> مدیریت سطوح دسترسی کاربران در سیستم‌های سازمانی بسیار پیچیده است. Yii2 دارای یک کامپوننت داخلی و به شدت منعطف برای RBAC است که اجازه می‌دهد نقش‌ها (Roles)، قوانین (Rules) و مجوزها (Permissions) را تعریف کنید. این داده‌ها را می‌توان در فایل‌های متنی یا جداول پایگاه داده ذخیره و مدیریت کرد.</li>
</ul>
<h3 dir="rtl" lang="fa">کارایی، کشینگ و مدیریت صف (Queue)</h3>
<p dir="rtl" lang="fa">برای پروژه‌هایی که با ترافیک بالا مواجه هستند، کارایی پردازش اهمیت حیاتی دارد.</p>
<p dir="rtl" lang="fa">۱. <strong>مکانیزم‌های چندلایه کشینگ:</strong> Yii2 از انواع روش‌های کش شامل Data Caching، Fragment Caching (کش کردن بخش خاصی از قالب)، Page Caching (کش کامل صفحه) و HTTP Caching پشتیبانی می‌کند. سازگاری کامل با سیستم‌های ذخیره سازی پرسرعت مانند Redis و Memcached به صورت پیش فرض در تنظیمات فریم ورک تعبیه شده است.</p>
<p dir="rtl" lang="fa">۲. <strong>مدیریت کارهای پس زمینه با Yii2 Queue:</strong> برای جلوگیری از مسدود شدن درخواست‌های کاربر، کارهایی مانند ارسال ایمیل‌های انبوه، پردازش تصاویر یا تولید خروجی‌های سنگین باید به صف منتقل شوند. افزونه رسمی <code>yiisoft/yii2-queue</code> از درایورهای مختلفی مانند دیتابیس، Redis، RabbitMQ و Beanstalkd پشتیبانی می‌کند تا کارها به صورت غیرهمزمان در پس زمینه پردازش شوند.</p>
<h3 dir="rtl" lang="fa">توسعه API و تست پذیری</h3>
<p dir="rtl" lang="fa">امروزه بسیاری از پروژه‌ها به صورت جداگانه در سمت فرانت اند و بک اند توسعه می‌یابند. فریم ورک Yii2 ابزارهای قدرتمندی برای ساخت RESTful API ارائه می‌دهد:</p>
<ul dir="rtl" lang="fa">
<li><strong>پشتیبانی بومی از فرمت‌های خروجی:</strong> تنظیم پاسخ‌ها به صورت JSON یا XML تنها با چند خط تنظیمات ساده در کنترلر امکان پذیر است.</li>
<li><strong>مدیریت نرخ درخواست (Rate Limiting):</strong> برای جلوگیری از سوء استفاده از APIها، ویژگی Rate Limiting به راحتی با پیاده سازی اینترفیس RateLimitInterface روی مدل کاربر فعال می‌شود.</li>
<li><strong>تست نویسی:</strong> فریم ورک Yii2 به طور کامل با فریم ورک تست نویسی Codeception ادغام شده است. این موضوع به شما اجازه می‌دهد تا تست‌های واحد (Unit)، تست‌های عملکردی (Functional) و تست‌های پذیرش (Acceptance) را به راحتی بازنویسی و اجرا کنید.</li>
</ul>
<h3 dir="rtl" lang="fa">مقایسه کاربردی: Yii2 در برابر Laravel و Symfony</h3>
<p dir="rtl" lang="fa">برای انتخاب نهایی، مقایسه این فریم ورک با سایر رقبای بزرگ PHP به درک بهتر جایگاه آن کمک می‌کند:</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>معیار بررسی</th>
<th>فریم ورک Yii2</th>
<th>فریم ورک Laravel</th>
<th>فریم ورک Symfony</th>
</tr>
</thead>
<tbody>
<tr>
<td dir="rtl" lang="fa"><strong>عملکرد و سرعت (Throughput)</strong></td>
<td dir="rtl" lang="fa">بسیار بالا به دلیل ساختار سبک و Lazy Loading</td>
<td dir="rtl" lang="fa">متوسط (نیازمند بهینه سازی‌های متعدد)</td>
<td dir="rtl" lang="fa">بالا و پایدار در پروژه‌های بزرگ</td>
</tr>
<tr>
<td dir="rtl" lang="fa"><strong>سرعت توسعه اولیه</strong></td>
<td dir="rtl" lang="fa">بسیار سریع به لطف ابزار تولید کد Gii</td>
<td dir="rtl" lang="fa">سریع به دلیل ابزارهای آماده و اکوسیستم وسیع</td>
<td dir="rtl" lang="fa">متوسط به دلیل نیاز به پیکربندی‌های زیاد</td>
</tr>
<tr>
<td dir="rtl" lang="fa"><strong>سیستم مدیریت دسترسی</strong></td>
<td dir="rtl" lang="fa">دارای RBAC داخلی بسیار قدرتمند و منعطف</td>
<td dir="rtl" lang="fa">نیازمند پکیج‌های جانبی (مانند Spatie)</td>
<td dir="rtl" lang="fa">دارای سیستم امنیتی پیچیده و بسیار قوی</td>
</tr>
<tr>
<td dir="rtl" lang="fa"><strong>جامعه کاربری و اکوسیستم</strong></td>
<td dir="rtl" lang="fa">متوسط (بیشتر در فاز نگهداری و اصلاحات)</td>
<td dir="rtl" lang="fa">بسیار بزرگ و دارای پکیج‌های مدرن فراوان</td>
<td dir="rtl" lang="fa">بسیار بزرگ و تامین کننده کامپوننت‌های پایه</td>
</tr>
</tbody>
</table>
</div>
<p dir="rtl" lang="fa">از نظر چرخه پشتیبانی، هسته Yii2 در حال حاضر در فاز اصلاح باگ‌های امنیتی و حفظ سازگاری با نسخه‌های جدید PHP (مانند PHP 8.x) است و تمرکز تیم توسعه روی نسخه جدید یعنی Yii3 قرار دارد. در حالی که لاراول هر ساله نسخه‌های بزرگ جدیدی با ویژگی‌های نوین منتشر می‌کند. با این حال، پایداری کدهای نوشته شده با Yii2 و عدم نیاز به تغییرات مداوم به دلیل ارتقای نسخه‌ها، یک مزیت بزرگ برای پروژه‌های طولانی مدت تجاری محسوب می‌شود. برای بررسی ابزارها و پکیج‌های رسمی توسعه یافته، می‌توانید به مخزن پکیج‌های PHP در سایت <a href="https://packagist.org/" target="_blank" rel="nofollow noopener noreferrer">Packagist</a> مراجعه کنید.</p>
<h3 dir="rtl" lang="fa">نتیجه گیری و سناریوهای مناسب برای انتخاب Yii2</h3>
<p dir="rtl" lang="fa">فریم ورک Yii2 یک ابزار مهندسی شده، با ساختاری منظم و کارایی فوق العاده است. اگر پروژه شما ویژگی‌های زیر را دارد، Yii2 یک انتخاب کاملا منطقی و اقتصادی خواهد بود:</p>
<ul dir="rtl" lang="fa">
<li>پروژه‌هایی با ساختار داده‌ای پیچیده و جداول دیتابیس متعدد که نیاز به تولید سریع کدهای CRUD دارند.</li>
<li>سیستم‌های مدیریتی، پنل‌های سازمانی و اتوماسیون‌های اداری که امنیت بالا و مدیریت دسترسی‌های پیچیده (RBAC) از اولویت‌های اصلی آن‌ها است.</li>
<li>پروژه‌هایی که روی سرورهای اشتراکی یا با منابع محدود میزبانی می‌شوند و کارایی بالا همراه با مصرف کم حافظه در آن‌ها اهمیت دارد.</li>
</ul>
<p dir="rtl" lang="fa">در مقابل، اگر پروژه شما نیازمند استفاده مداوم از آخرین تکنولوژی‌ها و ابزارهای فرانت اند روز دنیا است و یا جامعه کاربری بسیار بزرگ برای حل چالش‌های روزمره اولویت اول شماست، ممکن است گزینه‌های دیگر انتخاب‌های مناسب تری باشند. با این حال، پایداری بی نظیر و سرعت اجرای فریم ورک Yii2 همچنان آن را به یکی از قابل اعتماد ترین ابزارهای توسعه وب تبدیل کرده است.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d8%b1%d8%a7%d9%87%d9%86%d9%85%d8%a7%db%8c-%d8%ac%d8%a7%d9%85%d8%b9-%d8%a7%d9%86%d8%aa%d8%ae%d8%a7%d8%a8-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%da%86%d8%b1%d8%a7-%d9%88-%da%86%da%af%d9%88%d9%86/">راهنمای جامع انتخاب فریم ورک: چرا و چگونه Yii2 را بررسی می‌کنیم؟</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d8%b1%d8%a7%d9%87%d9%86%d9%85%d8%a7%db%8c-%d8%ac%d8%a7%d9%85%d8%b9-%d8%a7%d9%86%d8%aa%d8%ae%d8%a7%d8%a8-%d9%81%d8%b1%db%8c%d9%85-%d9%88%d8%b1%da%a9-%da%86%d8%b1%d8%a7-%d9%88-%da%86%da%af%d9%88%d9%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>معرفی و جایگاه .NET 10 در اکوسیستم دات‌ نت و مقایسه آن با .Net 9</title>
		<link>https://tarahanenovin.ir/blog/%d9%85%d8%b9%d8%b1%d9%81%db%8c-%d9%88-%d8%ac%d8%a7%db%8c%da%af%d8%a7%d9%87-net-10-%d8%af%d8%b1-%d8%a7%da%a9%d9%88%d8%b3%db%8c%d8%b3%d8%aa%d9%85-%d8%af%d8%a7%d8%aa-%d9%86%d8%aa-%d9%88-%d9%85/</link>
					<comments>https://tarahanenovin.ir/blog/%d9%85%d8%b9%d8%b1%d9%81%db%8c-%d9%88-%d8%ac%d8%a7%db%8c%da%af%d8%a7%d9%87-net-10-%d8%af%d8%b1-%d8%a7%da%a9%d9%88%d8%b3%db%8c%d8%b3%d8%aa%d9%85-%d8%af%d8%a7%d8%aa-%d9%86%d8%aa-%d9%88-%d9%85/#respond</comments>
		
		<dc:creator><![CDATA[TNVN]]></dc:creator>
		<pubDate></pubDate>
				<category><![CDATA[اخبار و ترندها]]></category>
		<category><![CDATA[برنامه نویسی]]></category>
		<category><![CDATA[بک‌اند]]></category>
		<category><![CDATA[موبایل]]></category>
		<category><![CDATA[ویندوز]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[.net10]]></category>
		<category><![CDATA[.netCore]]></category>
		<category><![CDATA[asp]]></category>
		<category><![CDATA[dotNet]]></category>
		<category><![CDATA[dotNet10]]></category>
		<guid isPermaLink="false">https://tarahanenovin.ir/blog/?p=16</guid>

					<description><![CDATA[<p>معرفی و جایگاه .NET 10 در اکوسیستم دات‌ نت مایکروسافت طبق روال سالانه، پس از انتشار .NET 9 در نوامبر 2024، نسخهٔ بعدی یعنی .NET 10 را در نوامبر 2025 عرضه کرد. تفاوت مهم این دو نسخه در چرخهٔ پشتیبانی است: .NET 9 یک نسخهٔ STS (Standard Term Support) است؛ پشتیبانی آن تا حدود نوامبر 2026 ادامه دارد. .NET 10 یک نسخهٔ LTS (Long Term Support) است؛ پشتیبانی رسمی آن تا حدود نوامبر 2028 ادامه می‌یابد. از دید یک تیم توسعه حرفه‌ای، همین نکتهٔ LTS بودن .NET 10 به‌تنهایی آن را به گزینهٔ جدی‌تری برای پروژه‌های سازمانی، بلندمدت و محصولات تجاری تبدیل می‌کند. اما مزیت .NET 10 فقط در طول پشتیبانی نیست؛ تغییرات فنی در Runtime، کتابخانه‌ها، ASP.NET Core، Blazor، SDK/CLI و MAUI، مجموعه‌ای از بهبودهای عملی را نسبت به .NET 9 ارائه می‌دهند. مقایسه نسخه‌ها از نظر زبان و Runtime C# و نسخه زبان .NET 9 همراه با C# 13 عرضه شد؛ تمرکز روی ارتقای قابلیت‌های زبان، بهبود الگوها و استفاده راحت‌تر از ویژگی‌های جدید بود. .NET 10 با C# 14 همگام شده است؛ هرچند تغییرات زبان به‌صورت مستقل نسخه‌گذاری می‌شوند، اما عملاً .NET 10 بستری است که امکانات جدید زبان را بهتر پشتیبانی می‌کند. برای توسعه‌دهنده‌ای که روی معماری‌های مدرن، الگوهای پیشرفته و بهره‌گیری از ویژگی‌های جدید زبان تمرکز دارد، مهاجرت به .NET 10 فرصت استفاده از آخرین نسخهٔ C# را فراهم می‌کند. بهبودهای Runtime و JIT در .NET 10 نسبت به .NET 9 هر دو نسخه روی عملکرد Runtime و JIT تمرکز دارند، اما .NET 10 چند قدم جلوتر می‌رود: Escape Analysis پیشرفته‌تر در Previewهای .NET 10 (که بعدها در نسخه نهایی تثبیت شده‌اند) شاهد: تحلیل escape برای فیلدهای structهای لوکال، تحلیل escape برای delegateها، هستیم؛ هدف این است که تخصیص‌های غیرضروری روی heap کاهش یابد و فشار GC کم‌تر شود. بهبود inlining تصمیم‌گیری هوشمندتر برای inline شدن متدها، منجر به کاهش call overhead و بهبود عملکرد در مسیرهای داغ (hot paths) می‌شود. بهینه‌سازی‌های ARM64 و write barrier برای سناریوهایی که روی سرورهای ARM64 و محیط‌های cloud مدرن اجرا می‌شوند، .NET 10 نسبت به .NET 9 عملکرد پایدارتر و سریع‌تر ارائه می‌کند. جمع‌بندی: اگر پروژهٔ شما حساس به عملکرد، latency و مصرف منابع است (مثلاً میکروسرویس‌های high-throughput، APIهای پرترافیک، سرویس‌های real-time)، بهینه‌سازی‌های Runtime در .NET 10، نسبت به .NET 9 ارزش مهاجرت را دارد. تغییرات کتابخانه‌ها، امنیت و JSON در .NET 10 APIهای جدید و بهبودهای عملکردی در .NET 10، در سطح کتابخانه‌های BCL و System.* چند تغییر مهم دیده می‌شود: ZIP و GZip اضافه شدن APIهای asynchronous برای ZIP، بهبود عملکرد GZipStream روی streamهای به‌هم‌پیوسته، باعث می‌شود سناریوهای فشرده‌سازی و انتقال داده حجیم کاملاً مدرن و بهینه شوند. Tracing و Observability پشتیبانی از out-of-process tracing برای Activityها، sampling برای Rate Limiting traceها، کنترل بیشتری روی ردیابی رفتار سیستم و مانیتورینگ سرویس‌ها می‌دهد. امنیت و Post-Quantum Cryptography (PQC) یکی از نقاط برجستهٔ .NET 10 نسبت به .NET 9، تمرکز جدی‌تر روی امنیت و به‌ویژه رمزنگاری پساکوانتومی است: اضافه شدن پشتیبانی از الگوریتم‌ها و قابلیت‌های مرتبط با Post-Quantum Cryptography به معنی آماده‌تر بودن .NET 10 برای تهدیدات نسل بعدی است. در کاربردهای بانکی، مالی، سازمانی و دولتی که نگاه بلندمدت به امنیت دارند، این ویژگی یک مزیت استراتژیک محسوب می‌شود. JSON و کنترل‌های strict در .NET 10 مجموعه‌ای از بهبودها در System.Text.Json ارائه شده است: امکان جلوگیری از propertyهای تکراری در JSON، گزینه‌های strict mode برای JSON serialization و validation. برای سرویس‌هایی که با ورودی غیرمطمئن، کلاینت‌های متعدد یا APIهای عمومی کار می‌کنند، این امکانات امکان اعتبارسنجی سخت‌گیرانه‌تر و جلوگیری از سناریوهای مبهم و آسیب‌پذیر را فراهم می‌کند. در .NET 9 چنین سطح کنترلِ صریح و سخت‌گیرانه کمتر در دسترس بود. ASP.NET Core در .NET 10 در برابر .NET 9 تمرکز .NET 9 در .NET 9، ASP.NET Core بیشتر روی این حوزه‌ها متمرکز بود: توسعهٔ Minimal APIها و ارتقای تجربه کدنویسی، NativeAOT برای سناریوهای ASP.NET Core، بهبود تحویل static assets (MapStaticAssets)، قابلیت‌های جدید Blazor و مدل‌های تعاملی، برخی بهبودهای اولیه در OpenAPI. این نسخه عملاً پایه‌های معماری وب مدرن روی دات‌ نت را تثبیت کرد؛ مخصوصاً برای پروژه‌های جدید مبتنی بر Minimal API و NativeAOT. تمرکز .NET 10 در .NET 10، ASP.NET Core یک لایه بالغ‌تر و سازمانی‌تر روی همان زیرساخت می‌سازد: OpenAPI 3.1 کامل و استانداردتر تولید و پشتیبانی OpenAPI 3.1، استفاده از XML documentation برای تولید schemaها، پشتیبانی از IOpenApiDocumentProvider برای دسترسی به سندها، استانداردسازی مستندات API را به سطح حرفه‌ای‌تری می‌برد. Validation پیشرفته برای Minimal API پشتیبانی از validation روی record typeها، اتصال validation به IProblemDetailsService برای پاسخ‌های خطا استاندارد، باعث می‌شود APIهای شما از ابتدا با قراردادهای معتبر و مطابق best practice ساخته شوند. امنیت مدرن: Passkey در Identity پشتیبانی از passkey در ASP.NET Core Identity، سکیوریتی Auth و Login را به‌روزتر و همسو با استانداردهای مدرن وب می‌کند. JSON Patch با System.Text.Json امکان استفاده از JSON Patch بدون وابستگی به Newtonsoft.Json، اکوسیستم را یکپارچه‌تر و عملکرد را بهتر می‌کند. به‌طور کلی، اگر در .NET 9 زیرساخت اصلی را ساختید، در .NET 10 بیشتر روی استانداردسازی، امنیت، observability و تست‌پذیری تمرکز می‌کنید. Blazor: از تجربه توسعه تا عملیات و Diagnostics Blazor در .NET 9 .NET 9 برای Blazor محوریت را روی: unified rendering، تعامل‌پذیری، prerendering، تجربه full-stack، گذاشت. یعنی تمرکز بیشتر بر مدل برنامه‌نویسی و تجربه توسعه‌دهنده بود. Blazor در .NET 10 در .NET 10، نگاه عملیاتی و production-ready غالب است: Runtime diagnostics برای Blazor WebAssemblyامکان مشاهده رفتار اپلیکیشن در اجرا و مانیتورینگ بهتر را فراهم می‌کند. Tracing و metrics بهبود یافتهبرای سناریوهای جدی‌تر در observability. Preload assetهای framework در WebAssemblyبهبود سرعت بارگذاری اولیه اپلیکیشن. بهبود navigation و NotFoundپشتیبانی بهتر از صفحه‌های Not Found و متد NavigationManager.NotFound(). سازگاری بهتر خروجی build با JavaScript bundlerهاادغام با زنجیره‌های مدرن فرانت‌اند راحت‌تر می‌شود. نتیجه عملی این است که Blazor در .NET 10 بیش از گذشته برای استقرار جدی، مانیتورینگ و نگه‌داری در محیط‌های production آماده است، در حالی که .NET 9 بیشتر بر تجربه توسعه و مدل جدید رندر تمرکز داشت. SDK و CLI: ابزارهای توسعه در .NET 10 در .NET 10، SDK و CLI تعدادی قابلیت مهم جدید ارائه می‌کنند: Platform-specific .NET toolsامکان تعریف و اجرای ابزارهایی که به پلتفرم خاص وابسته‌اند. اجرای one-shot ابزارهااجرای سریع و کوتاه‌مدت ابزارها و اسکریپت‌ها بدون نیاز به نصب دائمی. ابزار اسکریپتی جدید dnxتسهیل اجرای سناریوهای اسکریپتی و فایل‌محور. گزینهٔ --cli-schema برای introspectionامکان بررسی و تحلیل ساختار CLI برای ابزارسازی و automation. نسبت به .NET 9، این امکانات برای تیم‌هایی که روی DevOps، automation، اسکریپت‌نویسی و ساخت ابزارهای داخلی کار می‌کنند، تفاوت محسوسی ایجاد می‌کند. .NET MAUI: تجربه اپلیکیشن کراس‌پلتفرم MAUI در .NET 9 .NET 9 برای MAUI بیش از هر چیز روی: full trimming، NativeAOT برای iOS، Mac Catalyst و Windows، تمرکز داشت؛ اما NativeAOT در آن زمان برای Android کامل نبود. تمرکز اصلی روی بهبود عملکرد و کاهش حجم خروجی بود. MAUI در .NET 10 در .NET 10، علاوه بر ادامه بهبود عملکرد و کیفیت، ویژگی‌های زیر دیده می‌شود: مدرن‌سازی MediaPicker, nullable pickerها (بهبود مدل داده و راحتی توسعه), XAML global و implicit namespaces برای نظم بهتر در XAML، امکان intercept کردن web requestها، بهبودهای build و کیفیت برای Android و پلتفرم‌های Apple. این تغییرات، تجربه توسعه، نگه‌داری و عملکرد اپلیکیشن‌های کراس‌پلتفرم را نسبت به .NET 9 بالغ‌تر می‌کند. جمع‌بندی: چه زمانی از .NET 9 به .NET 10 مهاجرت کنیم؟ مزیت‌های کلیدی .NET 10 نسبت به .NET 9 چرخه پشتیبانی بلندمدت (LTS) تا حدود 2028، مناسب پروژه‌های سازمانی. Runtime و JIT سریع‌تر و هوشمندتر برای سناریوهای با بار بالا. امنیت پیشرفته‌تر با Post-Quantum Cryptography و کنترل‌های strict در JSON. ASP.NET Core بالغ‌تر با OpenAPI 3.1، validation استاندارد، Passkey، JSON Patch روی System.Text.Json. Blazor production-ready‌تر با diagnostics، tracing و سازگاری بهتر با bundlerها. SDK/CLI و ابزارهای جدید برای automation و اجرای اسکریپت‌ها. MAUI مدرن‌تر با XAML بهینه، media و شبکه بهتر و بهبودهای build. اگر الان روی .NET 9 هستید اجبار فوری برای مهاجرت وجود ندارد؛ .NET 9 تا نوامبر 2026 پشتیبانی می‌شود. اما اگر: API عمومی و مستندات OpenAPI جدی دارید، نیاز به کنترل امنیتی سخت‌گیرانه و JSON strict دارید، روی Blazor، MAUI یا میکروسرویس‌های high-throughput کار می‌کنید، یا پروژه شما horizon زمانی فراتر از 2026 دارد، مهاجرت به .NET 10 منطقی و از نظر فنی و استراتژیک قابل دفاع است. برای پروژه‌های جدید برای هر پروژه جدید که امروز طراحی می‌شود، انتخاب .NET 10 به دلیل LTS بودن و امکانات فنی جدید، گزینهٔ استاندارد و توصیه‌شده است.</p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d9%85%d8%b9%d8%b1%d9%81%db%8c-%d9%88-%d8%ac%d8%a7%db%8c%da%af%d8%a7%d9%87-net-10-%d8%af%d8%b1-%d8%a7%da%a9%d9%88%d8%b3%db%8c%d8%b3%d8%aa%d9%85-%d8%af%d8%a7%d8%aa-%d9%86%d8%aa-%d9%88-%d9%85/">معرفی و جایگاه .NET 10 در اکوسیستم دات‌ نت و مقایسه آن با .Net 9</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></description>
										<content:encoded><![CDATA[<h2 dir="rtl" lang="fa">معرفی و جایگاه .NET 10 در اکوسیستم دات‌ نت</h2>
<p dir="rtl" lang="fa">مایکروسافت طبق روال سالانه، پس از انتشار .NET 9 در نوامبر 2024، نسخهٔ بعدی یعنی .NET 10 را در نوامبر 2025 عرضه کرد. تفاوت مهم این دو نسخه در چرخهٔ پشتیبانی است:</p>
<ul dir="rtl" lang="fa">
<li><strong>.NET 9</strong> یک نسخهٔ <strong>STS</strong> (Standard Term Support) است؛ پشتیبانی آن تا حدود نوامبر 2026 ادامه دارد.</li>
<li><strong>.NET 10</strong> یک نسخهٔ <strong>LTS</strong> (Long Term Support) است؛ پشتیبانی رسمی آن تا حدود نوامبر 2028 ادامه می‌یابد.</li>
</ul>
<p dir="rtl" lang="fa">از دید یک تیم توسعه حرفه‌ای، همین نکتهٔ LTS بودن .NET 10 به‌تنهایی آن را به گزینهٔ جدی‌تری برای پروژه‌های سازمانی، بلندمدت و محصولات تجاری تبدیل می‌کند. اما مزیت .NET 10 فقط در طول پشتیبانی نیست؛ تغییرات فنی در Runtime، کتابخانه‌ها، <a href="http://ASP.NET" target="_blank" rel="nofollow noopener noreferrer">ASP.NET</a> Core، Blazor، SDK/CLI و MAUI، مجموعه‌ای از بهبودهای عملی را نسبت به .NET 9 ارائه می‌دهند.</p>
<h2 dir="rtl" lang="fa">مقایسه نسخه‌ها از نظر زبان و Runtime</h2>
<h3 dir="rtl" lang="fa">C# و نسخه زبان</h3>
<ul dir="rtl" lang="fa">
<li><strong>.NET 9</strong> همراه با <strong>C# 13</strong> عرضه شد؛ تمرکز روی ارتقای قابلیت‌های زبان، بهبود الگوها و استفاده راحت‌تر از ویژگی‌های جدید بود.</li>
<li><strong>.NET 10</strong> با <strong>C# 14</strong> همگام شده است؛ هرچند تغییرات زبان به‌صورت مستقل نسخه‌گذاری می‌شوند، اما عملاً .NET 10 بستری است که امکانات جدید زبان را بهتر پشتیبانی می‌کند.</li>
</ul>
<p dir="rtl" lang="fa">برای توسعه‌دهنده‌ای که روی معماری‌های مدرن، الگوهای پیشرفته و بهره‌گیری از ویژگی‌های جدید زبان تمرکز دارد، مهاجرت به .NET 10 فرصت استفاده از آخرین نسخهٔ C# را فراهم می‌کند.</p>
<h3 dir="rtl" lang="fa">بهبودهای Runtime و JIT در .NET 10 نسبت به .NET 9</h3>
<p dir="rtl" lang="fa">هر دو نسخه روی عملکرد Runtime و JIT تمرکز دارند، اما .NET 10 چند قدم جلوتر می‌رود:</p>
<ul dir="rtl" lang="fa">
<li>
<p dir="rtl" lang="fa"><strong>Escape Analysis پیشرفته‌تر</strong></p>
<p dir="rtl" lang="fa">در Previewهای .NET 10 (که بعدها در نسخه نهایی تثبیت شده‌اند) شاهد:</p>
<ul dir="rtl" lang="fa">
<li>تحلیل escape برای فیلدهای structهای لوکال،</li>
<li>تحلیل escape برای delegateها،</li>
</ul>
<p dir="rtl" lang="fa">هستیم؛ هدف این است که تخصیص‌های غیرضروری روی heap کاهش یابد و فشار GC کم‌تر شود.</p>
</li>
<li>
<p dir="rtl" lang="fa"><strong>بهبود inlining</strong></p>
<p dir="rtl" lang="fa">تصمیم‌گیری هوشمندتر برای inline شدن متدها، منجر به کاهش call overhead و بهبود عملکرد در مسیرهای داغ (hot paths) می‌شود.</p>
</li>
<li>
<p dir="rtl" lang="fa"><strong>بهینه‌سازی‌های ARM64 و write barrier</strong></p>
<p dir="rtl" lang="fa">برای سناریوهایی که روی سرورهای ARM64 و محیط‌های cloud مدرن اجرا می‌شوند، .NET 10 نسبت به .NET 9 عملکرد پایدارتر و سریع‌تر ارائه می‌کند.</p>
</li>
</ul>
<p dir="rtl" lang="fa"><strong>جمع‌بندی:</strong> اگر پروژهٔ شما حساس به عملکرد، latency و مصرف منابع است (مثلاً میکروسرویس‌های high-throughput، APIهای پرترافیک، سرویس‌های real-time)، بهینه‌سازی‌های Runtime در .NET 10، نسبت به .NET 9 ارزش مهاجرت را دارد.</p>
<h2 dir="rtl" lang="fa">تغییرات کتابخانه‌ها، امنیت و JSON در .NET 10</h2>
<h3 dir="rtl" lang="fa">APIهای جدید و بهبودهای عملکردی</h3>
<p dir="rtl" lang="fa">در .NET 10، در سطح کتابخانه‌های BCL و System.* چند تغییر مهم دیده می‌شود:</p>
<ul lang="en">
<li>
<p lang="en"><strong>ZIP و GZip</strong></p>
<ul dir="rtl" lang="fa">
<li>اضافه شدن APIهای asynchronous برای ZIP،</li>
<li>بهبود عملکرد <code>GZipStream</code> روی streamهای به‌هم‌پیوسته،</li>
</ul>
<p dir="rtl" lang="fa">باعث می‌شود سناریوهای فشرده‌سازی و انتقال داده حجیم کاملاً مدرن و بهینه شوند.</p>
</li>
<li>
<p lang="en"><strong>Tracing و Observability</strong></p>
<ul dir="rtl" lang="fa">
<li>پشتیبانی از out-of-process tracing برای Activityها،</li>
<li>sampling برای Rate Limiting traceها،</li>
</ul>
<p dir="rtl" lang="fa">کنترل بیشتری روی ردیابی رفتار سیستم و مانیتورینگ سرویس‌ها می‌دهد.</p>
</li>
</ul>
<h3 dir="rtl" lang="fa">امنیت و Post-Quantum Cryptography (PQC)</h3>
<p dir="rtl" lang="fa">یکی از نقاط برجستهٔ .NET 10 نسبت به .NET 9، تمرکز جدی‌تر روی امنیت و به‌ویژه <strong>رمزنگاری پساکوانتومی</strong> است:</p>
<ul dir="rtl" lang="fa">
<li>اضافه شدن پشتیبانی از الگوریتم‌ها و قابلیت‌های مرتبط با <strong>Post-Quantum Cryptography</strong> به معنی آماده‌تر بودن .NET 10 برای تهدیدات نسل بعدی است.</li>
<li>در کاربردهای بانکی، مالی، سازمانی و دولتی که نگاه بلندمدت به امنیت دارند، این ویژگی یک مزیت استراتژیک محسوب می‌شود.</li>
</ul>
<h3 dir="rtl" lang="fa">JSON و کنترل‌های strict</h3>
<p dir="rtl" lang="fa">در .NET 10 مجموعه‌ای از بهبودها در <code>System.Text.Json</code> ارائه شده است:</p>
<ul dir="rtl" lang="fa">
<li>امکان جلوگیری از <strong>propertyهای تکراری</strong> در JSON،</li>
<li>گزینه‌های <strong>strict mode</strong> برای JSON serialization و validation.</li>
</ul>
<p dir="rtl" lang="fa">برای سرویس‌هایی که با ورودی غیرمطمئن، کلاینت‌های متعدد یا APIهای عمومی کار می‌کنند، این امکانات امکان اعتبارسنجی سخت‌گیرانه‌تر و جلوگیری از سناریوهای مبهم و آسیب‌پذیر را فراهم می‌کند. در .NET 9 چنین سطح کنترلِ صریح و سخت‌گیرانه کمتر در دسترس بود.</p>
<h2 dir="rtl" lang="fa"><a href="http://ASP.NET" target="_blank" rel="nofollow noopener noreferrer">ASP.NET</a> Core در .NET 10 در برابر .NET 9</h2>
<h3 dir="rtl" lang="fa">تمرکز .NET 9</h3>
<p dir="rtl" lang="fa">در .NET 9، <a href="http://ASP.NET" target="_blank" rel="nofollow noopener noreferrer">ASP.NET</a> Core بیشتر روی این حوزه‌ها متمرکز بود:</p>
<ul dir="rtl" lang="fa">
<li>توسعهٔ <strong>Minimal API</strong>ها و ارتقای تجربه کدنویسی،</li>
<li><strong>NativeAOT</strong> برای سناریوهای <a href="http://ASP.NET" target="_blank" rel="nofollow noopener noreferrer">ASP.NET</a> Core،</li>
<li>بهبود تحویل static assets (<code>MapStaticAssets</code>)،</li>
<li>قابلیت‌های جدید Blazor و مدل‌های تعاملی،</li>
<li>برخی بهبودهای اولیه در OpenAPI.</li>
</ul>
<p dir="rtl" lang="fa">این نسخه عملاً پایه‌های معماری وب مدرن روی دات‌ نت را تثبیت کرد؛ مخصوصاً برای پروژه‌های جدید مبتنی بر Minimal API و NativeAOT.</p>
<h3 dir="rtl" lang="fa">تمرکز .NET 10</h3>
<p dir="rtl" lang="fa">در .NET 10، <a href="http://ASP.NET" target="_blank" rel="nofollow noopener noreferrer">ASP.NET</a> Core یک لایه بالغ‌تر و سازمانی‌تر روی همان زیرساخت می‌سازد:</p>
<ul dir="rtl" lang="fa">
<li>
<p dir="rtl" lang="fa"><strong>OpenAPI 3.1 کامل و استانداردتر</strong></p>
<ul dir="rtl" lang="fa">
<li>تولید و پشتیبانی OpenAPI 3.1،</li>
<li>استفاده از XML documentation برای تولید schemaها،</li>
<li>پشتیبانی از <code>IOpenApiDocumentProvider</code> برای دسترسی به سندها،</li>
</ul>
<p dir="rtl" lang="fa">استانداردسازی مستندات API را به سطح حرفه‌ای‌تری می‌برد.</p>
</li>
<li>
<p dir="rtl" lang="fa"><strong>Validation پیشرفته برای Minimal API</strong></p>
<ul dir="rtl" lang="fa">
<li>پشتیبانی از validation روی record typeها،</li>
<li>اتصال validation به <code>IProblemDetailsService</code> برای پاسخ‌های خطا استاندارد،</li>
</ul>
<p dir="rtl" lang="fa">باعث می‌شود APIهای شما از ابتدا با قراردادهای معتبر و مطابق best practice ساخته شوند.</p>
</li>
<li>
<p dir="rtl" lang="fa"><strong>امنیت مدرن: Passkey در Identity</strong></p>
<p dir="rtl" lang="fa">پشتیبانی از <strong>passkey</strong> در <a href="http://ASP.NET" target="_blank" rel="nofollow noopener noreferrer">ASP.NET</a> Core Identity، سکیوریتی Auth و Login را به‌روزتر و همسو با استانداردهای مدرن وب می‌کند.</p>
</li>
<li>
<p lang="en"><strong>JSON Patch با System.Text.Json</strong></p>
<p dir="rtl" lang="fa">امکان استفاده از JSON Patch بدون وابستگی به Newtonsoft.Json، اکوسیستم را یکپارچه‌تر و عملکرد را بهتر می‌کند.</p>
</li>
</ul>
<p dir="rtl" lang="fa">به‌طور کلی، اگر در .NET 9 زیرساخت اصلی را ساختید، در .NET 10 بیشتر روی استانداردسازی، امنیت، observability و تست‌پذیری تمرکز می‌کنید.</p>
<h2 dir="rtl" lang="fa">Blazor: از تجربه توسعه تا عملیات و Diagnostics</h2>
<h3 lang="en">Blazor در .NET 9</h3>
<p dir="rtl" lang="fa">.NET 9 برای Blazor محوریت را روی:</p>
<ul lang="en">
<li>unified rendering،</li>
<li>تعامل‌پذیری،</li>
<li>prerendering،</li>
<li>تجربه full-stack،</li>
</ul>
<p dir="rtl" lang="fa">گذاشت. یعنی تمرکز بیشتر بر مدل برنامه‌نویسی و تجربه توسعه‌دهنده بود.</p>
<h3 lang="en">Blazor در .NET 10</h3>
<p dir="rtl" lang="fa">در .NET 10، نگاه عملیاتی و production-ready غالب است:</p>
<ul lang="en">
<li><strong>Runtime diagnostics برای Blazor WebAssembly</strong>امکان مشاهده رفتار اپلیکیشن در اجرا و مانیتورینگ بهتر را فراهم می‌کند.</li>
<li><strong>Tracing و metrics بهبود یافته</strong>برای سناریوهای جدی‌تر در observability.</li>
<li><strong>Preload assetهای framework در WebAssembly</strong>بهبود سرعت بارگذاری اولیه اپلیکیشن.</li>
<li><strong>بهبود navigation و NotFound</strong>پشتیبانی بهتر از صفحه‌های Not Found و متد <code>NavigationManager.NotFound()</code>.</li>
<li><strong>سازگاری بهتر خروجی build با JavaScript bundlerها</strong>ادغام با زنجیره‌های مدرن فرانت‌اند راحت‌تر می‌شود.</li>
</ul>
<p dir="rtl" lang="fa">نتیجه عملی این است که Blazor در .NET 10 بیش از گذشته برای استقرار جدی، مانیتورینگ و نگه‌داری در محیط‌های production آماده است، در حالی که .NET 9 بیشتر بر تجربه توسعه و مدل جدید رندر تمرکز داشت.</p>
<h2 dir="rtl" lang="fa">SDK و CLI: ابزارهای توسعه در .NET 10</h2>
<p dir="rtl" lang="fa">در .NET 10، SDK و CLI تعدادی قابلیت مهم جدید ارائه می‌کنند:</p>
<ul lang="en">
<li><strong>Platform-specific .NET tools</strong>امکان تعریف و اجرای ابزارهایی که به پلتفرم خاص وابسته‌اند.</li>
<li><strong>اجرای one-shot ابزارها</strong>اجرای سریع و کوتاه‌مدت ابزارها و اسکریپت‌ها بدون نیاز به نصب دائمی.</li>
<li><strong>ابزار اسکریپتی جدید <code>dnx</code></strong>تسهیل اجرای سناریوهای اسکریپتی و فایل‌محور.</li>
<li><strong>گزینهٔ <code>--cli-schema</code> برای introspection</strong>امکان بررسی و تحلیل ساختار CLI برای ابزارسازی و automation.</li>
</ul>
<p dir="rtl" lang="fa">نسبت به .NET 9، این امکانات برای تیم‌هایی که روی DevOps، automation، اسکریپت‌نویسی و ساخت ابزارهای داخلی کار می‌کنند، تفاوت محسوسی ایجاد می‌کند.</p>
<h2 dir="rtl" lang="fa">.NET MAUI: تجربه اپلیکیشن کراس‌پلتفرم</h2>
<h3 lang="en">MAUI در .NET 9</h3>
<p dir="rtl" lang="fa">.NET 9 برای MAUI بیش از هر چیز روی:</p>
<ul lang="en">
<li><strong>full trimming</strong>،</li>
<li><strong>NativeAOT</strong> برای iOS، Mac Catalyst و Windows،</li>
</ul>
<p dir="rtl" lang="fa">تمرکز داشت؛ اما NativeAOT در آن زمان برای Android کامل نبود. تمرکز اصلی روی بهبود عملکرد و کاهش حجم خروجی بود.</p>
<h3 lang="en">MAUI در .NET 10</h3>
<p dir="rtl" lang="fa">در .NET 10، علاوه بر ادامه بهبود عملکرد و کیفیت، ویژگی‌های زیر دیده می‌شود:</p>
<ul dir="rtl" lang="fa">
<li>مدرن‌سازی <code>MediaPicker</code>,</li>
<li>nullable pickerها (بهبود مدل داده و راحتی توسعه),</li>
<li><strong>XAML global و implicit namespaces</strong> برای نظم بهتر در XAML،</li>
<li>امکان intercept کردن web requestها،</li>
<li>بهبودهای build و کیفیت برای Android و پلتفرم‌های Apple.</li>
</ul>
<p dir="rtl" lang="fa">این تغییرات، تجربه توسعه، نگه‌داری و عملکرد اپلیکیشن‌های کراس‌پلتفرم را نسبت به .NET 9 بالغ‌تر می‌کند.</p>
<hr />
<h2 dir="rtl" lang="fa">جمع‌بندی: چه زمانی از .NET 9 به .NET 10 مهاجرت کنیم؟</h2>
<h3 dir="rtl" lang="fa">مزیت‌های کلیدی .NET 10 نسبت به .NET 9</h3>
<ol dir="rtl" lang="fa">
<li><strong>چرخه پشتیبانی بلندمدت (LTS)</strong> تا حدود 2028، مناسب پروژه‌های سازمانی.</li>
<li><strong>Runtime و JIT سریع‌تر و هوشمندتر</strong> برای سناریوهای با بار بالا.</li>
<li><strong>امنیت پیشرفته‌تر</strong> با Post-Quantum Cryptography و کنترل‌های strict در JSON.</li>
<li><strong><a href="http://ASP.NET" target="_blank" rel="nofollow noopener noreferrer">ASP.NET</a> Core بالغ‌تر</strong> با OpenAPI 3.1، validation استاندارد، Passkey، JSON Patch روی System.Text.Json.</li>
<li><strong>Blazor production-ready‌تر</strong> با diagnostics، tracing و سازگاری بهتر با bundlerها.</li>
<li><strong>SDK/CLI و ابزارهای جدید</strong> برای automation و اجرای اسکریپت‌ها.</li>
<li><strong>MAUI مدرن‌تر</strong> با XAML بهینه، media و شبکه بهتر و بهبودهای build.</li>
</ol>
<h3 dir="rtl" lang="fa">اگر الان روی .NET 9 هستید</h3>
<ul dir="rtl" lang="fa">
<li>
<p dir="rtl" lang="fa"><strong>اجبار فوری برای مهاجرت وجود ندارد</strong>؛ .NET 9 تا نوامبر 2026 پشتیبانی می‌شود.</p>
</li>
<li>
<p dir="rtl" lang="fa"><strong>اما</strong> اگر:</p>
<ul dir="rtl" lang="fa">
<li>API عمومی و مستندات OpenAPI جدی دارید،</li>
<li>نیاز به کنترل امنیتی سخت‌گیرانه و JSON strict دارید،</li>
<li>روی Blazor، MAUI یا میکروسرویس‌های high-throughput کار می‌کنید،</li>
<li>یا پروژه شما horizon زمانی فراتر از 2026 دارد،</li>
</ul>
<p dir="rtl" lang="fa">مهاجرت به <strong>.NET 10</strong> منطقی و از نظر فنی و استراتژیک قابل دفاع است.</p>
</li>
</ul>
<h3 dir="rtl" lang="fa">برای پروژه‌های جدید</h3>
<p dir="rtl" lang="fa">برای هر پروژه جدید که امروز طراحی می‌شود، <strong>انتخاب .NET 10 به دلیل LTS بودن و امکانات فنی جدید، گزینهٔ استاندارد و توصیه‌شده است.</strong></p>
<p>نوشته <a href="https://tarahanenovin.ir/blog/%d9%85%d8%b9%d8%b1%d9%81%db%8c-%d9%88-%d8%ac%d8%a7%db%8c%da%af%d8%a7%d9%87-net-10-%d8%af%d8%b1-%d8%a7%da%a9%d9%88%d8%b3%db%8c%d8%b3%d8%aa%d9%85-%d8%af%d8%a7%d8%aa-%d9%86%d8%aa-%d9%88-%d9%85/">معرفی و جایگاه .NET 10 در اکوسیستم دات‌ نت و مقایسه آن با .Net 9</a> اولین بار در <a href="https://tarahanenovin.ir/blog">نوین هاب</a>. پدیدار شد.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tarahanenovin.ir/blog/%d9%85%d8%b9%d8%b1%d9%81%db%8c-%d9%88-%d8%ac%d8%a7%db%8c%da%af%d8%a7%d9%87-net-10-%d8%af%d8%b1-%d8%a7%da%a9%d9%88%d8%b3%db%8c%d8%b3%d8%aa%d9%85-%d8%af%d8%a7%d8%aa-%d9%86%d8%aa-%d9%88-%d9%85/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
